Five behaviors that v1.46 ships but had no test coverage. All now pinned.
A) --host all idempotency (test/gen-skill-docs-idempotency.test.ts)
The default test ran Claude host only. Non-Claude hosts (Codex, Factory,
Cursor, OpenClaw, GBrain, Slate, OpenCode, Hermes, Kiro) each have their
own output paths and could carry their own non-deterministic fields. We
hit a "--host all needed for freshness check" mid-/ship. Now: two
consecutive `bun run gen:skill-docs --host all` runs must produce
byte-identical outputs across a per-host sample (.agents/, .cursor/,
.factory/, .gbrain/). Catches per-host adapter regressions before CI.
B) --catalog-mode=full opt-out (test/catalog-mode-full.test.ts)
The legacy escape hatch had zero tests. 6 new tests across two layers:
static (CATALOG_MODE_ARG parsed; conditional gate present; default is
"trim"; invalid value throws) + smoke (actual --catalog-mode=full run
produces a multi-line `description: |` block + omits "## When to invoke"
body section; mutates the working tree then restores in a finally block).
C) parity-baseline-v1.44.1.json integrity (test/parity-baseline-integrity.test.ts)
The baseline is the source of every v1→v2 number cited in the
CHANGELOG v1.46.0.0 entry. Anyone could edit it without test failure
until now. 8 new tests pin: existence, tag, capturedFromCommit
allowlist, expected v1.44 numbers (51 skills, ~2,915 KB, ~9,319
catalog tokens), CHANGELOG references this file by path, per-skill
shape, and a SHA256 byte-stability hash. Any edit fails with a clear
"if intentional, update EXPECTED_HASH AND the CHANGELOG numbers" signal.
D) Live appliesTo gate end-to-end (test/resolver-entry.test.ts extended)
The unwrapResolver unit tests covered the function; the gen-skill-docs.ts
substitution loop that USES the gate had no integration coverage. 6 new
tests simulate the exact 4-line shape from gen-skill-docs.ts:457-467
against synthetic registries: plain-function fires unconditionally,
gated fires when true / empty-string when false, mixed registries
compose, parameterized resolvers respect gates, unknown resolvers throw.
E) Per-skill min-size floor (test/skill-size-budget.test.ts extended)
The existing 200-byte body coverage-floor is a noise floor — a skill
that lost 99.75% of content still passes. 1 new test asserts every
skill stays ≥80% of its v1.44.1 baseline size (the parity-suite
content invariants only covered 10 of 51 skills; the remaining 41
were uncovered). SECTIONS_EXTRACTED hook in place for v2.0.0.0 when
the sections/ pattern legitimately shrinks ship/plan-ceo/etc. past
the floor.
Test plan:
- bun test focused 17-file suite: 1202 pass, 0 fail
(+23 new tests vs the pre-fill 1179 baseline)
- catalog-mode=full mutates working tree then restores cleanly
- --host all idempotency runs two full gen passes in <1s on this machine
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Three untested surfaces from the v1.46.0.0 work. All three would have
caught real bugs we shipped (and fixed) on this branch.
1. test/helpers/budget-override.test.ts — 7 tests pin the audit-trail
contract for EVALS_BUDGET_OVERRIDE_REASON and
GSTACK_SIZE_BUDGET_OVERRIDE_REASON. Without this, the audit logger
could silently drop events and overrides become invisible. Tests
cover: required fields per JSONL line, CI provenance capture
(CI/GITHUB_ACTIONS/branch/commit), local-runner defaults,
append-only behavior, missing-directory recovery, and unwritable-
path resilience (logs warning instead of throwing).
2. test/terse-build.test.ts — 16 tests pin --explain-level=terse
behavior across the 4 gated resolvers and the composed preamble.
Default vs terse vs undefined-ctx all asserted. Without this, a
refactor that breaks the explainLevel threading silently regresses
the opt-in compression path; the runtime EXPLAIN_LEVEL: terse gate
still works so users wouldn't notice. Tier-1 invariant pinned
(terse-only-affects-tier-2+).
3. test/gen-skill-docs-idempotency.test.ts — 2 tests catch the class
of bug behind the v1.45.0.0 timestamp flap. Two consecutive
gen-skill-docs runs must produce byte-identical outputs across
STABLE_OUTPUTS (proactive-suggestions.json, SKILL.md, ship/SKILL.md,
plan-ceo-review/SKILL.md, office-hours/SKILL.md, gstack/llms.txt).
--dry-run reports zero stale files after a fresh gen. CI freshness
regressions surface as test failures BEFORE a PR is opened.
Test plan:
- bun test test/helpers/budget-override.test.ts: 7 pass
- bun test test/terse-build.test.ts: 16 pass
- bun test test/gen-skill-docs-idempotency.test.ts: 2 pass
- Full focused suite (15 test files): 1179 pass, 0 fail (+45 new tests
vs the pre-fill baseline of 1134)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>