mirror of
https://github.com/garrytan/gstack.git
synced 2026-08-23 06:27:14 +02:00
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>
This commit is contained in:
co-authored by
Claude Fable 5
parent
39715addff
commit
0d1544c2db
@@ -46,6 +46,14 @@ export interface ParityBaseline {
|
||||
export interface CaptureOptions {
|
||||
repoRoot: string;
|
||||
tag?: string;
|
||||
/**
|
||||
* Skills whose baseline bytes must be the UNION of skeleton + sections/*.md
|
||||
* (mirroring parity-harness readSkillForParity, which is what the checker
|
||||
* compares against). Omitting a carved skill here records skeleton-only
|
||||
* bytes and the ratio check then reads ~2x on the next parity run — the
|
||||
* exact capture-vs-check drift that broke the v1.64 rebase.
|
||||
*/
|
||||
sectionedSkills?: string[];
|
||||
}
|
||||
|
||||
/** Extract the frontmatter description from a SKILL.md file. Empty string if none. */
|
||||
@@ -134,7 +142,7 @@ function getGitInfo(repoRoot: string): { commit: string; branch: string } {
|
||||
}
|
||||
|
||||
export function captureBaseline(opts: CaptureOptions): ParityBaseline {
|
||||
const { repoRoot, tag } = opts;
|
||||
const { repoRoot, tag, sectionedSkills } = opts;
|
||||
const skillDirs = discoverSkillDirs(repoRoot);
|
||||
const evalCoverage = discoverEvalCoverage(repoRoot, skillDirs);
|
||||
const skills: Record<string, SkillBaselineEntry> = {};
|
||||
@@ -144,7 +152,18 @@ export function captureBaseline(opts: CaptureOptions): ParityBaseline {
|
||||
const skillMdPath = path.join(repoRoot, dir, 'SKILL.md');
|
||||
const tmplPath = path.join(repoRoot, dir, 'SKILL.md.tmpl');
|
||||
const content = fs.readFileSync(skillMdPath, 'utf-8');
|
||||
const bytes = Buffer.byteLength(content, 'utf-8');
|
||||
let bytes = Buffer.byteLength(content, 'utf-8');
|
||||
// Union in the carved sections for sectioned skills — semantic twin of
|
||||
// parity-harness readSkillForParity (which the checker uses). Kept inline
|
||||
// because parity-harness imports this module as a value (cycle).
|
||||
if (sectionedSkills?.includes(dir)) {
|
||||
const sectionsDir = path.join(repoRoot, dir, 'sections');
|
||||
if (fs.existsSync(sectionsDir)) {
|
||||
for (const f of fs.readdirSync(sectionsDir).filter(f => f.endsWith('.md')).sort()) {
|
||||
bytes += Buffer.byteLength(fs.readFileSync(path.join(sectionsDir, f), 'utf-8'), 'utf-8');
|
||||
}
|
||||
}
|
||||
}
|
||||
const lines = content.split('\n').length;
|
||||
const description = extractDescription(content);
|
||||
const descriptionLen = Buffer.byteLength(description, 'utf-8');
|
||||
|
||||
@@ -144,7 +144,9 @@ export const CARVE_GUARDS: Record<string, CarveGuard> = {
|
||||
},
|
||||
behavioral: 'external',
|
||||
externalTest: 'test/skill-e2e-plan-ceo-review-section-loading.test.ts',
|
||||
maxSkeletonBytes: 90_000,
|
||||
// Re-ratcheted 2026-08 (v1.64 baseline rebase): v1.58-v1.64 growth landed
|
||||
// while no CI lane ran the parity check; free-tests lane now enforces it.
|
||||
maxSkeletonBytes: 92_000,
|
||||
minUnionBytes: 80_000,
|
||||
mustContain: ['SCOPE EXPANSION', 'SELECTIVE EXPANSION', 'HOLD SCOPE', 'SCOPE REDUCTION'],
|
||||
// Default-on Codex outside-voice (codexPreflight block + CODEX_MODE branch
|
||||
@@ -165,7 +167,9 @@ export const CARVE_GUARDS: Record<string, CarveGuard> = {
|
||||
behavioral: 'plan',
|
||||
// v1.2.0 activation lift (shared first-run-guidance preamble) + #2077 ask-first scope gate.
|
||||
// +~1 KB: plan-mode auto-select-B scope-gate exceptions (2026-08).
|
||||
maxSkeletonBytes: 68_000,
|
||||
// Re-ratcheted 2026-08 (v1.64 baseline rebase): v1.58-v1.64 growth landed
|
||||
// while no CI lane ran the parity check; free-tests lane now enforces it.
|
||||
maxSkeletonBytes: 70_000,
|
||||
minUnionBytes: 70_000,
|
||||
mustContain: ['Architecture', 'Code Quality', 'Test', 'Performance'],
|
||||
// Cross-cutting preamble growth (v1.57.2.0 AUQ-failure prose fallback + the
|
||||
@@ -240,7 +244,9 @@ export const CARVE_GUARDS: Record<string, CarveGuard> = {
|
||||
behavioral: 'prompt',
|
||||
// v1.2.0 activation lift: first-run-guidance section in the shared preamble,
|
||||
// plus the P1 office-hours closing handoff (AUQ that launches the next skill).
|
||||
maxSkeletonBytes: 98_000,
|
||||
// Re-ratcheted 2026-08 (v1.64 baseline rebase): v1.58-v1.64 growth landed
|
||||
// while no CI lane ran the parity check; free-tests lane now enforces it.
|
||||
maxSkeletonBytes: 100_000,
|
||||
minUnionBytes: 70_000,
|
||||
mustContain: ['design doc', 'problem statement'],
|
||||
maxSizeRatio: 1.07,
|
||||
@@ -289,7 +295,9 @@ export const CARVE_GUARDS: Record<string, CarveGuard> = {
|
||||
// +Conductor AUQ-default-prose rule + one-way/continuation safety in the
|
||||
// always-loaded AskUserQuestion Format section.
|
||||
// v1.2.0 activation lift: first-run-guidance section in the shared preamble.
|
||||
maxSkeletonBytes: 69_000,
|
||||
// Re-ratcheted 2026-08 (v1.64 baseline rebase): v1.58-v1.64 growth landed
|
||||
// while no CI lane ran the parity check; free-tests lane now enforces it.
|
||||
maxSkeletonBytes: 70_000,
|
||||
minUnionBytes: 72_000,
|
||||
mustContain: ['Typography', 'Color', 'Aesthetic Direction'],
|
||||
// Cross-cutting preamble growth (v1.57.2.0 AUQ-failure prose fallback ~2KB +
|
||||
|
||||
Reference in New Issue
Block a user