docs: convert 21 dead BACKLOG anchors, repair 23 source-link targets, file #1098-#1100 (BACKLOG #1095) - #283
Merged
Conversation
A `BACKLOG.md:<line>` anchor cannot survive an actively edited ledger. The file moved 6,318 -> 6,616 lines during this work alone, and of 43 anchors repo-wide, every one examined had drifted onto unrelated text. Five that were past EOF a day earlier are now IN range and land on plausible-looking wrong items, which is worse than dangling. Item numbers survive both editing and archival, so that is what these become. Root cause, and it is not gradual drift: commit 4ea1501 (the master test plan) is NOT a descendant of 03f1fbd (the 185-item archival). They were parallel branches. The plan's anchors were authored against an 8,742-line ledger and landed beside a commit that cut it to 3,858, so they were stale on arrival, not over time. Recovery was per-site reading with the citing prose as the primary evidence -- it usually names the item inline -- backed by resolving each anchor against the pre-archival ledger at 03f1fbd^. Every mapping was then put to an adversarial reviewer instructed to refute by default. 32 of 43 survived; the 11 refusals were not noise and are deliberately NOT converted here: - Eight sites where the citing CLAIM is dead, not just the pointer. The alerting chapter still asserts #139 and PHI.md "currently contradict each other" when #139 was corrected 2026-08-01 and the code fixed by #323 on 2026-08-02; the ranked-backlog row for #338 is a pre-shipping snapshot. Repointing those would relaunder a false present-tense claim as a fresh, durable-looking reference. They need a content fix, which is a different change. - Six anchors that cannot be attributed to any item, including one pointing at an un-numbered narrative bullet. Left uniform rather than half-repaired: uniform staleness is at least detectable, and a confident wrong pointer is not. - Three that are not citations at all -- two inside a fenced transcript in #1083 reproducing scanner output, and #347's own Source paragraph narrating the falsification test that made the status checker fail on purpose. One mapping was recovered after the review: 16-security-phi:891's "no dormancy contingency" quotes #89's title ("hl7apy security hardening -- dormant-upstream contingency") almost verbatim. One proposal was refuted only on fragment uniqueness, not on the item; applying line-scoped rather than globally makes it safe, which is how all of these were applied.
The repo's file_path:line_number citation convention had leaked inside the href: [`pipeline/alerts.py:27`](messagefoundry/pipeline/alerts.py:27). No prefix makes that resolve. Owner's ruling was to move the line out of the target and keep it in the link text, where it already sits -- no second convention, and nothing lost. These carry a second defect that hid behind the first. The targets were also root-relative, the class #280 repaired across 333 hrefs in this same subtree; they were skipped there because link_check.py deliberately skips ":<line>" targets, so each defect concealed the other. Both are fixed here: the line comes out and the ../../../ prefix goes in, matching the form #280 established in these files. All 23 targets were confirmed to exist before rewriting. Repo-wide there are now zero file:line hrefs, so --include-line-cites reports nothing new -- the checker's skip is now a safety net rather than a suppression.
#1095 recorded four measured counts and three of them were wrong -- in the way the item itself is about. Its href figure of 13 was low by two orders of magnitude against at least 629 repaired sites. Its two anchor counts moved between filing and repair, and not because anything improved: this file grew 6,318 -> 6,616 lines, so five anchors that were safely past EOF came back INTO range and now land on plausible-looking wrong items. A dangling pointer degrades into a confident one as the file grows, which is the sharpest argument for the item-number convention. Root cause of the anchor class recorded, because it is not gradual drift: commit 4ea1501 (the master test plan) is not a descendant of 03f1fbd (the 185-item archival). Parallel branches, so anchors written against an 8,742-line ledger landed beside a commit that cut it to 3,858 -- stale on arrival. It also explains the anchor citing line 8429, absurd against 6,616 and ordinary against 8,742. The markdown-only scope note is discharged rather than left open. The predicted sweep of harness/, ide/src/, messagefoundry/, scripts/, tests/, packaging/ and .github/workflows/ ran over 1,219 files: 68 nonexistent paths, none of them a rotted citation -- test fixtures, withheld directories, and past-tense historical comments. The prediction was wrong and the reason is kept: citations in code are written about the past, prose citations are written as pointers. Three items filed, numbers allocated with alloc.ps1: #1098 -- the coordination hook prints a session UUID in the column a commit SHA occupies. Small, but it is an instrument answering a different question from the one its header asks, with nothing in the output saying so. #1099 -- #1094 says "the archival pass generates the anchor". There is no archival tooling at all; the move is manual. The sentence sits in the archive as settled record and points maintenance at a generator that was never built. #1100 -- the nine sites where the citing CLAIM is dead, not just the pointer, split out of #1095 rather than repointed. The alerting chapter still sets exit criteria requiring that #139 and PHI.md be made to agree when #139 was corrected 2026-08-01 and the code fixed by #323 on 2026-08-02. Converting those pointers would attach a durable reference to a false claim, which is worse than leaving the stale anchor visible. Found by the adversarial pass: every one was proposed as a clean repoint by a first reader and refuted by a second who checked the claim against the code rather than against the anchor.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes out the remaining docs half of BACKLOG #1095. Independent of #281 (the link-resolution gate): the two branches trial-merge clean and merge order does not matter.
What this changes
docs/BACKLOG.md:1234anchor points at a line number that moves the moment anything above it is edited, so these were already wrong and would keep going wrong. Item references survive edits.file_path:line_numberconvention appears inside link targets, where it cannot resolve as a path under any prefix.Verification, and why it is stated rather than assumed
This is a docs-only PR, which is this repo's blind mode, not its cheap one: the doc-drift guards live in pytest gated on
code == 'true', and.mdis in thenoncodeallowlist, so they skip pre-merge and fire on the push tomainafterwards. Run locally instead, using the exact command from the ungated doc-guard step in.github/workflows/ci.yml:Result: 175 passed, 89 skipped. All 89 skips are
tests/test_threat_model_doc_drift.py, which asserts againstdocs/security/THREAT-MODEL.md- vault-only and absent from this tree by design (the ADR 0156 class thatci.ymlalready documents). No skip here is masking a failure in the guards that can see this tree.Branch is current with
mainat time of push (git merge origin/mainreported already up to date), so the diff above is the whole change.Provenance
Authored by the session in worktree
sweet-dhawan-57cbc8(claude/citation-link-rot-4808fe). Pushed and opened by the coordinator session under an explicit owner grant covering external repo actions; the commits are unmodified from that session's tips, anchored by tagbackup/1095-docs-ee9f10b4.