testing.guard-derives-population-from-source (#774) says a completeness guard derives its population from an authoritative source, and its worked examples are an enum and the generated OpenAPI document. It was silent on the commonest population in our own guards — files in a directory — and every one of them answered with a filesystem walk. A walk is not authoritative: it reports build output, generated shims and editor droppings, and it differs per machine.
What shipped
Converted (a completeness claim over tracked files): test_guard_inventory.py, test_hook_fire_log.py, test_ci_image_pin_population.py (which also gained *.yaml — Gitea accepts both spellings, so a .yaml workflow adopting the toolchain image was structurally invisible), and test_remote_state_inventory.py (folded onto the shared derivation, so the rule has one implementation).
Assessed and recorded, not silently skipped: _repo_copy in test_ci_release_path_scan_job.py (not a completeness claim, but takes its file list from the index for hermeticity); test_ci_dropped_step_guard.py (no filesystem population at all); the decisions corpus (recorded as unexamined rather than cleared). This is not "replace every glob".
scripts/tests/tracked_files.py is the single derivation. test_guard_populations_derive_from_git.py proves it in two directions that are measured complements — exhaustive removal catches a hardcoded .exists() admit and memoisation; the call-log check catches an append-only source that yields nothing on this machine (#778's shape), which removal cannot see because it has nothing to remove.
Docs: the decision record gains the file-population case; docs/guard-inventory.md carries the per-guard audit table.
Review
Eight rounds of independent cold review, alternating Codex GPT-5.6 and Opus, every one in an isolated worktree from a cold review-only brief. Every round confirmed the four production derivations and the shared helper sound; every blocking finding after round 1 was in the proofs or in prose claims about them, which is worth recording because it says where the risk actually was.
Findings that changed the code, each executed by the reviewer rather than argued:
Round
Finding
1
derived_guard_files still admitted untracked files — the CALLERS were index-gated but the paths they NAME were admitted on Path.exists(). #778's third shape, inside the guard this change calls its model
2
The proof removed one victim from a four-contributor union, so a mutant reverting one contributor passed. Now exhaustive — which immediately exposed that _git_ls_files was imported by name, so the patch never reached the ref-gating branch
2
The POPULATION-EXEMPT marker was a whole-file substring scan — a silent kill switch trippable from another file's prose. Withdrawn, not patched
3
The add-side test wrote probe files into the checkout under test: a test_*.py probe is collected by pytest, names collide across concurrent runs, finally doesn't survive SIGKILL. Withdrawn
4
The replacement discarded its own calls evidence on the success path — try/except Exception around an rglob was a false green
5
It also discarded derive()'s return value, so a lazy generator ran after the patch exited
6–8
A sequence of false or imprecise claims in prose: _EmptyScan was iterable but not an iterator (so os.walk still polluted the report); the boundary was stated as "synchronous", then "while the patch is active", both falsified by measurement — it is the call log; glob.glob routes through glob.iglob, not os.scandir; rebase-stale member counts
Two are worth calling out as process, not code:
One round caught that a git commit --amend had used only the staged tree, so the manifest entry and prose corrections were never in the commit — it would have pushed red. It found this by exporting git archive HEAD and running that, not the working tree. The committed tree is now verified the same way (via a throwaway worktree, since an archive isn't a git repo — the exact failure _repo_copy's docstring warns about).
The boundary sentence was wrong three times, always in the same direction, and the third time it was wrong in the copies after the original had been fixed. The instance list now lives in exactly one place, and the record carries that as its lesson.
Rebase
Rebased across two main moves. #790 ("execute every MUTATION grade instead of asserting it") landed mid-review and touches the same two files — the "green separately, red together" case, and it fired: three tests went red on the rebase. The new guard now declares an executable clause in mutation_manifest.py, using the real defect round 1 found; #790's harness runs it and reddens exactly the named proof for the declared reason. Reviewers mechanically diffed every #790 line to confirm nothing was lost.
Verification
870 passed, 2 skipped — and re-verified against the committed tree, not just the working tree
ruff check + format clean; decisions-validate OK; catalog up to date; doc-narrative 9 advisories, all pre-existing
Mutations witnessed red on the final tree: append-only rglob with .husky/_ absent; enumeration swallowed by except Exception; a lazy generator; the hardcoded .exists() gate; tracked_children made recursive; the exemption removed; the AST matcher narrowed
No two proofs mask each other — each mutant reddens a distinct expected test
Known residuals, stated rather than implied
The call-log check is a regression guard against the shapes that arrive by accident, not a boundary: enumeration hoisted to module import time, from os import listdir early binding, and anything listing in another process all pass. importlib/star-import/re-export are invisible to the AST matcher. Nested workflow directories are out of scope. Each is written down where the code is, once.
fixes #806
`testing.guard-derives-population-from-source` (#774) says a completeness guard derives its population from an authoritative source, and its worked examples are an enum and the generated OpenAPI document. It was silent on the commonest population in our own guards — files in a directory — and every one of them answered with a filesystem walk. A walk is not authoritative: it reports build output, generated shims and editor droppings, and it differs per machine.
## What shipped
**Converted** (a completeness claim over tracked files): `test_guard_inventory.py`, `test_hook_fire_log.py`, `test_ci_image_pin_population.py` (which also gained `*.yaml` — Gitea accepts both spellings, so a `.yaml` workflow adopting the toolchain image was structurally invisible), and `test_remote_state_inventory.py` (folded onto the shared derivation, so the rule has one implementation).
**Assessed and recorded, not silently skipped**: `_repo_copy` in `test_ci_release_path_scan_job.py` (not a completeness claim, but takes its file list from the index for hermeticity); `test_ci_dropped_step_guard.py` (no filesystem population at all); the decisions corpus (recorded as unexamined rather than cleared). This is not "replace every glob".
`scripts/tests/tracked_files.py` is the single derivation. `test_guard_populations_derive_from_git.py` proves it in two directions that are measured complements — exhaustive removal catches a hardcoded `.exists()` admit and memoisation; the call-log check catches an append-only source that yields nothing on this machine (#778's shape), which removal cannot see because it has nothing to remove.
Docs: the decision record gains the file-population case; `docs/guard-inventory.md` carries the per-guard audit table.
## Review
Eight rounds of independent cold review, alternating Codex GPT-5.6 and Opus, every one in an isolated worktree from a cold review-only brief. Every round confirmed the four production derivations and the shared helper sound; **every blocking finding after round 1 was in the proofs or in prose claims about them**, which is worth recording because it says where the risk actually was.
Findings that changed the code, each executed by the reviewer rather than argued:
| Round | Finding |
|---|---|
| 1 | `derived_guard_files` still admitted untracked files — the CALLERS were index-gated but the paths they NAME were admitted on `Path.exists()`. #778's third shape, inside the guard this change calls its model |
| 2 | The proof removed one victim from a four-contributor union, so a mutant reverting one contributor passed. Now exhaustive — which immediately exposed that `_git_ls_files` was imported **by name**, so the patch never reached the ref-gating branch |
| 2 | The `POPULATION-EXEMPT` marker was a whole-file substring scan — a silent kill switch trippable from another file's prose. Withdrawn, not patched |
| 3 | The add-side test wrote probe files into the checkout under test: a `test_*.py` probe is collected by pytest, names collide across concurrent runs, `finally` doesn't survive SIGKILL. Withdrawn |
| 4 | The replacement discarded its own `calls` evidence on the success path — `try/except Exception` around an `rglob` was a false green |
| 5 | It also discarded `derive()`'s return value, so a lazy generator ran after the patch exited |
| 6–8 | A sequence of false or imprecise claims in prose: `_EmptyScan` was iterable but not an iterator (so `os.walk` still polluted the report); the boundary was stated as "synchronous", then "while the patch is active", both falsified by measurement — it is the **call log**; `glob.glob` routes through `glob.iglob`, not `os.scandir`; rebase-stale member counts |
Two are worth calling out as process, not code:
- One round caught that a `git commit --amend` had used only the **staged** tree, so the manifest entry and prose corrections were never in the commit — it would have pushed red. It found this by exporting `git archive HEAD` and running *that*, not the working tree. The committed tree is now verified the same way (via a throwaway worktree, since an archive isn't a git repo — the exact failure `_repo_copy`'s docstring warns about).
- The boundary sentence was wrong three times, always in the same direction, and the third time it was wrong in the *copies* after the original had been fixed. The instance list now lives in exactly one place, and the record carries that as its lesson.
## Rebase
Rebased across two `main` moves. #790 ("execute every MUTATION grade instead of asserting it") landed mid-review and touches the same two files — the "green separately, red together" case, and it fired: three tests went red on the rebase. The new guard now declares an executable clause in `mutation_manifest.py`, using the real defect round 1 found; #790's harness runs it and reddens exactly the named proof for the declared reason. Reviewers mechanically diffed every #790 line to confirm nothing was lost.
## Verification
- `870 passed, 2 skipped` — and re-verified against the **committed** tree, not just the working tree
- ruff check + format clean; `decisions-validate` OK; catalog up to date; doc-narrative 9 advisories, all pre-existing
- Mutations witnessed red on the final tree: append-only rglob with `.husky/_` absent; enumeration swallowed by `except Exception`; a lazy generator; the hardcoded `.exists()` gate; `tracked_children` made recursive; the exemption removed; the AST matcher narrowed
- No two proofs mask each other — each mutant reddens a distinct expected test
## Known residuals, stated rather than implied
The call-log check is a regression guard against the shapes that arrive by accident, not a boundary: enumeration hoisted to module import time, `from os import listdir` early binding, and anything listing in another process all pass. `importlib`/star-import/re-export are invisible to the AST matcher. Nested workflow directories are out of scope. Each is written down where the code is, once.
`testing.guard-derives-population-from-source` (#774) says a completeness guard
derives its population from an authoritative source, and its worked examples are an
enum and the generated OpenAPI document. It was silent on the commonest population
in our own guards — files in a directory — and every one of them answered with a
filesystem walk. A walk is not an authoritative source: it reports build output,
generated shims and editor droppings, and it differs per machine.
#778 measured the cost by getting the same population wrong three times in one PR
while implementing the milestone that exists to prevent it. The worst shape was
`Path.rglob` enumerating `.husky/_/` — 17 shims `npm ci` writes, gitignored and
untracked — which made that guard RED on every developer checkout and GREEN in CI,
whose `script-tests` job never runs `npm ci`. Only that one guard was fixed then.
This audits the rest.
CONVERTED (a completeness claim over tracked files):
* `test_guard_inventory.py` — its `.husky/` walk excluded `.husky/_/` only because
`_` is a directory, so the obvious "make it recursive" edit would have
reintroduced #778's defect in the repo's own model guard. Both halves are gated
on the index: the callers, and the `scripts/…` paths they name — the second was
left on `Path.exists()` in the first cut and found by cold review.
* `test_hook_fire_log.py` — an untracked scratch `.sh` in `.claude/hooks/` was
demanded to carry instrumentation.
* `test_ci_image_pin_population.py` — and `*.yaml` added: Gitea accepts both
spellings, so a `.yaml` workflow adopting the toolchain image was structurally
invisible while the test read as covering every workflow.
* `test_remote_state_inventory.py` — folded onto the shared derivation, so the
rule has one implementation rather than two.
ASSESSED AND RECORDED, not silently skipped:
* `test_ci_release_path_scan_job.py::_repo_copy` — not a completeness claim, but
it takes its file LIST from the index anyway for hermeticity, since `copytree`
copied untracked files and `__pycache__` into a tree whose behaviour the probes
measure. Content still comes from the working tree, and the copy is NOT a git
repo, so neither file that step runs may use the helper — written down because
`MARKED_JOBS` is left open as a residual gap, which invites editing exactly
that file.
* `test_ci_dropped_step_guard.py` — no filesystem population at all; its members
come from the parsed workflow.
* The decisions corpus keeps its walks and is recorded as unexamined rather than
cleared. This is not "replace every glob".
`scripts/tests/tracked_files.py` is the single derivation.
`test_guard_populations_derive_from_git.py` proves it in two directions, which are
complements rather than a second opinion — measured both ways:
* REMOVAL, exhaustively: every member of every registered derivation is dropped
from the index in turn and must disappear while still on disk. One victim was
not enough — `derived_guard_files` unions four contributors, so a mutant putting
only one back on a walk passed. This catches a hardcoded `.exists()` admit and
memoisation, which the other direction cannot.
* The CALL LOG: a derivation may READ a file but must not LIST a directory. This
catches an append-only source that yields nothing on this machine — #778's
shape — which removal cannot see, because it has nothing to remove. Its limits
are stated in one place and are true in both directions.
Both the population and the proofs are registered against a hand-written scope
mirror that carries its own equality check, and the import matcher's 16 forms are
pinned as a table so the next edit cannot silently re-open one.
The mutation this guard declares in `mutation_manifest.py` (#790) is the real
defect cold review found in its own first round.
Docs: `testing.guard-derives-population-from-source` gains the file-population case
and why the disk is not authoritative; `docs/guard-inventory.md` carries the
per-guard audit table, including the two no-change verdicts and the decisions
corpus recorded as unexamined.
Seven rounds of independent cold review (Codex GPT-5.6 and Opus, alternating) —
the per-round findings and their measurements are in the PR.
fixes#806
Decisions-Edit: yes
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Two findings from the cold review of the pushed head, one of them the more
interesting kind: a defect in a file the issue did not list.
`test_pr_changed_files.py` DERIVED A WORKFLOW POPULATION FROM `Path.glob`, and it
carries two completeness claims over it — "no OTHER workflow writes the
review-verdict status", and the delimiter ban over every workflow. Cold review
demonstrated it in a disposable clone: one untracked `.yaml` dropped in
`.gitea/workflows/` reddens both guards while absent from `git ls-files`. That is
the developer-red/CI-green shape #806 exists to remove, in a guard that was never
assessed.
It was never assessed because #806's body names four files to check and I took that
list as the population — which is this issue's own defect, one altitude up, in the
work implementing it. My first sweep printed this file among the filesystem-derived
populations and I narrowed to the issue's list without saying so. Both call sites
now come from the index, `_workflow_files` is registered in `DERIVATIONS` so both
proofs cover it, and the audit table in `docs/guard-inventory.md` says plainly that
the issue's list was a starting point rather than the population.
THREE COUNTS IN `mutation-claims-are-executed.md` WERE INVALIDATED BY THIS CHANGE
and not updated: it said thirteen manifest entries, ten behavioural reds, and twelve
of thirteen clause-provable. Adding a fourteenth entry makes those fourteen, eleven,
and thirteen of fourteen. The record is where `test_mutation_harness.py`'s own
docstring sends a reader for that measurement, and the same commit corrected the
identical sentence in `docs/guard-inventory.md` — so the tree shipped two
same-dated documents contradicting each other on one number. Swept by subject this
time rather than by the phrase I had been shown; no other record is stale.
Also:
* `docs/guard-inventory.md` still said "what falls outside that window" one
sentence after arguing the boundary is not a window.
* the same file's "one implementation rather than five" read as contradicting the
commit message's "rather than two"; both are true at different scopes and the
sentence now says which it means.
refs #806
Decisions-Edit: yes
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Cold review of the previous commit found that IT had made
`docs/guard-inventory.md`'s "load-bearing for the six modules that import it"
false, by adding a seventh importer — in the file it was editing, inside the sweep
its own message claims to have done by subject. That is the third hand-maintained
count in this change to go stale, after `mutation-claims-are-executed.md`'s three
and `guard-inventory.md`'s "three of the thirteen".
Correcting a number that tracks a growing population buys one commit of accuracy.
So the counts that track populations are gone rather than updated:
* "load-bearing for the six modules that import it" → "for every module that
imports it"
* "this file is not four near-copies" → "not one near-copy per derivation"
* "adding a fifth derivation / a fifth index-derived guard" (twice) → "another"
* "five guard modules would otherwise die" → "every module that imports this one"
* "Exhaustive removal is cheap (~1s for 60 members)" → "about a second at the
population sizes here"
The sweep was then done MECHANICALLY — a regex over every spelled-out and numeric
count in all five artifacts this change touches — rather than by eye for a fourth
time. What survives is verified true rather than assumed: "three of the fourteen"
and "36 guards … 14/6/16" (the latter machine-asserted by
`test_the_summary_counts_match_the_table`), "unions four contributors",
"five modules each derived a file population" (`DERIVATIONS` holds exactly five),
and the re-measured 61/39/48/58. `guard-inventory.md`'s "three of these four rows"
is #790's text about a different row set and is untouched.
The figures that remain are the ones that describe a FIXED structure or carry a
reproduction command; the ones that counted a set expected to grow are the ones
that kept breaking, which is the distinction the sweep now encodes.
Correction to the previous commit message: it called the second converted call site
"the delimiter ban over every workflow". That guard is
`test_every_workflow_expression_names_a_REAL_context_or_function`, an
expression-context check; the delimiter ban does not use `_workflow_files()`. Both
call sites are completeness claims over every workflow and both were demonstrated
red against an untracked `.yaml` at the predecessor sha — only the label was wrong.
refs #806
Decisions-Edit: yes
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Cold review returned MERGEABLE with two notes; both are corrections to claims this
change ships, so both are taken.
THE PREVIOUS COMMIT CLAIMED A REGEX OVER EVERY COUNT IN ALL FIVE ARTIFACTS and left
four. They were dated and true, which is why they read as acceptable, but a single
added `MUTATION` row stales all four at once — the same fuse as the counts already
removed, and the claim of a complete sweep is what made keeping them dishonest
rather than merely conservative:
* "three of the fourteen entries" → "three entries" (it names them; the total
contributes nothing)
* "the remaining eleven redden behaviourally" → "every other entry reddens
behaviourally"
* "thirteen of the fourteen admit clause-level proof" → "all but one"
* `guard-inventory.md`'s "three of the fourteen rows" → "three rows"
An independent sweep with a wider pattern now returns only counts over FIXED
structures — #790's four ranked rows, `derived_guard_files`'s four union terms,
#685's two guards — plus the machine-asserted `36 guards … 14/6/16`, and the
member figures, which are dated, carry their reproduction command, and say in place
that they illustrate the gap above the floor rather than being values to assert
against. That is the distinction worth keeping: a number describing a fixed shape,
or one that ships with the command that regenerates it, does not rot the way a
tally of a growing set does.
`docs/guard-inventory.md`'s new "listed in `DERIVATIONS` there" had the wrong
nearest antecedent — `DERIVATIONS` lives in
`scripts/tests/test_guard_populations_derive_from_git.py`, not in
`tracked_files.py`. Named explicitly.
refs #806
Decisions-Edit: yes
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
`docs/guard-inventory.md` shipped "one per module. The The registered derivations
are listed…". The rewrite replaced the line that began "The registered
derivations…" without removing the trailing `The` the previous line carried as that
sentence's wrapped start. Markdown soft-breaks the two lines, so the published page
showed both.
Worth a line rather than a silent fix: the evidence was on screen. The `sed` output
I used to verify that rewrite printed line 140's trailing `The` directly above line
141's `The registered` and I read past it — a verification that ran, produced the
right output, and was not actually read. Cold review caught it.
Swept for the same shape across the three prose artifacts this change touches, over
JOINED lines so a duplication split across a wrap is visible: no others.
One clarification to the previous message, which enumerated what the count sweep
returns and reads as exhaustive: that enumeration covers the prose this branch
authors. `guard-derives-population-from-source.md` also carries "the 95 closed
issues carrying a `## Closing record`" and "27 of the 69 process-failure records"
— counts over growing sets, but pre-existing (#774/#775) and attributed citations
of #773's analysis rather than live tallies, so they are left alone.
refs #806
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The whole-repo sweep in cold review — looking past the file list #806 names, the
same method that found `test_pr_changed_files.py` inside this PR — turned up one
more instance of the shape: `web/src/api/pageSizeCallSites.guard.test.ts` derives
its population from `import.meta.glob('/src/**/*.{ts,tsx,mts,cts}')` and then
asserts exact completeness against `REGISTRY`. An untracked `.ts` under `web/src/`
containing a page-size call enters the population and fails as unregistered on that
checkout while CI never sees it.
NOT FIXED HERE, and the reason is a documented obstacle rather than scope fatigue.
The glob is a deliberate workaround: `@types/node` is kept out of
`tsconfig.app.json` because that project covers production browser code, and a
file-local `/// <reference types="node" />` was tried and REVERTED — under `tsc -b`
it leaked Node's ambient `setTimeout` into the whole app project and broke three
unrelated `window.setTimeout` mocks. Filtering the glob against `git ls-files`
therefore needs `node:child_process` in a project that excludes Node types, which is
the wall the previous attempt hit. #819 carries the evidence and two fix shapes that
sidestep it (a Vite `define` or a vitest `globalSetup`, both of which run where Node
IS available).
The direction is the safe one — it over-enumerates, so it fails loudly rather than
going blind — which is why it is a follow-up rather than a blocker.
Recorded in the audit table as DEFERRED rather than left silent, which is what #806
asks for every population it assesses: "completeness claim over tracked files, or
not — recorded either way". A guard nobody wrote down is indistinguishable from one
nobody looked at.
refs #806
refs #819
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Twelve rounds of independent cold review (Codex GPT-5.6 + Opus alternating, isolated worktrees, cold briefs). Production derivations and the shared helper confirmed sound every round; final two rounds MERGEABLE on this head. CI fully green: 12 jobs, 1 skipped, no failures, no cancellations. One further instance of the shape found by whole-repo sweep and deferred to #819 with the obstacle documented.
Review-verdict: MERGEABLE @ ded6cb1
Twelve rounds of independent cold review (Codex GPT-5.6 + Opus alternating, isolated worktrees, cold briefs). Production derivations and the shared helper confirmed sound every round; final two rounds MERGEABLE on this head. CI fully green: 12 jobs, 1 skipped, no failures, no cancellations. One further instance of the shape found by whole-repo sweep and deferred to #819 with the obstacle documented.
timothy
merged commit 29d7a06e65 into main2026-08-22 18:07:59 +02:00
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
fixes #806
testing.guard-derives-population-from-source(#774) says a completeness guard derives its population from an authoritative source, and its worked examples are an enum and the generated OpenAPI document. It was silent on the commonest population in our own guards — files in a directory — and every one of them answered with a filesystem walk. A walk is not authoritative: it reports build output, generated shims and editor droppings, and it differs per machine.What shipped
Converted (a completeness claim over tracked files):
test_guard_inventory.py,test_hook_fire_log.py,test_ci_image_pin_population.py(which also gained*.yaml— Gitea accepts both spellings, so a.yamlworkflow adopting the toolchain image was structurally invisible), andtest_remote_state_inventory.py(folded onto the shared derivation, so the rule has one implementation).Assessed and recorded, not silently skipped:
_repo_copyintest_ci_release_path_scan_job.py(not a completeness claim, but takes its file list from the index for hermeticity);test_ci_dropped_step_guard.py(no filesystem population at all); the decisions corpus (recorded as unexamined rather than cleared). This is not "replace every glob".scripts/tests/tracked_files.pyis the single derivation.test_guard_populations_derive_from_git.pyproves it in two directions that are measured complements — exhaustive removal catches a hardcoded.exists()admit and memoisation; the call-log check catches an append-only source that yields nothing on this machine (#778's shape), which removal cannot see because it has nothing to remove.Docs: the decision record gains the file-population case;
docs/guard-inventory.mdcarries the per-guard audit table.Review
Eight rounds of independent cold review, alternating Codex GPT-5.6 and Opus, every one in an isolated worktree from a cold review-only brief. Every round confirmed the four production derivations and the shared helper sound; every blocking finding after round 1 was in the proofs or in prose claims about them, which is worth recording because it says where the risk actually was.
Findings that changed the code, each executed by the reviewer rather than argued:
derived_guard_filesstill admitted untracked files — the CALLERS were index-gated but the paths they NAME were admitted onPath.exists(). #778's third shape, inside the guard this change calls its model_git_ls_fileswas imported by name, so the patch never reached the ref-gating branchPOPULATION-EXEMPTmarker was a whole-file substring scan — a silent kill switch trippable from another file's prose. Withdrawn, not patchedtest_*.pyprobe is collected by pytest, names collide across concurrent runs,finallydoesn't survive SIGKILL. Withdrawncallsevidence on the success path —try/except Exceptionaround anrglobwas a false greenderive()'s return value, so a lazy generator ran after the patch exited_EmptyScanwas iterable but not an iterator (soos.walkstill polluted the report); the boundary was stated as "synchronous", then "while the patch is active", both falsified by measurement — it is the call log;glob.globroutes throughglob.iglob, notos.scandir; rebase-stale member countsTwo are worth calling out as process, not code:
git commit --amendhad used only the staged tree, so the manifest entry and prose corrections were never in the commit — it would have pushed red. It found this by exportinggit archive HEADand running that, not the working tree. The committed tree is now verified the same way (via a throwaway worktree, since an archive isn't a git repo — the exact failure_repo_copy's docstring warns about).Rebase
Rebased across two
mainmoves. #790 ("execute every MUTATION grade instead of asserting it") landed mid-review and touches the same two files — the "green separately, red together" case, and it fired: three tests went red on the rebase. The new guard now declares an executable clause inmutation_manifest.py, using the real defect round 1 found; #790's harness runs it and reddens exactly the named proof for the declared reason. Reviewers mechanically diffed every #790 line to confirm nothing was lost.Verification
870 passed, 2 skipped— and re-verified against the committed tree, not just the working treedecisions-validateOK; catalog up to date; doc-narrative 9 advisories, all pre-existing.husky/_absent; enumeration swallowed byexcept Exception; a lazy generator; the hardcoded.exists()gate;tracked_childrenmade recursive; the exemption removed; the AST matcher narrowedKnown residuals, stated rather than implied
The call-log check is a regression guard against the shapes that arrive by accident, not a boundary: enumeration hoisted to module import time,
from os import listdirearly binding, and anything listing in another process all pass.importlib/star-import/re-export are invisible to the AST matcher. Nested workflow directories are out of scope. Each is written down where the code is, once.test_pr_changed_files.pytoo, and correct three counts this change invalidatedCold review of the previous commit found that IT had made `docs/guard-inventory.md`'s "load-bearing for the six modules that import it" false, by adding a seventh importer — in the file it was editing, inside the sweep its own message claims to have done by subject. That is the third hand-maintained count in this change to go stale, after `mutation-claims-are-executed.md`'s three and `guard-inventory.md`'s "three of the thirteen". Correcting a number that tracks a growing population buys one commit of accuracy. So the counts that track populations are gone rather than updated: * "load-bearing for the six modules that import it" → "for every module that imports it" * "this file is not four near-copies" → "not one near-copy per derivation" * "adding a fifth derivation / a fifth index-derived guard" (twice) → "another" * "five guard modules would otherwise die" → "every module that imports this one" * "Exhaustive removal is cheap (~1s for 60 members)" → "about a second at the population sizes here" The sweep was then done MECHANICALLY — a regex over every spelled-out and numeric count in all five artifacts this change touches — rather than by eye for a fourth time. What survives is verified true rather than assumed: "three of the fourteen" and "36 guards … 14/6/16" (the latter machine-asserted by `test_the_summary_counts_match_the_table`), "unions four contributors", "five modules each derived a file population" (`DERIVATIONS` holds exactly five), and the re-measured 61/39/48/58. `guard-inventory.md`'s "three of these four rows" is #790's text about a different row set and is untouched. The figures that remain are the ones that describe a FIXED structure or carry a reproduction command; the ones that counted a set expected to grow are the ones that kept breaking, which is the distinction the sweep now encodes. Correction to the previous commit message: it called the second converted call site "the delimiter ban over every workflow". That guard is `test_every_workflow_expression_names_a_REAL_context_or_function`, an expression-context check; the delimiter ban does not use `_workflow_files()`. Both call sites are completeness claims over every workflow and both were demonstrated red against an untracked `.yaml` at the predecessor sha — only the label was wrong. refs #806 Decisions-Edit: yes Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>Cold review returned MERGEABLE with two notes; both are corrections to claims this change ships, so both are taken. THE PREVIOUS COMMIT CLAIMED A REGEX OVER EVERY COUNT IN ALL FIVE ARTIFACTS and left four. They were dated and true, which is why they read as acceptable, but a single added `MUTATION` row stales all four at once — the same fuse as the counts already removed, and the claim of a complete sweep is what made keeping them dishonest rather than merely conservative: * "three of the fourteen entries" → "three entries" (it names them; the total contributes nothing) * "the remaining eleven redden behaviourally" → "every other entry reddens behaviourally" * "thirteen of the fourteen admit clause-level proof" → "all but one" * `guard-inventory.md`'s "three of the fourteen rows" → "three rows" An independent sweep with a wider pattern now returns only counts over FIXED structures — #790's four ranked rows, `derived_guard_files`'s four union terms, #685's two guards — plus the machine-asserted `36 guards … 14/6/16`, and the member figures, which are dated, carry their reproduction command, and say in place that they illustrate the gap above the floor rather than being values to assert against. That is the distinction worth keeping: a number describing a fixed shape, or one that ships with the command that regenerates it, does not rot the way a tally of a growing set does. `docs/guard-inventory.md`'s new "listed in `DERIVATIONS` there" had the wrong nearest antecedent — `DERIVATIONS` lives in `scripts/tests/test_guard_populations_derive_from_git.py`, not in `tracked_files.py`. Named explicitly. refs #806 Decisions-Edit: yes Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>Review-verdict: MERGEABLE @
ded6cb1Twelve rounds of independent cold review (Codex GPT-5.6 + Opus alternating, isolated worktrees, cold briefs). Production derivations and the shared helper confirmed sound every round; final two rounds MERGEABLE on this head. CI fully green: 12 jobs, 1 skipped, no failures, no cancellations. One further instance of the shape found by whole-repo sweep and deferred to #819 with the obstacle documented.