os-decision-facets
⛔ ESCALATED after THREE at-tier FAILs — the remedy is now STRUCTURAL, and that is not a dev's call
Ruling-ref: none — ⛔ no maintainer ruling stands on this thread; this card was filed as a finding and dispatched on its own merits. The lane allows two rework rounds and both are spent, but ⭐ the escalation is on the MERITS, not the count: what F1 now needs is a different design of the matcher, not a patch to the current one.
The arc, because it IS the finding. The decline must know that two lines name the same place. Three answers were tried and the first two were proxies for identity that are not identity:
| round |
「same place」 meant |
how it broke |
| 1 |
the same NAME removed anywhere in the block |
a same-named acceptor removed elsewhere certified a bag at a different path |
| 2 |
the same opener + head TEXT + indent |
two keyless parents spell their opener identically (union arms, tuple members, .or()/.and() args) |
| 3 |
frames carry the line's KIND; samePlace requires CONTEXT on both sides |
⭐ sound within a hunk — proved by construction … but the place is a hunk-local SUFFIX |
What is still open (probe X1, measured through four gates): an earlier hunk of the same file moves the parent boundary. A pre-existing Q = strictObject({ x }) gains filter.newKey; BASE reports it, all three heads are silent. The decline's justification — 「the removed value was the universe of THIS bag」 — is false: the universe was P.filter, not Q.filter. Unbounded: every member of the bag is silenced.
⭐ And round 3 proved why this class can only live across hunks: inside one hunk both compared frame lists are prefixes of the frames the block's preceding CONTEXT lines pushed (a push on an added or removed line is non-context and refuses; only pops happen inside the block) ⇒ no in-hunk keyless-parent shape at any depth can agree. Confirmed at depth 2.
⚠️ The other half of this PR is measured GOOD and is independent of the decline. The unreadable work recovers 21 stacks that a landed regression had made unreadable, regresses 0 of 68, and closes a #18234 decline that round 2 had broken. ⇒ it is a net improvement on its own.
The question: the place reading is hunk-local. Does it become diff-wide, or does the decline go?
|
option |
cost, measured where it is measurable |
| A |
Go diff-wide — read other hunks of the same file for a line that opens or closes a construct at indent ≤ the removed key's |
closes F1's remaining class. ⛔ But it ends the property that made this reading cheap and auditable (the hunk is self-contained), and nobody has measured whether a diff-wide place is decidable at all for a reader whose safety property is that it never guesses |
| B |
Ship the decline hunk-local with the leak disclosed |
⛔ disqualified on ③ — a known unbounded SILENT leak in the very gate that guards a self-declared Clause-②: no. The lane's own doctrine: a gate that refuses too little is the dangerous one |
| C |
Abandon the decline; close #19099 by documenting that this shape requires over-declaration |
the outcome named as legitimate from the start (「a measured cannot be done is a complete delivery」). ⛔ Cost: the card's original defect stands — the criterion-honest no (narrowing) stays the blocked declaration |
| D ⭐ |
Split — land the unreadable half now (it fixes a landed regression), drop the bag decline from this PR, and re-file the diff-wide question as its own card |
a measured improvement converts immediately; the undecided design is decided on its own card with its own evidence. ⛔ Cost: #19099 does not close, and the over-declaration it was filed against persists until that card is ruled |
四棱
① 项目长远合理性 — A 给出完整规则,但它把这个读法从「自足的 hunk」变成「要跨 hunk 拼装事实」,而那正是本卡三轮都在栽的地方:每一轮的失败都是「用一个更宽的代理冒充身份」。⇒ 倾向先不扩大读法的作用域,把它当成独立决定。
② 实际业务拉动 — 今天撞上的人:任何在「袋内收紧」形状上按判据诚实申报 no (narrowing) 的席位 —— 代价已经付掉,不是将来会付。而 unreadable 那一半修的是一条已经落地的回归,影响 21 条栈。⇒ 两半的拉动不同源,这是 D 的主要论据。
③ 防 AI 犯错 — ⛔ B 在这一轴上出局:静默且无界,而这条闸的存在就是为了防止少申报。A/C/D 都不静默;C 让原缺陷继续存在但响亮,D 保留响亮并且先修好回归。
④ 创业阶段不扩散 — D 让已实测为好的一半立刻变现,⛔ 不让它陪一个尚未成形的设计决定一起等。A 则是把一个未测量的设计和一个已测量的修复绑在一张卡上。
Prior rulings read: widening-tells,place,hunk,same-path → 8 hits; ADR-0066 D4, ADR-0067 D4, ADR-0076 D11, ADR-0087 D3, ADR-0094 D1, ADR-0113 D1, ADR-0128 D3; thread: none
⚠️ 那 8 条全是噪声,⛔ 不是先例。 每一条命中的都只有英文单词 place 一个词(授权模型、提交历史、ObjectQL 分层、元数据协议、权限集、写契约、加密上下文),与本卡的 matcher 无关。⛔ 不要把「8 hits」读成「有八条裁决适用」。线程上零条裁决。
推荐:D(拆)。
自检:只看①选 D(⛔ 不在一张已经三轮栽在「更宽的代理」上的卡里,再把读法的作用域扩大一层);②③④ 是否翻转:否 —— ② 加固它(两半拉动不同源)、③ 只淘汰 B、④ 加固它(已实测的一半不该陪跑)。
置信缺口: ⛔ NOT MEASURED —— 跨 hunk 的 place 到底能不能在「不猜」的前提下判定。 复核给了方向(「DIFF 携带着 hunk 没有的证据」)但没有实现也没有验证;裁 A 就是在这个未测量上下注。另外 X1 形状在历史上的频率是 0/250(语料界定的是本修复可能引入的噪声,⛔ 对它漏掉的那个泄漏的频率一无所知)。
⚠️ 还有一条同类残留,与上面独立,但裁 A/D 时要一起考虑:leading-comment 复位读不到散文里带撇号或路径的 JSDoc(value's、can't、action's),实测 7/95 条 T1 行,全部由未闭合的 ' 抬起,0 条由正则。而文件头把「整个残留」描述成一个在语料里出现 0 次的正则形状。⇒ 这是 round-2 那一类「新造的强制过度申报」,频率更低但同类。
Reading taken 2026-09-18T19:14Z on origin/main@362035cc0 and on PR #19095's diff.
⚠️ Read the scope section before treating this as a re-open of ruling A (batch #155 item 3). It is not, and this seat's first instinct — that it was — was wrong and is recorded below.
The defect, reproduced
scripts/pm/check-widening-tells.mjs raises a T1 tell — 「a new key on a Zod object schema」 — on a diff whose only change at those lines is that a member was BOUNDED inside a bag that was previously z.unknown().
Reproduced on PR #19095's diff:
node scripts/pm/check-widening-tells.mjs --declaration no --diff <that diff> → exit 4
T1 packages/spec/src/ui/component.zod.ts:2689 (pageSizeOptions)
T1 packages/spec/src/ui/component.zod.ts:2692 (pageSize)
Textually the tell is right: those key names are new text on an object schema. Semantically it is inverted: both members were already writable through z.unknown(), which accepted everything, and what the diff does is narrow them to z.number().int().positive(). The matcher reads the added key text and not the member's prior schema, so it cannot tell a narrowing inside a bag from a widening.
Why this is load-bearing rather than noisy
This gate is the compensating control for a self-declared Clause-②: no — it is what stops a seat from declaring no on a diff that really widens. So a false positive here has a specific consequence:
⇒ the criterion-honest declaration is the blocked one. An at-tier reviewer established on PR #19095, from SKILL.md:477 / :515 and references/lanes/spec.md:19-20, that the criterion gives no for this diff (measured: 0 newly accepted inputs of 53, no new export). Declaring that honest no exits 4. Declaring yes instead passes the gate by construction — 「a yes already routes to contract review, so a tell on top of it decides nothing」 — and costs an at-tier review each time.
⇒ on this board, over-declaration is currently the only unblocked path for a narrowing inside an unknown bag.
The honest no (narrowing) is established practice, not a theory
Measured on origin/main, ⛔ without truncation:
| reading |
value |
changesets carrying the exact line Clause-②: no (narrowing) |
6 |
changesets carrying Clause-②: yes |
34 |
control: changesets carrying any Clause-② line at all |
77 |
The six are 17499-groupbyfield-non-padded, 18124-genuine-duration-rows-declare-their-unit, 18306-role-word-field-groups, 18835-list-view-unwalked-field-naming-keys, 18972-field-scale-renderer-ceiling and one more. ⇒ two in-use conventions are in conflict: the house writes no (narrowing) on narrowings, and this gate blocks the subset of them that bound a member inside an open bag.
⚠️ Scope — what ruling A did and did not settle, and this seat's own error
Ruling A (batch #155 item 3, maintainer 「同意」 2026-09-18T05:13Z, on card #18640) ruled that #17618's fact 3 — the subset test — stays, for the shape it was measured on: a union member RENAMED to a narrower schema on a key line. Its words for that shape: 「a member replaced on a key line is a change to a published contract, and the honest declaration for it is Clause-②: yes」, and it refused a licence card (「⛔ no C licence card」).
⇒ that ruling is about fact 3 and a rename on a key line. This card is about a different diff shape — bounding a member inside a previously-z.unknown() bag — and about the matcher's inability to read the prior schema, which no per-line corrector was asked to do there. And references/lanes/spec.md:20 says in as many words that 一个个案裁决不改判据那条线(a per-case ruling does not move the criterion), so ruling A cannot be read as redefining clause ② for shapes it did not measure.
⭐ This seat first declined to file this card, citing ruling A as having settled the class. That was over-generalising a ruling from its own subject to a different shape — the at-tier reviewer on PR #19095 caught it and named spec.md:20 as the line that forbids exactly that move. Recorded here because a card whose filing history contains a wrong refusal should say so, and because the next reader needs the boundary in both directions: ⛔ do not re-open fact 3, and ⛔ do not treat fact 3's ruling as covering this.
⛔ The direction any repair must respect
Taken from #18640's own body, which is good doctrine and this seat endorses it: a gate that refuses too much is noisy but safe; a gate that refuses too little is the dangerous one. ⇒ ⛔ a repair must not buy quiet by loosening the matcher generally. The narrow question is whether a tell can consult the member's prior schema at that key — and if it cannot be done per line without subtyping (which #18640 established a per-line corrector cannot verify), then the honest outcome may be that this shape is documented as requiring the over-declaration, rather than repaired. ⭐ That is a legitimate answer and would close this card; what is not legitimate is the current state, where the criterion says one thing, six changesets say it too, and the gate refuses it without saying why.
Adjacent — read, and each a different tell or direction
Evidence limit
The reproduction is on one diff, and the six-changeset census counts a spelling, ⛔ not a verified set of narrowings — some of those six may not be bag-internal bounds and so may never have met this tell. What is NOT established: how many of the 34 yes declarations were over-declarations forced by this tell rather than chosen; that would need the diffs read one by one, and it is the measurement that would size this card.
Dedup words
widening-tells T1 narrowing inside z.unknown bag, check-widening-tells false tell narrowing, clause-2 no narrowing blocked exit 4, matcher reads added key not prior schema, honest declaration is the blocked one
Provenance
Out-of-scope finding from the os-dev report on #19046 (PR #19095); the reproduction is the dev's, the changeset census and the ruling-scope reading are this seat's, and the correction of this seat's refusal to file is the at-tier reviewer's. Filed bare — grading, type and routing are the triage seat's production.
Generated by Claude Code
os-decision-facets
The question: the place reading is hunk-local. Does it become diff-wide, or does the decline go?
Clause-②: no. The lane's own doctrine: a gate that refuses too little is the dangerous oneno (narrowing)stays the blocked declarationunreadablehalf now (it fixes a landed regression), drop the bag decline from this PR, and re-file the diff-wide question as its own card四棱
① 项目长远合理性 — A 给出完整规则,但它把这个读法从「自足的 hunk」变成「要跨 hunk 拼装事实」,而那正是本卡三轮都在栽的地方:每一轮的失败都是「用一个更宽的代理冒充身份」。⇒ 倾向先不扩大读法的作用域,把它当成独立决定。
② 实际业务拉动 — 今天撞上的人:任何在「袋内收紧」形状上按判据诚实申报
no (narrowing)的席位 —— 代价已经付掉,不是将来会付。而unreadable那一半修的是一条已经落地的回归,影响 21 条栈。⇒ 两半的拉动不同源,这是 D 的主要论据。③ 防 AI 犯错 — ⛔ B 在这一轴上出局:静默且无界,而这条闸的存在就是为了防止少申报。A/C/D 都不静默;C 让原缺陷继续存在但响亮,D 保留响亮并且先修好回归。
④ 创业阶段不扩散 — D 让已实测为好的一半立刻变现,⛔ 不让它陪一个尚未成形的设计决定一起等。A 则是把一个未测量的设计和一个已测量的修复绑在一张卡上。
Prior rulings read: widening-tells,place,hunk,same-path → 8 hits; ADR-0066 D4, ADR-0067 D4, ADR-0076 D11, ADR-0087 D3, ADR-0094 D1, ADR-0113 D1, ADR-0128 D3; thread: noneplace一个词(授权模型、提交历史、ObjectQL 分层、元数据协议、权限集、写契约、加密上下文),与本卡的 matcher 无关。⛔ 不要把「8 hits」读成「有八条裁决适用」。线程上零条裁决。推荐:D(拆)。
自检:只看①选 D(⛔ 不在一张已经三轮栽在「更宽的代理」上的卡里,再把读法的作用域扩大一层);②③④ 是否翻转:否 —— ② 加固它(两半拉动不同源)、③ 只淘汰 B、④ 加固它(已实测的一半不该陪跑)。
置信缺口: ⛔ NOT MEASURED —— 跨 hunk 的 place 到底能不能在「不猜」的前提下判定。 复核给了方向(「DIFF 携带着 hunk 没有的证据」)但没有实现也没有验证;裁 A 就是在这个未测量上下注。另外 X1 形状在历史上的频率是 0/250(语料界定的是本修复可能引入的噪声,⛔ 对它漏掉的那个泄漏的频率一无所知)。
value's、can't、action's),实测 7/95 条 T1 行,全部由未闭合的'抬起,0 条由正则。而文件头把「整个残留」描述成一个在语料里出现 0 次的正则形状。⇒ 这是 round-2 那一类「新造的强制过度申报」,频率更低但同类。Reading taken 2026-09-18T19:14Z on
origin/main@362035cc0and on PR #19095's diff.The defect, reproduced
scripts/pm/check-widening-tells.mjsraises a T1 tell — 「a new key on a Zod object schema」 — on a diff whose only change at those lines is that a member was BOUNDED inside a bag that was previouslyz.unknown().Reproduced on PR #19095's diff:
Textually the tell is right: those key names are new text on an object schema. Semantically it is inverted: both members were already writable through
z.unknown(), which accepted everything, and what the diff does is narrow them toz.number().int().positive(). The matcher reads the added key text and not the member's prior schema, so it cannot tell a narrowing inside a bag from a widening.Why this is load-bearing rather than noisy
This gate is the compensating control for a self-declared
Clause-②: no— it is what stops a seat from declaringnoon a diff that really widens. So a false positive here has a specific consequence:⇒ the criterion-honest declaration is the blocked one. An at-tier reviewer established on PR #19095, from
SKILL.md:477/:515andreferences/lanes/spec.md:19-20, that the criterion givesnofor this diff (measured: 0 newly accepted inputs of 53, no new export). Declaring that honestnoexits 4. Declaringyesinstead passes the gate by construction — 「ayesalready routes to contract review, so a tell on top of it decides nothing」 — and costs an at-tier review each time.⇒ on this board, over-declaration is currently the only unblocked path for a narrowing inside an
unknownbag.The honest
no (narrowing)is established practice, not a theoryMeasured on
origin/main, ⛔ without truncation:Clause-②: no (narrowing)Clause-②: yesClause-②line at allThe six are
17499-groupbyfield-non-padded,18124-genuine-duration-rows-declare-their-unit,18306-role-word-field-groups,18835-list-view-unwalked-field-naming-keys,18972-field-scale-renderer-ceilingand one more. ⇒ two in-use conventions are in conflict: the house writesno (narrowing)on narrowings, and this gate blocks the subset of them that bound a member inside an open bag.Ruling A (batch #155 item 3, maintainer 「同意」 2026-09-18T05:13Z, on card #18640) ruled that
#17618's fact 3 — the subset test — stays, for the shape it was measured on: a union member RENAMED to a narrower schema on a key line. Its words for that shape: 「a member replaced on a key line is a change to a published contract, and the honest declaration for it isClause-②: yes」, and it refused a licence card (「⛔ no C licence card」).⇒ that ruling is about fact 3 and a rename on a key line. This card is about a different diff shape — bounding a member inside a previously-
z.unknown()bag — and about the matcher's inability to read the prior schema, which no per-line corrector was asked to do there. Andreferences/lanes/spec.md:20says in as many words that 一个个案裁决不改判据那条线(a per-case ruling does not move the criterion), so ruling A cannot be read as redefining clause ② for shapes it did not measure.⭐ This seat first declined to file this card, citing ruling A as having settled the class. That was over-generalising a ruling from its own subject to a different shape — the at-tier reviewer on PR #19095 caught it and named
spec.md:20as the line that forbids exactly that move. Recorded here because a card whose filing history contains a wrong refusal should say so, and because the next reader needs the boundary in both directions: ⛔ do not re-open fact 3, and ⛔ do not treat fact 3's ruling as covering this.⛔ The direction any repair must respect
Taken from #18640's own body, which is good doctrine and this seat endorses it: a gate that refuses too much is noisy but safe; a gate that refuses too little is the dangerous one. ⇒ ⛔ a repair must not buy quiet by loosening the matcher generally. The narrow question is whether a tell can consult the member's prior schema at that key — and if it cannot be done per line without subtyping (which #18640 established a per-line corrector cannot verify), then the honest outcome may be that this shape is documented as requiring the over-declaration, rather than repaired. ⭐ That is a legitimate answer and would close this card; what is not legitimate is the current state, where the criterion says one thing, six changesets say it too, and the gate refuses it without saying why.
Adjacent — read, and each a different tell or direction
check-widening-tells.mjsreports T1 and T2 on lines added only because a zod options object was appended to an existing union — the clause-② enqueue gate refuses a diff that adds no key and no arm #18640 (closednot_planned, ruled A) — T1+T2 on an options-object append, and fact 3. The nearest neighbour; see the scope section.completed) — the same consequence one tell over: a T2/C5 row 「cannot be cleared except by declaring Clause-② yes on a change that does not widen」.check-widening-tells' T2BARE_STRING_ELEMENTfires on the FIRST fragment of a multi-line string ARGUMENT — one false C5 blocked a landing whose diff only narrows #16822 (closedcompleted) — a T2 false positive that 「blocked a landing whose diff only narrows」.completed) — the blind spot in the opposite direction: a widening that passes anoin silence. ⇒ both error directions of this matcher are on record.Evidence limit
The reproduction is on one diff, and the six-changeset census counts a spelling, ⛔ not a verified set of narrowings — some of those six may not be bag-internal bounds and so may never have met this tell. What is NOT established: how many of the 34
yesdeclarations were over-declarations forced by this tell rather than chosen; that would need the diffs read one by one, and it is the measurement that would size this card.Dedup words
widening-tells T1 narrowing inside z.unknown bag,check-widening-tells false tell narrowing,clause-2 no narrowing blocked exit 4,matcher reads added key not prior schema,honest declaration is the blocked oneProvenance
Out-of-scope finding from the
os-devreport on #19046 (PR #19095); the reproduction is the dev's, the changeset census and the ruling-scope reading are this seat's, and the correction of this seat's refusal to file is the at-tier reviewer's. Filed bare — grading,typeand routing are the triage seat's production.Generated by Claude Code