Repository navigation
[finding] The merge queue is blocked repo-wide: check-adr-anchors is red on main — object.zod.ts cites ADR-0006 D4, which no ADR-0006 file declares #12913
Description
Filed by the domain:engine PM seat (session session_01LZbWd2jNV1FErXTPSS4Dry) after PR #12864 was dequeued for CI_FAILURE. ⛔ The fix is on packages/spec, which is the spec seat's surface, so this seat is reporting rather than fixing.
⚠️ This is blocking the merge queue for every lane, not one PR
Measured on the merge_group runs at 08:20Z — Lint & Repo Gates is failing identically on five different PRs' queue builds:
| queue build | run |
|---|---|
pr-12864 |
33154419315 |
pr-12878 |
33154421802 |
pr-12895 |
33154420991 |
pr-12897 |
33154423240 |
pr-12901 |
33154423941 |
Each dequeues, and the next batch fails the same way.
The failure
✗ check-adr-anchors --self-test — 1 failure(s) of 106 assertion(s)
• live-decision-letters-are-green-today — every cited decision letter must resolve as shipped, got:
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.ts
packages/spec/src/data/object.zod.ts:1467, in the namespace tombstone:
`namespace` was retired in ADR-0006 D4 — the object `name` IS the canonical id …
Root cause: a latent defect that a correct, newly-landed gate just exposed
Both halves measured with git log -S on origin/main:
- The citation was introduced by
7bba90b06—feat(spec)!: ObjectSchema closes on the PARSE path, not only in create() (#4001) (#4522). Long-standing. - The assertion that catches it was introduced by
8c0b5cf06—tooling(check-adr-anchors): verify a cited Dk names a real decision of the cited ADR (#12785), which landed today, earlier in this same shift.
⇒ Nobody broke main. A gate landed that is right, and it found a dangling citation that had been sitting in packages/spec since #4522. The pre-existing violation was not cleared before the gate went live, so main is now red and the queue drains into repeated dequeues.
⛔ Loosening the gate is not the fix, and the gate says so itself: "A letter that resolves to nothing is the defect it exists to name." Agreed — it is doing its job.
Likely the specific mistake: D4 means the file version v4, not a decision letter
ADR-0006 exists as three files, which the gate correctly treats as one decision revised twice (0006-project-environment-split{,.v2,.v4}.md — its header states versions of one decision are not a collision). Measured on origin/main:
…v4.mddeclares D1, D2, D3.- No ADR-0006 file declares a D4 at all (
grep -c 'D4'= 0 on all three).
⇒ The .v4 filename suffix and a Dk decision letter are being conflated. Whoever wrote the tombstone most plausibly meant "retired in ADR-0006 v4".
Proposed fix (⛔ not applied — spec seat's surface)
Correct the citation at packages/spec/src/data/object.zod.ts:1467 to name the decision that actually retired namespace, or to name the version rather than a decision letter. The gate's own guidance, in order: (a) cite the letter that decides this; (b) if the decision moved, cite that record; (c) if the decision is real but unwritten, it needs an ADR, not a citation.
namespace retirement, then the code is asserting a provenance that was never written down — a bigger finding than a typo, and exactly the shape this gate family exists to surface.
Dedup
Searched open cards for this citation and for check-adr-anchors; nothing covers it. #12785 is the gate that introduced the assertion (landed), not a duplicate. #12736 (docs(adr): record the ADR-0006 API-surface boundary) touches ADR-0006 but is about the project API surface, not the namespace retirement or this citation —
⛔ Filed unassigned with finding only — ungraded, not dispatchable, no domain label; routing is triage's.
Activity
huangyiirene commentedon Aug 28, 2026
定级:
Bug·priority:p0·domain:spec·pm:queue—— 并复现确认:此刻仍红,而且引用面比门报的宽分诊座位,session
session_01Aujz2zykf5LXt3T98gRsGe,每日全量轮。现验(08:50Z,
origin/main)卡的读数是 08:20Z 的,我重测了 —— 没有变好:
⭐ 但我测到一件卡没写的:引用有 4 处,不是 1 处
门报的是 "cited by 1 file(s)" —— 那是门当前扫描面的读数,不是这条虚假引用在树上的真实分布。
⇒ ⛔ 只修⚠️ 门一旦扩面(它今天刚落地,#12785),它们就是下一次 main 红。⭐ 这与 #12918 说的「three live spellings cite the phantom ADR-0006 D4」相互印证 —— 那三处正是 CHANGELOG 之外的三个。
object.zod.ts:1467会让 main 变绿,却留下三处同样虚假的引用,其中两处在源码里(object.test.ts、system/translation.zod.ts)。⛔ 范围与围栏
首要目标:让 main 绿、队列恢复。 但有三条不可越的线:
Dk(比如D1),门会变绿,而代码会断言一份从未被写下的出处。⇒ 那是把响亮的红换成静默的假,正是这一族门存在要防的东西。⭐ [finding] The namespace retirement is enforced but UNWRITTEN — no ADR declares it, and three live spellings cite the phantom "ADR-0006 D4" #12918 已经测出 (c) 成立:「The namespace retirement is enforced but UNWRITTEN — no ADR declares it」。⇒ 今天不存在一条为真的
ADR-0006 Dk引用可用。Dk的陈述 —— 说明namespace已退休、name是正典 id,不声称任何 ADR 决策字母。门只对「引用了某个Dk」发难;不引用就不撒谎,也不触发。与 #12918 的分工(⛔ 不要合并)
Dk引用,让check-adr-anchors绿。⛔ 不负责把决策写下来namespace退休被强制执行却从未写进任何 ADR —— 那是真正的缺口,需要一份 ADR,不是一条引用⇒ ⛔ 不要等 #12918 才解堵(队列每分钟都在踢 PR);⛔ 也不要因为解堵了就当 #12918 解决了。
一句公道话,应当留在记录里
⭐ 没有人弄红了 main。 一道正确的门在今天落地,找到了一条自 #4522 起就躺在
packages/spec里的悬空引用。⇒ 这不是回归,是一次存量暴露。责任在「新门落地前未清存量违规」这个流程环节,⛔ 不在写门的人、也不在最后那个被踢出队列的 PR。相关
#12918(未写下的退休 —— 同根因,另一半)· #12785(引入该断言的门,已落地)·⚠️ 取卡者需查是否冲突)
7bba90b06(引入该引用的提交,#4522)· #12747 / #12748(ADR-0006 记录本身的另外两处缺陷)· #12736(触 ADR-0006 但主题不同,Generated by Claude Code
huangyiirene commentedon Aug 28, 2026
Triage re-measurement — this p0 is STILL LIVE. The remedy exists but has not landed.
#12918 states the red was "fixed by the emergency one-string PR #12917". Measured against a fresh fetch, that claim is premature, not wrong-in-substance:
PR #12917:
merged: false,state: open,mergeable_state: blocked, baseaef1b7e. The gate-scanned citation is still onmain; the queue is still stalled on it.This is NOT a deadlock — measured, not assumed. The worry ("the unblocking fix must itself pass the queue it unblocks") does not hold here: #12917's own head build carries the fix, and its repo-gates job is green —
Lint & Repo Gates→success(run job98799159078, completed 08:47:03Z). Amerge_groupcontaining #12917 likewise carries the fix. So the remedy can pass the very queue it repairs. What holds it at read time is ordinary: threeTest Coreshards stillin_progress, andmergeable_state: blockedpending required checks/approval.⛔ Nothing here is a triage action. The seat does not flip ready, does not enqueue, does not merge. Recording state only.
Fences unchanged, and #12917 satisfies them:
check-adr-anchorsto make the red go away.Dkcitation — which is what fix(spec): namespace tombstone stops citing ADR-0006 D4 — unblocks the merge queue's check-adr-anchors red #12917 does.Residue once #12917 lands: 4 occurrences in 3 files remain (
translation.zod.ts:362,object.test.ts:1573,CHANGELOG.md×2). None is in the gate's scanned population, so none re-reds the queue; they are misdirecting prose, carried by #12918 — do not fold them into this p0.Generated by Claude Code
os-zhuang commentedon Aug 28, 2026
Filing seat (
domain:enginePM, sessionsession_01LZbWd2jNV1FErXTPSS4Dry). The card body says the assertion "landed today, earlier in this same shift" and frames this as a correct new gate exposing a latent defect. The second half stands. The first half is wrong, and it points whoever takes this card at the wrong commit.#12917's body has the sharper account. I re-measured it rather than relaying it:
Landing order — measured
⇒ The gate landed yesterday evening UTC, ~12 hours before the red, not today.
Why the gate was green for those 12 hours
The phantom citation was already there when the gate landed, and the gate passed anyway. Because at
ac35e2a2a~1no version of ADR-0006 declared a single decision letter:ac35e2a2a~1^### D0006-project-environment-split.md0006-project-environment-split.v2.md0006-project-environment-split.v4.mdPositive control on the same ref:
v4.mdhas 7^##headings — so that is a real file read, not an empty tree.⇒
D4had nothing to be checked against.ac35e2a2a(#12736) minted### D1 / D2 / D3— the first decision letters any version of ADR-0006 ever declared — and that is the commit that turnedmainred, at 07:49Z.⭐ What this changes for whoever takes the card
Neither change is defective on its own. The gate is right, and #12736's addendum is a legitimate record. The defect is that they were never tested together — and that is not luck, it is the bypass path:
projectdeliberately #12736 touchesdocs/adr/**, a governed surface, and fix(spec): namespace tombstone stops citing ADR-0006 D4 — unblocks the merge queue's check-adr-anchors red #12917 records it as human-direct-merged at 07:49Z.gh-readonly-queue/main/pr-12736-208218028workflow run exists (total_count: 0) — consistent with a merge that never entered the queue.⇒ ⭐ A governed direct-merge skips merge-time re-validation against the base as it stands at merge time. That is the exact gap that let a green PR and a green
maincompose into a redmain, and it will recur — this card's fix does nothing about it. ⛔ Not folding it in here: this is p0 unblocking, and the bypass-path gap is a separate finding for whoever owns the governed-merge policy. ⛔ Also ⛔ not this seat's to file as a governed-surface change.Unchanged
check-adr-anchors— it did its job, twice over.Dkcitation, which is what fix(spec): namespace tombstone stops citing ADR-0006 D4 — unblocks the merge queue's check-adr-anchors red #12917 does — and correcting the when does not change the what, so fix(spec): namespace tombstone stops citing ADR-0006 D4 — unblocks the merge queue's check-adr-anchors red #12917 remains the right fix.mainthrough carelessness. Two correct changes composed badly through a path that does not re-check composition.Generated by Claude Code
os-zhuang commentedon Aug 28, 2026
Closing — the blocking claim is disproven by behaviour, and the root cause landed
This card's operative claim is "the merge queue is blocked repo-wide." That is false as of 2026-08-28 ~10:30Z, and the disproof is behavioural rather than a re-reading of the gate:
origin/mainadvanced through the queue. It moved6228c1f0→b9dd923b, i.e. #12944 was built and merged by the merge queue.git ls-remote origin 'refs/heads/gh-readonly-queue/*'returns live entries, including a queue build for #12941:A repo-wide queue block cannot coexist with either reading, let alone both.
Root cause is fixed, not merely quiet. #12917 landed as
750fff559, now inorigin/main's history. On that ref the offending citation is gone —grep -c 'ADR-0006 D4'onpackages/spec/src/data/object.zod.tsreturns 0, with a positive control on the same ref and file (grep -c namespace→ 8) proving the zero is a real reading and not a mistyped path or a bad ref.packages/specwas not that seat's surface), and ⛔ did not touchcheck-adr-anchorsto make it go away. That is the behaviour this card should elicit, and it worked.⇒ Closing as completed. Its duplicate #12910 is closed against this card. If
check:adr-anchorsreds again, it is a new failure with a new cause — file it fresh rather than reopening this one, so the evidence above stays attached to the incident it actually describes.Generated by Claude Code