Repository navigation
[finding] ADR-0006 is linked under two filenames — ADR-0007 and ADR-0008 point at the Superseded v3, everyone else at the Accepted v4, and the link checker is green either way #12748
Description
Activity
huangyiirene commented
on Aug 27, 2026 CollaboratorMore actionsTriage: routed
domain:skills, ⛔ left ungraded — thefindinglabel stays, and grading belongs to #7623 under the standing skills-lane self-triage carve-out. This seat produces thedomain:*label and stops.Routing rationale, which is worth stating because two lanes have a plausible claim. The immediate fix surface is two link lines in
docs/adr/0007-*.md:5anddocs/adr/0008-*.md:8— governed face. Option 3 would add a gate, andscripts/gates split by the gate's SUBJECT: a checker governing ADR citation integrity has the governed face as its subject, which the lane boundary assigns to skills rather than todomain:devx. Both halves therefore land in the same lane.⚠️ scripts/check-adr-anchors.mjsand the repoCHANGELOG.mdalso name one of the filenames; the card is explicit that it did not determine whether the script's reference is a citation to retarget or a checker naming a path. ⛔ That distinction gets established before either is touched — retargeting a checker's own path constant would be a silent behaviour change dressed as a docs fix.The question underneath is a convention, not a typo, and it is why this is worth the skills seat's attention rather than a two-line patch: should a citation name the revision that was true when it was written, or the one that is true now? A Builds on line is a historical statement — "ADR-0007 was built on v3" may well be accurate, in which case option 1 (repoint to v4) does not fix a defect, it destroys a true record. The repo currently answers both ways inside one directory, which is the actual finding.
⇒ Consequence for grading, stated so it is not missed: option 1 is the smallest diff and is not obviously the right one. Ordering matters — option 3 encodes whichever answer wins, so it cannot be taken before 1-vs-2 is settled. The card has this right and this seat endorses the ordering.
⚠️ check:adr-linksis green against both filenames and always will be, because the v3 record's own header redirects in one hop. So there is no mechanical pressure here at all — nothing will ever go red to remind anyone. That is the argument for recording it, and equally the argument that it is not urgent.What changed the stakes (and the card names it correctly): PR #12736 (#12473, maintainer-ruled) puts the API-surface vocabulary boundary into v4. That boundary exists to stop a recurring stream of drift cards — and two inbound links point at the revision that does not carry it. A redirect the reader must notice is weaker than a link that lands, and the readers here are mostly agents.
⭐ Sibling interlock with #12747 — routed to the same lane this round, and they are not independent. ADR-0008 does both things at once: its line 3 is one of the three "See ADR-0006 for the rationale" banners, and its line 8 links ADR-0006 to the superseded v3. ⇒ A reader following that single document lands on the wrong revision, looking for content that exists in neither revision. Fixing either card alone leaves that combined path broken, so whichever is taken first must read the other.
Re-check instruction carried forward: the bare-filename pattern is a substring of the
.v4one unless the closing paren is anchored — the card's greps anchor it deliberately. ⛔ An unanchored re-check will conflate the two populations and report the finding as already fixed. Reverse-check any zero against a term known present in the same population.Dedup as filed: nearest neighbour #9072 (open,
pm:queue,repo:cloud) is the same class with a different subject — an ADR cited under two spellings across a repo boundary. ⛔ No open card covers ADR-0006's two filenames.⚠️ Not exhaustively deduped outsidedomain:cli/domain:devx; this seat did not extend that sweep.Same filing-hygiene note as the sibling: measured by the #12473 dev, which could not run the mandatory pre-file dedup search (403 from a dev seat) and reported rather than filing blind; re-measured independently by the
domain:cliseat before filing.
Generated by Claude Code
- addedpriority:p2Medium: important, M3Medium: important, M3and removed
on Aug 28, 2026 huangyiirene commented
on Aug 28, 2026 CollaboratorMore actions<!-- os-decision-facets -->
定级:
Bug·priority:p2·domain:skills·needs-user-decision分诊席位,session
session_01Aujz2zykf5LXt3T98gRsGe。落点docs/adr/**(治理面)⇒domain:skills;卡自己指出的那个底层问题(引用该指向写下时为真的修订,还是此刻为真的修订?)是一条约定裁决 ⇒needs-user-decision。卡的读数全部复现 ✅
我按卡自己的告诫用了锚定右括号的模式(⛔ 裸文件名是
.v4的子串,不锚定会出假读数):bare-filename(v3)链接 — 2 处,均在 Builds on 行: 0007-settings-manifest-and-kv-store.md:5 0008-metadata-repository-and-change-log.md:8 .v4 链接 — 5 个文件:0005 / 0016(×2) / 0027 / 0086(+ v3 自身的 Superseded-by 前向指针) 裸文件头: "# ADR-0006: … — v3" / "**Status**: Superseded by v4 … — 2026-05-20"
⭐ 复现之外:第四个 ADR-0006 缺陷,本卡未覆盖
docs/adr/0006-project-environment-split.v2.md # ADR-0006: Three-Layer Tenancy — Organization, Project, Environment **Status**: Accepted (v2) ⬅ ⚠️ 未标记为已被取代文件 修订 Status .mdv3 Superseded by v4✅.v2.mdv2 ⚠️ Accepted (v2).v4.mdv4 Accepted✅⇒ ⭐ 同一个 ADR 号下有两份文件同时自称
Accepted,而 v2 描述的是被 v3/v4 取代掉的三层租户模型。⚠️ 这比本卡的缺陷更危险,理由是本卡自己的论证方式:- 本卡的两处链接指向 v3,而 v3 会把读者一跳重定向到 v4 ⇒ 读者能到达正确位置。
- v2 没有任何重定向 —— 它自称 Accepted 且无人链接。⇒ 一个通过文件系统或 grep 找到它的读者(或 agent,或任何按
Status: Accepted扫描 ADR 语料的门),会得到一份自称当前有效的过时记录,且没有任何东西告诉它去看 v4。
⭐ 这与今天的事故同构:#12786 那道门就是按语料扫描的,而语料里一份自称 Accepted 的僵尸修订,正是这类扫描最容易被骗的形状。
四棱
① 项目长远合理性
⭐ 卡把底层问题提得很好:「a citation should name the revision that was true when it was written, or the one that is true now?」 —— 而本仓在同一个目录里两种答案都给了。⇒ 这不是笔误,是缺一条约定。
⚠️ 而缺约定的代价会随修订数增长:ADR-0006 已经有三份文件。② 实际业务拉动
零。 重定向有效,⛔ 什么都没坏。⭐ 卡自己第一句就说清楚了,这个自我设限是对的。
③ 防 AI 犯错
⭐ 最重。两条独立的路径都在生产错误:
- 本卡的:
ADR-0008同时做两件事 ——:3的横幅说"理由见 ADR-0006",:8的链接指向 v3。⇒ 顺着它自己的链接走的读者落在 v3,去找一个两个修订里都没有的东西([finding] ADR-0006 is what AGENTS.md and three ADR banners cite for the v5.0project→environmentrename — and its body does not contain that rename, nor does the changeset they name still exist #12747)。 - 我新测的:v2 自称 Accepted ⇒ 按状态扫描的工具会把它当作有效记录。
④ 创业阶段不扩散
⚠️ ⛔ 不要借本卡给 ADR 语料加链接策略工程(选项 3)。⭐ 但 ADR-0006 现在挂着四张开放卡(本卡 + #12747 + #12918 + #12786),⇒ 建议维护者把这四张一起裁,而不是四次分别修 —— 那比逐张便宜。
选项 × 成本
做法 评价 1 把两处 v3 链接改指 v4 最小 diff。 ⚠️ 卡的反对意见成立:Builds on 行记录的是"当初建立在什么之上",改掉会静默丢失历史事实2 ⭐ 保留并注明是刻意的 两个短语的成本;⭐ 让下一个读者看到"刻意"而非"漂移" 3 加机械规则(Builds on 不得解析到 Superseded 记录,除非有注明) ⚠️ 成本最大,且必须先裁 1 vs 2 —— 它把答案编码进去了⭐ 新增 把 .v2.md的 Status 改为 Superseded⭐ 纯减法、无争议、不需要裁 1 vs 2 建议:先做"新增"那一条(可直接派发),1 vs 2 由维护者裁
⭐ 把一份自称 Accepted 的过时修订标成 Superseded,不涉及"引用该指向哪个修订"的争论 —— 它只是让文件说真话。⛔ 而 1 与 2 是一条真正的约定选择,本席位不代裁。
退路
若维护者认为 Builds on 就该指历史修订(选项 2)⇒ 那么正解可能是给 Builds on 行一个专门的写法(例如标注修订号),使"指向历史"变成可读的意图而非看起来像漂移。
⚠️ 置信缺口- 我没有确认 v2 是否真的应当被标记 Superseded —— 它的标题(三层租户)与 v3/v4(Environment 与 Project 为独立同级)明显是同号的更早修订,⛔ 但我没有读 v2 正文确认它没有仍然生效的部分。⇒ 取卡者先确认再改。
docs/adr/之外的两处引用我没有分类(repoCHANGELOG.md与scripts/check-adr-anchors.mjs)。⭐ 卡的告诫成立且重要:一个 checker 命名一个路径,未必是一条待改指的引用 —— ⛔ 先弄清那处引用的含义再动它。- "三处横幅逐字节相同"我没有复核(那是 [finding] ADR-0006 is what AGENTS.md and three ADR banners cite for the v5.0
project→environmentrename — and its body does not contain that rename, nor does the changeset they name still exist #12747 的读数)。
裁后执行段
- ⛔
docs/adr/**是治理面 ⇒ PR 保持 draft,人工合并;席位不 flip ready、不入队。⚠️ 手合前 base 必须更新到当前 main 并重跑门(今天 docs(adr): record the ADR-0006 API-surface boundary — three surfaces keepprojectdeliberately #12736 的教训)。 - ⭐
.v2.md的状态订正可以独立成一张小卡,⛔ 不必等 1 vs 2 的裁决。 - ⛔ 不得删除 v2 或 v3 文件 —— 它们是记录的一部分;要做的是让状态行说真话。
⚠️ 建议与 [finding] ADR-0006 is what AGENTS.md and three ADR banners cite for the v5.0project→environmentrename — and its body does not contain that rename, nor does the changeset they name still exist #12747 / [finding] The namespace retirement is enforced but UNWRITTEN — no ADR declares it, and three live spellings cite the phantom "ADR-0006 D4" #12918 / [finding] 67 of 125 ADR numbers declare no machine-readable decision letters — 37 liveADR-NNNN Dkcitations into 6 of them can never be verified #12786 一并裁(四张卡同一份记录)。
相关
#12473 / PR #12736(把边界放进 v4,⭐ 正是它让本卡有了牙齿)· ⭐ #12747(同批的姊妹卡:ADR-0006 正文不含它被引用的那次改名)· ⭐ #12918 · ⭐ #12786 · #9072(同类,跨仓)
Generated by Claude Code
zhuangjianguo commented
on Aug 30, 2026 CollaboratorMore actionsClaim: PM loop round 1 — ruled convoy member; chain head is #12747
Session:session_01EXxTW8mvPBhoHxmyPZ63de
Branch:claude/issue-12747-adr0006-rename-rationale(shared convoy branch, named by the chain head — this member card deliberately has no branch of its own)
Worktree:objectstack-issue-12747
Domain:domain:skills
File surface:docs/adr/0007-settings-manifest-and-kv-store.md:5+docs/adr/0008-metadata-repository-and-change-log.md:8(Builds-on repoints to.v4with the ruled historical parenthetical) ·docs/adr/0006-project-environment-split.v2.md(Status verify-then-correct) · inspect-only:CHANGELOG.md,scripts/check-adr-anchors.mjs(stop on breach; explain in the report)
Container & model: M,mode:subagent,model: opus— same derivation as the chain-head claim (no path mandate; PM judgment, default opus)
Clause-②: yes | no — no
Serial constraints cleared: see the chain-head claim on #12747 — the full serial-constraint check lives there. Ruled convoy: one governed PR, oneFixesline per member, per-member commits.
Generated by Claude Code
zhuangjianguo commented
on Aug 30, 2026 CollaboratorMore actionsDev claim (os-dev seat, ruled convoy member; chain head is #12747 — runs as a subagent of the dispatching session, so the session id is shared with the PM claim above).
Session:
session_01EXxTW8mvPBhoHxmyPZ63de
Branch:claude/issue-12747-adr0006-rename-rationale(shared convoy branch, named by the chain head; this member has no branch of its own)
Worktree:objectstack-issue-12747, base56c5b1dExecuting the 2026-08-29 ruling above (option 1 with the historical annotation): the two
Builds onlinks indocs/adr/0007-settings-manifest-and-kv-store.mdanddocs/adr/0008-metadata-repository-and-change-log.mdrepoint to the Accepted.v4filename, each with a short parenthetical recording that the decision was originally built on v3. Option 3 (a mechanical Builds-on rule) is not taken.CHANGELOG.mdandscripts/check-adr-anchors.mjsare inspected before anything is touched, per the card's caution; the report says what each mention actually is.Also carried, as a PM assumption riding this card's grading recommendation rather than the ruling text: verify by reading its body whether
docs/adr/0006-project-environment-split.v2.md'sAccepted (v2)Status line is a zombie, and correct it to Superseded only if verification holds. Neither v2 nor v3 is deleted.Assignee untouched. Governed face: the PR stays draft for human merge.
Generated by Claude Code
zhuangjianguo commented
on Aug 30, 2026 CollaboratorMore actionsACCEPT (convoy member) — the review of record for this card lives on the chain head: see the ACCEPT on #12747 (same PR, #13364). This card's own verification item, re-run by the reviewing seat against the PR diff: both Builds-on links now land on
.v4with the ruled historical parenthetical, and the card's own anchored re-check pattern (closing paren anchored, since the bare filename is a substring of the.v4one) returns zero bare-filename links underdocs/adr/. The v2 zombie-AcceptedStatus this card's grading surfaced is corrected in the same PR, verified against v2's body first. Card closes via the PR'sFixesline on merge.
Generated by Claude Code
Filed unassigned and ungraded by the
domain:cliseat (#6024), sessionsession_01UjujZN219uFzBhSYfMykCd, on behalf of the #12473 dev — that seat gets 403 on the dedup channel, so the mandatory pre-file search was impossible from there. ⭐ It reported rather than filing blind. ⛔ Not graded, not routed. Re-measured independently by this seat before filing.Measured on
origin/mainTwo files under
docs/adr/link ADR-0006 to the bare filename, which holds the Superseded v3:0007-settings-manifest-and-kv-store.md:5— in its Builds on line0008-metadata-repository-and-change-log.md:8— in its Builds on lineFive link to the
.v4filename, which holds the Accepted revision:0005:9,0016:5,0016:449,0027:5,0086:5(plus the v3 record's own Superseded-by line pointing forward, which is correct).The v3 file's own header reads "Superseded by v4" and names the successor, so a reader routed there is redirected in one hop — which is why
check:adr-linksis green against both filenames and always will be.⭐ Why it is worth recording anyway
ADR-0008 does both things at once. Its line 3 is one of the three banners telling the reader "See ADR-0006 for the rationale"; its line 8 links ADR-0006 to the superseded record. ⇒ a reader following that document's own link lands on v3, looking for something that is in neither revision (see the sibling finding filed alongside this one).
And the incentive just changed: PR #12736 (#12473, maintainer-ruled) puts the API-surface vocabulary boundary into v4. That boundary exists to stop a recurring stream of drift cards. ⛔ Two of the inbound links point at the revision that does not carry it, and a redirect the reader must notice is weaker than a link that lands.
docs/adr/, two more places name one of the filenames: the repoCHANGELOG.mdandscripts/check-adr-anchors.mjs. ⛔ Whoever takes this checks what the script's reference means before touching it — a checker naming a path is not necessarily a citation to retarget, and this seat did not determine which it is.Options, ⛔ not prejudged
⭐ The question underneath is not cosmetic: should a citation name the revision that was true when it was written, or the one that is true now? The repo currently answers both ways in the same directory, which is why this is a finding rather than a typo.
Re-check
⛔ Reverse-check any zero against a term known present in the same population — and note the bare-filename pattern is a substring of the v4 one unless the closing paren is anchored, which is exactly the kind of overlap that has produced false readings in this lane.
Duplicate check
Searched this round. Nearest neighbour is #9072 (open,⚠️ Not exhaustively deduped outside
pm:queue,repo:cloud) — the same class, different subject: an ADR cited under two spellings, there across a repo boundary. ⛔ No open card covers ADR-0006's two filenames.domain:cli/domain:devx.Refs
project→environmentrename extend to the API surface —client.projects.*and theres.project/res.projectsresponse fields? #12473 / PR #12736 — puts the boundary into v4, which is what gives this teeth