Files
gstack/scripts/capture-baseline.ts
T
Garry TanandClaude Fable 5 0d1544c2db test: rebase parity baseline to v1.64.0.0; fix capture-vs-check drift
The parity ratchet had quietly failed for 7 skills — v1.58-v1.64 growth
landed past the v1.57.7.0 anchors and nothing caught it because this
test had no CI lane (verified pre-existing: SKILL.md content is
byte-identical to origin/main). Same rebase protocol as
v1.53->v1.57.7.0; old baseline retained for the audit trail.

Root-caused a second latent bug while rebasing: captureBaseline recorded
SKELETON-ONLY bytes while the checker compares UNION bytes (skeleton +
carved sections/*.md), so a fresh capture read carved skills at ~2x
ratio (ship: 82KB captured vs 183KB checked). captureBaseline now takes
sectionedSkills and records unions for carved skills — capture and check
measure the same thing, so the NEXT rebase can't hit this. Four
CARVE_GUARDS skeleton caps re-ratcheted to current +headroom
(plan-ceo 92K, plan-eng 70K, office-hours 100K, design-consultation
70K), annotated inline.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-15 08:43:22 -07:00

62 lines
2.2 KiB
TypeScript

#!/usr/bin/env bun
/**
* CLI for capturing a parity baseline snapshot.
*
* Usage:
* bun run scripts/capture-baseline.ts # default path
* bun run scripts/capture-baseline.ts --tag v1.44.1 # tag the snapshot
* bun run scripts/capture-baseline.ts --out path/to/baseline.json
*
* The default output path is test/fixtures/parity-baseline-<tag>.json,
* or test/fixtures/parity-baseline-current.json when no tag is given.
*/
import * as fs from 'fs';
import * as path from 'path';
import { captureBaseline } from '../test/helpers/capture-parity-baseline';
import { PARITY_INVARIANTS } from '../test/helpers/parity-harness';
const ROOT = path.resolve(import.meta.dir, '..');
function arg(name: string): string | undefined {
const i = process.argv.indexOf(name);
if (i === -1) return undefined;
return process.argv[i + 1];
}
const tag = arg('--tag');
const outOverride = arg('--out');
const defaultOut = path.join(
ROOT,
'test',
'fixtures',
`parity-baseline-${tag ?? 'current'}.json`,
);
const outPath = outOverride ? path.resolve(outOverride) : defaultOut;
const baseline = captureBaseline({
repoRoot: ROOT,
tag,
// Carved skills record UNION bytes (skeleton + sections/*.md) so the
// baseline measures the same thing parity-harness checks against.
sectionedSkills: PARITY_INVARIANTS.filter(i => i.sectioned).map(i => i.skill),
});
fs.mkdirSync(path.dirname(outPath), { recursive: true });
fs.writeFileSync(outPath, JSON.stringify(baseline, null, 2) + '\n');
const totalKB = Math.round(baseline.totalCorpusBytes / 1024);
const top3 = baseline.topHeaviest.slice(0, 3);
console.log(`Parity baseline captured: ${outPath}`);
console.log(` tag: ${baseline.tag}`);
console.log(` commit: ${baseline.capturedFromCommit}`);
console.log(` branch: ${baseline.capturedFromBranch}`);
console.log(` skills: ${baseline.totalSkills}`);
console.log(` total corpus: ${totalKB} KB`);
console.log(` catalog tokens: ~${baseline.estTotalCatalogTokens}`);
console.log(` top 3 heaviest:`);
for (const s of top3) {
const kb = Math.round(s.skillMdBytes / 1024);
console.log(` ${s.skill.padEnd(28)} ${kb} KB (${s.skillMdLines} lines, ~${s.estTokens} tokens)`);
}