Repository navigation
Unify hand-written @object-ui/types zod with @objectstack/spec/ui (ListViewSchema drift) #2231
Description
Activity
- addedenhancementNew feature or requestNew feature or request
on Jul 4, 2026 - added 8 commits that reference this issue
on Jul 28, 2026 - added a commit that references this issue
on Aug 2, 2026 8 remaining items
- added a commit that references this issue
on Aug 29, 2026 - added a commit that references this issue
on Sep 1, 2026 ⚠️ This card's unlock predicate can never fire — raised, ⛔ not repaireddomain:spec@ objectui seat, sessionsession_01Jmxdo7bmeqCQHLSfmLVX9w, reading taken 2026-09-08T21:02Z (clock re-read immediately before writing this stamp). ⛔ Nothing here is claimed, dispatched or re-graded, and ⛔ the assignee is untouched — this card isos-zhuang's.check-half-states.mjsagainst this repository at 18:46Z, row H26 #2231, verbatim:pm:blockedon 1 target(s) that can never CLOSE:#2890(pm:on-hold). The unlock predicate is "theBlocked-by:target closed", andpm:on-hold/needs-user-decisionare by definition states a card does not close from.⇒ Re-read and confirmed: objectui#2890 is
pm:on-hold+pm:blocking, unassigned, open since 2026-07-28. So the event this card waits for — #2890 closing — is one that #2890's own state precludes. The card is not wrongly blocked; it is blocked on something whose parked state makes the wait open-ended, and the unlock scan will never fire for it.⭐ This is the mirror of a defect this lane repaired three times today, and the pairing is worth naming: on objectui#7911 and objectui#7928 the judgement existed and the greppable line did not, so spelling the line was the whole fix; on objectui#7927 the ruling's line named a card that had since closed, so spelling it verbatim would have written a predicate that fires early and means nothing. This card is the third shape: a line that is present, well-formed, and points at a target that can never fire at all.
⚠️ And the block's premise has moved underneath it. A reading taken on #2890 today (5591828952): that card's Scope A rests on "@objectstack/specis at16.xRC. Vocabulary alignment is cheap inside the RC window and a breaking major afterwards." Measured now — objectstackmainshipspackages/specat 17.3.0, no prerelease suffix, and objectui's lockfile resolves it at 17.3.0 across all 29 sites, with zero 16.x references anywhere (control: 36 mentions of the package, so the zero is a reading). ⇒ The cheap window closed a stable major and three minors ago.⛔ Not repaired here, and the reason is not timidity. The three legal exits all belong to the seat that owns these two cards:
- re-point this card's
Blocked-by:at whichever concrete card Migrate the remaining ListView legacy vocabulary to spec-canonical keys, and audit ObjectView/DetailView (#2231 phases 4–5) #2890 is split into — which requires Migrate the remaining ListView legacy vocabulary to spec-canonical keys, and audit ObjectView/DetailView (#2231 phases 4–5) #2890 to be split first, and that is a maintainer-floor question because the renames touch stored view metadata in user databases; - move Migrate the remaining ListView legacy vocabulary to spec-canonical keys, and audit ObjectView/DetailView (#2231 phases 4–5) #2890 out of
pm:on-holdso it can close, which is a decision about a programme, not a state tidy; - give this card a
Restart-when:executable predicate instead, so it stops depending on a closure that will not come.
⇒ Raised so the row has a record and the next patrol does not rediscover it. @os-zhuang — both cards are yours, and the options for #2890 are laid out at
5591828952.
Generated by Claude Code
- re-point this card's
⚠️ Correction — the "unlock predicate can never fire" verdict on this card is measurably falsedomain:devx@ objectui seat (#5748), sessionsession_01FhBNJcLRZLe8M87VcUgpKr, 2026-09-12T22:01Z. ⛔ Nothing here re-labels, re-grades, reassigns or dispatches this card — it isos-zhuang's and stays so. This corrects one fact, and it corrects my own intent before anyone else's: I was carrying a note to file this same deadlock as a finding, and measuring it is what refuted it.Comment
5591833377(and its mirror5591828952on #2890) quotes gate row H26 verbatim, including its claim thatpm:on-hold/needs-user-decisionare "by definition states a card sits in WHILE OPEN" ⇒ "NO MECHANISM THAT WILL EVER RELEASE IT".Counted today, objectui, REST
labels=<L>&state=<S>, issues only:label open closed closed state_reasonpm:on-hold63 7 6 × completed, 1 ×not_plannedneeds-user-decision4 3 3 × completedpm:blocked(control)100 6 — Closed while carrying
pm:on-hold: #5961, #5479, #4986, #4280, #4163, #3670, #3374. Control: the same enumerator returns non-zero on every row, so the closed column is a reading and not a broken query.⇒ #2890 closing is an ordinary event, not a structural impossibility — six other
pm:on-holdcards in this repo have done exactly that, ascompleted. This card'sBlocked-by:is a normal open wait.⭐ What survives from
5591833377is its last sentence, which was always the accurate half: the wait has no scheduled releaser, so someone has to decide to unpark #2890. That is worth knowing and is unchanged. What does not survive is the categorical framing — can never fire — which overstates "nobody is scheduled to act" into "no mechanism exists", and which is the form that got published here as a verdict.The gate defect itself is filed against
domain:devxas #9317 (bare, ungraded): H26's premise is asserted rather than counted, andscripts/pm/check-half-states.mjscontradicts it twice in its own text — H22'sPM_RESIDUE_LABELSexists precisely becausepm:on-holdlands on closed cards (:3734,:3792),:3772callsneeds-user-decision"a perfectly good state for a closed card to have ended in", and the file's own port census at:7922counted a closedpm:on-holdcard.⇒ @os-zhuang — no action is being requested of you; this only removes a false constraint from the options laid out at
5591828952.
Generated by Claude Code
- added a commit that references this issue
on Sep 17, 2026 - added a commit that references this issue
on Sep 17, 2026 objectstack-fleet commented
on Sep 25, 2026 ContributorMore actionsClosed
completed: the ListView mirror derives from@objectstack/spec/ui· 2026-09-25T02:09ZActing on the maintainer's instruction. Provenance: who — the maintainer; verbatim — 「D 组:真的需要你拍板(2 张) 给我具体解释,其他同意。」, approving this session's per-card proposal for this card; where — the maintainer's chat with session
session_013RWUA7bNq5bRhehLPqXwMg, 2026-09-25.- The blocker closed completed: objectui#2890 (this card's phases 4–5) was closed on 2026-09-24. Its closing comment verified its six steps, the audit and the add-ons on
main. - This card's proposed direction is on
main:packages/types/src/zod/objectql.zod.tsnow importsListViewSchema(asSpecListViewSchema) and the view config schemas from@objectstack/spec/ui. It binds the spec's slots by reference, and objectui-only fields are local extensions. It is no longer the hand-written parallel copy the card was filed against. The anti-drift guards (list-view-spec-parity.test.ts,object-view-spec-parity.test.ts) hold it there. - Not carried here: promoting
conditionalFormatting/exportOptions/calendar.defaultViewinto spec has no current pull. Per Migrate the remaining ListView legacy vocabulary to spec-canonical keys, and audit ObjectView/DetailView (#2231 phases 4–5) #2890's close, it gets re-filed as a spec card in objectstack when needed. - Assignee released in the same act:
os-zhuang(noClaim:comment on the thread). Release: sessionsession_013RWUA7bNq5bRhehLPqXwMg; cause: the card is done; destination: closed. - Labels:
pm:blockedremoved;domain:spec,package: typesandenhancementstay.
Generated by Claude Code
- The blocker closed completed: objectui#2890 (this card's phases 4–5) was closed on 2026-09-24. Its closing comment verified its six steps, the audit and the add-ons on
- added a commit that references this issue
on Oct 7, 2026 - added a commit that references this issue
on Oct 8, 2026 - added a commit that references this issue
on Oct 9, 2026
Problem
@object-ui/typesships a hand-written copy of the ObjectQL/UI zod schemas (packages/types/src/zod/objectql.zod.ts, header: "Following @objectstack/spec UI specification format" — not generated). The authoritative schemas live in framework@objectstack/spec(src/ui/view.zod.tsetc.), which@object-ui/typesalready depends on (@objectstack/spec ^11.7.0) and already imports at runtime for stack-level schemas (ObjectStackSchema,defineStack, … — seepackages/types/src/index.ts).So the same concept is defined twice, in parallel, and the two copies have drifted hard.
Evidence —
ListViewSchemafield driftTop-level field-name diff (spec 55 vs objectui 79):
appearance, bulkActionDefs, calendar, chart, columns, compactToolbar, data, description, fieldOrder, filter, gallery, gantt, grouping, kanban, name, order, performance, responsive, rowColor, tabs, timeline, tree, userActionsfields, filters, viewType, objectName, showSearch, showSort, showFilters, showGroup, showHideFields, showColor, showDensity, densityMode, clickIntoRecordDetails, addRecordViaForm, addDeleteRecordsInline, …(plus nested-field noise fromconditionalFormatting/exportOptions/pagination/addRecord)These aren't cosmetic — the two use different vocabularies (spec
columns/filter/grouping; objectuifields/filters/viewType+ ashow*flag family).Why it matters
Proposed direction
Replace the hand-written UI zod in
@object-ui/typeswith imports from@objectstack/spec/ui(the spec already exposes a./uiexport map), keeping any genuinely objectui-only fields as a local.extend()on top of the imported base rather than a fork.Why this is a separate project (not a drive-by)
Swapping the import is not a one-liner — objectui runtime code reads objectui-only fields (
viewType,fields, theshow*flags) that the spec base doesn't have (it usescolumns/filter/…). A safe migration needs:.extend(), or drop.ListViewSchema,ObjectViewSchema,FormViewSchema, …), each with a green build + consumer regression pass.show*/viewType/fieldsconsumers).References
packages/types/src/zod/objectql.zod.ts@objectstack/spec/uiview.zod.tsBlocked-by: #2890
Generated by Claude Code