feat(goose): add local v1.49 canary routing, smoke gates, and migration docs
Wire Portal and TKMind proxy to loopback Goose v1.49 via canary env blocks, with verification scripts, Phase 2/3 evidence baselines, and rollback runbooks so local upgrade stays isolated from stable 1.41 and production. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,76 @@
|
||||
#!/usr/bin/env node
|
||||
/**
|
||||
* Phase 2 orchestrator: cost / memory drift / portal canary verification.
|
||||
*/
|
||||
import { spawnSync } from 'node:child_process';
|
||||
import path from 'node:path';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
|
||||
const root = path.join(path.dirname(fileURLToPath(import.meta.url)), '..');
|
||||
|
||||
const checks = [
|
||||
{ name: 'phase1-all', script: 'check-goosed-v149-all.mjs', required: true },
|
||||
{ name: 'cost-smoke', script: 'check-goosed-v149-cost-smoke.mjs', required: false },
|
||||
{ name: 'memory-drift', script: 'compare-goose-v149-memory-manifest.mjs', required: true },
|
||||
{ name: 'memory-failopen', script: 'check-goosed-v149-memory-failopen.mjs', required: true },
|
||||
{ name: 'web-smoke', script: 'check-goosed-v149-web-smoke.mjs', required: true },
|
||||
{ name: 'skills-smoke', script: 'check-goosed-v149-skills-smoke.mjs', required: true },
|
||||
{
|
||||
name: 'deepseek-tools',
|
||||
script: 'check-goosed-v149-deepseek-tools.mjs',
|
||||
required: false,
|
||||
},
|
||||
{
|
||||
name: 'thinking-preservation',
|
||||
script: 'check-goosed-v149-thinking-preservation.mjs',
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
name: 'message-sanitize',
|
||||
script: 'compare-goose-v149-message-sanitize.mjs',
|
||||
required: true,
|
||||
},
|
||||
{ name: 'canary-portal', script: 'check-goosed-v149-canary-portal.mjs', required: true },
|
||||
{ name: 'portal-smoke', script: 'check-goosed-v149-portal-smoke.mjs', required: false },
|
||||
];
|
||||
|
||||
function run(script, extraEnv = {}) {
|
||||
const result = spawnSync(process.execPath, [path.join(root, 'scripts', script)], {
|
||||
cwd: root,
|
||||
env: { ...process.env, ...extraEnv },
|
||||
encoding: 'utf8',
|
||||
});
|
||||
return {
|
||||
ok: result.status === 0,
|
||||
status: result.status,
|
||||
stdout: result.stdout?.trim() ?? '',
|
||||
stderr: result.stderr?.trim() ?? '',
|
||||
};
|
||||
}
|
||||
|
||||
const results = [];
|
||||
|
||||
for (const check of checks) {
|
||||
const item = { ...check, ...run(check.script) };
|
||||
results.push(item);
|
||||
const label = check.required ? 'required' : 'optional';
|
||||
console.log(`[goose-v149-phase2] ${item.ok ? 'OK' : 'FAIL'} (${label}) ${check.name}`);
|
||||
if (item.stdout) console.log(item.stdout);
|
||||
if (!item.ok && item.stderr) console.error(item.stderr);
|
||||
}
|
||||
|
||||
const failedRequired = results.filter((item) => item.required && !item.ok);
|
||||
const failedOptional = results.filter((item) => !item.required && !item.ok);
|
||||
|
||||
if (failedRequired.length) {
|
||||
console.error(`GOOSE_V149_PHASE2_FAIL: ${failedRequired.map((item) => item.name).join(', ')}`);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
if (failedOptional.length) {
|
||||
console.log(
|
||||
`GOOSE_V149_PHASE2_OK_WITH_SKIPS: ${failedOptional.map((item) => item.name).join(', ')}`,
|
||||
);
|
||||
} else {
|
||||
console.log('GOOSE_V149_PHASE2_OK');
|
||||
}
|
||||
Reference in New Issue
Block a user