Files
gstack/docs/test-audit-2026-09.md
T
Garry Tan 55fbe77195 v1.91.24.0 test: audit wave — PR evals keep finished work, honest ceilings, EVAL_POLICY v2, faster free suite (#3031)
* chore(scripts): retire hollow and legacy paid package scripts behind one-release stubs (W8a, DX-4, CEO-31)

test:codex*, test:evals*, test:e2e*, test:gate, test:periodic, eval:bg,
eval:bg:all, eval:flake-rank, eval:watch and test:audit now print their
replacement and exit 1 via scripts/retired-command.ts. CONTRIBUTING.md
carries the same table; test/retired-commands.test.ts pins both. Eval CLI
empty-state hints point at eval:bg:pr.

* chore: delete dead update-readme-throughput, eval-watch, orphan fixtures and QA_FUNCTIONAL_INPUTS (W8b, CEO-24)

Retired with named behavior:
- update-readme-throughput.ts + readme-throughput test: replaced a README
  anchor that no longer exists from a JSON file that was never produced;
  the script was a no-op. Guarantee withdrawn (nothing to protect).
- eval-watch.ts + its dashboard tests: rendered ~/.gstack-dev/e2e-live.json
  and _partial-e2e.json, written only by unsharded runs, so it showed
  nothing for every supported (sharded) entry point. Guarantee withdrawn;
  live progress is the gstack-detach log or gh run watch. Manual-review
  rendering stays covered by eval-list and eval-summary tests.
- Orphan fixtures (autoplan-pending-artifact-ae.json, autoplan-existing-app/,
  autoplan-sign-in-ui/, parity baselines v1.47.0.0/v1.57.7.0/v1.69.1.0):
  no test, touchfile or script reads them; superseded baselines stay in
  git history.
- QA_FUNCTIONAL_INPUTS: exported, never imported.

* refactor(test-free): delete dead WORKER_HOSTILE list and buildShardArgs parallel mode

Neither had a production caller: full-suite mode runs shard processes, so the
worker quarantine was inert and --parallel was never passed (W8b).

* docs(test-value): narrow prompt-byte contract to machine-read tokens (D2)

Define prompt-byte contract as machine-read tokens (markers, field names,
command lines, enum values, file paths, security-boundary strings) and add a
sentence-pin glossary entry: convert to structural checks or delete when a
behavioral eval covers the behavior.

* test(ratchet): count free tests that slice a paid test's source

A free test that binds readFileSync(<paid test file>) and cuts it with
.slice() tests the paid harness's code out of context even when it imports a
lib/ symbol. Record the 15 existing files with reasons; new ones fail with fix
text. Self-test covers positive and negative shapes.

* test(browse): un-quarantine compare-board; all 16 board tests pass headless (W8d, CEO-24)

The GSTACK_COMPARE_BOARD_TESTS opt-in hid a headless mismatch that no
longer reproduces: all 16 tests pass on Bun 1.4.0 with the bundled
headless Chromium, solo, repeated, and beside other in-process browser
files. Protected behavior (the comparison-board DOM contract the
plan-design-review/office-hours/design-consultation feedback loop polls)
is checked on every free run again.

* test: replace silent existsSync early returns with explicit skips or assertions (W8d)

- browse/test/build.test.ts: server-node.mjs checks skip only when the
  bundle is absent and GSTACK_EXPECT_BINARIES is unset; the free CI lane
  and test:ubicloud build it and set the flag, so a dropped build step
  fails with the build command instead of passing with no assertions.
- gstack-update-check: VERSION is tracked; the guard could only hide a bug.
- gen-skill-docs host leakage/frontmatter checks assert the host tree
  exists (the module-level render always produces it).
- cso-docker staged-runtime test uses test.skipIf so reports show it as
  skipped, not passed.

* test(ship): convert ship-workflow-clarity sentence pins to structural checks

Add test/helpers/prompt-structure.ts (between, expectTokens, expectAbsent,
expectOrdered, expectMentions) with fix text on failure. ship-workflow-clarity
now pins headings, step order and machine-read tokens (commands, fields, enum
and status strings); safety rules are meaning-level keyword checks. Wording is
judged by the 'ship/SKILL.md workflow' judge in skill-llm-eval.
Sentence pins: 90 -> 0.

* ci: add platform-qualification lane for opt-in ML, gitleaks and Swift tests (W8d, CEO-24)

security-bench + security-live-playwright L4 (SECURITY_BENCH), the real
gitleaks 8.30.1 memory-ingest cases (GSTACK_TEST_GITLEAKS) and the
DebugBridge Swift build invariants (GSTACK_TEST_SWIFT) self-skip in every
lane today. No scheduled lane has their prerequisites, so per CEO-24 they
move to an owned dispatch + quarterly workflow instead of being deleted.
Each job was run locally (ML 10 pass, gitleaks 130 pass; Swift needs
macOS). test/platform-qualification-workflow.test.ts pins gate variable,
job and file together.

* fix(scripts): capture-baseline and preflight-agent-sdk no longer act on --help or typos (W8e)

capture-baseline parses its flags strictly: --help prints usage, an unknown
or valueless flag exits 2, and only a valid invocation writes a fixture
(--help used to write test/fixtures/parity-baseline-current.json).
preflight-agent-sdk gains --help, rejects unknown flags, and runs the live
SDK query (API spend) only with --live.

* test(evals): register the three keyless periodic paid files with case ids (W1b)

skill-e2e-auq-consistency, skill-e2e-auq-verbose-vs-carved-ab and
codex-e2e-recommendation-substance now carry touchfiles, a periodic tier and
kind rule (one trial, unchanged), so editing one selects its own case instead
of restoring the full PR gate. The verbose A/B case also registers the vendored
pre-cut fixture it reads, and review-army-migration-safety registers the SQL
fixture it reads.

* feat(evals): narrow PR fallback for free-only inputs (W1a, CEO-13/20, ENG-13)

The PR profile now exempts the duration seeds, every free-lane workflow
(explicit list; inventory test fails on an unclassified workflow, .yaml
and workflow_call included), scripts/ubicloud/** and fixtures declared in
the explicit FREE_FIXTURES map. Each remaining unknown file carries a label
and fix (needs touchfile entry / add to FREE_ONLY_PR_FILES / real unknown
dependency). evals.yml itself still restores the full gate.

* ci: delete ci-image.yml; the eval workflows already build and push the same content-hash tag (W8f)

evals.yml, evals-periodic.yml and evals-marathon.yml each compute the
identical hashFiles() tag and build/push it (with :buildcache and :latest)
when missing, so ci-image's push trigger and weekly cron were no-ops
(30-day median 0.5 min, 36/36 success). ci-image-tag-binding now pins the
three eval workflows.

* ci(evals): key periodic/marathon concurrency on ref+event; branch periodic dispatch skips the gate census (W2a, ENG-9, CEO-04)

* refactor(paid): drop ~160 unused imports; leaf paid-types/paid-select modules break the paid-* import cycle (W8c)

* ci(quality-gate): per-PR concurrency, free runner, drop unscoped bun audit (W2a, W8f)

- Concurrency keys on pull_request.number || run_id, so back-to-back main
  pushes no longer cancel each other's credential scan.
- ubuntu-24.04 instead of a billed 8-vCPU Ubicloud runner for a ~1 min job.
- bun audit --audit-level=critical ran on every PR regardless of diff, so a
  newly published advisory turned unrelated PRs red, with its own ignore
  policy. dependency-review (lockfile PRs, fail >= high) and the weekly OSV
  sweep remain the dependency gates.

* chore(test-free): refresh the free duration seed from the audit's Ubicloud recording

Adds the 19 files merged after the last refresh, including the 115 s
claude-overlay-setup that packed as ~1 s and doubled a shard (W6a). The seed
is re-recorded on the final tree at the end of this wave.

* ci: move tiny ubicloud-standard-2 jobs to free ubuntu-24.04 runners (W8f)

actionlint, skill-docs, dependency-review, version-gate and pr-title-sync
are sub-minute jobs; GitHub-hosted runners are free for this public repo.

* feat(test-free): pessimistic unseeded packing, seed growth ratchet and CI health summary

- Unseeded files pack at the seed's p99 instead of p75 (W6a).
- --ci-plan warns in the job summary past 5 unseeded files; --ci-verify
  lists shards that outran their prediction by 1.5x (and 30 s) plus every
  flaky pass absorbed by the serial retry (W6a, W7a job summary).
- test/free-seed-ratchet.test.ts fails when a seeded file over 60 s is not
  on scripts/free-test-seed-allowlist.json, when an entry is stale, and when
  the allowlist grows versus its merge-base copy unless the new entry is an
  annotated exception with a todo (CEO-10, DX-7). free-plan runs it with
  full history so the shrink check is real in the required lane.
- Every message names the fix command and docs anchor (DX-6).

* feat(evals): state PR coverage mode, counts, reuse and fallback files in the summary and comment (CEO-13)

* test: make the tracked-tree skill-doc freshness check local-only; tidy skill-docs header (W8f)

Every free CI shard regenerates the tracked SKILL.md files before running
tests, so the --dry-run freshness assertion compared the regenerated tree
with itself and could not fail there. It now skips under GitHub Actions;
skill-docs.yml's git diff --exit-code is CI's freshness gate. Removes a
stale concurrency comment in skill-docs.yml.

* ci(free-tests): install zsh so the bash+zsh portability arms run (W6f)

~42 zsh-arm tests (aside-probe-shell, qa-browser-preservation,
generated-docs-fences) skipped in CI because zsh is not in the runner image.
All 141 tests in those files pass with zsh present.

* feat(evals): executors write negative receipts at the execution boundary (CEO-25, ENG-6)

A completed single-trial rule/judge shard that did not pass now writes its
negative receipt beside the pass receipts in the slice artifact, so a
cancelled run's FAIL still blocks an older PASS when its report never runs.
Receipts merge negatives first and order by (run attempt, completedAt); a
same-second FAIL/PASS tie resolves to FAIL. The runner call site is a
one-line hunk in scripts/test-paid-shards.ts.

* docs(cso): state that contained runtime/scanner execution is unavailable today

The scanner catalog is empty while its build inputs await review and the
runtime catalog holds no qualified profile until the private evaluator
exists, so /cso runs static assessment only. AGENTS.md, README and
docs/cso-release-qualification.md now say so; docs/cso-scanners.md
already did.

* test(helpers): expectMentions splits on sentence ends only

Clauses joined by ';' or ':' are one rule; splitting there made a reworded
rule fail for punctuation.

* test(plan-ceo): convert skill-ceo-section-ordering sentence pins

Safety and authority rules (never/do not/stop/only/without/wait/approval) are
meaning-level expectMentions checks; other sentence pins are dropped. Headings,
labels, option rows, placeholders and machine-read lines (auto-decide
annotation, Mode:/approved decisions format, STATUS/SOURCE fields,
CROSS-MODEL marker, gstack-ceo-mode-handoff) stay as tokens; ordering checks
unchanged. Behavior is covered by the periodic PTY case in
skill-e2e-plan-ceo-review-section-loading.test.ts.
Sentence pins: 210 -> 23.

* test(helpers): expectMentions treats wrapped lines as one sentence

Templates hard-wrap prose; only sentence ends and blank lines separate rules.

* test(gen-skill-docs): convert sentence pins to meaning checks or drop them

Safety/authority sentences become expectMentions keyword checks; other English
sentences are dropped (wording is judged by the per-skill workflow judges in
skill-llm-eval and the E2E cases in touchfiles-data). Commands, config keys,
markers (PLAN MODE EXCEPTION, NO UNRESOLVED DECISIONS, Gate outcome), field
names and alternation-based meaning regexes stay. Removed the now-empty
'contains opt-in AskUserQuestion text' test (only pinned a sentence; the
resolver's AskUserQuestion wiring is covered by the codex second-opinion
tests in the same describe). Lane E's existsSync hunks are untouched.
Sentence pins: 216 -> 65 (remaining lines carry machine tokens).

* ci(windows): shard the Windows lane via --ci-plan/--ci-run/--ci-verify; move native campaigns to native-qualification.yml

- windows-free-tests.yml: a Linux plan job curates and packs the Windows-safe
  files into 6 shards, one strict serial shard per windows-latest job, and a
  Linux aggregate verifies exact coverage and every result (8.1 min on one
  runner today). --windows-only now combines with the CI modes; the plan binds
  the curated file set (W6e).
- Every Windows plan and --list run prints the curated count with its top
  exclusion reasons in the job summary; a free ratchet fails when the curated
  subset drops below its floor, with the fix (W6e).
- The four Dia/cookie diagnostic dispatch campaigns move to the dispatch-only
  native-qualification.yml with one exclusive `mode` choice input, so their
  red dispatch runs no longer read as a red PR lane (W8f). Their workflow pins
  move to test/windows-native-workflows.test.ts; the boolean-exclusivity
  guard is replaced by the choice input.

* feat(paid): per-slice CI job ceilings and an in-process slice deadline with not_run/hung outcomes and checkpoints (W2c, ENG-2)

* fix(pass-rates): segment trial history strictly by EVAL_POLICY version

Reader-compatibility floor for EVAL_POLICY v2 (ENG-14/CEO-35/DX-12). Only
trials under the reader's own policy version feed labels and alarms; older
policy trials stay visible but are never scored or used as a drift baseline;
trials from a newer policy are ignored with a printed count and fix text.
Reverting the later v2 writer commits leaves a reader that cannot pool v2
records into v1 series (the pre-PR reader at 2db0b3a does: it reports a
mixed fixture as FAILING with drift alarms).

* docs: one contributor command table; retired commands, seed sources and current workflows (W8g, DX-5, DX-13, CEO-12)

- CONTRIBUTING.md gains 'Which command do I run?' (task -> command ->
  cost/time -> needs, including branch validation via gh workflow run);
  CLAUDE.md, AGENTS.md and TESTING_INTERNALS.md link to it instead of
  repeating command lists. Tier tables drop retired commands and stale
  per-run dollar estimates.
- Retired names (test:evals, test:e2e, eval:bg, eval:flake-rank, eval:watch,
  ...) are gone from CLAUDE.md, CONTRIBUTING.md, TESTING_INTERNALS.md,
  ARCHITECTURE.md and USING_GBRAIN_WITH_GSTACK.md.
- The flake-ledger claim now says what happens: CI uploads flake-ledger-*
  artifacts; eval:pass-rates reads only the local ledger.
- TESTING_INTERNALS states that only test:ubicloud --record-durations
  produces an acceptable duration seed (DX-13).
- CI section: quality gate no longer runs bun audit; dependency-review's
  real trigger; the platform-qualification lane.
- docs/test-audit-2026-09.md gets a corrections section for its stale claims.
- TODOS.md: audit follow-ups (post-merge metrics, stub removal, name reclaim,
  diff-aware planner); eval-watch shard-awareness and the image freshness
  tripwire closed as won't-do.

* feat(evals): recover receipts of cancelled PR runs (W1c, CEO-14/34, ENG-4/5/7)

A new recover-receipts job runs base-ref code with actions: read, restores
the PR's store, merges the receipts of completed cancelled evals.yml runs
for this PR (provenance-checked, at most 5, oldest first, negatives first),
reconstructs completed panel negatives with panelVerdict() (partial panels
get no credit) and keeps a recovery.json checkpoint that never advances past
an unresolved run. plan-slices keeps contents: read, takes the store as an
artifact, turns reuse off when recovery degraded or a run is unresolved, and
carries the whole store to slices-report so nothing is lost. Any gh problem
degrades to no recovered receipts with a named reason.

* feat(evals): classify this wave's free-only tools and workflows for PR selection

platform-qualification.yml, retired-command.ts, test-health-report.ts,
bump-harness-version.ts and eval-bg.ts never run inside a paid case.

* feat(evals): debounce PR push bursts before planning paid slices (W1d, CEO-15, ENG-11, DX-7)

A tiny ubuntu-24.04 job waits 90 s only on synchronize when another run for
the PR started in the last 15 minutes; cancel-in-progress supersedes, and a
run that outlives the wait reports "superseded by <sha>" and plans nothing.
Labels: evals-no-debounce skips the wait, evals-fresh disables receipt reuse.

* perf(test): move the real-process browser settlement cases out of test-free-shards.test.ts (W6b)

The 19 owned-browser settlement modes were 85 s of the file's 95 s and could
not be packed apart from the fast runner unit cases. They move to a shared
fixture with two files (lifecycle 47 s, ownership 39 s); the unit file drops
to 10 s. Same modes, same assertions.

* chore(evals): delete the finished validation_phase dispatch and its inline planner (W8f)

Retirement (CEO-24): the protected behavior was a one-off cookie-repair
validation subset (eight dependent cases) and a quality/behavior split of
the census; that validation is complete, so the guarantee is withdrawn.
Branch validation dispatches evals.yml with evals_all.

* perf(test): inject the office-hours record grace in non-cooperative deadline tests

* perf(test): shrink aside-render process slack via GSTACK_RENDER_SLACK_MS in timeout tests

* perf(test): make the memorable lock give-up configurable for lock-contention tests

* perf(test): check install-timeout knob normalization through its own setup lines

* perf(test): inject a 2 s storage-reset deadline in the late isolated dispatch test

* perf(test): shorten the slow gbrain fake to 1 s, still past the 300 ms probe timeout

* ci(free-tests): run only cso-docker-integration in the free CSO Docker job (F16)

cso-node-lifecycle-integration and cso-stack-cold-integration need
GSTACK_CSO_TEST_STACK images and always skipped there; they stay in the CSO
runtime workflows through test:cso:docker.

* test(gen-skill-docs,plan-ceo): split mixed sentence pins into tokens and rules

Sentences that wrap a backticked or bold token keep the token (expectTokens)
and, when they state a safety rule, a keyword check; short safety sentences
(25-39 chars) get the same treatment.

* test(plan-ceo): convert ceo-workflow-clarity.test.ts sentence pins

Safety and authority sentences become expectMentions keyword checks (reword
freely, keep the rule); other English sentence pins are dropped. Headings,
labels, placeholders, commands, field names, enum/status tokens and ordering
checks stay. Behavior and wording: periodic PTY case skill-e2e-plan-ceo-review-section-loading and the plan-ceo workflow judges.
Sentence pins: 13 -> 1.

* test(plan-eng): convert eng-review-routing.test.ts sentence pins

Safety and authority sentences become expectMentions keyword checks (reword
freely, keep the rule); other English sentence pins are dropped. Headings,
labels, placeholders, commands, field names, enum/status tokens and ordering
checks stay. Behavior and wording: plan-eng E2E cases (skill-e2e-plan-eng-*) and the plan-eng workflow judge.
Sentence pins: 28 -> 6.

* test(plan-eng): convert eng-scope-entry-ap.test.ts sentence pins

Safety and authority sentences become expectMentions keyword checks (reword
freely, keep the rule); other English sentence pins are dropped. Headings,
labels, placeholders, commands, field names, enum/status tokens and ordering
checks stay. Behavior and wording: plan-eng E2E cases (skill-e2e-plan-eng-*) and the plan-eng workflow judge.
Sentence pins: 16 -> 5.

* test(plan): convert plan-scope-selection.test.ts sentence pins

Safety and authority sentences become expectMentions keyword checks (reword
freely, keep the rule); other English sentence pins are dropped. Headings,
labels, placeholders, commands, field names, enum/status tokens and ordering
checks stay. Behavior and wording: plan-review E2E cases and workflow judges in skill-llm-eval.
Sentence pins: 19 -> 2.

* test(qa): convert qa-lazy-sections.test.ts sentence pins

Safety and authority sentences become expectMentions keyword checks (reword
freely, keep the rule); other English sentence pins are dropped. Headings,
labels, placeholders, commands, field names, enum/status tokens and ordering
checks stay. Behavior and wording: qa/qa-only E2E cases (skill-e2e-qa-*) and the qa workflow judge.
Sentence pins: 71 -> 11.

* test(qa): convert qa-browser-preservation.test.ts sentence pins

Safety and authority sentences become expectMentions keyword checks (reword
freely, keep the rule); other English sentence pins are dropped. Headings,
labels, placeholders, commands, field names, enum/status tokens and ordering
checks stay. Behavior and wording: qa/qa-only E2E cases (skill-e2e-qa-*) and the qa workflow judge.
Sentence pins: 25 -> 11.

* test(qa): convert qa-probe-gates.test.ts sentence pins

Safety and authority sentences become expectMentions keyword checks (reword
freely, keep the rule); other English sentence pins are dropped. Headings,
labels, placeholders, commands, field names, enum/status tokens and ordering
checks stay. Behavior and wording: qa/qa-only E2E cases (skill-e2e-qa-*) and the qa workflow judge.
Sentence pins: 20 -> 5.

* test(qa): convert qa-checkpoint-evidence.test.ts sentence pins

Safety and authority sentences become expectMentions keyword checks (reword
freely, keep the rule); other English sentence pins are dropped. Headings,
labels, placeholders, commands, field names, enum/status tokens and ordering
checks stay. Behavior and wording: qa/qa-only E2E cases (skill-e2e-qa-*) and the qa workflow judge.
Sentence pins: 7 -> 5.

* test(qa): convert qa-evidence.test.ts sentence pins

Safety and authority sentences become expectMentions keyword checks (reword
freely, keep the rule); other English sentence pins are dropped. Headings,
labels, placeholders, commands, field names, enum/status tokens and ordering
checks stay. Behavior and wording: qa/qa-only E2E cases (skill-e2e-qa-*) and the qa workflow judge.
Sentence pins: 4 -> 3.

* test(design): convert design-consultation-contract.test.ts sentence pins

Safety and authority sentences become expectMentions keyword checks (reword
freely, keep the rule); other English sentence pins are dropped. Headings,
labels, placeholders, commands, field names, enum/status tokens and ordering
checks stay. Behavior and wording: design-consultation E2E/judge cases in touchfiles-data.
Sentence pins: 44 -> 11.

* test(outside-voice): convert run-in-background-guidance.test.ts sentence pins

Safety and authority sentences become expectMentions keyword checks (reword
freely, keep the rule); other English sentence pins are dropped. Headings,
labels, placeholders, commands, field names, enum/status tokens and ordering
checks stay. Behavior and wording: outside-voice E2E cases and plan-review workflow judges.
Sentence pins: 35 -> 5.

* test(spec): convert spec-template-invariants.test.ts sentence pins

Safety and authority sentences become expectMentions keyword checks (reword
freely, keep the rule); other English sentence pins are dropped. Headings,
labels, placeholders, commands, field names, enum/status tokens and ordering
checks stay. Behavior and wording: spec E2E/judge cases in touchfiles-data.
Sentence pins: 36 -> 21.

* perf(evals): 420 s census slice budget; case-shard skill-e2e-qa-workflow; seed its case walls (W5c)

* feat(evals): evals.yml dispatch contract for eval:bg (CEO-17/29, DX-1, ENG-8/12)

workflow_dispatch gains base_ref, base_sha, expected_sha, nonce and
pr_receipts. The nonce appears in run-name so the dispatcher resolves its
own run; evals_all=false runs the PR profile against base_sha/base_ref; a
checkout that differs from expected_sha fails before any paid work with a
named fix; pr_receipts reads that PR's receipts read-only through the
recover-receipts artifact path (never the cache) and never saves.

* ci(windows): pack the Windows lane with Windows-measured durations (W6e)

The first sharded run (37221451711) finished in 6.0 min: the Linux seed has
browse/test/cookie-import-native-job.test.ts at ~0 s (its cases skip on
Linux) but it takes 122 s on Windows, so one shard ran 242 s against an 84 s
prediction. The plan now reads scripts/free-test-durations-windows.json; a
record_durations dispatch times every Windows-safe file alone and uploads it.

* test(free): settlement case files import the runner rule they exercise

Keeps the split files out of the test-of-test ratchet: the retry-eligibility
rule is a direct runner import passed to the shared fixture.

* fix(marathon): no hollow plan-decision-classification shard; office-hours marathon scenario scoped to the pilot (W2f)

* test(free): satisfy the typecheck:test ratchet in the seed ratchet test

* refactor(ci-history): one shared GitHub history reader with the CI flake-ledger reader

Extract pass-rates' gh fetch layer into scripts/lib/ci-history.ts (CEO-09) and
add the W7a reader: paged run listings that fail whole on any page error,
per-run artifact downloads (cached, size-capped, data only), flake-ledger
parsing, the pre-registered flaky-file rule (> 5% of main free-tests runs over
a window of at least 20 runs, widened to the newest 20 runs when the window is
thinner), a job-summary table, and named unavailable reasons with next steps.

* feat(test-health): test:health report of the audit success metrics

scripts/test-health-report.ts (CEO-09/06/22/32, DX-8/9/12/13) prints every
success metric with its counting rule from CI history: PR full-fallback rate,
reused PR trial records, PR-lane spend per merged PR and per validated
revision, cancelled slice-minutes per week, push-to-verdict p50/p95, census
expected failed trials per run with raw failure rate per kind/class and
P(lane red) under the recorded panels vs single-trial aggregation, INFRA
re-dispatches, quarantine evidence (insufficient evidence distinct from
healthy), free flaky-pass rate, free/Windows wall, free serial time and the
net-complexity line. An unreadable input prints 'unavailable: <reason>; next:
<step>', never 0. --enforce fails on a flaky file (W7a) or > 5 unseeded free
files (CEO-10); unavailable checks never fail and keep the issue open.

* test(review): convert review-workflow-clarity.test.ts sentence pins

Safety and authority sentences become expectMentions keyword checks (reword
freely, keep the rule); other English sentence pins are dropped. Headings,
labels, placeholders, commands, field names, enum/status tokens and ordering
checks stay. Behavior and wording: review E2E cases (skill-e2e-review*) and the review workflow judge in skill-llm-eval.
Sentence pins: 85 -> 17.

* test(review): convert review-entry-and-design-clarity-au.test.ts sentence pins

Safety and authority sentences become expectMentions keyword checks (reword
freely, keep the rule); other English sentence pins are dropped. Headings,
labels, placeholders, commands, field names, enum/status tokens and ordering
checks stay. Behavior and wording: review E2E cases (skill-e2e-review*) and the review workflow judge in skill-llm-eval.
Sentence pins: 15 -> 4.

* test(review): convert review-enum-lifecycle.test.ts sentence pins

Safety and authority sentences become expectMentions keyword checks (reword
freely, keep the rule); other English sentence pins are dropped. Headings,
labels, placeholders, commands, field names, enum/status tokens and ordering
checks stay. Behavior and wording: review E2E cases (skill-e2e-review*) and the review workflow judge in skill-llm-eval.
Sentence pins: 8 -> 0.

* test(ship): convert ship-control-flow.test.ts sentence pins

Safety and authority sentences become expectMentions keyword checks (reword
freely, keep the rule); other English sentence pins are dropped. Headings,
labels, placeholders, commands, field names, enum/status tokens and ordering
checks stay. Behavior and wording: ship E2E cases (skill-e2e-ship*, skill-e2e-workflow) and the 'ship/SKILL.md workflow' judge.
Sentence pins: 74 -> 9.

* test(ship): convert ship-skip-requeue.test.ts sentence pins

Safety and authority sentences become expectMentions keyword checks (reword
freely, keep the rule); other English sentence pins are dropped. Headings,
labels, placeholders, commands, field names, enum/status tokens and ordering
checks stay. Behavior and wording: ship E2E cases (skill-e2e-ship*, skill-e2e-workflow) and the 'ship/SKILL.md workflow' judge.
Sentence pins: 28 -> 3.

* test(ship): convert ship-plan-completion-invariants.test.ts sentence pins

Safety and authority sentences become expectMentions keyword checks (reword
freely, keep the rule); other English sentence pins are dropped. Headings,
labels, placeholders, commands, field names, enum/status tokens and ordering
checks stay. Behavior and wording: ship E2E cases (skill-e2e-ship*, skill-e2e-workflow) and the 'ship/SKILL.md workflow' judge.
Sentence pins: 28 -> 12.

* test(ship): convert ship-reentry-gates.test.ts sentence pins

Safety and authority sentences become expectMentions keyword checks (reword
freely, keep the rule); other English sentence pins are dropped. Headings,
labels, placeholders, commands, field names, enum/status tokens and ordering
checks stay. Behavior and wording: ship E2E cases (skill-e2e-ship*, skill-e2e-workflow) and the 'ship/SKILL.md workflow' judge.
Sentence pins: 16 -> 4.

* test(ship): convert ship-document-release-dispatch.test.ts sentence pins

Safety and authority sentences become expectMentions keyword checks (reword
freely, keep the rule); other English sentence pins are dropped. Headings,
labels, placeholders, commands, field names, enum/status tokens and ordering
checks stay. Behavior and wording: ship E2E cases (skill-e2e-ship*, skill-e2e-workflow) and the 'ship/SKILL.md workflow' judge.
Sentence pins: 11 -> 4.

* test(ship): convert ship-apple-gate.test.ts sentence pins

Safety and authority sentences become expectMentions keyword checks (reword
freely, keep the rule); other English sentence pins are dropped. Headings,
labels, placeholders, commands, field names, enum/status tokens and ordering
checks stay. Behavior and wording: ship E2E cases (skill-e2e-ship*, skill-e2e-workflow) and the 'ship/SKILL.md workflow' judge.
Sentence pins: 7 -> 0.

* test(ship): convert ship-skip-actor.test.ts sentence pins

Safety and authority sentences become expectMentions keyword checks (reword
freely, keep the rule); other English sentence pins are dropped. Headings,
labels, placeholders, commands, field names, enum/status tokens and ordering
checks stay. Behavior and wording: ship E2E cases (skill-e2e-ship*, skill-e2e-workflow) and the 'ship/SKILL.md workflow' judge.
Sentence pins: 6 -> 1.

* test(ship): convert ship-template-redaction.test.ts sentence pins

Safety and authority sentences become expectMentions keyword checks (reword
freely, keep the rule); other English sentence pins are dropped. Headings,
labels, placeholders, commands, field names, enum/status tokens and ordering
checks stay. Behavior and wording: ship E2E cases (skill-e2e-ship*, skill-e2e-workflow) and the 'ship/SKILL.md workflow' judge.
Sentence pins: 5 -> 4.

* test(ship): convert ship-publication-gates.test.ts sentence pins

Safety and authority sentences become expectMentions keyword checks (reword
freely, keep the rule); other English sentence pins are dropped. Headings,
labels, placeholders, commands, field names, enum/status tokens and ordering
checks stay. Behavior and wording: ship E2E cases (skill-e2e-ship*, skill-e2e-workflow) and the 'ship/SKILL.md workflow' judge.
Sentence pins: 5 -> 2.

* test(ship): convert ship-review-loop.test.ts sentence pins

Safety and authority sentences become expectMentions keyword checks (reword
freely, keep the rule); other English sentence pins are dropped. Headings,
labels, placeholders, commands, field names, enum/status tokens and ordering
checks stay. Behavior and wording: ship E2E cases (skill-e2e-ship*, skill-e2e-workflow) and the 'ship/SKILL.md workflow' judge.
Sentence pins: 3 -> 1.

* test(ship): convert ship-version-sync.test.ts sentence pins

Safety and authority sentences become expectMentions keyword checks (reword
freely, keep the rule); other English sentence pins are dropped. Headings,
labels, placeholders, commands, field names, enum/status tokens and ordering
checks stay. Behavior and wording: ship E2E cases (skill-e2e-ship*, skill-e2e-workflow) and the 'ship/SKILL.md workflow' judge.
Sentence pins: 5 -> 2.

* test(ship): convert ship-pr-liveness-policy.test.ts sentence pins

Safety and authority sentences become expectMentions keyword checks (reword
freely, keep the rule); other English sentence pins are dropped. Headings,
labels, placeholders, commands, field names, enum/status tokens and ordering
checks stay. Behavior and wording: ship E2E cases (skill-e2e-ship*, skill-e2e-workflow) and the 'ship/SKILL.md workflow' judge.
Sentence pins: 4 -> 0.

* test(plan-review): convert plan-review-cases.test.ts sentence pins

Safety and authority sentences become expectMentions keyword checks (reword
freely, keep the rule); other English sentence pins are dropped. Headings,
labels, placeholders, commands, field names, enum/status tokens and ordering
checks stay. Behavior and wording: plan-review E2E cases and workflow judges in skill-llm-eval.
Sentence pins: 58 -> 15.

* test(autoplan): convert autoplan-phase-order.test.ts sentence pins

Safety and authority sentences become expectMentions keyword checks (reword
freely, keep the rule); other English sentence pins are dropped. Headings,
labels, placeholders, commands, field names, enum/status tokens and ordering
checks stay. Behavior and wording: autoplan E2E cases (skill-e2e-autoplan-*) and the autoplan workflow judge.
Sentence pins: 42 -> 11.

* test(autoplan): convert autoplan-phase-handoff.test.ts sentence pins

Safety and authority sentences become expectMentions keyword checks (reword
freely, keep the rule); other English sentence pins are dropped. Headings,
labels, placeholders, commands, field names, enum/status tokens and ordering
checks stay. Behavior and wording: autoplan E2E cases (skill-e2e-autoplan-*) and the autoplan workflow judge.
Sentence pins: 20 -> 4.

* test(autoplan): convert autoplan-snapshot.test.ts sentence pins

Safety and authority sentences become expectMentions keyword checks (reword
freely, keep the rule); other English sentence pins are dropped. Headings,
labels, placeholders, commands, field names, enum/status tokens and ordering
checks stay. Behavior and wording: autoplan E2E cases (skill-e2e-autoplan-*) and the autoplan workflow judge.
Sentence pins: 21 -> 5.

* test(outside-voice): convert outside-voice-preflight.test.ts sentence pins

Safety and authority sentences become expectMentions keyword checks (reword
freely, keep the rule); other English sentence pins are dropped. Headings,
labels, placeholders, commands, field names, enum/status tokens and ordering
checks stay. Behavior and wording: outside-voice E2E cases and plan-review workflow judges.
Sentence pins: 26 -> 9.

* test(ask-format): convert resolver-ask-user-format.test.ts sentence pins

Safety and authority sentences become expectMentions keyword checks (reword
freely, keep the rule); other English sentence pins are dropped. Headings,
labels, placeholders, commands, field names, enum/status tokens and ordering
checks stay. Behavior and wording: AUQ E2E cases (skill-e2e-auq-*); prompt-injection rule kept as a meaning check.
Sentence pins: 32 -> 15.

* test(skills): convert binding-template-drift.test.ts sentence pins

Safety and authority sentences become expectMentions keyword checks (reword
freely, keep the rule); other English sentence pins are dropped. Headings,
labels, placeholders, commands, field names, enum/status tokens and ordering
checks stay. Behavior and wording: workflow judges in skill-llm-eval.
Sentence pins: 19 -> 13.

* test(skills): convert carve-plan-fixture.test.ts sentence pins

Safety and authority sentences become expectMentions keyword checks (reword
freely, keep the rule); other English sentence pins are dropped. Headings,
labels, placeholders, commands, field names, enum/status tokens and ordering
checks stay. Behavior and wording: workflow judges in skill-llm-eval.
Sentence pins: 20 -> 6.

* test(land-and-deploy): convert land-and-deploy-postfail.test.ts sentence pins

Safety and authority sentences become expectMentions keyword checks (reword
freely, keep the rule); other English sentence pins are dropped. Headings,
labels, placeholders, commands, field names, enum/status tokens and ordering
checks stay. Behavior and wording: land-and-deploy E2E cases and its workflow judge.
Sentence pins: 21 -> 14.

* test(land-and-deploy): convert land-and-deploy-ci-gate.test.ts sentence pins

Safety and authority sentences become expectMentions keyword checks (reword
freely, keep the rule); other English sentence pins are dropped. Headings,
labels, placeholders, commands, field names, enum/status tokens and ordering
checks stay. Behavior and wording: land-and-deploy E2E cases and its workflow judge.
Sentence pins: 5 -> 4.

* test(land-and-deploy): convert land-and-deploy-flow.test.ts sentence pins

Safety and authority sentences become expectMentions keyword checks (reword
freely, keep the rule); other English sentence pins are dropped. Headings,
labels, placeholders, commands, field names, enum/status tokens and ordering
checks stay. Behavior and wording: land-and-deploy E2E cases and its workflow judge.
Sentence pins: 5 -> 3.

* test(office-hours): convert office-hours-completion.test.ts sentence pins

Safety and authority sentences become expectMentions keyword checks (reword
freely, keep the rule); other English sentence pins are dropped. Headings,
labels, placeholders, commands, field names, enum/status tokens and ordering
checks stay. Behavior and wording: office-hours E2E cases (skill-e2e-office-hours*).
Sentence pins: 16 -> 1.

* test(plan-ceo): restore the stale closing-route guard

The negative check for 'Closing hooks' / 'return to section' guards a retired
route token, not a sentence; the first conversion pass dropped it.

* ci(test-health): weekly test-health workflow with an honest tracking issue

New test-health.yml (CEO-18/DX-9): Monday 10:00 UTC after the periodic census
plus dispatch, free ubuntu-24.04 runner, permissions contents:read +
actions:read + issues:write only. Runs bun run test:health --since-days 7
--enforce; an enforced failure upserts one tracking issue, a run with
unavailable inputs keeps it open and lists them, and it closes only when every
enforced check has evidence and passes. Only main runs touch the issue.

* feat(evals): an edited paid test file runs its own gate cases in the PR lane (DX-11)

A gate case outside the audited fast profile is selected when its single
owning paid test file changed and the runner can select it by name (its
Bun test is named by the case id). The manifest records directCases and
validation accepts only recorded, name-addressable ones; the runner and
planner read the file->cases map from test-pr-profile. Cases the runner
cannot address stay deferred with the fix. An inventory test covers every
owned gate case. Touches one hunk each in test-paid-shards.ts and
lib/paid-plan.ts, and pr-shared-input-selection.test.ts's ship-skip pin.

* ci(osv): tracking issue for scheduled reds and a 14-day suppression expiry test

F11/W8f: a failed main OSV scan now upserts one tracking issue and a clean
scan closes it (scheduled reds notified no one during the August backlog).
A free test fails 14 days before any .osv-scanner.toml ignoreUntil (all four
expire 2026-11-30), with the fix: upgrade and delete, or re-justify and move
the date.

* test(ship,review): keep guards against retired fail-open instructions

'skip silently' on reviewer failure and 'do not block /ship on subagent
failure' were harmful instructions, not prose style; keep them absent with the
shortest distinctive phrase.

* feat(eval-select): default to the pr profile

DX-10: eval:select previews the PR lane's selection by default, matching
test:pr and eval:bg:pr; --profile full (or EVALS_PROFILE=full) keeps the plain
touchfile selection.

* test(evals): type-clean the recovery gh fake (typecheck:test ratchet)

* chore(windows): record the Windows duration seed (run 37221963236)

573 Windows-safe files timed alone on windows-latest; cookie-import-native-job
is 102 s there. Six shards now predict 154 s each.

* feat(evals): eval:bg dispatches the pushed ref to CI or runs locally under a 1.5x-planned cap (W5d, CEO-17/29, DX-1/2/3/7, ENG-12/19)

* feat(runners): --help on both shard runners via the shared flag loop; paid runner header describes today's planner/executor/report (W8e)

* test(windows): drop the stale Playwright exclusion and force-include probe-proven files (W6e)

A temporary windows-latest probe (run 37221995077) ran each of the 97 files
excluded for 'launches Playwright browser' or 'raw /tmp/ path' alone: all 17
Playwright files pass (Chromium is installed and Bun drives it there), and 41
of the /tmp files pass with executed cases. The Playwright pattern is removed
and the 41 files are force-included with the probe as their reason; the 36
real failures stay excluded. The curated subset grows from 573 to 631 files
and the ratchet floor follows. Windows curation moves to
scripts/lib/windows-curation.ts (the runner drops to 2000 lines).

* test(free): one install fixture cloned from a read-only seed (W6c, ENG-1)

Merge test/helpers/setup-codex-scope-fixture.ts into install-fixture.ts.
The checkout is built once per test file into a read-only seed and cloned
per fixture with copy-on-write where the filesystem has it (full copy
otherwise), restoring each file's own mode; clones never hard-link the
seed because put() and tests write in place. Callers register
afterAll(cleanupSeed); Bun's runner fires no exit event, so seeds of
killed runs are swept by pid. test/install-fixture.test.ts is the ENG-1
tripwire: put/setVersion/chmod in one clone leave the seed and a sibling
unchanged, and clones share no inodes with the read-only seed.

* test(free): split claude-overlay-setup by describe (W6b)

The 115 s serial file becomes default/lifecycle/installs files (5/4/3
tests, unchanged bodies) sharing test/helpers/claude-overlay-fixture.ts,
so the shard packer can balance them.

* test(cso): convert cso-contracts.test.ts sentence pins

Safety and authority sentences become expectMentions keyword checks (reword
freely, keep the rule); other English sentence pins are dropped. Headings,
labels, placeholders, commands, field names, enum/status tokens and ordering
checks stay. Behavior and wording: cso E2E/judge cases (skill-e2e-cso*, cso-eval).
Sentence pins: 16 -> 8.

* test(cso): convert cso-preserved.test.ts sentence pins

Safety and authority sentences become expectMentions keyword checks (reword
freely, keep the rule); other English sentence pins are dropped. Headings,
labels, placeholders, commands, field names, enum/status tokens and ordering
checks stay. Behavior and wording: cso E2E/judge cases (skill-e2e-cso*, cso-eval).
Sentence pins: 10 -> 3.

* test(cso): convert cso-eval.test.ts sentence pins

Safety and authority sentences become expectMentions keyword checks (reword
freely, keep the rule); other English sentence pins are dropped. Headings,
labels, placeholders, commands, field names, enum/status tokens and ordering
checks stay. Behavior and wording: cso E2E/judge cases (skill-e2e-cso*, cso-eval).
Sentence pins: 7 -> 4.

* test(browser): convert aside-driver.test.ts sentence pins

Safety and authority sentences become expectMentions keyword checks (reword
freely, keep the rule); other English sentence pins are dropped. Headings,
labels, placeholders, commands, field names, enum/status tokens and ordering
checks stay. Behavior and wording: Aside/browse E2E cases; the installer ban stays a meaning check.
Sentence pins: 27 -> 9.

* test(browser): convert third-party-actions.test.ts sentence pins

Safety and authority sentences become expectMentions keyword checks (reword
freely, keep the rule); other English sentence pins are dropped. Headings,
labels, placeholders, commands, field names, enum/status tokens and ordering
checks stay. Behavior and wording: Aside/browse E2E cases; the installer ban stays a meaning check.
Sentence pins: 17 -> 2.

* test(skills): convert skill-validation.test.ts sentence pins

Safety and authority sentences become expectMentions keyword checks (reword
freely, keep the rule); other English sentence pins are dropped. Headings,
labels, placeholders, commands, field names, enum/status tokens and ordering
checks stay. Behavior and wording: workflow judges in skill-llm-eval.
Sentence pins: 19 -> 6.

* test(skills): convert workflow-excerpt.test.ts sentence pins

Safety and authority sentences become expectMentions keyword checks (reword
freely, keep the rule); other English sentence pins are dropped. Headings,
labels, placeholders, commands, field names, enum/status tokens and ordering
checks stay. Behavior and wording: workflow judges in skill-llm-eval.
Sentence pins: 37 -> 10.

* test(skills): convert question-tuning-registry-path.test.ts sentence pins

Safety and authority sentences become expectMentions keyword checks (reword
freely, keep the rule); other English sentence pins are dropped. Headings,
labels, placeholders, commands, field names, enum/status tokens and ordering
checks stay. Behavior and wording: workflow judges in skill-llm-eval.
Sentence pins: 4 -> 0.

* test(skills): convert host-conformance.test.ts sentence pins

Safety and authority sentences become expectMentions keyword checks (reword
freely, keep the rule); other English sentence pins are dropped. Headings,
labels, placeholders, commands, field names, enum/status tokens and ordering
checks stay. Behavior and wording: workflow judges in skill-llm-eval.
Sentence pins: 4 -> 4.

* test(memory): convert memory-ingest-landing.test.ts sentence pins

Safety and authority sentences become expectMentions keyword checks (reword
freely, keep the rule); other English sentence pins are dropped. Headings,
labels, placeholders, commands, field names, enum/status tokens and ordering
checks stay. Behavior and wording: memory-ingest free tests that run the binary.
Sentence pins: 11 -> 9.

* test(windows): exclude the skip-only claude-overlay setup files from the Windows subset

Their real-setup cases are describe.skipIf(win32); after the split their bin/
spawns live in the shared helper, so the source scan stopped seeing them.

* test(skills): convert agents-digest.test.ts sentence pins

Safety and authority sentences become expectMentions keyword checks (reword
freely, keep the rule); other English sentence pins are dropped. Headings,
labels, placeholders, commands, field names, enum/status tokens and ordering
checks stay. Behavior and wording: the owning skills' E2E cases and workflow judges; CLI/hook output and fixture-data pins in the tail were left alone.
Sentence pins: 1 -> 0.

* test(skills): convert brain-preflight.test.ts sentence pins

Safety and authority sentences become expectMentions keyword checks (reword
freely, keep the rule); other English sentence pins are dropped. Headings,
labels, placeholders, commands, field names, enum/status tokens and ordering
checks stay. Behavior and wording: the owning skills' E2E cases and workflow judges; CLI/hook output and fixture-data pins in the tail were left alone.
Sentence pins: 2 -> 1.

* test(skills): convert codex-skill-isolation.test.ts sentence pins

Safety and authority sentences become expectMentions keyword checks (reword
freely, keep the rule); other English sentence pins are dropped. Headings,
labels, placeholders, commands, field names, enum/status tokens and ordering
checks stay. Behavior and wording: the owning skills' E2E cases and workflow judges; CLI/hook output and fixture-data pins in the tail were left alone.
Sentence pins: 1 -> 0.

* test(skills): convert office-hours-review.test.ts sentence pins

Safety and authority sentences become expectMentions keyword checks (reword
freely, keep the rule); other English sentence pins are dropped. Headings,
labels, placeholders, commands, field names, enum/status tokens and ordering
checks stay. Behavior and wording: the owning skills' E2E cases and workflow judges; CLI/hook output and fixture-data pins in the tail were left alone.
Sentence pins: 2 -> 1.

* test(skills): convert onboarding-moved-literals.test.ts sentence pins

Safety and authority sentences become expectMentions keyword checks (reword
freely, keep the rule); other English sentence pins are dropped. Headings,
labels, placeholders, commands, field names, enum/status tokens and ordering
checks stay. Behavior and wording: the owning skills' E2E cases and workflow judges; CLI/hook output and fixture-data pins in the tail were left alone.
Sentence pins: 2 -> 2.

* test(skills): convert open-gstack-browser-liveness.test.ts sentence pins

Safety and authority sentences become expectMentions keyword checks (reword
freely, keep the rule); other English sentence pins are dropped. Headings,
labels, placeholders, commands, field names, enum/status tokens and ordering
checks stay. Behavior and wording: the owning skills' E2E cases and workflow judges; CLI/hook output and fixture-data pins in the tail were left alone.
Sentence pins: 3 -> 2.

* test(skills): convert plan-floor-review.test.ts sentence pins

Safety and authority sentences become expectMentions keyword checks (reword
freely, keep the rule); other English sentence pins are dropped. Headings,
labels, placeholders, commands, field names, enum/status tokens and ordering
checks stay. Behavior and wording: the owning skills' E2E cases and workflow judges; CLI/hook output and fixture-data pins in the tail were left alone.
Sentence pins: 3 -> 2.

* test(skills): convert plan-review-report-recording.test.ts sentence pins

Safety and authority sentences become expectMentions keyword checks (reword
freely, keep the rule); other English sentence pins are dropped. Headings,
labels, placeholders, commands, field names, enum/status tokens and ordering
checks stay. Behavior and wording: the owning skills' E2E cases and workflow judges; CLI/hook output and fixture-data pins in the tail were left alone.
Sentence pins: 4 -> 2.

* test(skills): convert regression-1539-review-self-verify.test.ts sentence pins

Safety and authority sentences become expectMentions keyword checks (reword
freely, keep the rule); other English sentence pins are dropped. Headings,
labels, placeholders, commands, field names, enum/status tokens and ordering
checks stay. Behavior and wording: the owning skills' E2E cases and workflow judges; CLI/hook output and fixture-data pins in the tail were left alone.
Sentence pins: 4 -> 0.

* test(skills): convert skill-fixture.test.ts sentence pins

Safety and authority sentences become expectMentions keyword checks (reword
freely, keep the rule); other English sentence pins are dropped. Headings,
labels, placeholders, commands, field names, enum/status tokens and ordering
checks stay. Behavior and wording: the owning skills' E2E cases and workflow judges; CLI/hook output and fixture-data pins in the tail were left alone.
Sentence pins: 6 -> 3.

* test(skills): convert template-context-parity.test.ts sentence pins

Safety and authority sentences become expectMentions keyword checks (reword
freely, keep the rule); other English sentence pins are dropped. Headings,
labels, placeholders, commands, field names, enum/status tokens and ordering
checks stay. Behavior and wording: the owning skills' E2E cases and workflow judges; CLI/hook output and fixture-data pins in the tail were left alone.
Sentence pins: 1 -> 0.

* test: restore pins on renderer output and paid-fixture inputs

cso-contracts (the report renderer's required empty phrase), memory-ingest
(binary output), carve-plan-fixture, ship-skip-actor and cso-eval (inputs the
paid harness builds) assert product or fixture output, not skill prose, so the
value-bar narrowing does not apply to them.

* feat(eval-policy): v2 series identity, HARNESS_VERSION guard and identity backtest

W4a (CEO-27/ENG-3/DX-6), not yet wired to the writer: caseSeriesIdentitiesV2
keys a case by the bytes it owns (paid test file, fixtures, its skills' prompt
files including the generated SKILL.md) plus HARNESS_VERSION, and records the
full consumed-input fingerprint as provenance. scripts/harness-version.json
pins the blob of every shared-harness file (GLOBAL_TOUCHFILES plus the session
runners, PTY harness, e2e gate and LLM judge), one line per file;
test/harness-version.test.ts fails on drift with both fixes, and
scripts/bump-harness-version.ts records the decision: --bump (new series for
every case) or --non-behavioral (compatibility entry, no reset).
eval-trial-series --backtest replays identities over weekly main revisions
and recorded trials (ENG-3/DX-12).

* feat(pass-rates): weekly history is main's scheduled runs plus main dispatches

W4b: pass-rates reads evals-periodic history from main only, keeping scheduled
runs and main dispatches and never a branch dispatch, so back-to-back branch
validation runs neither feed pass rates nor count as weeks for quarantine
expiry or drift. --branch <name> still reads one branch's runs for inspection.

* docs(test-audit): EVAL_POLICY v2 decision memo with the identity backtest

D1 memo (CEO-33, ENG-3, DX-12, CEO-27): P(green) arithmetic, false-blocking
targets, the v2 identity rule and harness guard, weekly history, W4c evidence
(the named 'stochastic' cases pass 26/27 to 34/34, so they stay rule), the
backtest over 29 weekly main revisions and 14,898 recorded trials, what it
means for quarantine reachability, alternatives (gating vs trended, adaptive
panels not adopted, buy vs build), and the rollback proof on the pre-PR reader.

* feat(eval-policy): EVAL_POLICY v2 writer: case-owned series identity

The v2 writer, last commit of the W4 block (DX-12/ENG-14/ENG-21): the report
job's stamp now writes caseSeriesIdentitiesV2 (case-owned bytes plus
HARNESS_VERSION) as series_identity, the full consumed-input fingerprint as
series_fingerprint and harness_version as provenance, and EVAL_POLICY.version
is 2 (approved 2026-10-04, D1). The v1 touchfile identity is removed.
Rollback = revert this commit (and the W4 commits above the reader-compat
floor); readers then ignore the v2 records with a printed count.

* test: restore pins on paid-harness prompt inputs

review-enum-lifecycle and plan-review-report-recording assert the prompt a
paid case's harness builds (opts.prompt / call.prompt), a fixture contract,
not skill prose.

* test(security): check injected safety lines on meaning, not capitals

content-security, the canary instruction and the arm judge prompt still must
carry their never-follow / never-output / exact-"none" rules; the checks are
case-insensitive keyword checks so emphasis can change. The UNTRUSTED envelope
markers and "none" value stay exact tokens. (Hidden element stripping fails
locally only because Playwright Chromium is not installed; same at base.)

* test(plan-ceo): keep the outside-voice scope-summary rule as a meaning check

The first codemod pass left an empty if body (TS1313).

* chore(windows): re-record the Windows duration seed for the 631-file subset (run 37222668939)

* ci(free-tests): summarize every shard's flake ledger in the aggregate job (W7a)

The aggregate downloads flake-ledger-* (one subdirectory per shard) and
appends lane C's `scripts/test-health-report.ts flake-summary` output to the
job summary before strict verification. The runner's own flaky table is
dropped so the ledger reader stays the single source; --ci-verify keeps the
shard-overrun warning.

* feat(evals): free test files anywhere and the stored-zip helper never restore the full PR gate (W1a)

The CEO-23 replay found design/test free tests forcing fallback (36485436963).

* feat(evals): replay recorded PR pushes through today's selector (CEO-23, ENG-18)

scripts/replay-pr-selection.ts reports per push the recorded vs replayed
mode and case count, dropped gate cases, retired failed cases and every
miss (a failed case that depends on the diff but is no longer selected).

* refactor(evals): one case-sharded carve-section-loading file with a case id and touchfiles per skill (W5a)

* test(free): hold qa-deadline's full-pipe case on a FIFO, not a paused Bun stream

Bun gives a child 'pipe' stdio a unix socketpair, so whether the 2 MB fill
actually blocks depends on the parent's reader and the host's socket buffer
sizes. CI (run 36761671811, both attempts) saw exit 0 after ~130 ms; with
net.core.{w,r}mem_default=4 MiB locally the old case fails 3/3 the same way.
A FIFO the test never reads is bounded by the kernel pipe buffer, so the
receipt write genuinely blocks and the 5 s settlement deadline must fire.
The 7 s bound now starts once the preload has queued the write.

* test(free): event-driven waits in pty-output-wake

close-releases-observers: the 500 ms wall race becomes an ordering check
(the waiter is released while only SIGINT has been sent, before close's
escalation finishes), and the Bun.spawn spy fakes only the PTY launch so a
shard neighbor's in-process spawn cannot add a stray SIGTERM (CI runs
36015568981, 36036582721, 36074636848).

continuous-redraws: the fixture spinner stops once the observer has made
five coalesced reads, so the run reaches its work deadline with no redraw
in flight. Streaming right up to the deadline raced the helper's screen
drain and failed as 'PTY screen parse failed; viewport is incomplete'
(5 CI runs 09-30..10-03; 4/40 locally under 8 busy loops, 0/40 after).

* test(free): session-runner long-capture handshake waits for the collected Read event

The fake CLI's init line arms the runner's work-phase timer, so the worker's
handshake (work-ready + a >200 s timer) could pass before the runner's read
loop had collected the Read event printed just before work-ready. Advancing
the clock then killed the run with the Read lost: readSection false (CI run
37194511124). The worker now also waits for the runner's own progress line
for that Read. Forcing the observed ordering (work-ready 200 ms before the
Read line) fails the old test deterministically and passes the new one.

* test(free): budget-override restores the CI variables it rewrites

Its provenance cases set and then deleted CI, GITHUB_ACTIONS, GITHUB_REF_NAME,
GITHUB_SHA and the GitLab CI_* names without restoring them, so in a CI shard
every later file ran with CI unset. qa-only-cleanup's real browse daemons
then launched Chromium without --no-sandbox, the sandbox failed on the
runner, and both real-Chromium cases timed out with 'QA cleanup fixture did
not become ready' (shard 12 attempt 1 of six runs on 10-04, retry alone
green). Retained startup log: 'Chromium sandboxing failed!', child env with
no CI. Reproduced 3/3 with CI=true, userns denied and budget-override ahead
of qa-only-cleanup in one process; 0/3 after.

* test(free): pr-shared-input-selection names its base and package history

Every selection now passes EVALS_BASE and packageVersionOnly explicitly, so
no case reads the checkout's git state. Before, 12 calls ran
detectBaseBranch and the cumulative case diffed package.json against
merge-base(origin/main, HEAD) — the ambient input that turned main red in
runs 36572856858 and 36594314027. A PATH git spy counts 14 git calls in the
old file and 0 now.

* feat(evals): derive PR-lane dependents for unmapped files instead of restoring the full gate

scripts/pr-dependencies.ts derives, from the checked-out tree, which paid
cases consume each repository file: test import closures, repo paths and
path.join segments in code/shell/skill text (whole-line comments and
selection data excluded), bin script names, compiled binaries by outfile
path (scripts/build.sh), package scripts, template placeholders through
RESOLVERS, and host configs by host id. The global touchfiles' import
closure is global.

PR selection: an unmapped file with derived consumers puts the run in the
new 'dependents' mode (every dependent gate case and judge, no profile cut);
a tracked file under a derivable directory that nothing reaches is exempt;
periodic/marathon workflows, .gitignore and tsconfig.test.json never run
the PR gate. PR_FULL_GATE_FILES is the fail-closed list (deps, CI image,
setup, build, evals.yml and its actions, test preload, tsconfig.json,
.gitattributes, the skill generator and preamble resolvers, the eval
policy). Untracked or underivable files restore the full gate with fix
text. The summary and PR comment list derived dependents.

* feat(evals): replay misses count derived dependents; report wave vs ordinary pushes (CEO-23)

* test: drop FREE_FIXTURES entries for fixtures deleted in W8b

* test: re-shape the census attribution fixture to qa-workflow and carve case shards

* test: census fixture case order

* ci: 420 s PR-lane slices with per-slice ceilings; periodic tracking issue only on main

evals.yml joins the census lanes at the 420 s slice budget (W5c/CEO-15) and
indexes each eval slice's job timeout from .plan.sliceCiTimeoutMinutes with
the slice-deadline clock as its first step (W2c/ENG-2). evals-periodic.yml's
tracking-issue upsert and close run only on refs/heads/main, so a branch
dispatch whose gate census is skipped (CEO-04) never opens or closes #2755.

* docs: integrate lane docs for the audit wave (eval-bg backends, PR fallback, policy v2, ceilings, evidence)

- CLAUDE.md: 'Running evals as an agent' describes scripts/eval-bg.ts's
  dispatch and local backends, forcing flags, the sentinel and status;
  eval:select's PR-profile default; prompt-structure helper and value-bar
  terms. instruction-facts now requires scripts/eval-bg.ts in that section.
- CONTRIBUTING.md: decision table gains test:health, eval:select default,
  eval:bg backends and the include_gate_census / evals_all dispatch lines;
  420 s runners and per-runner ceilings; flake ledger, OSV tracking issue
  and expiry test, weekly test health; prompt-structure guidance.
- AGENTS.md: build commands name the eval:bg backend choice and test:health.
- docs/TESTING_INTERNALS.md: anchors the fix texts point to
  (#pr-paid-lane-fallback, #pass-rate-policy-versions, #harness-version,
  #flake-ledger, #duration-seed), receipts/recovery/debounce, per-slice
  ceilings, the slice deadline with not_run/hung and checkpoints, the eval-bg
  cap formula in place of the detach floors, EVAL_POLICY v2 history, carve
  case shards via --case.
- docs/test-audit-2026-10.md: CEO-23 replay (165/168 -> 164/168
  full-fallback, 0 misses), ENG-17 slice table (re-measured on this tree),
  D2 prose-pin metric.
- TODOS.md: progress note on 'Let pass-rate history decide the rest'.
- test/testing-internals-anchors.test.ts: every TESTING_INTERNALS.md#anchor
  named in code must match a heading.

* test(free): hold qa-deadline's blocked-output-pipe receipts on a FIFO

The five 'guard %s receipts survive a blocked output pipe' cases filled a
paused Bun child pipe with 2 MiB. That pipe is a unix socketpair, so the
fill only blocks while the host's socket buffers are smaller than the write:
with net.core.{w,r}mem_default=4 MiB the old cases fail 13 of 15 case runs
(the guard finishes before the test resumes the stream). The held stream is
now a FIFO the test drains only after resume(), bounded by the kernel pipe
buffer; Windows keeps the paused pipe. Bounds and assertions are unchanged.

* test(free): qa-deadline waits for a written pid, not just the pid file

DRIVER and LEAF write their pid with writeFileSync, so under load ready()
can see the file before its digits and fail 'expected > 0, received 0'
(seen once in 150 loaded runs). After any early failure the finally
SIGKILLs the CLI, which orphans the detached command group; a leaf whose pid
file is not yet readable then keeps the output stream open and the case
hangs to its 15 s timeout (2/80 old-file runs and 3/310 FIFO-only runs
under 8 busy loops; the instrumented hang showed the CLI already SIGKILLed
by the finally). ready() now polls within the same 3 s bound until the file
holds a positive pid.

* fix(evals): a deleted file selects the dependents of the live files that still reference it

PR selection treated every path absent from the head tree as an unknown
dependency, so any PR that deleted a file forced the full gate. A deleted
path is now placed like a live one, against the head tree: a matching
touchfile selects its cases; live code, skill text or a full-gate input that
still references it (path, extensionless import target, relative import,
bin name, ancestor directory, compiled-binary outfile; whole-line comments
and data files excluded) contributes its dependents, a full-gate referencer
restores the full gate with a 'deleted but still referenced' fix, and an
unreferenced deleted path has no dependents. Deleted PR_FULL_GATE_FILES
entries still force the full gate. Tests that used absent paths as stand-ins
for new unmapped files now use tracked root files (or an explicit tracked
set); the CEO-23 replay counts misses through those references too.

* docs: integrate free-suite lane docs (seed anchor, Windows lane, native qualification, install fixture, flake rules)

- docs/TESTING_INTERNALS.md: '### Free suite duration seed' (the anchor the
  seed messages link) with DX-13, the 99th-percentile packing, --ci-plan
  warning, --ci-verify overruns and the CEO-10 seed ratchet; the Windows
  6-job lane, its Windows-measured seed and refresh dispatch, curation and
  WINDOWS_CURATED_FLOOR; native-qualification.yml modes; the merged
  install fixture; test-only timing knobs; the flake-ledger job summary,
  Windows ledger names and three free-suite flake rules; zsh in the
  Ubicloud mirror.
- scripts/test-health-report.ts links #free-suite-duration-seed, so the
  two seed messages share one heading (the anchor test caught the split).
- CONTRIBUTING.md: Windows seed refresh and native qualification rows;
  seed-source pointer. AGENTS.md: Windows six-job lane.
- docs/cso-release-qualification.md: the free CSO Docker job runs only
  cso-docker-integration.test.ts.
- docs/test-audit-2026-10.md: free-suite evidence lines.
- TODOS.md: CEO-11b progress note on the pre-push hook hang.

* test: final duration seeds on the integrated tree; retire the emptied cookie-validation-phases file

Linux seed re-recorded on Ubicloud standard-16 and the Windows seed from
dispatch run 37227140871, both at c903310. The seed allowlist drops the three
entries that are no longer over the ceiling. cookie-validation-phases lost its
validation-phase pins with W8f and its Windows/Dia pins moved to
windows-native-workflows with native-qualification.yml, so the file is
deleted and the curated Windows floor rises to 638. The Windows recorder writes
the seed at its default path so GSTACK_FREE_TEST_DURATIONS never leaks into
timed tests.

* test: re-express stale PR-lane pins against the new evals.yml contract

- ci-eval-cache: the profile/fresh expressions now include evals_all=false
  dispatches and pr_receipts/evals-fresh; the PR store is restored only by
  recover-receipts (still scoped to repository_id + PR, PR events only),
  plan-slices takes it as an artifact and never touches the cache, saves
  stay PR-only, EVALS_CACHE_PR binds pr_receipts dispatches, and the report
  verdict artifact carries report receipts.
- ci-paid-coordination: plan-slices needs only the two ubuntu coordination
  jobs (never the image); the fork/Dependabot clause is unchanged on
  plan-slices and also gates debounce and recover-receipts; only recovery
  holds actions: read.
- qa-supervision-selection: auq-consistency and auq-verbose-vs-carved-ab
  (W1b) reach claude-pty-runner and pty-screen through auq-sdk-capture,
  exactly as auq-format-gate does.
- paid-retry-supervision: the full-validation plan uses a tracked full-gate
  input (setup); an absent path is now a deletion placed by its references.

* ci(windows): record the Windows seed at the default path

* chore: HARNESS_VERSION non-behavioral decision for the audit-wave integration

* v1.91.20.0 release metadata: test, eval and CI audit wave

* test(compare-board): wait for the post-submit state the feedback POST settles

The two post-submit assertions read the board once, but the board disables
the submit button and shows the message only after its feedback POST
resolves. On a loaded Ubicloud shard the read beat the round trip (FLAKY-PASS
in the final free-suite run). Delaying the POST by 400 ms reproduces both
failures at HEAD; polling for the settled state passes.

* test(plan-eng plan-mode): run the seeded STOP-gate smoke in its own fixture project

The seeded plan proposes a custom test runner, so the review's Step 0 reads
the working tree's test setup. In the gstack checkout that is gstack's own
sharded runner, and the case timed out at 300 s in census 37228573062 after
this wave reshaped the runner. It now runs in a four-file Bun project with
git history, with the product-notice suppression auto-decide-preserved's
standalone fixture already uses. Local pass on Bun 1.4.0 + Claude Code
2.1.284: asked in 121 s, seed tokens observed.

* test(plan-mode evidence): pin the seeded eng smoke's isolated fixture cwd and env

* ci(image): Git >= 2.44 so paid shared-libs cases run the supported safe-git path

bin/gstack-safe-git prefixes every /deslop-shared-libs Git read with
--no-lazy-fetch, which noble's git 2.43 rejects (exit 129). The eval image
therefore ran every paid shared-libs case on the unsupported-Git fallback:
local history unavailable, branch HEAD unknown. shared-libs-read-only failed
on exactly that in PR run 37230639146 ("Current branch HEAD: unknown. The
safe-git probe failed (unknown option: --no-lazy-fetch, git 2.43.0)") and in
2 of 74 earlier PR runs. The image installs current Git from the Ubuntu Git
Maintainers PPA and fails its build if --no-lazy-fetch is missing; the
deliberate unsupported-Git case keeps its fake Git.

* eval: pool matching branch census trials into main's pass-rate series (D1 option b)

Approved 2026-10-05. eval:pass-rates also reads completed branch census runs
in the weekly window. A branch trial counts only toward a series a main run
also has (same case-owned bytes, HARNESS_VERSION, model and CLI), so a branch
extends main's history but never starts or becomes a case's current series;
weeks for quarantine expiry still count main runs only. The D1 backtest put
this at 67 of 210 cases with enough trials for the entry rule, against 0 of
195 on main alone.

* C2: /qa defines its outcome filename fields; QA report templates name the measured timing fields

Low judge samples in failing panels named both: qa workflow (37186854666)
'an undefined {user} in the outcome filename', and qa-only workflow
(37198445662) 'template asks for Duration / durationMs totals while
reporting.md mandates Probe budget and Guarded command time'. The qa
union stays under its 1.11 size ratio (93292 of 93294 bytes).

(cherry picked from commit e14c0c1de1)

* C2: Browser Quick gets a feasible budget; QA loop names its directory and stop path

Judge rationales on the qa-only panels (2 of the last 3) cited the 30 s
Browser Quick budget: homepage + 5 targets, each a checkpoint write and a
guarded command, left ~5 s per probe. Quick is now 180 s (method text: 3
minutes); the qa-only-no-fix paid check expects the same native deadline.
PROBE_DIR points at its source line, a stopped loop goes to the final
report steps (annotations, materialize, Markdown), and /review and /ship
say that after smoke expiry only plan checks rerun in revalidation.

(cherry picked from commit 78d4a2a343)

* qa: fit the C2 judge fixes under the qa and review size caps

Brings GSTA-21's qa.ts trims (3bd625d, ce73af0) for the cherry-picked C2
wording: PROBE_DIR keeps 'owned', the stop line points at §4, and the
post-expiry rule is one sentence, so /review fits its cap. qa measures
93,303 / 84,049 = 1.11010 against the same 1.1102 cap GSTA-21 set. The
qa-only workflow judge passed 10 of 10 local trials on this wording (7 of 10
before the C2 fixes).

* test: qa-only fixture keeps its caller-set 30 s deadline

The qa-only-no-fix fixture tells the model to start the guard with 30 s
(a caller limit), so its deadline assertion's default stays 30 000 ms; the
product's Browser Quick default (180 s) does not apply to it. Reverts the
helper and its test to their base.

(cherry picked from commit e36e622add)

* test: qa-quick sets a caller probe limit and drains past its session budget

C2 raised Browser Quick's native budget to 180 s. qa-quick is the only gate case
on the native budget, and its wall went 194 s (main periodic, pre-C2) -> 254 s and
274 s (this PR's runs) -> 300 s session timeout (run 37242691913): the agent now
probes every navigation target with a checkpoint, then needs ~80 s to report.
Like qa-only-no-fix, the eval now sets a caller probe limit (30 s), scopes the
fixture, and gives bun's outer timeout the session drain margin instead of racing
the 300 s session. The product's 180 s budget and the session budget are unchanged.
Diagnostic rerun passed in 195 s.

(cherry picked from commit f8dc64031e)

* chore: restore the audit wave's package scripts after the main merge (version 1.91.23)

* qa: keep main's one-sentence post-expiry rule for /review and /ship

The C2 variants ("step 4c reruns plan checks only" and "even in 4c") read
to the review workflow judge as conflicting with Step 5.8's repeat-pass
reruns: 6 of 10 local trials passed with the longer sentence and PR run
37248650879 failed on the shorter one. Main's "Post-expiry smoke rechecks are
not-run." passed 10 of 10. qa (9/10), qa-only (10/10) and
ship-managed-hook-refresh (10/10) were measured on the same tree.

* v1.91.24.0: move off the slot #3036 claims
2026-10-05 01:29:54 +00:00

50 KiB
Raw Blame History

Test audit 2026-09: evidence

Evidence for the test-reduction branch (plan approved through /autoplan: "A, approve as-is"; UC1 resolved as delete). Base: 65bfb0c (v1.91.6.0). Wherever the plan asks for a PR-body table or verify item, it resolves here.

Commits

Commit Workstream
G Test-infrastructure dead code
F Product tests that fake the product → real-boundary tests
A Tests of dead eval code (reachability-driven)
B-cleanup Paid lane cleanup (B1–B4, B6, B7)
C Retire the never-green finding-count cluster, trim its helpers
D Fold per-incident series into detector owners
H Startup readiness marker for the plan-count history PTY
E Derived touchfile closure invariant (behavior change)
B5 Tier-lane skip and census judges (behavior change)
B8 Default capture model for eleven paid evals (behavior change)
Guard Ratchet, shared resolver, CONTRIBUTING, TODOS, portfolio, this doc
Release Durations refresh, CHANGELOG, VERSION, docs sweep

C0 triage (recorded before commit G)

Recorded 2026-09-29 before commit G. Sources: weekly Periodic Evals runs 34812905093 (09-14, sha per run), 35567915613 (09-21, a6b3a575), 36385945043 (09-28, 65bfb0c-era). Preflight: gh authenticated (git.capy.ai proxy, account garrytan); gh run download 401s but the REST actions/artifacts/<id>/zip route works; all three runs' artifacts are retained (not expired). Per-file evidence: 09-28 = uploaded per-shard PTY artifacts (observation.json + terminal logs); 09-14/09-21 = per-shard failure tail in the eval-slices job log (bun output + observation dump + last-3KB terminal evidence). Local copies: audit workspace: c0/.

Classes: product = the skill did not ask per finding; harness = PTY/classifier/timeout/launch; budget = live model still progressing when the deadline hit. Agreement rule applied: harness and budget are both non-product classes; a file is deleted when every artifact is harness or budget (no artifact shows product), kept+excluded otherwise.

File 09-14 09-21 09-28 Class Action
skill-e2e-autoplan-chain harness: session exited in 13 s, no phase marker (launch) harness: observer saw only the phase-3 marker after context compaction; transcript references CEO, Design and DX methodology files and "Phase 3 complete" budget: timed out after ordered phase-1, 2, 2.5 hits (2 attempts, 160 min) harness/budget delete
skill-e2e-plan-ceo-finding-count harness: 5-finding case exited in 11 s; paired case timeout harness: model asked 8 finding decisions (SQL lookup, Email errors, Orders load, Tests, Sequencing, TODO…), classifier labelled all preReview → no_review_questions harness: classifier threw "Unsupported current CEO decision; cannot exclude it from the 4–7 count" (paired case reached plan_ready, review=2) harness delete
skill-e2e-plan-eng-finding-count harness: per-finding question D3 rendered; fingerprints are spinner garbage, step0=4 review=0 harness: retired legacy oracle "mandatory legacy regression coverage absent" with reviewCount=9, then shard wall timeout harness: model asked D1–D8/D9 per-finding decisions, all labelled preReview → deadline with review=0 harness delete
skill-e2e-plan-design-finding-count harness: exited in 1.7 s harness: BAND FAIL above ceiling (review=8 > 7 for 5 findings; asked per finding plus extras) budget: timeout at review=4 and review=5, still asking harness/budget delete
skill-e2e-plan-devex-finding-count harness: exited in 2.1 s harness: seed classifier missed missing-quickstart although reviewCount=9 and outcome=plan_ready; retry hit shard wall timeout pass (plan_ready, review=6) harness delete

No artifact shows a product failure, so C3's issue is not opened; C0-kept TODO entry not needed.

Security mapping (F)

| design/test/serve.test.ts mirror 'path traversal protection' (5) | design/test/serve.test.ts real serve() reload confinement | removing startsWith(allowedDir) guard in design/src/serve.ts → test 1 fails | | browse/test/terminal-agent-internal-handler.test.ts 1–3 (internalHandler/route source greps; auth gate for grant+revoke) | browse/test/terminal-agent-integration.test.ts "/internal/grant and /internal/revoke bearer auth" (no/wrong/valid × grant/revoke + state effect) | revoke route rewritten without internalHandler (no bearer check) → "revoke: no token…" and "unauthenticated revoke…" fail | | server-security-surface "/health carries no security field and server.ts does not import getStatus" (#2557) | extension-token "GET /health is liveness-only" (real /health body, default + headed/pinned-origin) | injecting security: 'protected' into the /health body → 2 fail | | server-security-surface "security.ts no longer exports the unfed status surface" | same /health body check: the only consumer of getStatus was /health.security; an unused export has no user-visible effect | (covered by the row above) | | server-security-surface "the sidepanel shield markup is gone" | same /health body check: the shield's only data source was /health.security, now asserted absent | (covered by the row above) | | server-security-surface:60-66 "server.ts still consumes the sidecar on the inject-scan path" (ENG-OV9) | pty-inject-scan "/pty-inject-scan — L4 sidecar verdict drives the response" (real buildFetchHandler, sidecar client mocked in a child bun test) | replacing if (sidecarAvail.available && verdict !== 'BLOCK') with if (false) in server.ts → fails | | server-security-surface:68-76 "security.ts keeps the pure combiner + canary exports" | browse/test/security.test.ts imports and exercises THRESHOLDS, combineVerdict, generateCanary, injectCanary, checkCanaryInStructure, extractDomain | un-exporting injectCanary → SyntaxError "Export named 'injectCanary' not found", security.test.ts fails | | server-security-surface "/health stays liveness-only: no token in any mode" | extension-token "GET /health never carries a token (IRON RULE)" (3, existing) + liveness-only test | injecting token: authToken → 5 fail | | server-auth "/health never serves a token — no headed-mode or chrome-extension carve-out" | extension-token IRON RULE tests (headed, pinned Origin, both) | injecting token: authToken → 5 fail | | server-auth "/health does not expose currentUrl or currentMessage"; security-audit-r2 "/health endpoint security" (2) | extension-token "GET /health is liveness-only" | injecting currentUrl: 'x' → 2 fail | | sidebar-tabs "/health no longer surfaces agentStatus or messageQueue length" | extension-token "GET /health is liveness-only" (also asserts terminalPort survives) | injecting agentStatus: 'idle' → 2 fail | | security-audit-r2 "Task 1: validateOutputPath uses realpathSync" source greps (4) + behavioral (5) | browse/test/path-validation.test.ts "validateOutputPath — symlink resolution" + "validateOutputPath" allow/deny cases (now importing path-security directly) | replacing both realpathSync resolutions in validateOutputPath with the unresolved path → symlink cases fail | | security-audit-r2 "results.push is present in the loop block"; "viewport case uses rawW/rawH" (identifier greps, not security contracts) | kept siblings: "validateOutputPath appears before page.screenshot() in the loop", "viewport case clamps width and height" | n/a — identifier names only | | test/skill-e2e-brain-privacy-gate.test.ts (paid, never green): privacy question fires once before any artifacts egress | test/gstack-skill-start.test.ts 'artifacts-sync consent is asked before any artifacts egress, and only in interactive sessions' | dropping the sync-mode gate on the daily pull → fails (pull stamp written with consent pending); dropping the interactive-only condition → fails (spawned session gets the gate) |

Mixed-file and consolidation inventory

F (product tests that fake the product)

File Block Decision
design/test/serve.test.ts whole file (16 tests against an inline mirror server) delete; replaced in place by 2 tests driving the real serve() on an ephemeral port
test/gbrain-init-rollback.test.ts 3 tests running a drifted local bash copy delete; rollback contract moved to test/gbrain-init-voyage-code-3.test.ts executing the template-extracted blocks
test/gbrain-init-voyage-code-3.test.ts local-copy voyage cases (4) move: now execute each template init block (3 sites)
test/gbrain-init-voyage-code-3.test.ts "demonstrates the #1798 collision" delete (tests zsh itself)
test/gbrain-init-voyage-code-3.test.ts template-grep count tests (3) keep (merged into one "template alignment" test)
browse/test/browser-manager-unit.test.ts "signature accepts an optional exitCode argument", "server.ts callback forwards exitCode…" delete (tautologies); real owner: server-factory "buildFetchHandler chains cfgBrowserManager.onDisconnect"
browse/test/memory-command.test.ts "12. text mode renders modificationHistory with evicted-count when > 0" delete (compares two local literals); gap: evicted-count suffix untested at owner
test/ios-qa-swiftui-tap-regression.test.ts (+2 fixtures, 98 KB) whole file delete
test/memory-ingest-no-put_page.test.ts whole file delete; gstack-memory-ingest.test.ts fake gbrain exits 99 on put/put_page
browse/test/terminal-agent-internal-handler.test.ts tests 1–3 delete; replaced by terminal-agent-integration "/internal/grant and /internal/revoke bearer auth" (3×2 + state effect)
browse/test/terminal-agent-detach-reattach.test.ts tests 1, 4, 5, 6 delete (dup of terminal-agent-ring-buffer-runtime)
browse/test/terminal-agent-detach-reattach.test.ts tests 2, 3, 7–10 keep
browse/test/server-security-surface.test.ts all 6 delete; see security mapping
browse/test/server-auth.test.ts "/health never serves a token — no headed-mode or chrome-extension carve-out", "/health does not expose currentUrl or currentMessage" move → extension-token "GET /health is liveness-only" + IRON RULE
browse/test/security-audit-r2.test.ts "/health endpoint security" (2) move → extension-token "GET /health is liveness-only"
browse/test/security-audit-r2.test.ts Task 1 block (4 source + 5 behavioral), "results.push is present…", "viewport case uses rawW/rawH…", AGENT_SRC delete; path-validation owns validateOutputPath
browse/test/security-audit-r2.test.ts escapeRegExp behavioral test keep, imports path-security directly (meta-commands re-export deleted)
browse/test/security-audit-r2.test.ts state-load, inbox, responsive, CSS validator ordering greps keep (only guard)
browse/test/sidebar-tabs.test.ts "/health no longer surfaces agentStatus or messageQueue length" move → extension-token liveness-only (also asserts terminalPort)
browse/test/sidebar-tabs.test.ts "browse/src/sidebar-agent.ts is gone", "sidebar-agent test files are gone" delete
browse/test/sidebar-ux.test.ts "stop button style exists", "stop button uses error color", "experimental-banner no longer uses amber…", "tool description uses system font not mono" delete + dead CSS (.stop-btn, .experimental-banner, .agent-tool, .agent-reasoning; 67 lines)
browse/test/sidebar-ux.test.ts "switchTab has bringToFront option" (dup of :50), "shutdown kills the terminal-agent via identity-based kill" (dup of terminal-agent-pid-identity), "quick actions toolbar has cookies button" (dup of sidebar-tabs quick-actions) delete
test/skill-validation.test.ts "Generated SKILL.md freshness" (3) delete (C14); gen-skill-docs placeholder regex widened to \w+
test/gen-skill-docs.test.ts "generated header is present in SKILL.md", "…in browse/SKILL.md" delete (C14); "every skill has a generated SKILL.md with auto-generated header" covers both
test/post-rename-doc-regen.test.ts "top-level SKILL.md exists and is regenerated" delete (C15)
test/static-no-legacy-writes.test.ts "office-hours/SKILL.md uses --log-session, not raw echo append" delete (C15); .tmpl sibling + freshness
make-pdf/test/coverage-gaps.test.ts all 19 cases move → diagram-prepass.test.ts (18) and render.test.ts (screenCss)

A (dead eval code)

Reachability tool: audit tool reach.ts (ts-morph; roots = every non-helper file importing test/helpers + bin/gstack-model-benchmark + the outside-voice shim; edges = identifier → top-level helper declaration; BFS to a fixed point; --prune removes unreached declarations and unused imports, rerun until 0). Baseline at 65bfb0c: 12 dead declarations = the 10 A4 names + execGit (auq-sdk-capture) + invokeAndObserve (claude-pty-runner). After A's test deletions: 33 dead (eng-seeded-coverage oracle closure 2,626 lines, autoplan-artifact-permission approvers 474, matchesAutoplanDigestRows 86, the 12 above); pass 2 → 0.

File Block Decision
25 A1 pure files + eng-native-seed-contract.test.ts all delete (all 61 native-seed-contract tests call evaluateEngSeedCoverage; its 3 blocks with live pty-runner asserts replay the plan-eng-finding-count callback; hasNativePlanTerminal / isQuestionlessNativePlanExit / classifyPlanCountFrame keep owners plan-count-pending-exit, plan-count-empty-review, plan-count-completion)
eng-count-ad-v2 "first attempt … D9 handoff", "prior successful plan Write…", "closed handoff…", "new task references…", "conditional closure…" delete (isEngCompletionHandoff)
eng-count-ad-v2 "new first-finding and handoff paths…" keep first-finding half (engFirstReviewAUQ); handoff half deleted
eng-count-ad-v2 census() keep, dead handoff predicate argument removed (retry census unchanged: administrative 0)
eng-count-ad-v2 6 live + touchfile test keep (touchfile test loses the eng-completion-handoff path line)
eng-resolution-block-position tests 1–3 delete (handoff / seed oracle)
eng-resolution-block-position "saved native Header and Options…" (createEngBatchingIssueCounter) keep
eng-seeded-completion-ai "complete native navigation preserves conflicting current states…" delete (handoff)
eng-task-pause-navigation-f359 all check()/handoff tests delete
eng-task-pause-navigation-f359 "handoff alone never supplies a native terminal…" keep (hasNativePlanTerminal); admin set now the completed call's signature
eng-next-handoff-ah 18 handoff tests + parser-ACK replay delete
eng-next-handoff-ah "exact final exit/report replay…", "actual pending ExitPlanMode…" keep (hasNativePlanTerminal, isCurrentPlanApprovalScreen)
eng-published-navigation ~150 handoff checks delete
eng-published-navigation retry, real-completed, D19, investigation, cf74 terminal replays keep (hasNativePlanTerminal); dead handoff/phase asserts inside removed
eng-seeded-coverage.test 23 oracle blocks + 6 describes built on evaluateEngSeedCoverage/isEngSeedDecisionAUQ delete
eng-seeded-coverage.test "Eng semantic native evidence boundary", touchfile test, "batching caller counts…" keep
autoplan-edit-digests-al / clipped-suffix-aq / pending-artifact approver cases (8/8/8) delete
same three recorder/launcher cases keep
11 A2 replay files all delete
autoplan-permission-viewport 27 tests (autoplan-phase-order + pty-current-screen) delete; captured settings-overwrite card assertion moved to claude-pty-runner.unit "isPermissionDialogVisible"
autoplan-phase-observation 44 tests (all via phase-order helpers) delete
eng-finding-fixture.test seeder + legacy-auth fixture tests (5) delete
eng-finding-fixture.test 2 prompt-builder pins of the paid eng-finding-count file keep until C (plan said "four prompt-builder tests"; only 2 are)
ceo-paired-payment-fixture, design-ui-scope, plan-skill-completion, pty-current-screen, required-reads, transcript-section-logger tests all delete
plan-count-fixture 3 design-ui-captured cases + captured-question fake plumbing delete
autoplan-phase-handoff readPlanSkillCompletion assertion in "captured parent text…" delete line; test kept
plan-seed-submission PtyCurrentScreen decoder swap to production createPtyScreen (58/58 pass)
touchfiles.test plan-skill-completion path in "native completion changes select the Design UI gate" removed from the each-list

B-cleanup (B1–B4, B6, B7)

File Block Decision
skill-llm-eval-spec, skill-e2e-spec-execute, gemini-e2e (+ gemini-session-runner + test), skill-e2e-ship-idempotency, 2 overlay opus-4-7 *-sonnet wrappers (+ fixture entries), skill-e2e-conductor-prose, codex-e2e-plan-format, skill-e2e-brain-privacy-gate all delete (B1/B7)
conductor-prose-observation-ao.test.ts + fixture all (evaluates the deleted paid caller's source) delete with its paid file
plan-tune-cathedral-fixture.test.ts all (evaluates the cathedral file's source under injected fakes) delete — the cathedral scenarios now run directly in the free suite (B3)
skill-llm-eval.test.ts "regression vs baseline" delete (B2)
skill-llm-eval.test.ts "command reference table", "snapshot flags reference", "browse/SKILL.md reference" collapse → one union judge "browse/SKILL.md reference" (B2)
skill-llm-eval.test.ts "baseline score pinning" fold into the union judge (pins eval-baselines.json browse_skill)
skill-e2e-opus-47.test.ts 3 negative routing controls move → skill-routing-e2e "journey-negatives" (same ≤1-of-3 bound); positives already in skill-routing-e2e
skill-e2e-ios.test.ts "ios-qa E2E (with device)" HAS_DEVICE stub delete (B3)
gstack-skill-start.test.ts new "artifacts-sync consent is asked before any artifacts egress…" add (B7: existing pins did not assert ordering)
paid census literals (paid-retry-supervision, paid-overlay-scheduling, overlay-lifecycle, overlay-measurement, paid-shards, touchfiles, periodic-fixture-selection, codex-eval-selection, paid-pr-profile) counts / key lists updated for the removed files and keys (no assertion removed except ones naming deleted keys)

C (retire finding-count cluster, C2 helper trim)

Rule: a free test block is deleted when every assertion subject is outside the post-C live closure (the pruned helpers, or a deleted paid file loaded through a registration adapter); a block that only uses dead code as an input builder for a live subject is kept and the builder is replaced or restored (rows below). LIVE blocks are kept. Touchfile self-assertions lose only the removed keys (E deletes them).

File Block Decision
test/skill-e2e-autoplan-chain.test.ts whole file delete (C1; C0 class harness/budget, see triage)
test/skill-e2e-plan-ceo-finding-count.test.ts whole file delete (C1; C0 class harness/budget, see triage)
test/skill-e2e-plan-design-finding-count.test.ts whole file delete (C1; C0 class harness/budget, see triage)
test/skill-e2e-plan-devex-finding-count.test.ts whole file delete (C1; C0 class harness/budget, see triage)
test/skill-e2e-plan-eng-finding-count.test.ts whole file delete (C1; C0 class harness/budget, see triage)
84 free test files (list in commit) whole file delete: every block exercised only pruned helpers or deleted paid files
test/autoplan-eval-budget.test.ts whole file (AUTOPLAN_CHAIN_BUDGET, dedicated slice) delete; timer-safe/explicit-override checks moved → eng-finding-retry-budget 'ordinary tiers and registered allocations remain unchanged'
test/plan-review-native-default.test.ts 3 tests (omitted multiSelect default) move → plan-review-decisions 'an omitted native multiSelect receives the false default only in evaluator input' (removal-checked)
test/autoplan-chain-fixture.test.ts 'native sequencing config reaches the real CLI reader…' move → plan-count-fixture.test.ts; other 3 tests delete (chain source pins)
test/eng-finding-fixture.test.ts, test/design-finding-fixture.test.ts whole file delete (read/import the deleted paid files)
test/ceo-current-decision-record.test.ts (PROD-TOUCH) all 28 delete: reads plan-ceo-review template only as input to the retired ceo-payment-findings counter
test/devex-finding-fixture.test.ts DX registration (8) + materialized devex-existing-sdk checks (5) delete (fixture consumed only by the deleted DX count eval); keep 'every host exposes the DX per-call rule…'
test/ceo-finding-fixture.test.ts 'native count registration: %s' (11) delete (imports the deleted paid file); fixture tests keep
test/eng-semantic-terminal.test.ts evaluateEngTerminalReview/buildEngSeedDecisionInput blocks (6), registration loops (7) delete; 'real native Exit…' and 'a late substantive answer…' keep with a direct id callback in place of the dead assessor
test/eng-seeded-coverage.test.ts 'Eng semantic native evidence boundary' describe, 2 mixed, touchfile test delete (buildEngSeedDecisionInput dead; validator owned by plan-review-decisions)
test/plan-count-fixture.test.ts (PROD-TOUCH) real PTY children worker keep; dead design/devex predicates replaced by inline caller policies; dead-classifier assertion removed
test/plan-count-native-input.test.ts design outside-voices cases keep; pickDesignCountOutsideVoices replaced by inline caller policy; autoplan routing test delete
test/plan-pending-question-pty.test.ts hook PTY test keep; autoplanSetupDecision navigation replaced by the fixed native key sequence
test/helpers/claude-pty-runner.unit.test.ts findModeOption (7), design/devex Step0 + first-review (14) delete; 2 prompt-parser tests keep with the dead boundary assertion trimmed
test/autoplan-method-read-audit.test.ts, autoplan-phase-handoff, autoplan-publication-guard, plan-count-session-cwd, autoplan-preconfigured-onboarding-ar (PROD-TOUCH) all but chain caller pins keep; helpers autoplan-method-read-audit.ts / autoplan-preconfigured-fixture.ts restored (they adapt the production phase-publication hook / skill-start)
test/autoplan-artifact-recorder, autoplan-edit-digests-al, eng-test-plan-edit-approval recorder tests keep; readPendingAutoplanArtifact restored (recorder is imported by claude-pty-runner)
test/carve-guards (helper) autoplan externalTest behavioral 'none' (chain was its only section-read proof; TODOS entry)
20 replay files (ceo-completion-handoff-m/-o, ceo-handoff-y, ceo-count-ad-v2, design-count-native-8525, …) MIXED/DEAD blocks delete; LIVE blocks keep (hasNativePlanTerminal admin exclusion owned by eng-published-navigation / eng-next-handoff-ah)

Helpers deleted (11): autoplan-setup-question, ceo-approach-pick, ceo-completion-handoff, ceo-payment-findings, design-artifact-question, design-count-fixture, design-count-outside, design-count-review, devex-count-fixture, devex-seed-coverage, eng-count-question-policy. claude-pty-runner and eng-seeded-coverage trimmed to the paid-root closure. 135 fixtures orphaned by these deletions removed (orphans.py diff against fe011e0), plus test/fixtures/devex-existing-sdk/. Known selection effect (not a regression by the plan's definition, E derives the closure): lib/autoplan-phase-publication.ts, bin/gstack-decision-log, lib/gstack-decision.ts and the recorder/dx-navigation helper imports of claude-pty-runner selected only the retired evals and now select none until E. Out of C2 scope, left as is: ceo-finding-fixture seedCeoPaymentProject/pickSuppliedCeoPlanStart and test/fixtures/ceo-existing-payment (no surviving paid consumer; not in the C2 helper list).

D (consolidate per-incident series)

Mechanism: each incident file is folded verbatim into its detector's owner test as one describe('<incident>') block (audit tool merge-into.ts); imports are hoisted and per-incident bindings restored as local consts, so every case runs the identical code against the identical fixture. Dropped only: tests asserting the incident file's own touchfile registration (E-type; the path no longer exists). Accounting per family = owner+incidents before vs owner after, pass count must equal before − dropped with 0 failures (audit tool family.sh). Touchfile lists that named an incident now name the owner (audit tool tfreplace.py). Rows are not rewritten into value tables: a verbatim fold cannot drop an incident-specific control (lane-3 C7 risk note).

Detector Owner Incident files folded (full paths) Tests before → after (self-registration dropped)
hasStaleFillRaceFinding test/ceo-section-loading-fixture.test.ts test/sdk-columnar-af, sdk-compact-sequence-aj, sdk-order-b-ag, sdk-ordered-schedule-ar, sdk-ordering-ae, sdk-original-order-ai, sdk-reported-coordination-ar, sdk-schedule-continuation-ah, sdk-stale-table-ad-v3 (.test.ts) 376 → 368 (8)
generateModelOverlay / resolveModel test/model-overlays.test.ts (new) test/model-overlay-fable-5, -gpt-5.6-sol, -gpt-6-astra, -opus-4-7, -opus-4-8, -sonnet-5 37 → 37 (0); every overlay phrase kept
coverageAuditVerdict / coverageAuditReadEvidence test/coverage-audit-evidence.test.ts test/coverage-audit-af, coverage-audit-aw, coverage-audit-shell-legend-at, coverage-checkbox-tail-av, coverage-diagram-legend-as, coverage-shell-display-aq (exercises coverageAuditReadEvidence) 149 → 145 (4)
autoplan phase completion test/autoplan-phase-observer.test.ts test/autoplan-phase-dash-ao, autoplan-with-result-au (autoplan-final-gate-ao deleted in C) 82 → 80 (2)
findNativeAutoDecision test/native-auto-decide.test.ts test/auto-decide-current-declaration, -explanatory-mode, -recommendation-scope, -saved-ai, -structured, -target-identity, auto-decision-state (auto-decide-fixture kept: real seeding) 859 → 858 (1)
claudeOutsideExecutions test/outside-voice-evidence.test.ts test/outside-background-ai, outside-voice-async 49 → 49 (0)
engStep0Boundary/engSetupAUQ/engFirstReviewAUQ test/eng-first-review.test.ts (new) test/eng-annotated-cache-au, eng-architecture-cache-av, eng-binding-retry-z, eng-binding-z, eng-cache-brief-am, eng-cache-owner-an, eng-cache-writes-as, eng-count-ad-v2, eng-declarative-as, eng-declared-retry-at, eng-first-category-af, eng-first-review-t, eng-injected-export-aq, eng-library-hooks-aq, eng-scope-y 256 → 247 (9)
hasNativePlanTerminal (completion/handoff) test/plan-count-completion.test.ts test/ceo-completion-handoff-m, ceo-completion-handoff-o, ceo-handoff-y, dx-manual-handoff-ao, plan-count-dx-handoff-o, eng-next-handoff-ah, eng-task-pause-navigation-f359, design-count-native-8525 129 → 129 (0)
createPlanCountPermissionGuard test/plan-count-file-permission.test.ts test/batching-permission-at, design-crop-gutter-ap, plan-count-crop-ak, plan-count-permission-ac, plan-count-quoted-frame-ak 125 → 121 (4)
ceo-mode-option test/ceo-mode-option.test.ts test/ceo-hold-commitment-ar, ceo-hold-posture-ag, ceo-mode-colon-at, ceo-mode-full-ad, ceo-mode-posture-ad, ceo-prerequisite-ad-v2 463 → 457 (6)
plan-scope-selection test/plan-scope-selection.test.ts test/design-scope-announcement-ao, design-scope-declaration-ak, design-scope-entry-aq, design-scope-selection-aj, eng-option-b-scope-al, plan-scope-recovery-av 90 → 84 (6)
planCountPrerequisitePick test/plan-count-prerequisite.test.ts (renamed from -n) test/plan-count-navigation-r, plan-count-prerequisite-n 38 → 37 (1)

Native-completion negative table: after C it survives in 3 files (14 per-incident copies in eng-first-review, 2 in plan-count-completion, 1 in dx-selected-navigation-ap), each applied to a different captured call and a different engFirstReviewAUQ branch. Collapsing them to one table is only sound after engFirstReviewAUQ checks native completion once at entry (each branch gates it separately today, claude-pty-runner.ts engFirstReviewAUQ); that is a harness behavior change on a paid verdict, so it is deferred (kept-vs-plan) rather than done here.

E (derived touchfile closure)

Selection regression definition (used by the E proof and the drop rule): a sample edit's --tier gate --profile pr --list output after the change is missing a paid case that the before-run selected through any path other than a free *.test.ts touchfile entry. Proof computed with computePaidCaseSelection (the function --list calls) at 689ef30 vs the E tree:

Sample edit Profile e2e before → after judges before → after lost gained
plan-eng-review/SKILL.md.tmpl pr 2 → 2 1 → 1 none none
plan-eng-review/SKILL.md.tmpl full 28 → 28 1 → 1 none none
test/helpers/claude-pty-runner.ts pr 0 → 1 0 → 0 none auq-format-gate
test/helpers/claude-pty-runner.ts full 15 → 20 0 → 0 none auq-format-gate, carve-section-loading, office-hours-section-loading, plan-ceo-section-loading, ship-section-loading
test/helpers/plan-count-fixture.ts pr 0 → 1 0 → 0 none auq-format-gate
test/helpers/plan-count-fixture.ts full 10 → 20 0 → 0 none auq-format-gate, carve-section-loading, office-hours-auto-mode, office-hours-section-loading, plan-ceo-section-loading, plan-design-review-plan-mode, plan-devex-review-plan-mode, plan-eng-review-plan-mode, plan-mode-no-op, ship-section-loading
bin/gstack-config pr 3 → 3 0 → 0 none none
bin/gstack-config full 9 → 9 0 → 0 none none
test/fixtures/plans/autoplan-dashboard.md pr 86 → 86 23 → 23 none none
test/fixtures/plans/autoplan-dashboard.md full 0 → 0 0 → 0 none none

Rewrite: 950 free *.test.ts entries removed from E2E/LLM-judge lists; 653 closure paths added (53 distinct helpers/fixtures across 123 keys), all real static imports or literal fixture paths of the key's paid file. Closure traversal stops at GLOBAL_TOUCHFILES modules (an edit there already selects everything) and ignores the selection modules themselves (touchfiles-data/touchfiles/test-selection, map-diffed). Keyless paid files (asserted): codex-e2e-recommendation-substance (census-only, PERIODIC_CI_EXCLUDE), skill-e2e-auq-consistency and skill-e2e-auq-verbose-vs-carved-ab (periodic tier gate only). Deleted: test/periodic-fixture-selection.test.ts (hand-copied inventory), test/fake-impeccable-touchfiles.test.ts, 45 per-file selection examples (self-registration / literal selectTests of test/ paths) in 41 files; two emptied files (autoplan-clipped-suffix-aq, codex-eval-selection) and their orphan fixture. Trimmed to non-test paths: 8 tests (CSO each, mode-question capture, live runtime each, mode input each, autoplan-review-discovery, autoplan-snapshot, review-entry-and-design-clarity-au, shared-libs-fixture generation, devex calibration, cookie judge helper exactness). Kept selection-semantics tests (ES-1): matchGlob suite, global touchfile, skill-specific, resolver→consumer equivalence, testing resolver, learnings rendering, browse/aside, gen-skill-docs scoped, unrelated/empty/union, LLM judge, SKILL root, completeness, tiers, dependency-path existence, reverse invariant; eval-cli-family, skill-fixture global, workflow-boundaries F9. Removal check: replacing test/fixtures/fake-impeccable.ts in one key makes the invariant print the paid file, the path, the import/literal chain, the key, the verify command and CONTRIBUTING.md#paid-test-touchfiles plus the lower-bound note.

Behavior-changing commits: kept or dropped

Commit Measurement Decision
E Selection proof above: no lost case for the four sample edits under either profile; growth only from real static dependencies kept
B5 Gate lane 52 → 42 files, weekly gate census 52 → 41 (judges skipped), periodic 77 → 69; PR-profile selection for the sample edits byte-identical before and after kept
B8 Paid run: gate 16/16 pass; periodic 28 pass, 6 fail (all in four files). Fallback taken: those four files keep claude-opus-4-7; seven files re-pinned. Estimated B8 delta after the fallback: +$0.69/week (opus −$1.43, sonnet +$2.12), below zero once C and B5 savings are counted kept (seven files)

B8 pre-spend estimate (recorded 2026-09-29, before any B8 paid run)

Source: latest weekly periodic artifacts (runs 36385945043 = 09-28, 35567915613 = 09-21), per-shard eval JSON cost_usd. Price ratio from test/helpers/pricing.ts: claude-fable-5-1 (default capture, lib/eval-model.ts) $10/$50 per MTok in/out; claude-opus-4-7 $15/$75 (ratio 0.667 on both); claude-sonnet-4-6 $3/$15 (ratio 3.33 on both).

Files Old pin Weekly $ (09-28) Est. weekly $ on default Delta
plan, design, plan-prosons, plan-format, qa-bugs, retro, office-hours-phase4 opus-4-7 15.78 10.52 −5.26
office-hours, office-hours-brain-writeback sonnet-4-6 0.91 3.03 +2.12
auq-matrix, workflow opus-4-7 no result in the retained artifacts — ≤ 0 (ratio 0.667)
B8 total 16.69 13.55 −3.14

Assumes the same token volume per case (a verbosity change moves this; the ratio applies to input and output alike). Wall clock: unchanged shard walls (budgets do not depend on model). Drop threshold, fixed now: B8 is dropped from this PR if its estimated net weekly dollars after C and B5 savings are above zero. Estimated net: −3.14 (B8) − C savings (five retired evals) − B5 savings (18 hollow shards, 23 census judges) < 0 → B8 proceeds to its one paid run. Fallback check: git log -S claude-sonnet-4-6 on skill-e2e-office-hours and -brain-writeback shows only 636175d / #2264 (infra hardening), no cost rationale → both re-pinned.

Paid validation and fallbacks

  • B2 union judge "browse/SKILL.md reference": PASS (clarity 4, completeness 4, actionability 4), $0.02. Fallback not taken; the three original browse judges are deleted.
  • B6 folded journey negatives in skill-routing-e2e: 3/3 unrouted, $0.36. Fallback not taken; skill-e2e-opus-47 deleted.
  • B8 re-pin run (commit B8 tree, EVALS_ALL=1, EVALS_TIER=gate then periodic, 11 files, detached, about $32 logged capture cost): gate 16 pass / 0 fail; periodic 28 pass / 6 fail / 33 skip. Failures, all passing in the 09-14, 09-21 and 09-28 weekly runs on the old pins, so attributed to the default model: plan-design-review-plan-mode (timeout at 300 s, no turns recorded), office-hours-phase4-fork (no two-alternative fork), plan-review-prosons-neutral-neg (output file not written), plan-ceo-review-selective and plan-eng-review (600 s timeouts), plan-ceo-review-expansion-energy (surface-framing score 3 < 4). Fallback taken: skill-e2e-design, -office-hours-phase4, -plan-prosons and -plan keep claude-opus-4-7 (TODOS entry); the other seven files stay re-pinned.
  • PR-profile list on the final diff (--tier gate --profile pr --list, no EVALS_ALL): unknown dependencies (deleted helpers, fixtures and workflow edits) restore every gate case: 86 of 192 tests, 38 of 42 shards. Recorded as data.
  • Gate census pre-spend estimate (recorded before running): 41 planned files (judges skipped). The 21 files with per-file cost in the retained weekly artifacts total about $22; the other 20 have no retained cost, so about $40–45 in all at the same average. Wall clock with 8 local workers: about 1–2 hours. The census is the one full paid run this PR spends on; the B8 run above already covered the re-pinned files.
  • Full gate census: results in the final report and PR body.

Before metrics (65bfb0c)

  • bun run test:ubicloud --record-durations (standard-16, 2026-09-29 04:34Z): EXIT 0, 1065 files one-per-shard, wall 142 s; recorded serial sum 1,888.2 s (committed durations file at 65bfb0c: see release commit diff). Raw copy: audit workspace: metrics/before-durations.json; log audit workspace: ubi-before.log
  • File/LOC counts: audit workspace: metrics/before-counts.txt
  • Paid --list: before-gate-list.txt (gate 58/119 files, 216 tests selected), before-periodic-list.txt (periodic 100/119) tracked test files: 1187 under test/: 982 test/ LOC (ts): 274208 test/helpers LOC: 51390 test/fixtures bytes: 16289330 total all test-file LOC: 279898
  • free tests: 27,331 passed, 0 failed (1065 shards)

After metrics (release commit, same counting script as before)

Measure Before (65bfb0c) After
Tracked *.test.ts files 1,184 957
test/*.test.ts files 979 755
test/ TypeScript lines 274,208 227,713
test/helpers lines 51,390 39,427
test/fixtures bytes 16,289,330 9,695,914
All *.test.ts lines 279,640 244,504
Free suite (Ubicloud standard-16, --record-durations) 1,065 files, 27,331 passing, 142 s wall, 1,888.2 s serial 857 files, 20,302 passing, 136 s wall, 1,737.7 s serial
Paid files / gate lane / periodic lane 119 / 58 / 100 100 / 42 / 69
Weekly gate census planned files 58 41
09-21 weekly periodic shard-minutes on files this branch removes 235 of 462 0

git diff --numstat 65bfb0c..release: production, CI and scripts 21 files (+90/−215); docs 6 (+574/−78 before the release docs sweep); tests 383 (+9,375/−44,379); test helpers 47 (+786/−12,749); fixtures 199 (−43,667).

Kept vs plan

  • Kept AUTOPLAN_PREFLIGHT_BUDGET_BYTES (G): skill-preflight-budget.test.ts enforces it on real generated output.
  • Deleted plan-tune-cathedral-fixture.test.ts beyond the plan (B3): it only replayed the renamed file's fixture.
  • eng-finding-fixture.test.ts: the plan named four prompt-builder tests; only two existed, and C deleted them with the paid file they read.
  • C0 agreement rule: harness and budget were treated as one non-product group; every artifact of the five files was harness or budget, none product.
  • C kept seven of the eight production-touching files; ceo-current-decision-record went because its template read only fed the retired counter. Three helpers were restored for kept tests (autoplan-method-read-audit.ts, autoplan-preconfigured-fixture.ts, readPendingAutoplanArtifact).
  • CARVE_GUARDS.autoplan became behavioral: 'none' (the retired chain was its only section-read proof).
  • D folds incident files verbatim into owner describe blocks rather than rewriting them into value tables, so no incident control can be dropped; the native-completion negative table is deferred (TODOS) because collapsing it changes engFirstReviewAUQ gating on a paid verdict.
  • E stops the closure walk at global touchfile modules and excludes the selection modules; helpers imported by a paid file now select every case that file registers (for example the cookie judge helpers select all judges).
  • H edited only plan-count-history: eng-semantic-terminal's sleeping cases and design-artifact-question went in C.
  • B5 has no CLI file selector to bypass the skip; running a file directly with bun test bypasses it.
  • Fixes to earlier commits: the B commit's census, judge-count, touchfile-count and selection literals were stale (nine free failures found by a full local run) and were fixed inside that commit before C.

Retained false positives (lane reports §4)

Lane 1

  • skill-e2e-hermetic-canary.test.ts — paid test of test infrastructure, but it is the only falsifiable proof the child env/auth/config is hermetic ($0.02, 5–8s, gate + PR profile). Keep.
  • paid-*.test.ts (8 files, 1,948 LOC, ~3.5s free) — they test scripts/test-paid-shards.ts (1,866 LOC) and test-pr-profile.ts, the real paid runner. Legit tooling tests. Minor smell only: paid-free-boundary.test.ts pins a sha256 of test/helpers/test-selection.ts and has incident-named tests (as at 06ed920, PR 2956).
  • llm-judge-abort.test.ts, llm-judge-frontier.test.ts (287 LOC, 74ms) — unit tests of the shared judge client every judge uses. Keep.
  • llm-judge-recommendation.test.ts — fixture-based negative coverage for judgeRecommendation (~$0.04). Keep.
  • make-pdf/test/e2e/* — run in the Linux free suite and again in make-pdf-gate.yml on macOS: different platform, so not a duplicate. ci-prereqs.test.ts is the anti-silent-skip tripwire. Keep.
  • Carve / overlay per-case wrappers — see C4. Keep.
  • overlay-harness-claude-dedicated-tools-vs-bash-sonnet — applies claude.md to Sonnet 4.6, a pairing production does render. Keep (unlike D5).
  • skill-e2e-office-hours posture judges, skill-e2e-benchmark-providers ($0.001) — quality benchmarks that CLAUDE.md explicitly classifies periodic. Keep.
  • codex-e2e-sol-scope.test.ts — never runs in CI, but it pins the current gpt-5.6-sol overlay behavior; move to manual lane (C2), do not delete.

Lane 2

  • autoplan-overwrite-progress-ax (70 LOC): tests autoplanPermissionProgressKey, used live at skill-e2e-autoplan-chain.test.ts:205. KEEP (could merge into a recorder/progress test).
  • autoplan-artifact-recorder.test.ts (7.5 s): owner of the live hook approval. KEEP; it's the proof that makes candidate 1 safe.
  • auq-format-always-loaded: greps generated SKILL.md for the AskUserQuestion format and per-skill cadence rules. This is a prompt-byte contract (retention bar). KEEP.
  • auq-error-fallback-hook, autoplan-publication-guard/-hook/-generation, autoplan-snapshot/-init/-obligations/-methodology-names/-phase-order, outside-voice-provenance, outside-voice-invocation/-preflight/-routing: exercise production hooks, bins, and resolvers. KEEP.
  • autoplan-review-discovery (14 s): real copy/symlink install layouts per host plus bin/gstack-autoplan-snapshot. KEEP. Most of the cost is one gen-skill-docs --host all into tmp, a candidate for sharing generated output across tests (perf, not deletion).
  • auq-parallel (17.4 s): tests the paid AUQ harness's concurrency, deadline, and cleanup through a mocked SDK. It's test-of-harness, but it guards paid-run cost and timeout behavior. KEEP; maybe reduce scenarios.
  • carve-guard-completeness, carve-section-ordering, carve-guards-negative: generated-output structure guards for carved skills, plus a negative control proving the guard fires. KEEP. carve-section-sharding and autoplan-eval-budget test paid-runner scheduling; they could MOVE next to the test-paid-shards tests but are fine as is.
  • outside-voice-fixture, carve-plan-fixture, autoplan-chain-fixture: tests of fixture builders used by paid evals. They're cheap and guard paid-run validity. KEEP (low priority).
  • Not audited in depth: autoplan-amend-input, autoplan-method-read-audit, autoplan-phase-handoff, autoplan-dual-voice-*, autoplan-owned-state, autoplan-preconfigured-onboarding-ar, autoplan-pending-question, auq-native-capture, batching-permission-at (its helper plan-count-file-permission.ts is live in the runner; its siblings plan-count-crop-ak, plan-count-permission-ac, and design-crop-gutter-ap are outside this lane).

Lane 3

  • plan-count-transcript.test.ts (252 LOC): looks like harness, but helpers/plan-count-transcript.ts is a re-export of lib/claude-public-transcript.ts, which production uses (lib/autoplan-phase-publication.ts, autoplan/bin/phase-publication-hook.ts). Keep; consider renaming to the lib owner. Same for plan-count-session-cwd and plan-count-cross-cwd-ancestry (import the lib directly).
  • design-checklist-sync.test.ts: generated-file drift contract (review/design-checklist.md from lib/design-catalog.ts), named in CLAUDE.md. Keep.
  • design-catalog, design-md, design-detect-contract, design-flag-utils, review-log, review-start-evidence (13.3 s, lib/review-evidence), office-hours-review, plan-tune, ship-version-sync, ship-template-redaction, ship-test-detection-markers, spec-quality-gate-secret-sink: test production modules/bins. Keep.
  • ship-review-loop.test.ts test 1 (no **STOP** … run /ship again across rendered hosts) is a real #2391 regression guard; tests 2–3 are exact-sentence pins ("stay in this invocation and loop") and could be loosened, but prose here is the skill's instruction, so not a deletion candidate.
  • ship-apple-gate.test.ts: ordering assertion (Apple adapter before branch gate) is behavior in prose. Keep.
  • spec-template-invariants, ship-workflow-clarity, ship-plan-completion-invariants, eng-scope-entry-ap, review-entry-and-design-clarity-au, design-scope-entry-aq, plan-scope-recovery-av, ceo-mode-preference-al (~400 toContain/toMatch on skill prose): mixed ordering checks (keep) and exact-sentence pins (fragile). Needs a per-assertion pass; not a deletion batch.
  • plan-skill-questions.test.ts (2,439 LOC, 22.6 s, 430 tests): helpers/plan-skill-questions.ts is used by 9 helpers and 2 fixture modules on the paid path; large but live. Candidate for C7-style consolidation later.
  • claude-pty-runner.ts exports: only 4 top-level declarations (111 LOC) unreachable from paid/helper code (isTrustDialogVisible, findModeOption, PLAN_SKILL_COUNT_FINALIZE_MS, isUnknownSlashCommandVisible); small, not pursued.

Lane 4

  • test/setup-codex-scope*.test.ts (5 files, 160 s, the biggest time sink in the lane): they spawn the real setup twice per case and assert no mutation of global or foreign skills. These are data-loss safety contracts, and each case covers a distinct layout, alias, or ownership shape. One exception: the first test in setup-codex-scope.test.ts, "fixture writes reject physical escapes…", tests the fixture guard, which is test infra. AGENTS.md mandates that guard, so it goes to lane 5 rather than being deleted.
  • test/cso-cli*.test.ts (73 s) and cso-scanner-cli: each test is a distinct CLI contract (recheck resolution, launcher trust, redaction, deadlines). They're slow because they go through the compiled launcher, which is the real boundary.
  • gstack-memory-ingest.test.ts (75 s): behavioral CLI tests with a fake gbrain. Only the "probes the gbrain executable directly…" source grep is weak; it's a minor candidate.
  • browse/test cookie- cluster (14 files, ~65 s):* behavioral security tests (decryption, origin policy, Keychain denial, isolated Chromium auth). There's no duplication beyond the different layers they cover.
  • browse xvfb (43 s), handoff (55 s), commands (36 s): real behavior. The expect(true) .toBe(false) calls in commands.test.ts sit inside try/catch "should not reach" blocks whose catch asserts the error message, so they aren't tautologies.
  • design/test/feedback-roundtrip.test.ts: its server is also a mirror, but the thing under test is the generated board JS in a real browser. The daemon file owns the server contract. Suggestion: point the browser at the real daemon to remove the mirror.
  • setup-gbrain-path4-structure.test.ts: a grep of template prose, but the prose (token never in argv or CLAUDE.md, STOP gates) is the prompt contract itself.
  • terminal-agent-pid-identity test 1 (repo-wide no pkill -f terminal-agent): the cheapest independent guard for a cross-session kill bug.
  • security-audit-r2 ordering greps (state load, inbox, responsive, CSS validator): the only guard today. Convert them, don't delete them.
  • sidebar-ux "welcome page has left-aligned text": it encodes a stated user design preference, and it's cheap.

Lane 5

  • Meta-tests guarding real CI contracts (KEEP):
    • ci-image-tag-binding (three-way hashFiles drift causes silent rebuilds)
    • ci-image-cli-pin (unpinned CLI broke the PTY harness 3×)
    • workflow-concurrency (the generic loop)
    • free-tests-workflow-wiring (secretless, no pull_request_target, least privilege)
    • evals-workflow-wiring, ci-eval-cache, e2e-tier-alignment (inert-demotion class)
    • paid-orphan-tripwire, eval-budgets-policy, eval-detach-timeout-floor, periodic-exclude-policy, gate-secret-scan
    • strict-output*, test-free-shards*, paid-shards/paid-retry-supervision/paid-run-manifest/paid-selection-propagation/paid-overlay-scheduling/ci-paid-coordination (they test the code that decides CI verdicts)
    • touchfiles-map-diff (real fail-closed selection logic)
    • hermetic-wiring (source grep that is brittle by design, retention bar)
    • spawnsync-timeout-tripwire and parity-suite (named by AGENTS.md)
    • llm-judge-frontier (judge parsing decides eval verdicts)
    • secret-sink-harness.test (negative controls run real setup-gbrain bins)
    • paid-free-boundary
  • Weak literal pins worth trimming later (not candidates): free-tests-workflow-wiring max-parallel: 20 + the exact matrix string. workflow-concurrency hard-pins actionlint.yml/skill-docs.yml. test-free-shards-sandbox-knobs "Linux caps at 16". parity-baseline-integrity pins CHANGELOG headline numbers, a docs-consistency check rather than behavior.
  • Paid-callback replays (26 files, for example review-n-plus-one-contract): tests of tests, but AGENTS.md step 4 explicitly requires them, and they catch broken pass predicates that would otherwise waste paid runs.
  • test/helpers/claude-pty-runner.unit.test.ts (3,694 LOC, 223 tests, 0.1 s): a large self-test of the 5,885-LOC PTY harness. The classifiers it covers (classifyVisible, parseNumberedOptions, Step0BoundaryPredicate…) are live in paid runs, so keep it. The per-capture blocks (captured F, captured G) belong to the per-incident consolidation lane.
  • Zero-importer helpers auq-parallel-worker, setup-gbrain-fixture-command, emulate-bun-windows-eexist are loaded by path (preload / generated import). benchmark-judge has a production caller (dynamic import in bin/gstack-model-benchmark).
  • browse/src __reset*/reset*ForTests exports (12): standard singleton-reset seams, keep.

Corrections (2026-10 audit)

Facts above that no longer hold, checked against main at v1.91.19.0:

  • codex-e2e-recommendation-substance is not census-only: it is no longer in PERIODIC_CI_EXCLUDE and runs in every periodic census.
  • The after-metrics are superseded. Five days after release the free suite had regrown by 132 test files and about 53% of serial time; the 2026-10 audit carries current numbers.
  • The duration seed again lacked 19 files, including the 115-second claude-overlay-setup.test.ts, which the planner packed as a short file.
  • browse/test/compare-board.test.ts stayed quarantined through this audit; its 16 tests now pass headless and run in the free suite again.
  • ci-image-tag-binding now pins evals.yml, evals-periodic.yml and evals-marathon.yml; ci-image.yml is deleted because those workflows push the same content-hash tag.
  • The weak literal pins listed under Lane 5 are still present.