Skip to content

[spec] Fold the three hand-written unrecognized_keys error maps into strictObject guidance — requires a set-keyed guidance form, and closes the alias-integrity gate's blind spot (#6416 direction 2) #6619

Description

@os-project-manager

Follow-up card for #6416's direction 2, deliberately split out of that card by triage (2026-08-07T17:54:18Z: "Direction 2 is a bigger card, not this one … a shared-mechanism change and deserves its own card rather than arriving as scope creep on the reorder"). Direction 1 (the in-place reorders) landed as PR #6453 (bf0ae9976).

What this card does

Migrate the three hand-written $ZodErrorMaps to the shared strictObject / strictUnknownKeyError machinery, deleting the hand-maintained template copies:

  • packages/spec/src/shared/visibility.tsstrictVisibilityError (the visibleWhen alias pointer)
  • packages/spec/src/ui/dashboard.zod.tsstrictWidgetAnalyticsError (three prescription branches)
  • packages/spec/src/data/object.zod.tsstrictTenancyError (per-key tombstone bullets)

The real decision inside it (why it is not mechanical)

dashboard.zod.ts's branches are keyed by set membership (LEGACY_WIDGET_ANALYTICS_KEYS, QUARANTINED_WIDGET_KEYS), which the guidance channel cannot express today — it prescribes per exact key. So the migration needs guidance to grow a set-keyed form (one prescription shared by a named key set). That is a shared-mechanism change on the text face: it changes what the shared template can SAY, not what any schema accepts (acceptance surface untouched ⇒ presumptively domain:spec-surface, per the #6416 triage's own reading — triage confirms).

Why it is worth doing (the gate blind spot)

alias-integrity.test.ts judges the two registries (strictObjectDeclarations() and directAliasTables()). A hand-rolled map registers in neither, so its aliases and prescriptions are unmeasured rather than clean — the exact blind spot #6416 named. Folding the three maps in pulls their alias pointers and prescriptions under the integrity gate.

#5593 has now landed (PR #6595, e0f300ba5) and it sharpens this card rather than absorbing it. That migration moved the 44 direct call sites to strictObject and dropped the ratchet to 0; measured on the merged ref, all three hand-written $ZodErrorMaps survive it untouched (strictVisibilityError at visibility.ts:113, strictWidgetAnalyticsError in dashboard.zod.ts, strictTenancyError at object.zod.ts:442) — exactly as this card predicted, because they are { error } maps rather than direct call sites. So they are now the only alias/guidance tables in the package that no registry sees, and the blind spot argument is stronger than when this card was filed. Re-price against the landed shape at dispatch: alias-table-registry.ts and the gate's "direct call site" section were deleted with the last call site, so the fold now targets strictObject directly with no interim registry to satisfy.

Inherited guardrails (do not re-derive)

Provenance

Metadata

Metadata

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions