Skip to content

[finding] A code: fed by a lower-case LOCAL in an object literal is reached by no vocabulary shape — the object-literal twin of the repaired assign-position gap #13478

Description

@claude

Recorded while closing the object-literal stamp position (#13233, PR #13477). Not fixed there, and deliberately: it is a third shape, not a loose end of that one, and no census has been run on it.

The gap

check-dispatcher-error-vocabulary.mjs now reads a code property of an object literal whose value is an identifier — but only when that identifier is a parameter of the enclosing declaration (objlithelper). When it is a lower-case local, no shape in either vocabulary gate reaches it:

const c = intent === 'x' ? 'NOT_CREATABLE' : 'NOT_OVERRIDABLE';
return { code: c, message };            // reached by nothing
  • objlithelper declines it — the identifier is not a parameter, so it is not a code-carrying helper.
  • objlitconst needs a SCREAMING_SNAKE identifier after the colon.
  • objlit needs a quoted literal.
  • objlittemplate needs backticks.
  • check:error-code-casing needs a quoted lowercase literal beside the token code, and there is none at this position.

So there is no site and no unresolved entry — the same "no verdict, no report, and nothing says so" shape that objlithelper was opened to close, one indirection over.

Why this is the same failure class as an already-repaired defect

This is the exact twin of what was repaired for the assignment position: a lower-case local holding a ternary or a ||/?? chain of literals was invisible there too, until the codehelper branch was taught to hand a non-parameter identifier to resolveConstant and emit under assignconst. The live case that motivated that repair — two 403s stamped through one such local in sys-metadata-repository.ts — was in the assign position. Nothing has established whether the object-literal position has a live instance, which is the whole point of filing rather than fixing.

resolveConstant already reduces exactly this expression class, so the machinery exists; what does not exist is a measurement of what admitting it would newly reach.

Declared, not discovered

This is on the record in the code rather than only here — OBJECT_LITERAL_CODE_HELPER_BLINDNESS in scripts/check-dispatcher-error-vocabulary.mjs names it under "what this closure deliberately does NOT do", as UNCLOSED and UNCENSUSED.

What a round on this would owe

The same discipline the position widening was held to: census first, then decide. Every new value admitted becomes a site needing a declaration row in packages/runtime/src/dispatcher-error-vocabulary.ts, and the reconciliation runs both ways, so the rows cannot land before the widening. The figures that matter are the ones that graded the sibling card:

  • helpers/sites newly reached, and how many reduce
  • new verdict rows owed
  • entries that reduce to nothing (each one a red with no verdict available unless it can be classified)
  • unregistered wire codes hiding — the row that decides whether this is a live defect or a preventive one

Sibling remainders in the same family


Generated by Claude Code

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions