Repository navigation
[finding] 67 of 125 ADR numbers declare no machine-readable decision letters — 37 live ADR-NNNN Dk citations into 6 of them can never be verified #12786
Description
Activity
huangyiirene commented
on Aug 27, 2026 CollaboratorMore actionsTriage: routed
domain:skills, ⛔ left ungraded (findingstays) — skills-lane findings are self-triaged by #7623 under the standing carve-out.⚠️ The routing needs its reasoning stated, because the ADR-citation family is deliberately split across two lanes this round and a reader will otherwise think one of them is a mistake:card subject lane #9592 (closed) / #12787 (closed this round) the gate — scripts/check-adr-anchors.mjs, its precision and its coveragedomain:devxthis card, and #12748 the corpus — what the ADR records should declare, and how citations into them should be spelled domain:skillsThe line is the gate's SUBJECT versus the document's content. A checker's own precision is code quality (devx); "should these 6 records grow decision letters, or should the 37 citations be respelled" is a question about the governed record itself, and option 1 lands in
docs/adr/**— governed surface, maintainer-merged per #6741. ⇒ Same lane as #12748, which asks the sibling question about citation spelling.Two notes for the skills seat, so they are not re-derived:
- ⭐ Option 1 is far narrower than the headline suggests. The headline is "67 of 125 numbers", but only 6 records are actually cited by letter today — ADR-0006, 0014, 0024, 0067, 0081 (and the sixth in that table). ⇒ The narrowest fix converts 37 unverifiable citations into checked ones by touching six documents, and it shrinks the note toward empty rather than capping it. That asymmetry (small edit, large verification gain) is the strongest argument on the card.
- ⛔ The rejected fourth option should stay rejected: an ordinal-to-letter inference in the gate (
D2= the 2nd### N.heading) was considered while building tooling:check-adr-anchorsshould verify that a citedADR-NNNN Dkdecision letter is a real heading of the cited ADR #9592 and rejected because "the record never writesD2, so the mapping would be the gate's invention rather than the document's statement, and a gate that manufactures the index it checks against cannot fail honestly." If anyone revisits this card, that is the option to not re-open.
Cross-link worth carrying: this card is axis ③'s objection in #12787, which closed this round partly because this population is large. ⇒ If this card resolves and the unverifiable set shrinks substantially, that is recorded there as reopen criterion 3 for the repo-wide coverage question. The two are sequenced, not duplicated.
⚠️ Note the corpus has two decision-numbering conventions (topical### Schema, ordinal### 1. …) and the citation convention fits only one. Whatever is decided, that is the underlying fact — ⛔ not a per-record oversight to patch six times without saying so.Measured on
origin/main@1246b4cf2; re-verify at grading, since PR #12785 was landing the note as this was filed.
Generated by Claude Code
Measured escalation on one row of this card's table:
ADR-0006 D4is no longer a "cannot verify" note — it is now a hard failing assertion, andcheck:adr-anchorsis RED onmainbecause of it.Found while implementing #12867 (the ADR-0006 D1 retirement addendum, PR #12908); filed here rather than as a new card because this card already names the exact site.
What changed since this card was measured: it recorded ADR-0006 as one of the 67 numbers declaring no decision letters, so
ADR-0006 D4scored the soft third verdict. PR #12736 then landed the ADR-0006 D1/D2/D3 addendum, which gives that record a real machine-readable letter index. The citation now resolves against an index that exists and is absent from it, which the gate treats as a failure rather than a note:✗ check-adr-anchors --self-test — 1 failure(s) of 106 assertion(s) • ADR-0006 D4 is cited by 1 file(s), but ADR-0006 declares no D4 — it decides: D1, D1.1, D1.2, D1.3, D2, D3 packages/spec/src/data/object.zod.tsBoth
node scripts/check-adr-anchors.mjs --self-testand the plain scan exit 1. The citing line ispackages/spec/src/data/object.zod.ts:1467:'`namespace` was retired in ADR-0006 D4 — the object `name` IS the canonical id 'Measured on
origin/main@0c2334f6c, with a positive control: I ran the scan against my branch and againstorigin/main's version of the ADR restored in place, and the two outputs are byte-identical — so this ismain's state, not an artifact of the addendum work.Triage note on this card's option 1 ("give the cited records decision letters"): for ADR-0006 that half-happened as a side effect. #12736 added the letters the record actually decides, and
D4was not among them because ADR-0006 does not decide namespace retirement anywhere. The remaining routes for this one site look like option 2 (respell the citation to name what the record does say) or locating the record that really did retirenamespaceand citing that. #12867's addendum deliberately did not mint aD4to green the gate: that card retires D1, and manufacturing a decision letter to satisfy a checker is the defect this gate exists to name.
Generated by Claude Code
- addedpriority:p1High: required for production / M2High: required for production / M2and removed
on Aug 28, 2026 huangyiirene commented
on Aug 28, 2026 CollaboratorMore actions<!-- os-decision-facets -->
定级:
Task·priority:p1·domain:skills·needs-user-decision分诊席位,session
session_01Aujz2zykf5LXt3T98gRsGe。needs-user-decision—— 选项 1 是编辑docs/adr/**⇒ ADR 类,人工地板,永不代裁(且按 #6741 路由到维护者自己的合并)。
priority:p1(卡未自定级) —— 理由见下:这张卡在 2026-08-27 19:23Z 填写,次日 07:49Z 它列表的第一行就引爆了。
⭐ 本卡不是"37 条无法验证的引用",是 37 根武装着的绊线
昨天的预言,今天的事故
卡的引用表第一行是:
ADR-0006 D4 1 site packages/spec/src/data/object.zod.ts⇒ 正是今天 07:49Z 让整条合并队列停摆的那一处(#12913 / #12917)。
机制是本卡没有点破的那一层。 门有三态(我从
scripts/check-adr-anchors.mjs:790-793读的):被引记录 判定 声明零字母 unverifiable—— 只报告,不判错声明了字母、但引用的不在其中 error⇒ 本卡列的 6 个号当时全在第一桶(绿)。#12736 给 ADR-0006 铸了 D1–D3,它跨进第二类,
D4同一秒掉进error桶。⇒ ⭐ 本卡的清单不是"待整理项",是"任何一个记录一旦声明任意一个决议字母,其引用立刻变成阻塞合并队列的红"的名单。
实测:还有 4 个号仍然武装着
ADR-0006 : 已声明字母 3 ⬅ 已引爆 ADR-0014 : 0 ADR-0024 : 0 ADR-0067 : 0 ADR-0081 : 0 ⬅ ⚠️ 仍武装 正对照 ADR-0028 → 6 个字母标题 ✅ 仪器能返回非零,这些零是真读数仍然暴露的引用(除已处理的 ADR-0006):
引用 站点数 ADR-0014 D21 ADR-0024 D42 ADR-0024 D5.22 ADR-0067 D24 ADR-0081 D12 合计 11 处 / 4 个号
⚠️ ⚠️ 最重要的一条:选项 1 就是引爆动作本身卡的选项 1 是「Give the cited records decision letters」。⛔ 照字面执行会立刻制造今天那场事故的复刻。
⭐ 今天的成因逐字就是这个:#12736 给 ADR-0006 加了
D1/D2/D3,而D4正被引用着,且没有同批修那处引用 ⇒ main 全红。⇒ 围栏(本卡最重要的产出):
给一个被按字母引用的记录添加决议字母时,必须在同一个 PR 里,要么把被引用的那个字母也真正声明出来,要么把引用改成不引字母的陈述。⛔ 二者必居其一,不得只加字母就走。
⚠️ 而这条对ADR-0024 D5.2尤其棘手:那是子字母形态,加D5不够,必须真的有D5.2。
四棱
① 项目长远合理性
⭐ 卡把根因说得很准:「the corpus has two decision-numbering conventions and the citation convention only fits one」 —— 67 个号按主题(
### Schema)或序数(### 1. A turn is a commit)编号,58 个按Dk。⇒ 长远正解是语料统一到一种可机读的编号,⛔ 但那是 131 个文件的工程,不是本卡。② 实际业务拉动
间接但已经兑现过一次:今天队列停摆一个多小时,多个 PR 被 CI_FAILURE 出队(#12895、pr-12897/12901/12905)。⇒ ⭐ 这一棱不再是假设,它有一次实测的成本。
③ 防 AI 犯错
⭐ 最重。引用一个不存在的字母,是 agent 找不到出处时的默认失败模式 —— #4522 就是这么产生
ADR-0006 D4的(#12918 已确立该退休从未被写下)。⚠️ 而门在 2026-08-27 之前根本查不出这一类,所以这些引用积累了数月无人知晓。
⭐ 卡拒绝"序数推断"的理由完全正确,值得原样保留:「the record never writesD2, so the mapping would be the gate's invention rather than the document's statement, and a gate that manufactures the index it checks against cannot fail honestly.」④ 创业阶段不扩散
⚠️ ⛔ 不要为此启动 131 文件的编号统一工程。⭐ 卡自己给出了最窄的范围并且是对的:今天真正被按字母引用的只有 6 个记录(现为 4 个),⇒ 只需处理这 4 个。
选项 × 成本(按今天的读数重估)
做法 成本 风险 1 给 4 个被引记录加字母 治理面 PR ×4 ⛔ 必须同批修引用,否则就是今天事故的复刻 2 ⭐ 把 11 处引用改成不声称字母的陈述(指向节标题/链接) 改代码,⛔ 不动 ADR ⭐ 不可能引爆,且这正是今天 #12917 用的解法 3 留着 0 ⚠️ 4 根绊线继续武装;任何人给这 4 个记录加一个字母就红建议:2
理由是不对称的:
- 2 拆除绊线,1 触碰绊线。 选项 2 把引用改成不引字母 ⇒ 无论那 4 个记录日后是否声明字母,都不会再红。
- 2 不碰治理面 ⇒ 走正常队列,⛔ 不需要人工手合,也就不经过今天暴露的那条"直合跳过复验"的路径。
- ⭐ 2 已经在今天被验证过一次:fix(spec): namespace tombstone stops citing ADR-0006 D4 — unblocks the merge queue's check-adr-anchors red #12917 就是把
ADR-0006 D4改成不带Dk的陈述,落地后 main 转绿、队列恢复。
退路
若维护者认为这些决议确实应当有字母(它们是真决策,值得可机读的编号)⇒ 取 1,⛔ 但必须逐个记录执行上面那条围栏,并且一个记录一个 PR,
⚠️ 不要一次改 4 个。
⚠️ 置信缺口- 我只测了"是否声明字母",⛔ 没有测那 11 处引用是否仍在树上。 卡的读数取自
1246b4cf2,此后 main 已推进很多。⇒ 取卡者第一步应重测那 11 处站点。 - 我的字母检测只覆盖三种语法(
### Dk/**Dk/| Dk),⛔ 未覆盖卡提到的第四种(Dk标题下的顶层列表声明Dk.1/Dka)。⚠️ ⇒ 某个号可能已通过第四种语法声明了字母而我没看见 —— 那会让它已经是红的而我报成"仍武装"。 58 + 67 = 125、131 文件这组普查数字我没有复现,只复现了与决策相关的那 5 个号。
裁后执行段
- 取 2(建议):改 11 处引用 ⇒ 落
packages/**与scripts/adr-anchors/*.json⇒ 跨车道(engine / services / spec / cli 都有),⚠️ 建议按域拆卡,⛔ 不要一个 PR 横扫。 - 取 1:⛔ 每个记录一个 PR,且必须同批处理其被引用的字母。治理面 ⇒ draft + 人工合并;
⚠️ 手合前 base 必须更新到当前 main 并重跑门(今天的教训)。 - ⛔ 无论取哪个:不得在门里加序数推断。卡已论证,我复述:一道自己制造索引再拿来检查的门,无法诚实地失败。
相关
#9592 / PR #12785(门与本卡的出处)· #6741(
docs/adr/**的治理路由)· ⭐ #12913 / #12917(本卡第一行今天引爆并被修复)· ⭐ #12918(该退休从未被写下 —— 与本卡是同一个洞的两半)· #12736(铸出 D1–D3 的那次治理直合)
Generated by Claude Code
Found while implementing #9592 (the
ADR-NNNN Dkdecision-letter check inscripts/check-adr-anchors.mjs, PR #12785). Filed as a finding, not fixed there: the remedy is an edit todocs/adr/**, which is governed surface routed to the maintainer's own merge per #6741, and the gate deliberately reports rather than forces it.Measured on
origin/main@1246b4cf2docs/adr/holds 131 files under 125 distinct ADR numbers. Grouping every number by whether any of its records declares a machine-readable decision letter, by the four grammars the corpus actually uses (### Dkheading,**Dk —**bold lead,| Dk |decision-table cell, and aDkheading's own top-level list declaringDk.1/Dka):The 67 number their decisions topically (
### Schema,### Hostname routing— ADR-0006, ADR-0014, ADR-0024, ADR-0081) or ordinally (### 1. A turn is a commit,### 2. Commits are atomic— ADR-0067 and ~20 others), never asDk.Why it matters now
The new check has to report a third verdict for them — "cannot verify" — because there is no index to resolve against. On the anchored surface alone that is 37 citations across 12 letter/file sites and 6 ADR numbers:
Each of those citations is a promise a reader cannot collect:
ADR-0067 D2is meaningful (that ADR's own amendment calls its second decision "the D2 join"), but the record never writesD2, so following the citation means counting headings and hoping.The gap is not the citation's fault and not the gate's: it is that the corpus has two decision-numbering conventions and the citation convention only fits one.
Options, for triage
An ordinal-to-letter inference in the gate (
D2= the 2nd### N.heading) was considered while building #9592 and rejected: the record never writesD2, so the mapping would be the gate's invention rather than the document's statement, and a gate that manufactures the index it checks against cannot fail honestly.Re-check
Refs: #9592 (the check) · PR #12785 (where the note ships) · #6741 (governed-surface routing for docs/adr/**)
Generated by Claude Code