Skip to content

tooling: nothing checks file:line citations, and ~70 had rotted #70

Description

@mtklein

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:

  1. 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.
  2. file:line-line ranges — same, plus the range should still contain the named thing.
  3. 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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions