Skip to content

finding(gates): the permission authoring shapes are not in PAYLOAD_SHAPES, so the retired-key class the gate exists to catch is invisible on the permission surface #6606

Description

@os-sales

Found while removing the retired allowRestore / allowPurge columns in objectui#6595. Recording only, deliberately unassigned — a coverage observation about the gate, not a defect on today's tree.

The observation

scripts/check-designer-field-key-parity.mjs exists for exactly one failure class, in its own words: "a designer offers a control that writes a key the spec refuses BY NAME." It reads each statically declared payload shape in PAYLOAD_SHAPES and compares its key set against the strict zod schema that judges it.

PAYLOAD_SHAPES currently names six shapes, and all six are the object/field designer path:

shapeoracle
FieldMetadataPayloadFieldSchema
ServerFieldSchemaFieldSchema
DesignerFieldDefinitionFieldSchema
ObjectMetadataPayloadObjectSchema
ServerObjectSchemaObjectSchema
ObjectDefinitionObjectSchema

The permission authoring path has the same two ingredients the gate needs and is in none of them: ObjectPerm / PermissionSetDraft in packages/app-shell/src/views/metadata-admin/permission-slice.ts are statically declared payload shapes, and ObjectPermissionSchema / PermissionSetSchema are exported strict zod objects that refuse unknown keys by name (measured 2026-08-27 against @objectstack/spec 17.2.0: an unknown key comes back as unrecognized_keys).

Why it is worth recording

objectui#6595 is an instance of precisely the class this gate was built for — an authoring control writing keys the spec is retiring — and it reached this repo as a hand-written card from the upstream retirement (objectstack#12497), not from CI. Nothing here would have flagged it, because the surface it lives on is outside the gate's reach.

The same holds for the return direction: once the @objectstack/spec bump carrying the retirement lands, a permission set still carrying the removed keys is a body the schema refuses, and no gate in this repo would say so.

Not a claim that the gate is broken

The gate's header is explicit that it covers a SUBSET, and states four ways a key can escape it. This is a seventh shape it does not yet name, not a hole it hides — filing so the extension is a decision someone makes rather than an omission nobody sees.

Consideration for whoever picks it up

ObjectPerm is a hand-written subset of the spec's ObjectPermission (it omits allowExport, readScope, writeScope — see objectui#6605). So a key-set comparison here would be one-sided in a useful way: the gate asks whether every key the shape can EMIT is accepted, and the omissions are a separate problem from the one this gate judges. Worth deciding deliberately whether the entry should also surface under-coverage, or stay strictly the emit-side check it is everywhere else.

Metadata

Metadata

Assignees

No one assigned

    Labels

    domain:devxobjectui devx stream: fix lands on .github/, scripts/ or release pipeline — devx lane cross-repopm:queue

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions