Three agents independently found rotted file:line citations on 2026-07-30, and nothing in the tree checks them. Roughly 70 were repointed in the tech-debt pass and more certainly remain.
The worst case found: ot6_codex.asm's header is the issue-#29 audit argument — a list of every writer of $021f, which is the evidence that a whole class of bug does not exist — and two of its four addresses were ~600 lines stale. That is not cosmetic. This repo's stated worst failure mode is someone trusting a confident-looking statement, and a citation that points at the wrong line is exactly that with extra credibility.
Others: surgery-map.md §1's entire line column was dead (+24 to +376 drift); vanilla-destructive-bugs.md's cross-document citations pointed into kits.md at a Terra spell row; kit-gau.md:100 sent Ot6LoadoutUnpack to :932 when it was at :1105; ff6/cfg/ff6-en.cfg:49 cites ot6.asm OT6_ANIMTICK, a symbol that exists nowhere.
What a checker would need to do
Citations appear in three places and only the first two are mechanical:
file:line in docs and code comments — resolvable: does the file exist, does it have that many lines, and (the useful part) does the line still look like what the citation claims? A citation naming a symbol (`Ot6BoostDmg` (ot6_kits.asm:1190)) can be checked by grepping for the symbol and comparing.
file:line-line ranges — same, plus the range should still contain the named thing.
- Bare filenames with no path (how every cross-file provenance note is written) — these survive file moves, which is a feature; they only need an existence check.
Suggested shape: a tools/check_citations.py joining make test's checker family (check_boss_rows.py, check_break_reach.py), which already enforce doc/data agreement and are the precedent. Start with the cheap wins — a citation past end-of-file is unambiguously wrong, and the scan that found the last seven of those took minutes.
Do not make it fail on drift it cannot verify. A line number that moved but still points at the right code is fine and there is no way to know; the check should catch pointing at nothing and pointing at a symbol that is not there, and stay quiet otherwise. A noisy checker gets suppressed, and then it is worse than none.
Related: line numbers rot fastest after refactors — the ot6_kits.asm split into ten files (3aa5e59) invalidated every ot6_kits.asm:NNN citation in docs/ and tools/tests/, and several were already wrong before it.
Three agents independently found rotted
file:linecitations on 2026-07-30, and nothing in the tree checks them. Roughly 70 were repointed in the tech-debt pass and more certainly remain.The worst case found:
ot6_codex.asm's header is the issue-#29 audit argument — a list of every writer of$021f, which is the evidence that a whole class of bug does not exist — and two of its four addresses were ~600 lines stale. That is not cosmetic. This repo's stated worst failure mode is someone trusting a confident-looking statement, and a citation that points at the wrong line is exactly that with extra credibility.Others:
surgery-map.md§1's entire line column was dead (+24 to +376 drift);vanilla-destructive-bugs.md's cross-document citations pointed intokits.mdat a Terra spell row;kit-gau.md:100sentOt6LoadoutUnpackto:932when it was at:1105;ff6/cfg/ff6-en.cfg:49citesot6.asm OT6_ANIMTICK, a symbol that exists nowhere.What a checker would need to do
Citations appear in three places and only the first two are mechanical:
file:linein docs and code comments — resolvable: does the file exist, does it have that many lines, and (the useful part) does the line still look like what the citation claims? A citation naming a symbol (`Ot6BoostDmg` (ot6_kits.asm:1190)) can be checked by grepping for the symbol and comparing.file:line-lineranges — same, plus the range should still contain the named thing.Suggested shape: a
tools/check_citations.pyjoiningmake test's checker family (check_boss_rows.py,check_break_reach.py), which already enforce doc/data agreement and are the precedent. Start with the cheap wins — a citation past end-of-file is unambiguously wrong, and the scan that found the last seven of those took minutes.Do not make it fail on drift it cannot verify. A line number that moved but still points at the right code is fine and there is no way to know; the check should catch pointing at nothing and pointing at a symbol that is not there, and stay quiet otherwise. A noisy checker gets suppressed, and then it is worse than none.
Related: line numbers rot fastest after refactors — the
ot6_kits.asmsplit into ten files (3aa5e59) invalidated everyot6_kits.asm:NNNcitation indocs/andtools/tests/, and several were already wrong before it.