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
Found while closing #10897 (teaching check-error-code-casing to read the
our-default slot in a code local's initializer). Filed rather than absorbed:
it is the OTHER gate's resolver, it is a behaviour change to a deliberate bound,
and #10897 was explicitly scoped to the recognizer.
The shape
declaredInitializers in scripts/check-dispatcher-error-vocabulary.mjs
anchors its head regex on const alone:
So a code held in a let reduces to nothing. resolveConstant answers null,
the codehelper branch reads that as "unreducible" and takes the documented
runtime-value bound — no site and no unresolved — even when the value is a
plain string literal sitting right there in the source.
That is not the bound #9568 wrote. Its words: "a value a source scan cannot
evaluate is out of reach; a value spelled out in every branch is not, whichever
shape it arrives through." A let initialized to a literal is spelled out. It
is out of reach only because of how the anchor is spelled.
Measured, with a positive control on each side
Driving deriveSites and findViolations on origin/main at 58563be069,
one fixture per row, each a complete export function that stamps err.code = code and throws:
shape
check:dispatcher-error-vocabulary
check:error-code-casing
let code = 'REASSIGN_FALLBACK'; if (x) code = 'REASSIGN_OTHER';
no site, no unresolved
0
let code = 'REASSIGN_FALLBACK'; if (x) code = p?.code || 'reassigned_lower_failed';
no site, no unresolved
0
control: const code = 'local_direct_failed'
1 site (assignconst)
0
control: const code = flag ? 'tern_lower_a' : 'tern_lower_b'
Rows 3 and 4 are the control that makes rows 1 and 2 readable rather than a
broken probe: the identical shape spelled const does reduce, lowercase
included, and does produce sites. Row 5 is the casing-gate control on the other
side. Row 1 is the sharpest one — both of its values are literals, both
unregistered, and no gate says a word.
I did not sweep the tree for live victims — that measurement belongs with
whoever takes this, since the right population depends on which half is being
closed. What is known: 47 code-named local declarations exist under packages/** (measured for #10897's blast radius), and at least one of them is
a let (packages/metadata-protocol/src/protocol.ts:6551, let code: unknown | null =). Whether any holds an unregistered literal is the
open question.
Search note
The issue-search endpoint is unavailable from an agent seat here ("sessions are
bound to their configured repositories"), so the duplicate check behind this
card is a title grep over the 100 most recently created open issues, not a full
search. Worth a second look before anyone starts.
Refs
#10897 / PR #10914 (where this was found) - #9568 (the ALL-OR-NOTHING reduction
and the bound this contradicts) - #9460 (the local-variable bound it refines) -
ADR-0112 D1
Found while closing #10897 (teaching
check-error-code-casingto read theour-default slot in a
codelocal's initializer). Filed rather than absorbed:it is the OTHER gate's resolver, it is a behaviour change to a deliberate bound,
and #10897 was explicitly scoped to the recognizer.
The shape
declaredInitializersinscripts/check-dispatcher-error-vocabulary.mjsanchors its head regex on
constalone:So a code held in a
letreduces to nothing.resolveConstantanswersnull,the
codehelperbranch reads that as "unreducible" and takes the documentedruntime-value bound — no site and no unresolved — even when the value is a
plain string literal sitting right there in the source.
That is not the bound #9568 wrote. Its words: "a value a source scan cannot
evaluate is out of reach; a value spelled out in every branch is not, whichever
shape it arrives through." A
letinitialized to a literal is spelled out. Itis out of reach only because of how the anchor is spelled.
Measured, with a positive control on each side
Driving
deriveSitesandfindViolationsonorigin/mainat58563be069,one fixture per row, each a complete
export functionthat stampserr.code = codeand throws:check:dispatcher-error-vocabularycheck:error-code-casinglet code = 'REASSIGN_FALLBACK'; if (x) code = 'REASSIGN_OTHER';let code = 'REASSIGN_FALLBACK'; if (x) code = p?.code || 'reassigned_lower_failed';const code = 'local_direct_failed'assignconst)const code = flag ? 'tern_lower_a' : 'tern_lower_b'assignconst)const code = p?.code || 'reassigned_lower_failed'local-fallback, after #10897)Rows 3 and 4 are the control that makes rows 1 and 2 readable rather than a
broken probe: the identical shape spelled
constdoes reduce, lowercaseincluded, and does produce sites. Row 5 is the casing-gate control on the other
side. Row 1 is the sharpest one — both of its values are literals, both
unregistered, and no gate says a word.
Two separable halves
let/vardeclarations. The cheap half, and the one that matches[finding]
check:dispatcher-error-vocabularystill cannot see a code held in a local ternary —sys-metadata-repository's live 403NOT_CREATABLE/NOT_OVERRIDABLE#9568's stated intent: widen thedeclaredInitializersanchor. The reason tobe careful rather than quick is that a
letcan be reassigned, so the setof values a
letholds is not simply its initializer — reducing it to theinitializer alone would report a value the program may not stamp, which is
the same wrongness the ALL-OR-NOTHING rule ([finding]
check:dispatcher-error-vocabularystill cannot see a code held in a local ternary —sys-metadata-repository's live 403NOT_CREATABLE/NOT_OVERRIDABLE#9568) exists to refuse. Thehonest widening probably reduces a
letonly when the file contains noreassignment of it, and reports it as unresolved when it does — never
silently, which is the bound this gate holds itself to everywhere else.
Bare reassignment (
code = p?.code || 'lit', no declarator) — row 2.Harder: no declaration to anchor on, and a textual scan has no scopes. Worth
recording, not necessarily worth closing. Note [finding] check-error-code-casing's ||/?? fallback recognizer anchors on the STAMP SITE only, so our authored default in a
const code = …initializer is still seen by no gate #10897's newlocal-fallbackrecognizer deliberately requires a declarator, so the casing gate does not
reach this one either.
Extent today: not swept
I did not sweep the tree for live victims — that measurement belongs with
whoever takes this, since the right population depends on which half is being
closed. What is known: 47
code-named local declarations exist underpackages/**(measured for #10897's blast radius), and at least one of them isa
let(packages/metadata-protocol/src/protocol.ts:6551,let code: unknown | null =). Whether any holds an unregistered literal is theopen question.
Search note
The issue-search endpoint is unavailable from an agent seat here ("sessions are
bound to their configured repositories"), so the duplicate check behind this
card is a title grep over the 100 most recently created open issues, not a full
search. Worth a second look before anyone starts.
Refs
#10897 / PR #10914 (where this was found) - #9568 (the ALL-OR-NOTHING reduction
and the bound this contradicts) - #9460 (the local-variable bound it refines) -
ADR-0112 D1
Generated by Claude Code
Generated by Claude Code