Files
ersatztv/docs/decisions/records/testing
timothy 402032db98 fix(786,789): sweep the retracted rule out of three sites, and reject duplicate table rows
Cross-family cold re-review (Codex/gpt-5.6) returned BLOCKED with four findings. All verified
independently before fixing.

1. HIGH — THE RETRACTED RULE WAS STILL STATED AS ACTIVE IN THREE PLACES. The previous commit
   replaced the guard/none rule in docs/guard-inventory.md and flipped `test`/`migrations` to
   `guard`, but left the superseded wording in test_workflow_job_guards.py's module docstring,
   docs/ci-cd.md, and the decision record's `rule:` — from which the generated catalog (and
   MemPalace) copied it faithfully. Those three explicitly called `docker-build.yml::test` `none`,
   which is the opposite of what the workflow now declares. A maintainer following the ACTIVE
   decision record could downgrade both required jobs, delete their rows, and every structural
   check would stay green, because the checkers read the markers and the markers would agree with
   the stale prose.

   This is `process.enumerate-clauses-to-close-a-sweep` failing on my own retraction: I fixed the
   site I was looking at and left the paraphrases. All three now state the verdict/artifact rule,
   and each carries the rejected reading explicitly so it does not come back. Swept by grepping
   the RETRACTED words, not the new ones — the only hits left are the deliberate
   rejected-alternative notes.

   Same commit: docs/ci-cd.md claimed "every job in every workflow declares two things", which its
   own table contradicts — `CI_EXECUTION_CLASS` is docker-build.yml only.

2. MEDIUM — A DUPLICATE ROW WAS SILENTLY COLLAPSED. `inventory_jobs()` built a dict, so two rows
   for one job overwrote each other, last-one-wins, and set equality still held both ways. The
   realistic arrival is a merge conflict leaving an ADVISORY and a GUARD row for the same job: the
   registry contradicts itself and its checker reports green. Rows are now kept as a list and
   counted against distinct keys by `test_no_job_has_TWO_rows`, with a mutation proof carrying its
   own negative control. Witnessed: planting a contradictory duplicate row for
   `pr-checks.yml::ci-image-pin` in the real file reddens two named tests; restoring it returns 48
   passed.

3. LOW — the toolchain-preflight row said it blocks "every downstream job". Measured: NOTHING
   `needs:` it (only `build` has a `needs:`, on test/migrations/scan), and it is not a required
   context. Corrected to what it actually blocks — a merge, through the combined commit status the
   consent gate reads (#598) — and why it must not consume the image it checks (#772).

4. LOW — the predicate's documented residue was partial. Now enumerated in both directions:
   false positives (trailing comment, echo string, heredoc body — stripping is line-based, not
   shell-aware) and false negatives (absolute path, script indirection, a `#` heredoc line that a
   later command strips and executes).

   One of those claims was WRONG as first written and is corrected to what execution shows:
   variable indirection is invisible ONLY when the assignment is not in the same run body.
   `$SDK_CMD build` with `SDK_CMD` from `env:` is missed; `SDK_CMD=dotnet` written in the same body
   IS caught, because the assignment line carries the bare token.

Re-review confirmed the four earlier findings are genuinely fixed: the classification is
consistent across all 17 jobs under the verdict/artifact rule with no job it would reclassify;
both repaired positive controls redden on an emptied population; the corrected functional-e2e
claim is true and the old wording has no matches; the adjacency residual is accurately disclosed
and not overstated; the summary counts assertion holds at (43, 6, 21, 21, 6, 16).

ruff 0.12.11 clean; decisions-validate OK; targeted suites 145 passed.

Refs #786
Refs #789
2026-08-28 22:14:44 +02:00
..