Files
ersatztv/scripts
timothy 0c3625d2e2 fix(786,789): reclassify test/migrations, de-vacuum two controls, correct a refuted claim
Cold adversarial review of b7e5c35fb returned BLOCKED with four substantive findings. All four
are real and all four are fixed here; each fix is demonstrated rather than asserted.

1. THE guard/none LINE EXCLUDED BOTH REQUIRED CONTEXTS. The rule was "a guard enforces an
   invariant about the REPOSITORY; a job exercising the PRODUCT is `none`". It reads as
   principled and put `test` and `migrations` outside the table — the two required Actions
   contexts on `main` per .gitea/required-status-contexts.json, i.e. exactly the jobs where a
   failure to fire is fail-OPEN against branch protection, and exactly the gap #786 exists to
   close. It also could not survive its own examples: `test` runs ToolCatalogTests.cs and
   web/src/api/*.guard.test.ts, the structural guards this document's own scope-limit item 2
   names.

   Replaced with a line that can be restated: a `guard` job's output is a VERDICT; a `none`
   job's output is an ARTIFACT. A `none` job can still go red — that is an error in producing
   the thing, not a finding about the repo. `test`, `migrations` and `functional-e2e` flip to
   `guard` and gain rows; `none` is now exactly the two image publishers plus renovate. The
   rejected rule is recorded so it is not re-adopted.

2. TWO POSITIVE CONTROLS WERE VACUOUS — both of them ones this commit series added, while the
   pre-existing sibling it copied was not. `len(_MUTANTS) == 2 * len(population)` is `2N == 2N`,
   a tautology at N=0, so an emptied population satisfied it while the parametrised proofs
   collected zero cases. Both now assert non-emptiness FIRST. Demonstrated after the fix, by
   degrading each population to empty:
     role mutation set        -> REDDENED: "declared_roles() is EMPTY ..."
     declaration mutation set -> REDDENED: "the workflow parsed to ZERO jobs ..."
     phantom-row proof        -> REDDENED: "the table parsed to nothing ..."

3. A MECHANISM CLAIM IN A DECISION RECORD WAS REFUTED BY EXECUTION. Four sites (the test
   docstring, docs/ci-cd.md, the record's `rule:`, and the generated catalog) said
   `functional-e2e` reaches dotnet only through scripts/e2e-local.sh and so is invisible to the
   step scan. It is not: that job runs `dotnet restore`, `npm ci`, `npm run build` and
   `dotnet build` in its own YAML, and the derivation detects it. Measured: the blind-spot set
   (declared toolchain minus detected-from-own-steps) is EMPTY today, all five jobs detected.
   Reworded to say that, and the converse is still not asserted because a future job could be
   written behind a script.

4. THE ADJACENCY RESIDUAL WAS UNDERSTATED. All three checks fail together under one edit that
   drops the container block, flips the marker AND moves the invocation into a script — the
   review verified it. Now disclosed in the code and in docs/ci-cd.md, with what actually bounds
   it: the failure MODE, not its likelihood. The job then dies on a missing binary, loudly,
   where #774's original defect sent a REQUIRED check green on the bare runner. A silent pass
   traded for a noisy crash, not a hole closed.

Also from the review: the docs-reminder row said the job "never fails" (its Checkout step can);
the phantom-row proof could not fail (it supplied its own phantom, so it now pins the unmutated
set to zero phantoms first); and the scope-limit paragraph was reworded from draft history into
a rejected-alternative note.

Review findings 6 and 7 (regex false positives on comments, false negative on `dotnet-ef`) were
already fixed in 75747fbca, which the reviewer did not see.

Suite: 1161 passed, 2 skipped. ruff 0.12.11 clean; decisions-validate OK.

NOTE for whoever sees a red `test_hook_fire_log.py::test_the_suite_does_not_write_to_the_
PRODUCTION_log` locally: it snapshots mtimes under ~/.cache/ersatztv/hook-fire/, which is shared
across worktrees and sessions, so a second Claude session running concurrently reddens it. Seen
once here with three session logs written during the window; green in isolation, both before and
after this change. That is ersatztv#809 / #822, not this diff.

Refs #786
Refs #789
2026-08-28 22:14:44 +02:00
..
2024-01-15 10:29:07 -06:00
2024-01-16 13:28:46 -06:00