Repository navigation
feat(ci): fail on line citations past the end of the cited file - #6855
Conversation
Add scripts/check-line-citations.py, a whole-repository lint-repo gate that fails when a markdown `path:N` / `path:N-M` citation names a line past the end of the tracked file it resolves to. Paths that resolve to nothing, URLs, external-repository citations, fenced examples and point-in-time records (ADRs, docs/upstream, CHANGELOGs, .changes) stay quiet. Line content is not judged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The failure message printed the first resolved candidate while comparing against the longest one. Add tests for the two-candidate rule and the docs/upstream and .changes record exclusions. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
|
Claude finished @kyle-sexton's task in 2m 16s —— View job Security review in progress
|
|
Claude finished @kyle-sexton's task in 5m 12s —— View job Code review complete
No blocking findings. Traced the detector against each of the 14 test cases by hand (regex lookbehind/lookahead, fence-state machine, two-base path resolution, longest-candidate selection) and didn't find a case the tests miss:
Could not independently verify: this sandbox's permission mode denies |
|
claude-security-review has reviewed this pull request through 03ed392; a later push is reviewed from there. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 9f26a6ad22
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
Claude finished @kyle-sexton's task in 1m 39s —— View job Security review (
|
|
claude-review has reviewed this pull request through 03ed392; a later push is reviewed from there. |
The line-citation gate matched a fence only after leading whitespace, so a fenced example inside `> ` or opening a list item was scanned as citations. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Claude finished @kyle-sexton's task in 1m 38s —— View job Security review (
|
|
Claude finished @kyle-sexton's task in 3m 57s —— View job Code review (
|

No related issue: measured in the LlgiOCmFG_w re-vet follow-up (stale line citations, 10 mechanical findings on 11 PRs in one week)
Summary
Across the 391 PRs merged 2026-10-03..10, review bots flagged stale
path:N/path:N-Mline citations 14 times on 11 PRs. 10 of those were mechanical: the cited line was past the end of the file (for example #6064, whereci.yml:2639was cited but the file had 2561 lines). Nothing checked for this before review.Fix
scripts/check-line-citations.pyscans every tracked*.mdforPATH:N,PATH:N-Mand comma lists of these (PATH:269-271,410-432). It resolves PATH against the repository root and the citing file's directory, against tracked files only, and fails when the highest cited line is past the end of every file it resolves to. It does not judge whether the line still says what the citation claims.10:30,host:port), URLs,owner/repo:pathcitations,path:N:Cline-and-column, fenced code blocks (sample output and illustrative rows), and point-in-time records (docs/adr/,docs/upstream/,CHANGELOG.md,.changes/), which cite the tree as it was when they were written.continue-on-errorstep inlint-repo(id: line_citations) and feedsline-citations=into the hygiene aggregator. It scans the whole repository because a citation usually goes stale when the cited file changes, and that change rarely touches the citing doc. It takes about 1 s.Backlog: with fences and records excluded, the repository has 0 violations, so the gate covers the whole repository from the start. The raw scan found 3 violations before those exclusions. None had a clear fix, so none were edited:
docs/adr/0004…,CLAUDE.md:13-30), which describes CLAUDE.md as it was then;docs/upstream/mattpocock-skills-v12-map.mdthat already says the cited lines no longer exist;textfence inrename-references/context/audit-modes.md.Verification
bash scripts/check-line-citations.test.sh: 14 tests pass. Firing cases: a line past the end, a range end past the end, a later item of a comma list, a path relative to the citing file, a citation ending a sentence. Quiet cases: valid line and range, a nonexistent path or bare basename, a URL with a port, an external repository citation, times, line:column, a fenced example, an ADR and a CHANGELOG. One more case checks that a citation after a closed fence still fires.python3 scripts/check-line-citations.pyon this tree exits 0.scripts/run-ruff.sh checkandformat --checkpass. shellcheck and actionlint are clean. These suites pass:aggregate-hygiene-results.sh --self-test,check-docs-only-gate.sh --check,check-fixture-git-isolation.sh --check,plan-test-lanes.test.sh,workflow-self-paths.test.sh,check-docs-only-gate.test.sh.selection-audit.test.shfails one case locally because strace is missing. It fails the same way onorigin/main.Related
scripts/check-code-metrics-config-reference.pywith its.test.shwrapper andlint-repostep.🤖 Generated with Claude Code