Uh oh!
There was an error while loading. Please reload this page.
spec(ui): UserActionsConfigSchema adopts group / hideFields / rowColor (ruled A on objectui#5435) - #11458
Conversation
#11195) The three toolbar affordances ListView already honours become authorable: objectui's normalize-list-view fold maps legacy showGroup/showHideFields/ showColor onto exactly these userActions keys, so the fold's own output now passes the save gate (ruled Option A on objectui#5435). Defaults copy the renderer's reads and the asymmetry is load-bearing: group defaults ON (ua?.group !== false), hideFields/rowColor default OFF (=== true). Cross-surface name collisions (component hideFields: string[], view-level rowColor: RowColorConfig) are documented on the describes; the object-block userActions vocabulary stays disjoint, now re-checked mechanically in object-strictness-batch20.test.ts. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01T9cDbY2NBiVJWYx3BpWfH2
📓 Docs Drift CheckThis PR changes 1 package(s): 2 hand-written doc(s) NAME something this change touched and may need an implementation-accuracy re-verification:
⛔ 3 release-owned page(s) also name something this change touched. These are read-only:
What this run could not see
Coarse fallback — 126 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): Which tree this was computed onThis run read A worktree cut from an older # while this PR is open — GitHub drops the merge commit once it closes
git fetch origin e2932d5af98fff6b35e525ca3b99e6dfd4c06805 && git checkout e2932d5af98fff6b35e525ca3b99e6dfd4c06805
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin 8542bd457765444626023db6ffeb6f8105f7f83e 51de14c509e29254339d5c75bbcde08dfc71523c && git checkout -B drift-repro 8542bd457765444626023db6ffeb6f8105f7f83e && git merge --no-ff 51de14c509e29254339d5c75bbcde08dfc71523c
node scripts/docs-audit/affected-docs.mjs --json 8542bd457765444626023db6ffeb6f8105f7f83e
|
Uh oh!
There was an error while loading. Please reload this page.
Fixes#11195
Held for contract review (clause ②) — accept-set widening on a contract schema;
needs:contract-reviewhangs on the card. Draft on purpose; the landing decision is the review's.What
UserActionsConfigSchema(packages/spec/src/ui/view.zod.ts:853, astrictObject) gains three boolean keys, implementing the ruling recorded on objectui#5435 (maintainer, 2026-08-22, decision-inbox digest, verbatim: 「接受所有」 — Option A):group— default truehideFields— default falserowColor— default falseobjectui's
normalize-list-view.tsfold maps legacyshowGroup/showHideFields/showColoronto exactly these keys, andListView.tsxhonours all three — so before this change the fold's own output was rejected by name at the save gate. The fold-map's own comment calls the three "pending promotion intoUserActionsConfigSchemaupstream"; this is that promotion, spelled exactly as the fold emits it. No shape or naming fork was forced — the stop-and-report clause on the card was not triggered.Defaults asymmetry is load-bearing
Copied from the renderer's reads, not chosen here:
ListView.tsxcomputesshowGroupasua?.group !== false(absent = shown) butshowHideFields/showColoras=== true(absent = hidden). Pinned inview.test.tswith a dedicated test naming those reads; normalising the three to one default would silently flip a toolbar affordance on every view that never wrote the key.The name collisions, and what the batch20 guard reads on the pair
Both pre-existing spellings stay untouched; each pair is toggle-vs-config, documented on the describes and in the schema docblock:
userActions.rowColor(boolean toggle, NEW) vs the list view's ownrowColor(RowColorConfigSchema— the colour rules the toggle exposes) and the component-registryrowColor(config,component.zod.ts).userActions.hideFields(boolean toggle, NEW) vs the record-details component'shideFields(string[]of field names to omit,component.zod.ts).object-strictness-batch20.test.tsreadings on the pair, post-adoption:UserActionsConfigSchema.shape(11 keys), asserts the three adopted keys are present, asserts zero overlap with the object block's five verbs (create/import/edit/delete/exportCsv), and asserts the object block still refusesgroup/hideFields/rowColorby name — the operative half of "disjoint": the wrong-layer write stays a loud rejection, never a silent second meaning.userActions: { sort: false }still rejects naming VIEW.Acceptance criterion (executed on the built dist at 51de14c)
Bounded in-place fix (declared)
packages/spec/src/data/object.zod.tsguidance comment (the wrong-layer guard's own rationale, lines 1726-1731): its enumeration of the view vocabulary went stale the same way the batch20 comment did — same defect class as pin 1 of the card, comment-only, mechanical (the shape is the evidence), no gate family added. Claim-surface supplement posted on the issue in the same round. No guidance/alias entries were added for the three new keys on the object block — that would be a behavioural extension outside this card; flagged in the report instead.Verification (all at 51de14c, clean tree; exit codes captured before any pipe)
pnpm --filter @objectstack/spec build— VERDICT command-exit 0pnpm --filter @objectstack/spec test— 419 files / 11157 tests passed, VERDICT command-exit 0pnpm --filter @objectstack/spec typecheck— VERDICT command-exit 0 (incl.check:test-typecheckOK line)pnpm --filter @objectstack/spec check:generated— 1 of 14 stale (check:docs); regenerated via--fix; re-run green. Build had already refreshedauthorable-surface/ui.json+authorable-defaults/ui.json; generated diff carries exactly the three keys + defaults.node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack, changeset from merge base 5a916c4): 26 derived gate commands run locally, all exit 0 — nul-bytes, changeset-gate-self-tests, objectui-changeset, adr-0087-registration, merge-driver, doc-anchors, doc-authoring, docs-audit-scope, docs-redirects, published-readme-links, quick-reference-counts, role-word, published-files, slot-lookup, spec-parsed-alias, test-source-alias, type-source-resolution, cross-package-test-inputs, engine-double-contract, where-matcher, spec empty-state / liveness / strictness-ledger / variant-docs, lint doc-formula-expressions / doc-security-posture.check:type-check-debt --re-measure(needs the full workspace build closure; exceeds the local foreground cap cold) was NOT run locally; CI runs it. Receipt: population = the 26 ledger entries insidescripts/check-type-check-coverage.mjsitself;@objectstack/specis not among them (it is COVERED via its owntypecheck, run green above); all TS changes in this diff live inpackages/spec; ledger packages see the change only through spec's built d.ts, where the delta is purely additive, andUserActionsConfigis referenced by 0 files outsidepackages/spec(repo grep over ts/tsx/mts excluding node_modules/dist). An additive extension of a type no ledger entry names cannot raise any entry's tsc error count.Changeset
minorfor@objectstack/spec(accept-set widening; not breaking, so no ADR-0087 disposition marker is required andcheck:adr-0087-registrationpasses).Downstream
Unblocks objectui#5435 (fold/renderer test alignment — their seat's follow-up; that card stays open and is additionally held on objectui's spec pin bump, currently at 17.1.0 per objectui#5716). No objectui files touched here.
Generated by Claude Code