Filed unlabelled by the domain:ui @ objectui execution seat, session 8ca04858-ea8e-5b85-9182-de59aa49e00c, as the cross-lane half of #6527. ⛔ domain:*, type and grading are triage's to produce — the routing below is a suggestion with its reasoning, not a label.
Suggested routing: domain:devx. The work lands in scripts/check-designer-field-key-parity.mjs, and gate-class scripts/ is devx's surface — the same routing #6606 got for the same script. The domain:ui seat is fenced out of it, which is why this is a separate card rather than a rider on #6527.
Blocked-by: #6527
Why this exists
The maintainer ruled option B on #6527 (2026-08-28): the three drifted retired-field-key lists on the designer seam converge into one tombstone registry, reached through a dedicated internal subpath of @object-ui/types. That registry is landing in PR #6627.
⭐ But a registry with no gate pinning it is a convention, and conventions drift. That is not a hypothetical here — it is the literal history this card's parent documents. From check-designer-field-key-parity.mjs's own header:
two independently maintained RETIRED_FIELD_KEYS = [indexed] sets … Every one of them was written AFTER an instance was found in production.
Three lists existed because nothing mechanically required them to agree. #6527 makes them agree today. This card is what keeps them agreeing.
What is being asked
Make the registry the gate's single source: check-designer-field-key-parity.mjs should derive what it checks from the tombstone registry rather than carrying its own copy of the key set, so that adding or retiring a key in one place cannot leave the gate asserting the old shape.
⚠️The per-site asymmetry is the load-bearing part and must survive. The registry is deliberately not a flat list — it encodes per-site applicability, because the lists were never nested:
⇒ A gate that flattens the registry into one key set would assert something the registry deliberately does not say. ⛔ Whatever shape this takes, it must be able to express "retired at these sites, not at those."
Prior art to read before starting
PR #6627 already pins the asymmetry at three layers on the product side, including a test that goes red if formula is ever added to the read door's applicable set. ⭐ That pin is #6526's ruling made mechanical — this card is the same idea one level out, at the gate.
Provenance
Filed unlabelled by the
domain:ui@ objectui execution seat, session8ca04858-ea8e-5b85-9182-de59aa49e00c, as the cross-lane half of #6527. ⛔domain:*,typeand grading are triage's to produce — the routing below is a suggestion with its reasoning, not a label.Suggested routing:
domain:devx. The work lands inscripts/check-designer-field-key-parity.mjs, and gate-classscripts/is devx's surface — the same routing #6606 got for the same script. Thedomain:uiseat is fenced out of it, which is why this is a separate card rather than a rider on #6527.Blocked-by: #6527
Why this exists
The maintainer ruled option B on #6527 (2026-08-28): the three drifted retired-field-key lists on the designer seam converge into one tombstone registry, reached through a dedicated internal subpath of
@object-ui/types. That registry is landing in PR #6627.⭐ But a registry with no gate pinning it is a convention, and conventions drift. That is not a hypothetical here — it is the literal history this card's parent documents. From
check-designer-field-key-parity.mjs's own header:Three lists existed because nothing mechanically required them to agree. #6527 makes them agree today. This card is what keeps them agreeing.
What is being asked
Make the registry the gate's single source:
check-designer-field-key-parity.mjsshould derive what it checks from the tombstone registry rather than carrying its own copy of the key set, so that adding or retiring a key in one place cannot leave the gate asserting the old shape.formulais stripped by the two WRITE-side lists and ⛔ must NOT be stripped by the READ door — ruled on app-shell: a draft carrying the retiredformulakey still round-trips to a hard 422, and the two ways out trade against each other #6526 (option B, closed via PR fix(app-shell): name the field and the Formula (CEL) editor in the retiredformula422 diagnostic #6624).ObjectFieldInspectorseeds its CEL editor fromdef.expression ?? def.formulaand the first edit migrates it; stripping it at the read door destroys authored expression text.sortOrderis present only atMetadataService, recorded as explicitly defensive rather than measured — objectui#6045 measured that no writer on this tree ever populated a field-level one.⇒ A gate that flattens the registry into one key set would assert something the registry deliberately does not say. ⛔ Whatever shape this takes, it must be able to express "retired at these sites, not at those."
Prior art to read before starting
PR #6627 already pins the asymmetry at three layers on the product side, including a test that goes red if
formulais ever added to the read door's applicable set. ⭐ That pin is #6526's ruling made mechanical — this card is the same idea one level out, at the gate.Provenance
domain:uiseat under the linkage-chore rule — which is this card.