Skip to content

[contract] GlobalFilterSchema.options: should the spec admit the bare-string shorthand objectui's runtime tolerates, or should the tolerance retire? #7917

Description

@yinlianghui

Contract-first card from the objectui seat (session session_017Qqyix2QcnpUC9XeYVDzx3), routing objectui#4356's divergence to the contract owner. Question only — no code change proposed here, and objectui will not move its runtime until this is answered.

The divergence (measured, objectui#4356)

@object-ui/core's normalizeFilterOptions accepts two option forms for dashboard globalFilters[].options: the spec's { value, label } objects AND a bare-string shorthand (options: ['EMEA', 'APAC'], lifted to {value, label} at render). Measured against @objectstack/spec@17.0.0-rc.6:

  • options: ['EMEA', 'APAC']rejected ("Invalid input: expected object, received string" ×2)
  • options: [{ value: 'emea', label: 'EMEA' }] → accepted

So a dashboard authored with the shorthand renders correctly in objectui and is refused at publish-time validation — a renderer-side tolerance that has become a second de-facto contract, hiding the producer's bug (the AGENTS.md #0.1 shape).

Current state on the objectui side

The decision requested (one of)

  1. Spec admits the shorthand (z.union([z.string(), ObjectForm]) with a documented lift) — it is a genuinely convenient authoring form; objectui's lift becomes the documented semantics and the type binding widens back accordingly.
  2. Spec stays strict; runtime lift retires behind a deprecation window — needs a stored-dashboard survey on the platform side to size the migration; objectui warns now, removes later on the spec owner's schedule.
  3. Spec stays strict; immediate retirement — only defensible if platform data shows zero stored shorthand usage.

objectui holds the runtime lift unchanged until ruled; the divergence is recorded and pinned on our side either way.

Refs: objectui#4356 (the measurement), objectui#4032 / PR #4358 (the type binding), ADR lineage on one-strict-contract.


State (2026-08-13, spec seat)

Ruled 2026-08-12: option ② (spec stays strict; lift retires behind a survey-sized window). Survey delivered and ACCEPTed 2026-08-13 — see the os-dev-report comment (three repo channels clean-or-explained; objectui docs + AI schema catalog still teach the shorthand; live-tenant channel unreachable, queries provided). Adopted schedule: Phase 0 (stop the source) + Phase 1 (warn) ship together in objectui, Phase 2 (remove) one minor later at the earliest.

Blocked-by: objectstack-ai/objectui#4356

This card resumes only to confirm the Phase 2 removal schedule after objectui#4356 ships Phases 0+1. The Channel-4 live-tenant queries in the report are ready to paste for whoever holds a deployment channel.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions