`check-capture-citations` exits 1 on a clean checkout of this branch, and would
have kept doing so for ever:
🔴 cited but NOT committed: 1
docs/re/captures/no-such-file-anywhere.png
`SEARCH` includes `tools`, so the scan reads this file -- and `selftest()`'s
planted fixture is a literal capture path. The checker cited its own test data,
to a file that will never exist by construction. A gate that is red before
anyone changes anything teaches people to ignore it, which is the opposite of
what Phase 4 built it for.
Excluding only this one file (`SELF`) keeps every other tool in scope. A real
citation belongs in a page, or in a tool that opens the capture -- never in the
checker itself.
Added a selftest case for it, because this is exactly the class of bug the rest
of this file already documents surviving: the ERE that matched nothing while
five ticks stayed green. Verified the guard can fail, rather than assuming it:
exclusion neutralised -> "own fixtures not counted 🔴 FAILED",
selftest rc=2, real check rc=1 reproducing the bug
exclusion restored -> selftest ok (7 cases), check rc=0
After the fix, on this branch:
captures committed : 212
cited by a page or a tool : 212
cited by nothing : 0
🔴 cited but NOT committed: 0 rc=0
which is also the first independent confirmation of Phase 4's "212 captures,
all cited" -- the checker now agrees with the page.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
CONSOLIDATION.md Phase 4. `tools/port/check-citations` has checked
`docs/port/*.md` since it was written; `docs/re/` never had one, and
`docs/re/captures/` is the largest thing in the repository -- the one place a
file can be added, never cited, and never noticed.
captures committed : 212
cited by a page or a tool : 212
cited but NOT committed : 0
🔴 THE PREMISE I STARTED FROM WAS WRONG FOUR TIMES, AND EACH CORRECTION IS IN
THE TOOL RATHER THAN JUST IN MY HEAD:
* "10 dangling citations" -- the real number was ONE. Eight were DIRECTORY
references, which resolve and are simply absent from `git ls-tree`; one was
a path at the end of a sentence with the full stop pulled into the match.
A checker that cries wolf nine times in ten teaches you to ignore it.
* The one real dangler, `live-submenu-unidentified.png`, was COMMITTED and
then deleted on 2026-08-30 while the page kept citing it and kept making
the claim it backs. Restored from 77e54e95 rather than dropping the link:
deleting evidence while keeping the conclusion is the thing this corpus
exists to prevent.
* Two "orphans" are opened BY FILENAME from `screen_match.py`, which builds
the directory separately. A path-only scan called them unreferenced and
deleting them would have broken the tool. The check now counts any
basename named anywhere.
* Pruning then EMPTIED two directories that pages cite as directories, and
the check went red on the very citations that made them evidence. It
caught its own damage. A file inside a cited directory is cited.
The selftest covers all of it, including the failure that actually happened:
an earlier version passed five green ticks while the scan silently returned
NOTHING, because `git grep -E` is POSIX ERE and cannot compile `(?:`. A
selftest that cannot see the failure that occurred is decoration.
46 orphaned captures dropped, 30.7 MB from the checkout. ⚠️ That reclaims no
repository space -- the blobs stay in history -- and it is not meant to. It
means every capture here is now evidence some page or tool actually uses.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>