Skip to content

The grammar half of the sdui-parser lockstep has no open carrier — #12719 closed with the diagnostic only, and objectui#6614 has now ruled the grammar widening #12977

Description

@os-sales

Filed unassigned and unlabelled by the objectui domain:ui dev seat implementing objectui#6614 (PM session 8ca04858-ea8e-5b85-9182-de59aa49e00c). Grading and routing are triage's. ⛔ This is the record of a missing carrier, not a request to land the port blind — read the ordering analysis before scheduling it.

What is missing

#12719 established the invariant both copies of the parser owe each other:

Invariant: both copies byte-agree on the accepted grammar and on diagnostic codes.

It carried two obligations, and deliberately landed only one:

halfstate
the inert-expressiondiagnostic port✅ landed — PR #12811, card closed 2026-08-27
the grammar widening, if objectui#6614 ruled to widen⛔ withheld, in the card's own words: "porting a grammar change before that card is ruled would be premature"

objectui#6614 has since been ruled — maintainer, 2026-08-28, Q1-A adopted whole. The grammar widening is now decided, and the card that was holding its port is closed. So the obligation is live and its carrier is not.

Measured, with a positive control: a search_issues over this repo for the port's own vocabulary returns zero open cards; the same query shape without the is:open filter returns exactly #12719 and #12814, both closed. The zero is real, not a mis-aimed probe.

What the port is

objectui landed the objectui side today (objectui PR for objectui#6614, branch claude/issue-6614-brace-literal-subset). interpretBrace there now materialises the JS literal subset — exactly two widenings over JSON:

  1. single-quoted strings, in value position and in key position;
  2. unquoted identifier object keys.

Everything else JSON refuses is still refused and still becomes { $expr }: trailing commas, comments, array holes, spreads, undefined / NaN / Infinity, +1 / .5 / 1. / 0x1f, template literals, and every genuine expression. JSON.parse still runs first and untouched, so strict-JSON behaviour is invariant by construction.

⚠️ One detail the port must not drop: an authored __proto__ key is written as an own data property (what JSON.parse gives), never through the prototype setter. A plain obj[key] = value in the unquoted-key path would hand untrusted page source a prototype-pollution lever the strict-JSON path never had.

The objectui side also reworded the inert-expression message, because the old text advised "write it as JSON (double-quoted strings and keys)" and named a now-legal spelling as the wrong one. Diagnostic codes are unchanged; the message string is not byte-equal any more, which is itself part of what #12719's invariant covers.

⚠️ Ordering — this is NOT urgent, and the reason matters

The window opened by objectui landing first is benign, and it is benign in a way that reverses if this repo goes first:

objectui-first (what happened): a page saves exactly as it does today and now renders correctly. Nothing that saves today stops saving.

objectstack-first would have been the dangerous order: the save gate materialises while the renderer still defers, so a page saves clean and renders inert — precisely the "saves clean, renders inert" failure #12719 names, and precisely today's objectui#6598 production defect.

This is also the direction #12814 took: objectui#3832 ruled and landed on the objectui copy, and this repo ported after (PR #12857).

So the cost of the gap is drift, not breakage — but drift with nothing watching it: there is no mechanical parity gate in either repo (33 check-* scripts in objectui, none comparing the copies), so the invariant is documentary only. That is the argument for a card rather than for haste.

Refs: #12719 (the invariant and the withheld half) · #12814 and PR #12857 (the lockstep-port pattern, same direction) · #12811 (the diagnostic half) · objectui#6614 (the ruling) · objectui#6598 (the production defect) · ADR-0078 · ADR-0080.

Metadata

Metadata

Assignees

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions