fix(test): adversarial findings — stable root key, symlink-alias dedupe, fixture-shape guard

Adversarial review (Claude subagent) verified the fixture's root-skill key was
the capture machine's checkout dirname: any non-gstack-named clone (every
Conductor worktree) failed the free suite, and the documented re-run-the-capture
recovery baked the local dirname into the committed fixture — silent corruption
through the tool's own protocol. The root skill is now pinned to ROOT_SKILL_KEY
('gstack', its frontmatter name). Symlink aliases are realpath-deduped (census
precedent): connect-chrome no longer gets its own ceiling, so Windows checkouts
that materialize the symlink as a plain file can't fail the stale-ceiling
set-equality test. New guards: fixture-shape validation (a string alwaysOnTotal
can no longer silently disable the ceiling), a mutation pin that the filter
shrinks the always-on ledger vs the raw bill, an alwaysOnTotal violation test
(the branch was load-bearing with only under-budget coverage), and an atomic
temp+rename fixture write. Fixture regenerated: 59 ceilings, alwaysOnTotal 6344.
Deferred with a TODO: anchoring transformFrontmatter's denylist strip to the
frontmatter block (latent, zero live collisions, pre-existing path).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Garry Tan
2026-08-25 02:53:25 +00:00
co-authored by Claude Fable 5
parent d80d3c3ed7
commit c11e44b93a
5 changed files with 107 additions and 12 deletions
+23 -1
View File
@@ -27,7 +27,7 @@
import { describe, test, expect } from 'bun:test';
import * as fs from 'fs';
import * as path from 'path';
import { checkBudget } from '../lib/context-bill';
import { buildBill, checkBudget } from '../lib/context-bill';
import {
buildRatchetBill,
captureContextBudget,
@@ -48,6 +48,28 @@ const budget: ContextBudget = JSON.parse(fs.readFileSync(BUDGET_FIXTURE_PATH, 'u
const bill = buildRatchetBill();
describe('context-budget ratchet', () => {
// checkBudget only enforces alwaysOnTotal when it is typeof number — a
// string or missing value from a hand edit or bad merge would silently
// turn the always-on ceiling OFF while every test stays green. Validate
// the fixture shape so the guard cannot be disabled by a typo.
test('fixture shape is valid (a malformed fixture must not silently disable ceilings)', () => {
expect(typeof budget.alwaysOnTotal).toBe('number');
expect(Number.isFinite(budget.alwaysOnTotal)).toBe(true);
const bad = Object.entries(budget.eagerPerInvocation).filter(
([, v]) => typeof v !== 'number' || !Number.isFinite(v),
);
expect(bad, `Non-numeric ceilings: ${bad.map(([k]) => k).join(', ')}. Re-run the capture.`).toEqual([]);
});
// Mutation pin: the fixture-skill filter must actually shrink the
// always-on sum vs the raw bill (deleting the totals recompute would leak
// fixture tokens under the headroom and never fail a ceiling).
test('filtering fixture skills shrinks the always-on ledger vs the raw bill', () => {
const raw = buildBill(path.join(import.meta.dir, '..'));
expect(bill.skills.some((s) => s.name.startsWith('test/'))).toBe(false);
expect(bill.totals.skillCount).toBeLessThan(raw.totals.skillCount);
expect(bill.totals.alwaysOnTokens).toBeLessThan(raw.totals.alwaysOnTokens);
});
test('always-on + eager ledgers stay under the fixture ceilings', () => {
// actual === null means "fixture names a skill missing from the tree" —
// the dedicated stale-fixture test below owns that case with a clearer