#!/usr/bin/env node /** * Verify Goose v1.49 local run profile keeps Memory on legacy owner (Phase 1 gate). */ import { readFileSync, existsSync } from 'node:fs'; import path from 'node:path'; import { fileURLToPath } from 'node:url'; import { describeGooseCanaryConfig, prepareGooseV149CheckEnv } from './goose-v149-canary.mjs'; const root = path.join(path.dirname(fileURLToPath(import.meta.url)), '..'); prepareGooseV149CheckEnv(process.env, root); const REQUIRED_MEMORY = { MEMORY_BACKEND: 'legacy', MEMORY_VECTOR_ENABLED: '0', MEMORY_AGENT_INJECTION_MODE: 'off', MEMORY_LIFECYCLE_ENABLED: '0', MEMORY_CANDIDATE_ENABLED: '0', }; function readText(relativePath) { const fullPath = path.join(root, relativePath); if (!existsSync(fullPath)) return ''; return readFileSync(fullPath, 'utf8'); } function parseEnvBlock(text) { const env = {}; for (const line of text.split('\n')) { const trimmed = line.trim(); if (!trimmed || trimmed.startsWith('#')) continue; const eq = trimmed.indexOf('='); if (eq < 0) continue; env[trimmed.slice(0, eq).trim()] = trimmed.slice(eq + 1).trim(); } return env; } function checkMemoryEnv(label, env) { const failures = []; for (const [key, expected] of Object.entries(REQUIRED_MEMORY)) { const actual = String(env[key] ?? '').trim(); if (actual !== expected) { failures.push(`${label}.${key}=${actual || '(unset)'} expected ${expected}`); } } return failures; } function main() { const failures = []; const runScript = readText('scripts/run-goosed-v149-local.sh'); for (const [key, expected] of Object.entries(REQUIRED_MEMORY)) { const pattern = new RegExp(`${key}=["']?\\$\\{${key}:-${expected}\\}["']?`); if (!pattern.test(runScript)) { failures.push(`run-goosed-v149-local.sh missing default ${key}=${expected}`); } } const switchScript = readText('scripts/switch-goose-v149-canary.sh'); for (const key of Object.keys(REQUIRED_MEMORY)) { if (!switchScript.includes(key)) { failures.push(`switch-goose-v149-canary.sh missing ${key} in canary block`); } } const canaryEnabled = String(process.env.TKMIND_GOOSE_CANARY ?? 'off').trim().toLowerCase() !== 'off'; if (canaryEnabled) { failures.push(...checkMemoryEnv('process.env', process.env)); } const canarySummary = describeGooseCanaryConfig(process.env); if (canarySummary.enabled && canarySummary.mode === 'all') { if (!String(canarySummary.primary).includes(':18049')) { failures.push(`canary primary must be v149 loopback, got ${canarySummary.primary}`); } } if (failures.length) { console.error('GOOSE_V149_MEMORY_POLICY_FAIL:'); for (const item of failures) console.error(` - ${item}`); process.exit(1); } console.log('GOOSE_V149_MEMORY_POLICY_OK: legacy owner enforced for v1.49 local/canary profile'); } main();