Found by measurement while producing the census for #12925. Recorded rather than fixed there: that card is about the kebab-case vocabulary and is fenced to one declaration, and this hole is casing-independent — a different defect class, so not a rider.
The shape
check-dispatcher-error-vocabulary.mjs has a codehelper shape for exactly the case where the literal does not live at the stamp site:
codehelper — the identifier is a PARAMETER of the enclosing function or constructor, which makes that function a code-carrying helper (postureError(code, message), makeError(status, code, message)). The literal then lives at the CALL SITES, at that parameter's index, and nowhere near a code token — so no code-anchored pattern in either this gate or check:error-code-casing can see it.
Its regex is anchored on an assignment: /\.code\s*=\s*([A-Za-z_$][\w$]*)\s*[;,\n)]/g. So the reasoning is implemented for a helper that writes obj.code = code, and not for the equally ordinary helper that builds an object literal — where modern TypeScript spells the same thing as shorthand, { severity, code, message }. No shape in either gate anchors there: objlit needs a quote, objlitconst needs a SCREAMING_SNAKE identifier after a colon, and codehelper needs the .code =.
Measured, with a control
Four one-file corpora through the real deriveSites and the real findViolations, with an unregistered code in each:
| # |
helper body |
code |
vocabulary gate |
casing gate |
| A (control) |
(e as any).code = code |
HELPER_SCREAMING |
1 site, shape codehelper |
0 |
| B |
return { severity: 'error', code, message } |
HELPER_SCREAMING |
0 |
0 |
| C |
return { severity: 'error', code, message } |
helper_lowercase |
0 |
0 |
| D |
return { severity: 'error', code: code, message } |
HELPER_SCREAMING |
0 |
0 |
A is the control that proves the instrument fires: the same helper genre, one line spelled differently, is detected. B, C and D return zero from both gates — including for a SCREAMING_SNAKE code that is in neither the ledger nor StandardErrorCode, which is precisely the value the vocabulary gate exists to report. D shows it is not the shorthand syntax alone: the longhand code: code misses too, because objlitconst requires the identifier to be SCREAMING_SNAKE and the conventional parameter name is code.
Why it matters
This is the #9223 / #9460 / #10918 genre one stamp position later — each of those was the same finding: a shape the gate's own prose claims to cover, implemented for one syntactic position and silently absent in the sibling position, so nothing was reported and nothing said so. The gate's declared bound is that a value it cannot reduce is REPORTED, never dropped; here no pattern fires at all, so there is nothing to report and no unresolved entry either.
A live instance exists today: Parser#error(code, message, start?, tag?) in packages/sdui-parser/src/parse.ts:276 pushes { severity: 'error', code, message, start, tag } and is called from 16 sites, each passing a literal at parameter index 0. Those particular 16 are kebab-case diagnostics and so are out of both gates' population for an independent reason (declared in #12925), which is why this hole has no visible victim in this repo right now — but the blindness is not conditional on their casing, as B and C show.
What a fix would have to decide
Not decided here:
Found by measurement while producing the census for #12925. Recorded rather than fixed there: that card is about the kebab-case vocabulary and is fenced to one declaration, and this hole is casing-independent — a different defect class, so not a rider.
The shape
check-dispatcher-error-vocabulary.mjshas acodehelpershape for exactly the case where the literal does not live at the stamp site:Its regex is anchored on an assignment:
/\.code\s*=\s*([A-Za-z_$][\w$]*)\s*[;,\n)]/g. So the reasoning is implemented for a helper that writesobj.code = code, and not for the equally ordinary helper that builds an object literal — where modern TypeScript spells the same thing as shorthand,{ severity, code, message }. No shape in either gate anchors there:objlitneeds a quote,objlitconstneeds a SCREAMING_SNAKE identifier after a colon, andcodehelperneeds the.code =.Measured, with a control
Four one-file corpora through the real
deriveSitesand the realfindViolations, with an unregistered code in each:(e as any).code = codeHELPER_SCREAMINGcodehelperreturn { severity: 'error', code, message }HELPER_SCREAMINGreturn { severity: 'error', code, message }helper_lowercasereturn { severity: 'error', code: code, message }HELPER_SCREAMINGA is the control that proves the instrument fires: the same helper genre, one line spelled differently, is detected. B, C and D return zero from both gates — including for a SCREAMING_SNAKE code that is in neither the ledger nor
StandardErrorCode, which is precisely the value the vocabulary gate exists to report. D shows it is not the shorthand syntax alone: the longhandcode: codemisses too, becauseobjlitconstrequires the identifier to be SCREAMING_SNAKE and the conventional parameter name iscode.Why it matters
This is the #9223 / #9460 / #10918 genre one stamp position later — each of those was the same finding: a shape the gate's own prose claims to cover, implemented for one syntactic position and silently absent in the sibling position, so nothing was reported and nothing said so. The gate's declared bound is that a value it cannot reduce is REPORTED, never dropped; here no pattern fires at all, so there is nothing to report and no unresolved entry either.
A live instance exists today:
Parser#error(code, message, start?, tag?)inpackages/sdui-parser/src/parse.ts:276pushes{ severity: 'error', code, message, start, tag }and is called from 16 sites, each passing a literal at parameter index 0. Those particular 16 are kebab-case diagnostics and so are out of both gates' population for an independent reason (declared in #12925), which is why this hole has no visible victim in this repo right now — but the blindness is not conditional on their casing, as B and C show.What a fix would have to decide
Not decided here:
codehelpershould recognise the object-literal position (shorthand and longhand) in addition to the assignment, which means anchoring on acodeproperty of an object literal whose value is an identifier that is a parameter of the enclosing function, rather than on.code =;{ code }shorthand is common, and every newly reached call site becomes a site needing a verdict row inpackages/runtime/src/dispatcher-error-vocabulary.ts. That number is unmeasured, and measuring it comes before widening anything — the same discipline [finding] a kebab-case diagnostic code is invisible to both vocabulary gates as a literal, and an undischargeable finding as a constant — the two gates' grammars have no spelling that classifies it #12925 records for the hyphen question.