Skip to content

Widen the ADR-reference guard from LinkML-only to the whole repository - #678

Merged
IanMayo merged 2 commits into
mainfrom
claude/widen-adr-ref-check
Aug 7, 2026
Merged

IanMayo merged 2 commits into
mainfrom
claude/widen-adr-ref-check

Conversation

@IanMayo

@IanMayo IanMayo commented Aug 7, 2026

Copy link
Copy Markdown
Member

Why

scripts/check-adr-refs.sh was wired into task lint by spec 205 to catch dangling ADR citations. It scans shared/schemas/src/linkml/*.yaml — which contains exactly 2 ADR citations.

The repository carries 588:

Location Files citing an ADR
specs/ 111
apps/ 23
shared/ 21
docs/ 11
services/ 3
CONSTITUTION.md, CLAUDE.md, STRATEGY.md 3

So roughly 99.7% of ADR references were never validated. The guard was effectively vestigial — it passed regardless of the state of the other 586 citations.

This matters because ADRs are load-bearing here: 38 decisions live as ### ADR-NNN: headings inside a single ~19k-word decisions.md, and CLAUDE.md instructs every session to check them before proposing architectural changes. A citation that silently resolves to nothing undermines that.

What changed

  • Scan the whole repository rather than one schema directory.
  • Reject malformed IDs as well as dangling ones. Our convention is exactly three digits; zero-padded four-digit forms look plausible in review but match no heading.
  • Scan git-tracked files via git ls-files rather than walking the working tree. This excludes node_modules, .venv and build output for free, and — more importantly — stops a developer's uncommitted scratch files from failing lint for everyone.
  • Report file:line for each failure instead of a bare list of IDs.

Runtime ~1.3s. Stays in task lint.

What it found

ADR-031 and ADR-032 are cited from 12 files but were never written. The numbering note in decisions.md shows they were reserved for the #248 / #249 extraction work and the headings never landed. Both are allowlisted in RESERVED with a pointer to that note rather than silently absorbed — whether to write them or retire the references is a decision for you, not this PR.

No other dangling or malformed reference exists across all 588 citations, so the repo is otherwise clean.

Verification

Case Result
Clean repository ✅ 588 citations / 38 ADRs, exit 0, 1.3s
Dangling ID in a tracked file ✅ exit 1, reports file:line
Malformed four-digit ID in a tracked file ✅ exit 1, reported separately from dangling
Untracked scratch file with bad IDs ✅ exit 0 — correctly ignored

Provenance

Extracted from #677 (graphify adoption), now closed unmerged. That work was trialled against the 20 most recent open issues and scored one clear win, two partial and seventeen no help — not enough to justify 26MB of committed artefacts and four workflows. This guard was the one component that stood on its own merits, and it has no dependency on graphify.

One unrelated finding from that PR, not fixed here and worth its own change: python-lint.yml runs unpinned uvx ruff while task lint runs lockfile-pinned uv run ruff, so CI and local can never agree — a newer ruff enabled Markdown code-block formatting and flagged 104 untouched files. That is an Article IX.2 pinning bug.


Generated by Claude Code

scripts/check-adr-refs.sh was wired into task lint by spec 205 to catch
dangling ADR citations, but it scanned only shared/schemas/src/linkml/*.yaml —
which contains just 2 ADR citations. The repository actually carries 588, across
specs/ (111 files), apps/ (23), shared/ (21), docs/ (11), services/ (3), plus
CONSTITUTION.md, CLAUDE.md and STRATEGY.md. Roughly 99.7% of ADR references
were never validated, so the guard was effectively vestigial.

Changes:

- Scan the whole repository rather than one schema directory.
- Reject malformed IDs as well as dangling ones. Our convention is exactly three
  digits; zero-padded four-digit forms look plausible in review but match no
  heading in decisions.md.
- Scan git-tracked files via `git ls-files` instead of walking the working tree.
  This keeps node_modules/.venv/build output out of scope for free, and stops a
  developer's uncommitted scratch files failing lint for everyone.
- Report file:line for each failure instead of a bare list of IDs.

Runtime is ~1.3s.

Found immediately: ADR-031 and ADR-032 are cited from 12 files but have no
`### ADR-NNN:` heading. The numbering note in decisions.md shows they were
reserved for the #248/#249 extractions and never written. Both are allowlisted
in RESERVED with a pointer to that note rather than silently absorbed —
whether to write them or retire the references is a separate decision. No other
dangling or malformed reference exists across all 588 citations.

Extracted from PR #677 (graphify adoption, closed unmerged). That work was
trialled against the 20 most recent issues and did not justify its cost; this
guard was the one component that stood on its own merits, and is independent of
graphify entirely.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012sWicQ3ssncgLmqYHw2VfA
@github-actions

github-actions Bot commented Aug 7, 2026 •

Copy link
Copy Markdown
Contributor

📋 Backlog Navigator

Review this PR's BACKLOG.md edits interactively:

👉 Open in Backlog Navigator

Updated for 042dea5 — the navigator reads BACKLOG.md live from this PR's head branch, so no rebuild is needed.

Carries the backlog update in the PR that does the work, so the board is
correct the moment this merges rather than needing a follow-up commit.

Strike-through applied to every non-empty cell per the existing convention
(the Epic cell is empty and stays so). Adds the issues.md entry the project
memory protocol calls for, recording the coverage numbers, the four verified
test cases, the ADR-031/032 finding, and the two open follow-ups.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012sWicQ3ssncgLmqYHw2VfA
@IanMayo
IanMayo temporarily deployed to debrief-preview-pr-678 August 7, 2026 14:24 Inactive
@IanMayo
IanMayo merged commit 03259f7 into main Aug 7, 2026
2 checks passed
@IanMayo
IanMayo deleted the claude/widen-adr-ref-check branch August 7, 2026 14:26

This branch was previously deployed

1 inactive deployment
debrief-preview-pr-678 — 042dea5b Deployed Aug 7, 2026 by IanMayo
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants