You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
[finding] Once system-context.mdx carries no line numbers, the os-regen mixed: 'line-anchors' comparator is the IDENTITY — the routing's stated safety argument, and three prose blocks, go stale together #16612
Filed unassigned by the execution seat working #15921. Ungraded and unrouted — domain:*, priority and type are triage's.
Blocked-by: #15921 — nothing here is true on origin/main today. It becomes true the moment #15921's branch lands, so the card exists before the landing rather than after it.
The mechanism
content/docs/permissions/system-context.mdx is routed merge=os-regen in .gitattributes, and it is the ONE row carrying a mixed field (scripts/regen-artifacts.mjs, mixed: 'line-anchors'). The comparator that field names is blankAnchorLineNumbers in scripts/doc-line-anchors.mjs, wired through MIXED_COMPARATORS in scripts/git-merge-regen.mjs. Its job (#14064) is to decide whether two revisions differ ONLY in the half a generator re-derives — if so the driver may defer, and if not it must not, because dropping a side would delete hand-written prose.
That comparator blanks file:line anchors. #15921 removes every one of them.
Measured in the #15921 worktree, on the same two revisions of the page:
base f2f6684cd5 | line anchors: 141 | blankAnchorLineNumbers is the identity: false
issue-15921 head | line anchors: 0 | blankAnchorLineNumbers is the identity: true
An identity comparator makes "equal modulo the generated half" mean "byte-identical". So after #15921 lands, this row defers essentially never and falls back to a text merge or a loud conflict.
Why this is a finding and not a bug
The behaviour change is in the SAFE direction and is not a regression to repair by reverting anything: silent prose deletion (the whole of #14064) becomes unreachable, because the driver can no longer conclude "lossless" on a page whose two revisions differ at all. What is lost is the #13646 convenience — 24 of the last 25 main commits to this page were pure anchor renumberings the driver absorbed for free, and none of those commits can exist any more either, because there are no numbers left to renumber.
What is left behind is stale text and an inert declaration, and both are the kind that read as current forever:
scripts/regen-artifacts.mjs — the row's comment block argues at length from "the merged tree's correct anchors are on NEITHER side (measured on fix(rest): require the resolved environment to belong to the caller at GET /ui/view/:object/:type #13625 — five conflicted anchors resolve to 4408/5771/6019/6382/6575 …)". That measurement is about line numbers this page no longer has. The mixed: 'line-anchors' value itself is now a comparator that can never say yes.
.gitattributes — the paragraph above the row calls the page "a generated file:line anchor table" and says the census gate "catches the stale anchors a merge leaves behind". There are no stale anchors of that kind to catch.
Not for this seat. Stated as options rather than a recommendation, because the routing is the merge driver's territory and #15921 was explicitly fenced out of it:
Keep the routing, retire mixed. The row stays routed and simply stops claiming a lossless-deferral case, which is what the identity comparator already does in practice. Cheapest, and NOT_DRIVER_MANAGED's reasoning may then apply instead.
Leave it exactly as it is and only fix the three prose blocks. Defensible — the identity comparator is not wrong, only vacuous — but it leaves a mixed field whose stated purpose no reader can verify.
pnpm check:merge-driver reconciles .gitattributes against regen-artifacts.mjs in both directions and is green on the #15921 branch, so nothing mechanical will raise this.
Re-check
git show origin/main:scripts/regen-artifacts.mjs | grep -n "line-anchors"
git show origin/main:scripts/git-merge-regen.mjs | grep -n "MIXED_COMPARATORS"
node -e "import('./scripts/doc-line-anchors.mjs').then(m=>{const t=require('fs').readFileSync('content/docs/permissions/system-context.mdx','utf8');console.log(m.extractLineAnchors(t).length, m.blankAnchorLineNumbers(t)===t)})"
No claim that the fallback to a text merge is harmful. It is measured to be the safer half of the trade; only the convenience is lost.
No design proposed. The three options above are the shape of the choice, not a recommendation.
Related: #14064 (the ruling that created the mixed field) · #13646 (the routing) · #13625 (the five-anchor measurement it argues from) · #15921 (the migration that makes the comparator vacuous).
维护者速读
system-context.mdx这一页被配置成「合并时交给我们自己的重算程序处理」。那套配置里有一个字段,声明「这两个版本只差在自动生成的那半,所以可以安全地丢掉一边」——它靠页面里的行号来判断。而 #15921 已经把这一页的行号全部删掉了,所以那个判断现在等于「两个版本必须一模一样」,也就是它永远不会说可以丢。这本来是往安全方向走的:再也不会有人的手写段落被静默丢掉。问题在分诊当时选的处置(把那个字段删掉)被开发席实测证明会把静默丢弃重新打开——因为那个字段不只是个比较器的答案,它还决定走哪一条驱动代码分支。那条实测之后,上一任 PM 席已经拒绝落地该选项并把卡退回分诊重判,而分诊至今没有再判,卡就这样在「可派」状态里躺了 5 天。
现在要的是一个字:保持字段不动、只把三段过期说明改成今天的事实(A);设计并落地一个新的比较器(B);还是把这一页从驱动里摘出去(C)?
① 项目长远合理性:A 缩小特例(删掉三段已经为假的散文,不新增任何机制);B 扩大(一个新比较器就是一份永久义务);C 缩小机制但把冲突解决成本转给人。
② 实际业务拉动:今天撞上的是任何编辑这一页的人 —— 现状是「每次真实编辑都落到文本合并或响亮冲突」,⛔ 没有人被静默伤害,所以拉动是把三段假话改真,不是恢复便利。
③ 防 AI 犯错:A 是响亮拒绝(冲突)优于静默容忍,且闭合;B 引入一个新的自由结构判断,恰是本卡缺陷的来源形状;C 响亮但把判断交给人。
④ 创业阶段不扩散:A remove(散文)优于 declare-and-maintain;B 是新增一个已声明键,永久义务;分诊原选的「删字段」在这一棱上最省,但③上被实测否决。
Prior rulings read: mixed,line-anchors,system-context,carries,line,numbers,os-regen,comparator,identity,routing,stated,safety (+6 more) → 100 hits; ADR-0076 D11, ADR-0110 D1, ADR-0131 D5, ADR-0006 D3, ADR-0056 D10, ADR-0058 D7, ADR-0076 D10, ADR-0087 D3, ADR-0087 D7; thread: 5
check-prior-rulings.mjs的告警是术语重叠触发的(它匹配上的是carries/line/numbers/routing这类通用词),⛔ 不是命中本卡的问题。判据:docs/adr共 139 个文件,os-regen/REGEN_ARTIFACTS/ merge-driver 意义上的mixed三者各 0 命中,而同一次 grep 的必中对照(ADR)命中 139 / 139 ⇒ 这三个 0 是真空,不是坏 grep(2026-09-19T04:21:20Z 现读)。⇒ 本卡不是被既有 ADR 裁决答过的执行卡。推荐:A(保持
mixed: 'line-anchors'不动,只改三段说明)。自检「只看①选 A;②③④ 是否翻转:②不翻转(没有人今天被静默伤害,拉动就是改真话)、③不翻转(A 是这三个里唯一既响亮又不引入新自由结构的)、④不翻转(A 净删散文)」。置信缺口:本席没有独立复现开发席那条「选项 1 会重新打开静默丢弃」的实测(证据在
5620351387,exit 0 且无冲突标记);若该实测不成立,分诊原选的删字段会重回桌面,而 A 的③理由随之变弱。⛔ 本席不代裁:落点是合并驱动的路由,而 #15921 被明确围栏排除在它之外。Governing text:scripts/regen-artifacts.mjs该行的注释块(声明mixed: 'line-anchors'的用途与其实测依据)·.gitattributes中该页merge=os-regen的路由段与其上方段落 ·scripts/doc-line-anchors.mjs模块头(自述为 docs 散文里行锚点的唯一读者)· #14064(该mixed字段存在的原因:防静默丢弃手写散文)Filed unassigned by the execution seat working #15921. Ungraded and unrouted —
domain:*, priority and type are triage's.Blocked-by: #15921— nothing here is true onorigin/maintoday. It becomes true the moment #15921's branch lands, so the card exists before the landing rather than after it.The mechanism
content/docs/permissions/system-context.mdxis routedmerge=os-regenin.gitattributes, and it is the ONE row carrying amixedfield (scripts/regen-artifacts.mjs,mixed: 'line-anchors'). The comparator that field names isblankAnchorLineNumbersinscripts/doc-line-anchors.mjs, wired throughMIXED_COMPARATORSinscripts/git-merge-regen.mjs. Its job (#14064) is to decide whether two revisions differ ONLY in the half a generator re-derives — if so the driver may defer, and if not it must not, because dropping a side would delete hand-written prose.That comparator blanks
file:lineanchors. #15921 removes every one of them.Measured in the #15921 worktree, on the same two revisions of the page:
An identity comparator makes "equal modulo the generated half" mean "byte-identical". So after #15921 lands, this row defers essentially never and falls back to a text merge or a loud conflict.
Why this is a finding and not a bug
The behaviour change is in the SAFE direction and is not a regression to repair by reverting anything: silent prose deletion (the whole of #14064) becomes unreachable, because the driver can no longer conclude "lossless" on a page whose two revisions differ at all. What is lost is the #13646 convenience — 24 of the last 25
maincommits to this page were pure anchor renumberings the driver absorbed for free, and none of those commits can exist any more either, because there are no numbers left to renumber.What is left behind is stale text and an inert declaration, and both are the kind that read as current forever:
scripts/regen-artifacts.mjs— the row's comment block argues at length from "the merged tree's correct anchors are on NEITHER side (measured on fix(rest): require the resolved environment to belong to the caller at GET /ui/view/:object/:type #13625 — five conflicted anchors resolve to 4408/5771/6019/6382/6575 …)". That measurement is about line numbers this page no longer has. Themixed: 'line-anchors'value itself is now a comparator that can never say yes..gitattributes— the paragraph above the row calls the page "a generatedfile:lineanchor table" and says the census gate "catches the stale anchors a merge leaves behind". There are no stale anchors of that kind to catch.scripts/doc-line-anchors.mjs— its module header opens on this page ("Measured oncontent/docs/permissions/system-context.mdxover 19 days, 101 of its 111 anchors rotted") and describes itself as the one reader of line anchors in docs prose. After [finding]system-context.mdxre-conflicts faster than one verification lap — the resolve→land window is measurably smaller than the gate union it requires #15921 the module has exactly one consumer left,scripts/git-merge-regen.mjs, and the page it was built for is not in its population any more.What the decision actually is
Not for this seat. Stated as options rather than a recommendation, because the routing is the merge driver's territory and #15921 was explicitly fenced out of it:
mixed. The row stays routed and simply stops claiming a lossless-deferral case, which is what the identity comparator already does in practice. Cheapest, andNOT_DRIVER_MANAGED's reasoning may then apply instead.NOT_DRIVER_MANAGED. [finding] #13646's fix routed a MIXED file tomerge=os-regen— the driver keeps one side whole and drops the other's hand-written prose, and the census gate cannot see the loss #14064 declined this because a page that conflicts hourly would land on a human who could not resolve the anchors correctly. That objection is now weaker: symbol anchors ARE hand-resolvable, since neither side's value depends on a position.mixedfield whose stated purpose no reader can verify.pnpm check:merge-driverreconciles.gitattributesagainstregen-artifacts.mjsin both directions and is green on the #15921 branch, so nothing mechanical will raise this.Re-check
What is deliberately NOT claimed
system-context.mdxre-conflicts faster than one verification lap — the resolve→land window is measurably smaller than the gate union it requires #15921 should have changed any of this. The dispatch fenced the merge driver off by name, and this seat kept that fence.Related: #14064 (the ruling that created the
mixedfield) · #13646 (the routing) · #13625 (the five-anchor measurement it argues from) · #15921 (the migration that makes the comparator vacuous).Generated by Claude Code