Skip to content

spec: editMode is read off the object document by objectui's runtime but the strict parse rejects it — declare or rule out #11408

Description

@os-sam

Out-of-scope finding from objectui#5362 (the consumer half of the #10144 split). Filed unassigned, not claiming.

Fact (measured on published @objectstack/spec 17.2.0)

editMode?: 'modal' | 'page' is an authored key on the object document that objectui's shipped runtime reads:

  • packages/app-shell/src/utils/recordFormNavigation.ts branches on objectDef.editMode !== 'page'; AppContent's central handleEdit dispatcher routes on it (modal form vs dedicated /record/:id/edit route).
  • objectui's CHANGELOG announces it as a feature ("ObjectSchemaMetadata.editMode — optional 'modal' | 'page' flag"), i.e. it is documented for authors, not host-composition surface.

The spec's object document neither declares it nor merely strips it — the strict parse rejects it loudly:

ObjectSchema.safeParse({ name: 't', fields: {...}, editMode: 'page' })
→ success: false
→ issues[0] = { code: 'unrecognized_keys', keys: ['editMode'], path: [] }

(Measured against the published artifact, node_modules/@objectstack/spec 17.2.0; the rejection message cites the #4001 strictness change. Positive control: the same document without editMode parses success: true.)

So an author who follows objectui's documentation and publishes editMode through any spec-validating path is rejected; the key only works through data sources that skip spec validation.

Why this is the #10144 family

#10144 (closed completed) ran declare-or-rule-out for titleFormat / listViews / icon — the three object-document keys objectui read but the spec did not declare. editMode is the measured residue of the same census: the one remaining member of objectui's retired hand-written ObjectSchemaMetadata mirror with a live runtime read. Under objectui#5362 it now lives in an explicitly-labeled client extension (ObjectSchemaClientExtensions), with a pinned test asserting the spec parse rejects it — so the client type stays honest either way, but the contract question is open:

  • Declare: the spec's object document adopts editMode (objectui then retires the extension member and lets the derivation carry it — the pinned tests flip and say so), or
  • Rule out: the key is judged UI-host configuration that does not belong on the object document, and objectui moves the affordance to wherever the ruling points (and retires its documentation of the key as authored surface).

No recommendation beyond the family precedent; both routes need the maintainer's contract-review tier per the #10144 pattern.

Back-links: objectui#5362 (ruling + consumer half), objectui PR (derivation + object-schema-metadata-spec-derivation.test.ts, which pins the current rejection).


Generated by Claude Code

Metadata

Metadata

Assignees

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions