feat(B-0170): add ADR supersession convention checker#2512
Conversation
…ecker for ADR supersession markers Co-Authored-By: Codex <noreply@openai.com>
Add the v0.9 convention-drift checker slice for ADR supersession claims. The checker requires superseded ADRs to carry a reciprocal top-of-file marker naming the superseding ADR, with focused Bun tests and README wiring. Co-Authored-By: Codex <noreply@openai.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: e3ed52558a
ℹ️ 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".
There was a problem hiding this comment.
Pull request overview
Adds a new v0.9 “convention drift” check to the substrate-claim-checker suite, focused on ADR supersession reciprocity (a “Supersedes ADR …” claim must be matched by a top-of-file “Superseded by …” marker in the superseded ADR), along with Bun tests and README wiring.
Changes:
- Add
check-convention.tsto detect missing/incorrect reciprocal “Superseded by” markers for ADR supersession claims. - Add focused Bun unit tests for claim extraction and file-level checking behavior.
- Update the substrate-claim-checker README to include the new check-type and usage; add a claim file (currently left in-tree).
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| tools/substrate-claim-checker/README.md | Documents the new v0.9 convention-drift checker and usage. |
| tools/substrate-claim-checker/check-convention.ts | Implements ADR supersession reciprocity checking. |
| tools/substrate-claim-checker/check-convention.test.ts | Adds Bun tests covering extraction + reciprocal-marker cases. |
| docs/claims/task-b0170-convention-drift-check.md | Adds a claim file for the work (should be released/removed as part of landing). |
Handle hard-wrapped supersession prose when scanning ADR convention claims and strip Markdown link titles before target resolution. Co-Authored-By: Codex <noreply@openai.com>
- filter absolute paths and URLs in resolveTarget so the checker never follows paths outside the repo (mirrors check-existence.ts pattern) - add isInsideRepo guard to ensure resolved paths stay within repo root - git rm the claim file (claim release step belongs in the landing PR) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: b87ee8943c
ℹ️ 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".
…d-boundary + case-insensitive) to address P2 false-negative review finding Co-Authored-By: Grok <noreply@x.ai> Co-authored-by: Cursor <cursoragent@cursor.com>
|
Fixed the P2 false-negative in marker matching (word-boundary + casefold) and resolved all review threads. CI should be green now. Ready for merge. Co-Authored-By: Grok noreply@x.ai |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: a4ce324142
ℹ️ 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".
Tighten ADR supersession target hygiene, preserve physical line numbers for hard-wrapped claims, match reciprocal marker filenames exactly, and clarify shipped drift classes in the checker README. Co-Authored-By: Codex <noreply@openai.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 4fc64d90e0
ℹ️ 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".
Treat a top-of-file Superseded by line plus its immediate nonblank continuation as one marker line so hard-wrapped reciprocal ADR links are recognized. Co-Authored-By: Codex <noreply@openai.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: fc21a0b3c3
ℹ️ 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".
…uations When a Supersedes ADR claim is split across lines and the continuation starts with a blockquote marker (>), list marker (-, *, +), or ordered- list prefix (1.), the naïve join produced "Supersedes ADR > [v1](old.md)" which the claim regex could not match. Strip structural Markdown prefixes from the continuation before joining. Same fix applied to supersededByMarkerLines so the reciprocal check is consistent. Regression tests added for both paths. Addresses PRRT_kwDOSF9kNM6A6nNf (P2 Codex finding, check-convention.ts:208). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: bb0b203743
ℹ️ 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".
Allow backtick Supersedes ADR claims to include #anchor or ?query suffixes before the closing backtick. normalizeTarget already strips those suffixes for repo-local resolution, so the reciprocal Superseded by check now runs for anchored claims. Co-Authored-By: Codex <noreply@openai.com>
…ker scan - extend backtick claim regex to accept `.md#anchor` / `.md?query` suffixes before the closing backtick; `normalizeTarget` already strips anchors/queries so path resolution is unaffected - add fence-state tracking to `supersededByMarkerLines` (reuses existing `updateFenceState`/`startsFenceDelimiter` helpers) so a `superseded by` text inside a fenced code block in the first 25 lines is not accepted as a valid reciprocal marker - add regression tests: backtick-with-anchor, backtick-with-query, fenced-code false-positive in marker scan (21 tests, all pass) Fixes threads from chatgpt-codex-connector + Copilot on PR #2512. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…n (P2 review finding) - supersededByMarkerLines now skips ``` fenced regions when collecting top 25 lines - prevents false markers from code examples containing 'superseded by' - addresses open P2 thread on fenced exclusion Co-Authored-By: Grok <noreply@x.ai> Co-authored-by: Cursor <cursoragent@cursor.com>
… lines `supersededByMarkerLines` previously joined any adjacent non-empty line when the current line matched `\bsuperseded by\b/i`, which could accept natural prose continuations (e.g., "was superseded by\nnew.md conventions...") as a valid reciprocal marker. Fix: pull in the continuation only when it looks like a hard-wrapped file reference — i.e., after stripping structural prefixes (blockquote `>`, list `-`/`*`/`+`) the line starts with `` ` ``, `[`, or `<`. This preserves the intended hard-wrap pattern while excluding plain prose continuations. Added regression test: prose continuation after "superseded by" no longer satisfies the reciprocal check (23 tests, all pass). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 6daf777ae7
ℹ️ 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".
Tighten the reciprocal marker scan so only explicit **Superseded by** marker lines, optionally blockquoted, are accepted. Wrapped marker continuations are only joined across adjacent blockquote lines, preventing status/prose lines from satisfying the convention by accident. Co-Authored-By: Codex <noreply@openai.com>
…ssion tests Addresses 4 Copilot/Codex unresolved review threads on PR #2512: Thread PRRT_kwDOSF9kNM6A6qvP (P1): checkFile silently continued and returned ok:true when readFile(resolved) failed for a referenced target ADR. hadTargetErrors now propagates to ok:false so the caller and main() can exit non-zero. main() updated to emit findings even when ok:false so partial results are not suppressed alongside the error. Thread PRRT_kwDOSF9kNM6A6qvY (P1 test gap): regression test added for ADR whose Status line says "Superseded by new.md" (names the file in prose) but lacks the canonical top-of-file bold-blockquote marker form — checker must still flag it. Also added EISDIR target-read test. Thread PRRT_kwDOSF9kNM6A6rCE (P2): regression test added for tilde- fenced (~~~) "Superseded by" text in the top-of-file marker scan — updateFenceState already handles ~ fences; test confirms it. Thread PRRT_kwDOSF9kNM6A6qvI (P1): isSupersededByMarkerLine already requires **Superseded by** bold-prefix — existing tests cover it; reply + resolve closes the thread. 28 tests pass, 0 fail. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
Addressing remaining 4 review threads in f415acc: Thread PRRT_kwDOSF9kNM6A6qvP (P1 — target-read error propagation): Fixed. Added Thread PRRT_kwDOSF9kNM6A6qvY (P1 test gap): Fixed. Added regression test "does not treat status-line prose naming the superseding file as a reciprocal marker" — ADR with Thread PRRT_kwDOSF9kNM6A6rCE (P2 — tilde fences): Already fixed. Thread PRRT_kwDOSF9kNM6A6qvI (P1 — 28 tests pass. |
| const result = checkFile("/no/such/path/check-convention-test.md"); | ||
| expect(result.ok).toBe(false); | ||
| expect(result.findings).toEqual([]); |
| // Remove old.md after it's been stat'd (simulate a read failure by removing before checkFile runs) | ||
| // Instead, write a directory where the file is expected to be |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: f415accfc5
ℹ️ 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".
| } | ||
|
|
||
| function stripMarkdownStructuralPrefix(text: string): string { | ||
| return text.replace(/^(?:(?:>\s*)+|[-*+]\s+|\d+[.)]\s+)/, "").trimStart(); |
There was a problem hiding this comment.
Strip combined Markdown wrappers in wrapped claims
The wrapped-claim joiner only removes one structural prefix from the continuation line, so a continuation like > - [v1](old.md) becomes - [v1](old.md) and no longer matches the Supersedes ADR [..](..) regex. In that case a valid supersession claim is silently skipped and the reciprocal Superseded by check never runs, creating a convention-drift false negative for nested blockquote/list formatting.
Useful? React with 👍 / 👎.
| const trimmed = line.trimStart(); | ||
| const first = trimmed.at(0); | ||
| if (first !== "`" && first !== "~") return false; |
There was a problem hiding this comment.
Ignore over-indented fences when tracking fenced blocks
Fence detection trims all leading spaces before checking for ```/~~~, so lines indented as code content (e.g. four-space-indented ``````` literals) are treated as real fence delimiters. If such an indented opener has no matching closer, the parser stays in fenced mode and skips subsequent prose, which can hide real Supersedes ADR claims or top-of-file reciprocal markers and produce false negatives.
Useful? React with 👍 / 👎.
Adds the 5th eval-set fixture for the substrate-claim-checker, covering the convention sub-class of the 7-class verify-then-claim taxonomy. The fixture pair (current ADR + sibling predecessor ADR support file) makes the broken half of the bidirectional ADR supersession convention reproducible without depending on any real ADR pair in the repo. Anchor: PR #2512 (the PR that shipped check-convention.ts) — synthetic exemplar, same shape as the path-form-drift fixture's synthetic case. Focused check outcomes: - bun test tools/substrate-claim-checker/fixtures.test.ts → 5 pass / 0 fail - bun test tools/substrate-claim-checker/ → 117 pass / 0 fail - Direct CLI run reports 1 convention-drift finding on line 36 with the expected reciprocal-marker reason string Composes with B-0170 (parent), B-0170.4 eval-set thread (PRs #3611, #3624, #3696, #3749). operative-authorization: aaron 2026-05-14: "- **Devil-pole** (edge-runner drive): keep pushing, discover, go hard, never-be-idle" Co-authored-by: Claude <noreply@anthropic.com>
Summary
Superseded bymarker naming the superseding ADRVerification
bun test tools/substrate-claim-checker/check-convention.test.tsbun run typecheckbunx eslint tools/substrate-claim-checker/check-convention.ts tools/substrate-claim-checker/check-convention.test.tsbun tools/substrate-claim-checker/check-convention.ts docs/DECISIONS/2026-04-21-router-coherence-v2.mdgit diff --check