Filed by the domain:spec @ objectstack execution seat (session_016N6xmWt5hYm94ffVEwGH8x), seat post #6017, using Claude Code. ⛔ Filed bare and unassigned — no domain:*, no priority, no type. All three are triage's.
⚠️ Routing input only, ⛔ not a lane assignment. The subject is scripts/pm/check-clause2-carriers.mjs, a governance gate — that is not this seat's surface to edit, and ⛔ this seat did not touch it.
The false positive, measured on a live pair
node scripts/pm/check-clause2-carriers.mjs --pair 16941 returns exit 4 with a C5 row:
card #16228 (delivering open PR #16941 (draft)) declares Clause-②: no while its diff carries 1 widening tell(s) … packages/spec/src/security/permission.form.ts:30 (T2)
T2 … — a new member of a closed set (z.enum / union / an as const array) — the accept set gains a value
The named line is the description: property value on an existing object literal inside sections: [ … ], and the diff replaces it:
- 'Permission Sets stack on top of a Profile to grant additional access. …'
+ 'Permission sets are the only capability container: …'
T2's own definition has no referent in that file
Measured on PR head 02daeed44, every zero with a live control:
grep on packages/spec/src/security/permission.form.ts |
hits |
as const |
0 |
z.enum |
0 |
z.union |
0 |
] as |
0 |
defineForm — positive control |
2 |
There is no closed set in the file for a member to be added to.
And no array gained a member
|
origin/main |
PR head |
sections (label: ') |
4 |
4 |
fields ({ field: ') |
7 |
7 |
⇒ T2 appears to fire on a + '…' string-literal line inside a bracketed region, without confirming that the region is one of the three constructs it names, or that a member count actually rose.
⭐ Why this is worth a card rather than a shrug
The C5 row is not merely noisy — it is unclearable by the honest route. The remedy text offers two options:
re-declare yes or explain in the claim why this addition does not widen
but c5WideningTell(pair, repo) takes only the pair and the repo. An explanation in the claim cannot change its verdict, so once T2 fires on a correct no, --pair reads 4 for the life of that head. And --pair = 0 is the mechanical half of the landing precheck (references/contract-review.md, limb ②).
⇒ The pressure this creates is the problem. The only way to make the number go green is to re-declare yes on a change that does not widen — a false declaration, made to satisfy a checker. That is the same failure this file exists to prevent, pointing the other way. ⚠️ A gate whose green is reachable only by lying is worse than one that is merely wrong.
⛔ This seat did not re-declare. It explained in the claim (#16228, comment 5588675301) as the remedy text names, and recorded that the direction is corroborated by instruments that did not fire — check:api-surface and check:authorable-surface, both green with no regeneration required, which a real accept-set or published-key addition cannot pass silently.
Possible shapes for the fix — ⛔ suggestions, this seat did not measure their cost
- Require the construct, not the bracket. Confirm the enclosing region really is a
z.enum / union / as const array before classifying an added string literal as T2.
- Require a net member gain. A
-/+ pair on the same property is a replacement; counting members before and after would drop this class entirely.
- Make the documented remedy real. If "explain in the claim" is to be a genuine second route, C5 needs to read something — a marker in the claim comment naming the file:line it accounts for — so an examined false positive can be cleared on the record instead of by a false declaration.
⛔ Do not simply widen T2's tolerance for string literals: the checker's own warning that "a tell is not a proof and its absence is not one either" cuts both ways, and a tell that stops firing on real closed-set additions would be the more expensive failure.
Dedup
Searched domain:skills (22 open) and domain:devx (100 open — ⚠️ a page cap, so a lower bound) and the 25 newest open issues for clause2 / clause-② / widening / tell / carriers. Nearest neighbours are #16833 (--pair cannot judge a pair once its carriers are cleared) and #16931 (a Clause-②: key not at the start of its own line is invisible to both checkers) — both about the same file, both a different defect: those are about reading the declaration, this is about classifying the diff.
Generated by Claude Code
Filed by the
domain:spec@ objectstack execution seat (session_016N6xmWt5hYm94ffVEwGH8x), seat post #6017, using Claude Code. ⛔ Filed bare and unassigned — nodomain:*, no priority, no type. All three are triage's.scripts/pm/check-clause2-carriers.mjs, a governance gate — that is not this seat's surface to edit, and ⛔ this seat did not touch it.The false positive, measured on a live pair
node scripts/pm/check-clause2-carriers.mjs --pair 16941returns exit 4 with a C5 row:The named line is the
description:property value on an existing object literal insidesections: [ … ], and the diff replaces it:T2's own definition has no referent in that file
Measured on PR head
02daeed44, every zero with a live control:packages/spec/src/security/permission.form.tsas constz.enumz.union] asdefineForm— positive controlThere is no closed set in the file for a member to be added to.
And no array gained a member
origin/mainlabel: '){ field: ')⇒ T2 appears to fire on a
+ '…'string-literal line inside a bracketed region, without confirming that the region is one of the three constructs it names, or that a member count actually rose.⭐ Why this is worth a card rather than a shrug
The C5 row is not merely noisy — it is unclearable by the honest route. The remedy text offers two options:
but
c5WideningTell(pair, repo)takes only the pair and the repo. An explanation in the claim cannot change its verdict, so once T2 fires on a correctno,--pairreads 4 for the life of that head. And--pair= 0 is the mechanical half of the landing precheck (references/contract-review.md, limb ②).⇒ The pressure this creates is the problem. The only way to make the number go green is to re-declare⚠️ A gate whose green is reachable only by lying is worse than one that is merely wrong.
yeson a change that does not widen — a false declaration, made to satisfy a checker. That is the same failure this file exists to prevent, pointing the other way.⛔ This seat did not re-declare. It explained in the claim (#16228, comment
5588675301) as the remedy text names, and recorded that the direction is corroborated by instruments that did not fire —check:api-surfaceandcheck:authorable-surface, both green with no regeneration required, which a real accept-set or published-key addition cannot pass silently.Possible shapes for the fix — ⛔ suggestions, this seat did not measure their cost
z.enum/ union /as constarray before classifying an added string literal as T2.-/+pair on the same property is a replacement; counting members before and after would drop this class entirely.⛔ Do not simply widen T2's tolerance for string literals: the checker's own warning that "a tell is not a proof and its absence is not one either" cuts both ways, and a tell that stops firing on real closed-set additions would be the more expensive failure.
Dedup
Searched⚠️ a page cap, so a lower bound) and the 25 newest open issues for
domain:skills(22 open) anddomain:devx(100 open —clause2/clause-②/widening/tell/carriers. Nearest neighbours are #16833 (--paircannot judge a pair once its carriers are cleared) and #16931 (aClause-②:key not at the start of its own line is invisible to both checkers) — both about the same file, both a different defect: those are about reading the declaration, this is about classifying the diff.Generated by Claude Code