Skip to content

finding(ui): the schema-settled $expand gate is now four hand copies, and four more views resolve the schema without gating on it #6482

Description

@claude

Recorded while implementing objectui#6453, which is where the third hand copy of the schema-settled gate was written. This card exists so the convergence question is asked deliberately rather than answered by accretion, and so the second half — five sibling views that resolve the schema but do not gate on it — is not lost.

Filed as an observation. Nothing here is a correctness defect; objectui#6481 (ObjectTree's unkeyed latch) is filed separately as one.

Where the family stands today

componentshapekeyed by object?
plugin-kanban/src/ObjectKanban.tsx{ key, def } | null, gates the whole fetch effect (objectui#6271)yes
plugin-view/src/ObjectView.tsx{ key, def } | null, gates the non-grid fetch effect (objectui#6419)yes
plugin-calendar/src/ObjectCalendar.tsx{ key, def } | null, gates the object-provider branch (objectui#6453)yes
plugin-tree/src/ObjectTree.tsxobjectSchema + a bare schemaSettled boolean (objectui#6014)no — objectui#6481

Four copies. objectui#6453's triage note asked the implementer to prefer adopting a shared helper if objectui#6419's landed shape extracted one; it did not (e929c562a touched only ObjectView.tsx, one test and a changeset), so objectui#6453 wrote the third copy deliberately and declared it. The reasons it did not extract, which are the inputs to this card rather than a pre-ruling of it:

  • The resolution half is genuinely common: useState<{key, def} \| null>(null), a key, ready = res !== null && res.key === key, def = ready ? res.def : null, and an effect whose every exit settles.
  • The gate half is not. ObjectCalendar keys on dataConfig.object ?? schema.objectName rather than schema.objectName, and gates one provider branch rather than the whole effect, because an inline value data set issues no metadata read at all — a whole-effect gate would hold its query open on a resolution nothing was going to produce. A helper would hold roughly the resolution half and leave each component its own gate placement.
  • A helper would have to live in @object-ui/react (AGENTS.md §3 bars React from @object-ui/core), which makes it a new export on a published package — a permanent public-surface commitment. All four plugins already depend on @object-ui/react, so it is feasible; the question is whether it is wanted.
  • Doing it would refactor two already-landed fixes (objectui#6271, objectui#6419) plus a fourth divergent copy.

The second half: five views resolve the schema but do not gate on it

Every other buildExpandFields consumer already lists the schema in its fetch effect's dependency list, so none of them carries the never-expands defect. They carry the other regime — two queries, the first unexpanded:

plugin-gantt/src/ObjectGantt.tsx:536 deps [... , objectSchema]
plugin-map/src/ObjectMap.tsx:708 deps [... , objectSchema]
plugin-timeline/src/ObjectTimeline.tsx:208 deps [... , objectDef]
plugin-list/src/ObjectGallery.tsx:354 deps [... , objectDef]
plugin-tree/src/ObjectTree.tsx:468 gated, but see objectui#6481

What that costs is not uniform, and objectui#6453 measured why. On ObjectCalendar, instrumented with three latency profiles: when the schema read is the slower of the two, the dependency version painted raw ids, reverted to the loading placeholder, then swapped — a three-step paint; when it was the faster one, the first response was discarded on arrival — a round trip bought and thrown away. ObjectKanban measured the discard case, ObjectView measured the visible-swap case. So whether gating is worth it in each of the five above is a per-component measurement, not an inference from this table.

What this card is asking for

A decision, then whatever work follows from it:

  1. Extract a shared settled-schema resolution hook, or keep hand copies? If extracted, the new export must be declared as a public-surface widening, not slipped in.
  2. Independently: measure each of the four ungated views and gate the ones where an extra re-run costs a visible wrong paint.

Related: objectui#6271, objectui#6419, objectui#6453, objectui#6481, objectui#6014.

Generated by Claude Code


Generated by Claude Code

Metadata

Metadata

Assignees

No one assigned

    Labels

    domain:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seatneeds-user-decision

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions