Skip to content

Commit e040b8c

Browse files
chore(objectui): bump the console pin to 0df67f2 (carries objectui#12089) (#22812)
Part of #15204 Clause-②: yes (widening: the html-page save gate and `os validate` accept an `element:repeater` bound through `dataSource` alone) This moves the bundled Console's objectui pin from `20c6d351ad74` (PR #22592) to `0df67f237c5ab46cbc65252c5f6bd05f2be44c48`. That commit is objectui `main` at dispatch and the merge of objectstack-ai/objectui#12089, C9 part 1 (objectstack-ai/objectui#7611): Setup's positions and permission sets read the registry, and the catalog's active switch writes the activation ledger through stage 2c's door. This is stage 5 of #15204 (stage plan 6094501866, stage-0 order correction 3 in 6095755866, claim amendment 6106816979). Stage 6a (#22793) waits on it. #15204 remains open for its remaining stages. The bump follows the repo's own procedure, as PR #22592 did: `scripts/bump-objectui.sh`, then `pnpm objectui:build` and `node scripts/gen-sdui-manifest-node.mjs`, then the gates they derive. It adds no step to that procedure. This is not a release act. The Version Packages PR is untouched, and this diff edits neither `packages/console/CHANGELOG.md` nor `packages/console/package.json`. The console's release input is the new `.changeset/console-0df67f237c5a.md`. ## Range - **REST `compare` on objectstack-ai/objectui**, `20c6d351ad74...0df67f2` (read 2026-10-11T07:48:57Z): `status: ahead`, `ahead_by: 21`, `behind_by: 0`, 293 files, merge base `20c6d351ad74`. The pin moves forward from `main`'s, and it contains objectui#12089's merge. - In the objectui object store, `git merge-base --is-ancestor 0df67f2 origin/main` exits 0. `20c6d351ad74..0df67f2` has 21 commits and 0 merges. Its 293 paths are 73 added, 219 modified, 1 renamed and 0 deleted. - The pin names exactly `0df67f237c5a`, as the dispatch ruled. objectui `main` has moved since, to `802f0bc41f39` (`git ls-remote`, 2026-10-11T08:22:44Z). This bump does not chase it. - **Cloud's `.objectui-sha` must not pass `0df67f237c5a` until cloud is on objectstack v18.** That decision is with the maintainer. Nothing in this PR touches cloud. ## The range's notable commits (breaking first) 1. **`12ff25631` (objectui#6349 batch 10), annotated breaking.** The row type of `@object-ui/plugin-designer`'s `VersionHistory` timeline is declared as `VersionHistoryEntry` instead of `VersionEntry`. In the same batch, `ConnectionState` gets one declaration, in `@object-ui/types`, and `@object-ui/providers`' `ThemeProvider` props become `ThemePreferenceProviderProps`. These are objectui TypeScript types. No ObjectStack key moves. 2. **`ce991bd70` (objectui#12085, objectui#12093): the one commit that moves an objectstack accept set.** `element:repeater` and `element:number` publish the node-level `dataSource` binding as their only query input. The regenerated `sdui.manifest.json` loses the repeater's `object` (required), `filter`, `sort` and `limit` inputs, and the number's `object` and `filter`. It is the html tier's half of the retirement `@objectstack/spec` already carries (#11509, `.changeset/11509-element-flat-binding-retired.md`). The renderer still reads the flat keys as the binding's fallback. The section below has the measurement. 3. `0df67f237` (objectui#12089, C9 part 1): Setup's positions and permission sets read the registry, through the metadata-admin pages' environment scope. This is the card's acceptance, measured below. 4. `5330afd1f` (objectui#12086): list views read an absent `userActions.editInline` as on, the v18 default. This is the consumer half of #22605, whose spec half (`f53f14bb3`, #22629) is already on `main`. A list view that declares neither key now offers in-place editing to a caller who may update the object. 5. Write affordances read one affordance-to-grant map: - `023f00d46` / `5af42dbbd` (objectui#12082): a create form asks the create grant, and eighteen write affordances, then five more that read no grant at all, read one affordance-to-grant map (the grid's row Edit/Delete, bulk Delete and inline edit, and the kanban card move among them); - `5f75cfad1` (objectui#12103): in-place and in-cell edit honour the field write grant, and the owner field the transfer grant. 6. Other console behaviour: - `29b994902` (objectui#12105): a promoted bulk action's field-backed param resolves through the shared action-param resolver. - `b7cd5c891` (objectui#12108): a create form says "Set automatically when saved." under a server-filled field. - `16c8810ac` (objectui#12081 item 2): a list's calendar view fetches the days it shows, in fetch batches. - `029bdaf45` (objectui#12081 item 8): the activity feed asks only a caller who may read `sys_activity`. - `5a65f7d57` (objectui#12109): an object entry is not drawn for a caller who cannot read the object. - `206505c34` (objectui#12104): a timeline groups an explicit `groupByField` by its display value. - `de302c731` (objectui#12078): the chatter reads and writes reactions as `sys_comment_reaction` records. That object is on `main` since #22566, and the column path stays for a framework without it. - `417e24567` (objectui#12079): an app that serves no navigation opens on an app-level empty state. - `4d0ff2331` (objectui#12080): a long flow screen keeps Submit / Confirm on screen. - `3c0f8069e` / `a21ff9a95` (objectui#12087, objectui#12097): marketplace installs wait until the app is served. 7. Types only: `d758f2f20` and `1b2d0160f` (objectui#6349 batches 8 and 9). No changeset: `a194b4e37` (objectui#12114, objectui's own scripts). The digest reads 28 releasing changesets of 29 across 21 non-merge commits, 1 release-nothing, and 1 commit with no changeset. None declares `major`, and one carries the author's breaking annotation. The highest declared level is `minor`, so the console changeset is `minor`. Its `adr-0087: TODO` placeholder is answered `not-required (no-migration-prescription)`, which names the annotated entry and the manifest move. ## Clause-②: what moves, measured The html-page save gate (`metadata-protocol` `runtime-authoring-gate.ts`) and the CLI's JSX gate (`os validate` / `compile` / `lint`) compile a page source against the SDUI manifest the console ships. The gate fails a save only on an error-severity diagnostic (`CompileResult.ok`). `compile()` from `@objectstack/sdui-parser` (this branch's build) was run against the previous manifest (the tracked file at `680a86b4c`) and the regenerated one: | page source | previous manifest | this manifest | |:--|:--|:--| | an `element:repeater` with `dataSource={{ object: "account" }}` and no flat `object` | `ok=false`, `error: missing-required-prop` | `ok=true`, no diagnostic | | an `element:repeater` with a flat `object` | `ok=true`, no diagnostic | `ok=true`, `warning: unknown-prop` | | an `element:repeater` with flat `object`, `filter`, `sort`, `limit` | `ok=true` | `ok=true`, four `unknown-prop` warnings | | an `element:number` with a flat `object` | `ok=true` | `ok=true`, `warning: unknown-prop` | | an `element:number` with `dataSource={{ object: "account" }}` | `ok=true` | `ok=true` | So the html tier now accepts a repeater bound through `dataSource` alone, which it refused before. Nothing it accepted before is refused now: the retired flat keys draw a non-gating warning. That makes it a widening, and it is declared `Clause-②: yes (widening)` on line 2 and in the console changeset. **A contract-tier review is owed for this PR.** The JSON tier does not move here: `@objectstack/spec` already retired those flat keys (#11509). ## Acceptance, measured in the browser The showcase was booted from this branch (`pnpm dev -- --fresh -p 38138`, `OS_PORT` exported), serving the console dist built at the new pin. At boot, `check:console-sha` printed "Console dist matches the objectui pin (objectui@0df67f237c5a)". The run used Chromium (`/opt/pw-browsers/chromium`, headless, 1440x900) and signed in through the form as the seeded platform admin. The boot and the run were held under the verify lock, and the server was torn down at the end. - **`system/permissions` lands on the registry catalog.** `/_console/apps/setup/system/permissions` redirects to `/_console/apps/setup/metadata/permission?scope=environment`. The page reads `GET /api/v1/meta/permission` (200) and `GET /api/v1/data/sys_metadata_activation?top=1000` (200), and nothing from `sys_permission_set`. It lists 17 permission sets, each from an Artifact source, each with a live switch. - **Switching a set off** (`showcase_auditor`): - request: `POST /api/v1/security/_activation/permission/showcase_auditor` with body `{"enabled":false}`; - response: `200 {"success":true,"data":{"type":"permission","name":"showcase_auditor","enabled":false}}`; - the switch reads `aria-checked="false"`. - **After a reload the switch still reads off** (`aria-checked="false"`). The ledger read answers one row: `metadata_type: "permission"`, `name: "showcase_auditor"`, `package_id: "com.example.showcase"`, `active: false`. - **The holder loses it.** The demo persona `auditor.demo@example.com` holds the `auditor` position, which binds `showcase_auditor`. That persona signed in and read its own permissions with `GET /api/v1/auth/me/permissions` at each step: - before: `["showcase_auditor","showcase_member_default","member_default"]`; - while off: `["showcase_member_default","member_default"]`; - after the restore: `["showcase_auditor","showcase_member_default","member_default"]`. - **Switched back on and restored.** Request: the same path with body `{"enabled":true}`. Response: `200 {"success":true,"data":{"type":"permission","name":"showcase_auditor","enabled":true}}`. After a reload the switch reads `aria-checked="true"`. - The admin is asked once to set the workspace timezone (objectui#11758). The run answered "Keep the default". The only console errors were a 404 and the signed-out session 401, both on the sign-in page before sign-in. ## What changed here (21 files, +519 / -157 = 676 changed lines, generated files included) | file | written by | gate that required it | |---|---|---| | `.objectui-sha` | `scripts/bump-objectui.sh 0df67f2… --no-commit` | Console Pin Gate builds what it names | | `.changeset/console-0df67f237c5a.md` | the same run (the digest). The later edits are the ADR-0087 answer and the `Clause-②` line | `check-adr-0087-registration`, `check:objectui-changeset` | | `sdui.manifest.json`, `scripts/sdui-manifest.record.json` | `node scripts/gen-sdui-manifest-node.mjs` over `.cache/objectui-0df67f237c5a` | `check-sdui-manifest.mjs` | | `packages/sdui-parser/objectui-lockstep.json` | `node scripts/check-sdui-lockstep.mjs --update`, `OBJECTUI_ROOT` at the built tree | `check:sdui-lockstep` | | 55 asserting citations in 14 files under `packages/spec/src`, and three quoted anchors of the dated `view.zod.ts` map record | re-measured by hand (below) | `check:objectui-pin-citations` (and `--verify-anchors`) | | `.changeset/objectui-pin-citations-0df67f237c5a.md` | hand-written, `@objectstack/spec` patch | Check Changeset (the shipped describes name the pin) | | `content/docs/references/ui/view.mdx` | `check:generated --fix` (`gen:docs`) | `check:docs` | - The manifest keeps 107 components. Its sha256 moves to `9d87162a3ef6…`, and only the two element rows above change (32 lines removed). objectui's workspace version stays 17.7.0. - The lockstep records 214 grammar lines (blob `0131f27cf86d`), 25 diagnostic codes and containment predicate `76c18fb95d1f`. All are unchanged; objectui's `packages/sdui-parser` is untouched by the range, so no port is owed. - `packages/spec/src/migrations/registry.ts` is gitignored on `main` now and is regenerated, not committed. - The bump script read the shared objectui checkout read-only (the range walks there: 21 commits). The console build ran with `OBJECTUI_ROOT` at a scratch repository with no refs of the sibling's own, using objectui's object store as its alternate. So the build's `git worktree add` and `worktree prune` registered nothing in the shared checkout. ## How the citations were re-measured - **Method.** Each asserting record's cited objectui files were resolved at `20c6d351ad74` and intersected with the range's changed paths. Every anchor in a changed file was mapped through `git diff -U0 20c6d35 0df67f2` and its text compared at both pins. A record whose cited files are all byte-identical (`git diff --quiet`) gains that sentence and no re-pointing. - **Changed cited files:** `ObjectGrid.tsx`, `ListView.tsx`, `ObjectCalendar.tsx`, `plugin-calendar/src/index.tsx`, `ObjectTimeline.tsx`, plugin-timeline's `renderer.tsx`, `ObjectKanban.tsx`, `KanbanBoardCore.tsx`, `KanbanImpl.tsx`, `plugin-kanban.mdx`, `MePermissionsProvider.tsx`, `PermissionProvider.tsx`, `record-details.tsx`, `basic/data-list.tsx`, `data-objectstack/src/index.ts`, `form.tsx` and plugin-view's `ObjectView.tsx`. The `en` / `zh` / `de` packs changed too, but not their `calendar.configRequired` strings. Every cited line moved or held byte-identical. - **Readings that changed around a cited read**, each said in its hop sentence: - `basic/data-list.tsx` (objectui#12085): the `element:repeater` row's two sentences that named the published flat inputs became false. Those were the required `object` input at `:320-326` and the binding published "beside these keys". Both are rewritten where they stand. The renderer still reads the four as the fallback. - `ObjectGrid.tsx` (objectui#12082): the `delete` verdict the implicit bulk-delete rides on now comes from the affordance map's `rowDelete` row. That row still asks the managed-object policy and the effective API operations, and now the delete grant too, so the `sys_api_key` record in `api-methods-batch-conformance.test.ts` still holds. Its selection block still hashes `c88443302d40…`, moved `4868-4895` -> `4897-4924`. `inlineEditable` reads the map's `listInlineEdit` row, still the authored `editable` AND the viewer's write verdict. - `ListView.tsx` (objectui#12081): the `case 'calendar'` arm gained a fetch-window callback. Its date-field reads are byte-identical and still declared-only, with no floor, and the fetch window's own copies (`:2495-2498`) read the declared bindings only. - **Two stale anchors corrected** on the `object-tree` flat-config record. Its opening still named the `case 'tree'` arm at its `47b1f0bb7` span (`3913-3932`), and its hop cited the `labelField` line as `:3986`, which is the `fields` line under it at `20c6d351a`. At this pin the arm is `4120-4144` and `labelField` is `:4140`. - **Counts re-taken by each record's own method.** - `keyboardNavigation`: 15 hit lines against 3 for `schema.editable`. - `ObjectKanban.tsx`'s `quickAdd` / `onQuickAdd` / `onCardClick`: 2 / 2 / 11. No `kanban-ui` registration outside tests. - The `ElementDataSourceGate` occurrences in the five `src/index.tsx` shells: 0, 3, 3, 3 and 4. `plugin-calendar`'s shell changed in its `HOST_CALLBACKS` list only. - The `schema.*` read sets: 19 names in `ObjectTimeline.tsx` and 5 in `renderer.tsx`, at both pins. - **Corpus counts.** The six migration entries' counts were re-taken with `git grep -o -F`. That method first reproduced every `20c6d351ad74` number: 8351 files, `objectstack` 18047, `@objectstack/spec` 7545, `useState` 2630, `timeout` 1694, `RuntimeConfig` 337, `resourceLimits` 2, `window` 4470, `period` 249, `interval` 213, `metrics` 456, `Span` 517, `SpanSchema` 57, `TTL` 184 and `tenant` 1340. - At the new pin they read: 8424 files, `objectstack` 18248, `@objectstack/spec` 7582, `useState` 2645, `timeout` 1705, `RuntimeConfig` 347, `resourceLimits` 2 (the same two `packages/app-shell` hits), `window` 4596, `period` 251, `interval` 233, `metrics` 456, `Span` 517, `SpanSchema` 57, `TTL` 184 and `tenant` 1357. - The zero tokens: 100 were checked (the exports of `plugin-lifecycle-advanced.zod.ts`, `tracing.zod.ts` and `metrics.zod.ts`, plus every named key). 98 read 0 at both pins; `Span` / `SpanSchema` read 517 / 57 at both. ## For the contract review: changed lines in `packages/spec/src/**` that are neither a comment nor a string fragment There are none. This was measured mechanically. Each of the 14 changed `.ts` files was scanned with the TypeScript scanner at `680a86b4c` and at the head, comments skipped and every string, template and regular-expression literal replaced by one placeholder token. The token sequences are identical in 12 of the 14 files. The other two are `18.system-metrics-jsdoc-durations-unit-in-key.ts` and `18.system-tracing-otel-exporter-durations-unit-in-key.ts`. Each gains one `+` joining one new string fragment (the older count) into its `reason` string. No identifier, key, value or export moves. The one shipped `describe` that changes is `FormField.span`'s, and only its sha moves. ## Gates and tests The derived gate union ran at the final head `ecd4ed7458`, on merge base `680a86b4c`. The tests and the builds ran at `7c7c5c8ab`, after a full workspace build at that tree (`turbo run build --concurrency=2 --filter=!@objectstack/docs`, 73 tasks, exit 0). The one commit between the two re-words a sentence inside the console changeset's ADR-0087 comment and touches nothing a build or a test reads. Exit codes were captured before any pipe. - **The gates this bump touches:** - **Console Pin Gate (local equivalent).** The dependency closure was built first: `turbo run build --concurrency=2 --filter=@objectstack/client --filter=@objectstack/spec --filter=@objectstack/sdui-parser`, 34 tasks, exit 0. Then `pnpm objectui:build` exited 0 (lock held 5m58s). Its log reads "Bundle canary 'import/jobs' present", "Single-zod canary: exactly one zod version literal {major:4,minor:6,patch:5}", "Console bundle carries THIS tree's @objectstack/spec, and only it" and "@objectstack/console dist ready (64368 KB) from objectui@0df67f237c5a". `check:console-sha` reads "Console dist matches the objectui pin (objectui@0df67f237c5a)" (exit 0), and `check:console-injection` reads "the dist carries this tree's copy, and not the published one" (exit 0). The CI job itself is NOT MEASURED here; it is CI's run. - `check:objectui-bump`: "bump-objectui self-test PASSED — 20 assertions across 5 cases" (exit 0). - `check-sdui-manifest.mjs`: "present, intact (sha256 9d87162a3ef6…, 107 components) and recorded at the live objectui pin 0df67f2…" (exit 0). - **Derived gates.** `node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack` derived 125 commands from 21 changed paths against merge base `680a86b4c`. All 125 ran and exited 0. The `--ran` reconciliation reads "125 derived famil(ies) accounted for — 125 run, 0 NOT-MEASURED (a DERIVED zero — all 125 recorded an exit code and none of them is 3)". Verdict lines: - `check:objectui-pin-citations`: "55 asserting objectui pin citation(s) match .objectui-sha (0df67f2), 145 historical citation(s) recorded and not checked, across 1976 spec source(s)." With `--verify-anchors` (`OBJECTUI_ROOT` at the objectui checkout): "13 anchor content assertion(s) verified against objectui at 0df67f2". - `check:sdui-lockstep`: "OK — this copy is byte-identical to objectui@0df67f237c5a (2026-10-11T07:26:10+00:00) over 214 grammar line(s) [blob 0131f27cf86d], agrees on all 25 diagnostic code(s) and on the `not-a-container` predicate [blob 76c18fb95d1f]". - `check-adr-0087-registration --base origin/main`: "1 declared-breaking changeset(s), each carrying an ADR-0087 disposition". `check-changeset-no-major --base origin/main`: "This diff introduces no `major` bump". - `check:generated`: "All 14 generated artifacts are up to date". `check:api-surface`: "public API surface + factory signatures unchanged". `check:docs`: "225 generated files in sync". `check:nul-bytes`: OK, no raw control bytes. - **Tests.** - `@objectstack/spec` (`pnpm --filter @objectstack/spec test`, `--project local`): 645 files, 19311 passed, 1 todo. `@objectstack/spec` typecheck (the scripts and test-layer checks included): exit 0. - `@objectstack/sdui-parser` test and typecheck: 14 files, 225 passed; exit 0. - `@objectstack/lint` `validate-jsx-pages.production-witness.test.ts`: 5 passed. `@objectstack/metadata-protocol` `protocol.runtime-authoring-gate.test.ts`: 133 passed. - `@objectstack/cli`, unit tier (`sdui-manifest`, `console.sha-drift`, `validate-build-gate-parity`, `console-resolve`): 4 files, 108 passed. The integration tier (`jsx-gate-manifest-notice.e2e.test.ts` among it) is declared to CI: this diff touches no integration-tier file and no spawn entry. - **Lint, narrowed and proven.** ESLint (`--no-inline-config`) over the 14 changed TS files under `packages/spec/src` gives 0 errors and 0 warnings, 14 files by the `--format json` count. The population is the `eslint.config.mjs` block that lints every `ts` file (line 971). The config never enables type-aware linting (line 328), so this diff cannot move the verdict on any file it does not touch. The repo-wide `pnpm lint` is CI's run. - **`main` after the cut.** `origin/main` gained five commits after `680a86b4c` (#22797, #22779, #22798, #22796, #22784, up to `098481744f`). None touches a file of this diff, so there is no merge here; CI and the merge queue judge the merge. ## Acceptance notes - **The editInline default flips in the console with this pin** (objectui#12086). The spec half (#22629) is already on `main`. The showcase's list views that declare neither `editInline` nor `inlineEdit` now offer in-place editing to a caller who may update the object. Noted, not measured in this run. Carrier: none. - **Writes.** This PR was opened through `scripts/pm/fleet-write/dispatch.mjs` (`pr_create`, draft), and its assignee set through `scripts/pm/label-write.mjs`. No label was written, `skip-changeset` included. No MCP write was used. _Seat note, 2026-10-11: this PR's earlier `Check Changeset` red was the gate's blind spot for the repo-root `sdui.manifest.json`. #22816 (stage 5-pre) fixed it on `main` at `5fdc1a890db5`, and this body edit re-runs the gate. Nothing above changed._ --- _Generated by [Claude Code](https://claude.ai/code/session_01Rerax7QTjKMPCUZxQUtPFR)_ --------- Co-authored-by: Claude <noreply@anthropic.com> Co-authored-by: objectstack-fleet[bot] <332303061+objectstack-fleet[bot]@users.noreply.github.com>
1 parent c4e7fa5 commit e040b8c

21 files changed

Lines changed: 519 additions & 157 deletions

‎.changeset/console-0df67f237c5a.md‎

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
---
2+
"@objectstack/console": minor
3+
---
4+
5+
Console (objectui) refreshed to `0df67f237c5a`. Frontend changes in this range:
6+
7+
Derived from the changesets objectui declared over the range — 28 releasing of 29 changesets added across 21 non-merge commits; omitted: 1 release-nothing changeset, 1 commit carrying no changeset (they ship no package code).
8+
9+
- **minor** — The Setup catalog for positions and permission sets reads the registry. It is built from the metadata-admin list and editors in their environment scope, not from new pages (object… (objectui `0df67f237`)
10+
- **minor** — A bulk action's field-backed param now renders its real control on the selection bar, and the confirm step names the picked record (objectui#12105). (objectui `29b994902`)
11+
- **minor** — A create form says when the server will fill a field: "Set automatically when saved." under a field whose `defaultValue` the server resolves at insert, while the field is empty (o… (objectui `b7cd5c891`)
12+
- **minor** — A calendar view in a list draws every record of the days it shows, not the first 100 records of the object (objectui#12081 item 2). (objectui `16c8810ac`)
13+
- **minor** — In-place edit on the record page and a list's in-cell edit honour the caller's field write grant, and the owner field honours the transfer grant (objectui#12103). (objectui `5f75cfad1`)
14+
- **minor** — List views read an absent `userActions.editInline` as on, the v18 protocol default (objectui#12086, the consumer half of objectstack#22605). A list view is editable in place by de… (objectui `5330afd1f`)
15+
- **minor** — Five write affordances that read no grant at all now read the affordance-to-grant map, so a caller without the grant is no longer offered a write the server then refuses (objectui… (objectui `5af42dbbd`)
16+
- **minor** — After a marketplace install into the environment the console is rendering, the package page waits until that environment serves the installed package's app, and only then refreshe… (objectui `3c0f8069e`)
17+
- **minor** — `element:repeater` and `element:number` publish the node-level `dataSource` binding as their only query input (objectui#12085). `@objectstack/spec` retires the element layer's fla… (objectui `ce991bd70`)
18+
- **minor** — A create form asks its fields the create question, so a role that may create records but not edit them can fill and submit the form (objectui#12082). Every console affordance that… (objectui `023f00d46`)
19+
- **minor** — **BREAKING** — The row type of the `VersionHistory` timeline is declared as `VersionHistoryEntry` instead of `VersionEntry` (objectui#6349, batch 10). `@object-ui/collaboration` publishes an unr… (objectui `12ff25631`)
20+
- **minor** — The props of this package's `ThemeProvider` are declared and exported as `ThemePreferenceProviderProps` instead of `ThemeProviderProps` (objectui#6349, batch 10). `@object-ui/reac… (objectui `12ff25631`)
21+
- **minor** — `ConnectionState` is a new export: the lifecycle state of one client connection, `'disconnected' | 'connecting' | 'connected' | 'reconnecting' | 'error'` (objectui#6349, batch 10)… (objectui `12ff25631`)
22+
- **minor** — The props of this package's minimal `AppShell` container are declared and exported as `MinimalAppShellProps` instead of `AppShellProps` (objectui#6349, batch 9). `@object-ui/layou… (objectui `1b2d0160f`)
23+
- **minor** — The props of this package's view switcher are declared and exported as `ListViewSwitcherProps` instead of `ViewSwitcherProps` (objectui#6349, batch 8). `@object-ui/plugin-view` pu… (objectui `d758f2f20`)
24+
- **patch** — **The console no longer offers an object to a caller who cannot read it** (objectui#12109). A navigation entry bound to an object (`type: 'object'`, by its `objectName`) is not dr… (objectui `5a65f7d57`)
25+
- **patch** — An object timeline with a `groupByField` draws one group per value, headed by the value's display name (objectui#12104). (objectui `206505c34`)
26+
- **patch** — An org install from the Marketplace catalog's "Your organization" strip, on a cloud-managed environment, now waits until the environment serves the installed package's app before… (objectui `a21ff9a95`)
27+
- **patch** — The console asks for recent activity only when the signed-in user may read it, and a failed read no longer shows as "No recent activity" (objectui#12081, item 8). (objectui `029bdaf45`)
28+
- **patch** — An app that serves the signed-in user no navigation now opens on an app-level empty state, not on the Studio home (objectui#12079). (objectui `417e24567`)
29+
- **patch** — The record chatter stores each reaction as the member's own `sys_comment_reaction` record, and stops writing the whole `sys_comment.reactions` column (objectui#12078; ruling A, am… (objectui `de302c731`)
30+
- **patch** — fix(console): a long flow screen or action parameter list keeps its Submit / Confirm on screen (objectui#12080) (objectui `4d0ff2331`)
31+
- **patch** — `ConnectionState` is re-exported from `@object-ui/types` instead of being declared a second time here (objectui#6349, batch 10). `@object-ui/data-objectstack` declared the same fi… (objectui `12ff25631`)
32+
- **patch** — `ConnectionState` is re-exported from `@object-ui/types` instead of being declared a second time here (objectui#6349, batch 10). `@object-ui/collaboration` declared the same five… (objectui `12ff25631`)
33+
- **patch** — Doc comments only. `UserDataAdapter` now carries the contract notes `@object-ui/app-shell` kept on its own copy of the interface: implementations must be safe to call concurrently… (objectui `1b2d0160f`)
34+
- **patch** — The props of the console's page header are declared as `ConsolePageHeaderProps` instead of `PageHeaderComponentProps` (objectui#6349, batch 8). `@object-ui/layout` publishes `Page… (objectui `d758f2f20`)
35+
- **patch** — Doc comment only. The `PageHeaderComponentProps` comment no longer says `@object-ui/app-shell` shares the name: the console's header props are now `ConsolePageHeaderProps`, so thi… (objectui `d758f2f20`)
36+
- **patch** — The props of the dashboard's read-only record drill drawer are declared as `DashboardRecordDetailDrawerProps` instead of `RecordDetailDrawerProps` (objectui#6349, batch 8). `@obje… (objectui `d758f2f20`)
37+
38+
⚠️ 1 of these carries a breaking change: 1 by the author's own breaking annotation in the changeset body — objectui declares no `major` inside a launch window (`scripts/check-changeset-no-major.mjs`). Each is marked **BREAKING** in the list above — read them before compiling the release record.
39+
40+
**In this console build, declared nowhere** — objectui merged 1 commit in this range with no `.changeset/*.md`. The code is inside the pin above and ships here, but nothing upstream declared it, so it appears in no objectui CHANGELOG and in no entry above. Listed by subject rather than counted, because a count cannot tell a dependency bump from a form-behaviour change (objectstack#6174); the upstream gate that would prevent this is objectui#3387.
41+
42+
- _(no changeset)_ fix(scripts): an injected tree hashes apart from an installed one, so a local Spec Main Shape Gate reproduction cannot leave verdicts a sibling worktree replays (objectui#12114) (… (objectui `a194b4e37`)
43+
44+
Clause-②: yes (widening: the html-page save gate and `os validate` read the SDUI manifest this console ships, and at this pin `element:repeater` and `element:number` publish the node-level `dataSource` binding as their only query input. A page source with `<element:repeater dataSource={{ object: 'account' }} />` and no flat `object` was refused with `missing-required-prop` against the previous manifest and passes against this one; a flat `object` / `filter` / `sort` / `limit` still passes, now with a non-gating `unknown-prop` warning.)
45+
46+
<!-- adr-0087: not-required (no-migration-prescription)
47+
This diff moves `.objectui-sha` and the artefacts that travel with it: this console
48+
changeset, the regenerated `sdui.manifest.json` and its record
49+
`scripts/sdui-manifest.record.json`, the re-recorded
50+
`packages/sdui-parser/objectui-lockstep.json` (its grammar region, diagnostic codes
51+
and containment predicate are unchanged across the range) and the re-measured pin
52+
citations in `packages/spec/src`, which carry their own `@objectstack/spec` patch
53+
changeset. It adds, removes or renames no ObjectStack-authorable key: no Zod schema,
54+
no spec declaration and no stored `sys_metadata` shape moves in it, so
55+
`objectstack migrate meta` has nothing here to rewrite, and this body carries no
56+
FROM/TO prescription of its own.
57+
The manifest is the one accept set that moves, and it moves in one direction. Its
58+
`element:repeater` row loses the `object` (required), `filter`, `sort` and `limit`
59+
inputs and its `element:number` row loses `object` and `filter` (objectui#12085,
60+
`ce991bd70`), the html tier's half of the retirement `@objectstack/spec` already
61+
carries with its own disposition (`element-flat-data-binding-retired`, #11509).
62+
Measured with `compile()` of `@objectstack/sdui-parser` against both manifests: a
63+
repeater bound through `dataSource` alone goes from `missing-required-prop` (error)
64+
to clean, and the flat keys go from clean to `unknown-prop` (warning, which the save
65+
gate does not refuse). Nothing that passed before is refused now.
66+
The range carries one declared-breaking objectui change, by its author's breaking
67+
annotation and not by a declared `major`: objectui#6349 batch 10 (`12ff25631`), the
68+
row type of `@object-ui/plugin-designer`'s `VersionHistory` timeline is declared as
69+
`VersionHistoryEntry` instead of `VersionEntry`. An objectui TypeScript type; no
70+
ObjectStack key. No commit subject in the range carries `!`. -->
71+
72+
objectui range: `20c6d351ad74...0df67f237c5a`
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
---
2+
'@objectstack/spec': patch
3+
---
4+
5+
The spec's objectui citations, and the shipped description text that names the `.objectui-sha` pin (the `FormField.span` describe and six migration-entry descriptions), are re-measured against the new console pin, objectui `0df67f237c5a`.
6+
7+
Clause-②: no
8+
9+
Every anchor was mapped through the objectui diff `20c6d351ad74..0df67f237c5a`: 293 paths over 21 commits, none deleted and one renamed (`resolveActionParams.ts`, which no record cites). Seventeen files a record cites changed on the hop, plus the `en` / `zh` / `de` packs (whose `calendar.configRequired` strings did not change): `ObjectGrid.tsx`, `ListView.tsx`, `ObjectCalendar.tsx`, `plugin-calendar/src/index.tsx`, `ObjectTimeline.tsx` and plugin-timeline's `renderer.tsx`, `ObjectKanban.tsx`, `KanbanBoardCore.tsx`, `KanbanImpl.tsx`, `plugin-kanban.mdx`, `MePermissionsProvider.tsx`, `PermissionProvider.tsx`, `record-details.tsx`, `basic/data-list.tsx`, `data-objectstack/src/index.ts`, `form.tsx` and plugin-view's `ObjectView.tsx`. Every cited line in them moved or held with its text byte-identical, and each record that cites one is re-pointed with a hop sentence that says by how much. The records that cite only byte-identical files gain a hop sentence that says so.
10+
11+
Three readings changed around a cited read, and each hop sentence says what it found:
12+
13+
- `basic/data-list.tsx`: the `element:repeater` registration no longer publishes the flat `object` / `filter` / `sort` / `limit` inputs; the node-level `dataSource` binding is its one published query input (objectui#12085). The renderer still reads the four as the binding's fallback. The row's two sentences that named the published inputs are rewritten where they stand.
14+
- `ObjectGrid.tsx`: the `delete` verdict the implicit bulk-delete is gated on now comes from the affordance-to-grant map's `rowDelete` row (objectui#12082). It still asks the managed-object policy and the object's effective API operations, now with the caller's delete grant beside them, so the `sys_api_key` reading holds. The `inlineEditable` verdict reads the same map's `listInlineEdit` row.
15+
- `ListView.tsx`: the calendar arm gained objectui#12081's fetch window. Its date-field reads are byte-identical and still declared-only, with no floor.
16+
17+
The re-read also corrects two anchors the previous hop left on the `object-tree` flat-config record: its opening still named the `case 'tree'` arm at its `47b1f0bb7` span, and its hop cited the `labelField` line one line low.
18+
19+
The six migration entries' corpus counts were re-taken with `git grep -o -F`, the method that reproduces every `20c6d351ad74` number. The corpus is now 8424 tracked files. Every token an entry counts as zero still reads zero (98 tokens). The controls moved with the corpus, for example `objectstack` from 18047 to 18248 and `timeout` from 1694 to 1705.
20+
21+
No key, default, enum member or export moves.

‎.objectui-sha‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
20c6d351ad74d2b14a93becdc134d51b91b2d2e6
1+
0df67f237c5ab46cbc65252c5f6bd05f2be44c48

‎content/docs/references/ui/view.mdx‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,7 @@ Column footer summary configuration
213213
| **required** | `boolean` | optional | Required override |
214214
| **hidden** | `boolean` | optional | Hidden override |
215215
| **colSpan** | `integer` | optional | Absolute column span (1-4). The renderer clamps it to the form grid's current column count, so the cell starts at a real column boundary at every surface width and never overflows (`colSpan: 4` in a 3-column grid renders as 3); a `colSpan` within the column count renders as authored, and `colSpan: 1` emits no span class at all. |
216-
| **span** | `Enum<'auto' \| 'full'>` | optional (default: `"auto"`) | Relative field width. 'auto' (default — omit it): the renderer sizes the field from its widget type × the current column count — at the pin this repo builds against (`.objectui-sha` = `20c6d351ad74`), only textarea, markdown, html, richtext and repeater resolve to the full column count (repeater reaches it through the wide `field:grid` widget it maps to). 'full': resolves to the form grid's full column count. How far down the container-query tiers that span is emitted is the renderer's, not this key's: at that same pin the renderer emits one clamped col-span class per multi-column tier (`@md:col-span-2 @2xl:col-span-3` for a 3-column grid), so the field takes the whole row at every multi-column tier, not just the widest. |
216+
| **span** | `Enum<'auto' \| 'full'>` | optional (default: `"auto"`) | Relative field width. 'auto' (default — omit it): the renderer sizes the field from its widget type × the current column count — at the pin this repo builds against (`.objectui-sha` = `0df67f237c5a`), only textarea, markdown, html, richtext and repeater resolve to the full column count (repeater reaches it through the wide `field:grid` widget it maps to). 'full': resolves to the form grid's full column count. How far down the container-query tiers that span is emitted is the renderer's, not this key's: at that same pin the renderer emits one clamped col-span class per multi-column tier (`@md:col-span-2 @2xl:col-span-3` for a 3-column grid), so the field takes the whole row at every multi-column tier, not just the widest. |
217217
| **widget** | `string` | optional | Custom widget/component name (overrides type-based inference) |
218218
| **language** | `string` | optional | Code editor language (for type=code) |
219219
| **keyField** | `{ field?: string; label?: string \| Record<string, string>; placeholder?: string \| Record<string, string>; helpText?: string \| Record<string, string>; … }` | optional | Key column config for record-typed fields |
@@ -343,7 +343,7 @@ Form-view select option — the object-field option shape minus the per-option `
343343
| **required** | `boolean` | optional | Required override |
344344
| **hidden** | `boolean` | optional | Hidden override |
345345
| **colSpan** | `integer` | optional | Absolute column span (1-4). The renderer clamps it to the form grid's current column count, so the cell starts at a real column boundary at every surface width and never overflows (`colSpan: 4` in a 3-column grid renders as 3); a `colSpan` within the column count renders as authored, and `colSpan: 1` emits no span class at all. |
346-
| **span** | `Enum<'auto' \| 'full'>` | optional (default: `"auto"`) | Relative field width. 'auto' (default — omit it): the renderer sizes the field from its widget type × the current column count — at the pin this repo builds against (`.objectui-sha` = `20c6d351ad74`), only textarea, markdown, html, richtext and repeater resolve to the full column count (repeater reaches it through the wide `field:grid` widget it maps to). 'full': resolves to the form grid's full column count. How far down the container-query tiers that span is emitted is the renderer's, not this key's: at that same pin the renderer emits one clamped col-span class per multi-column tier (`@md:col-span-2 @2xl:col-span-3` for a 3-column grid), so the field takes the whole row at every multi-column tier, not just the widest. |
346+
| **span** | `Enum<'auto' \| 'full'>` | optional (default: `"auto"`) | Relative field width. 'auto' (default — omit it): the renderer sizes the field from its widget type × the current column count — at the pin this repo builds against (`.objectui-sha` = `0df67f237c5a`), only textarea, markdown, html, richtext and repeater resolve to the full column count (repeater reaches it through the wide `field:grid` widget it maps to). 'full': resolves to the form grid's full column count. How far down the container-query tiers that span is emitted is the renderer's, not this key's: at that same pin the renderer emits one clamped col-span class per multi-column tier (`@md:col-span-2 @2xl:col-span-3` for a 3-column grid), so the field takes the whole row at every multi-column tier, not just the widest. |
347347
| **widget** | `string` | optional | Custom widget/component name (overrides type-based inference) |
348348
| **language** | `string` | optional | Code editor language (for type=code) |
349349
| **keyField** | `{ field?: string; label?: string \| Record<string, string>; placeholder?: string \| Record<string, string>; helpText?: string \| Record<string, string>; … }` | optional | Key column config for record-typed fields |

‎packages/sdui-parser/objectui-lockstep.json‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@
66
],
77
"objectui": {
88
"repo": "https://github.com/objectstack-ai/objectui.git",
9-
"rev": "20c6d351ad74d2b14a93becdc134d51b91b2d2e6",
10-
"revDate": "2026-10-09T22:57:23+00:00",
9+
"rev": "0df67f237c5ab46cbc65252c5f6bd05f2be44c48",
10+
"revDate": "2026-10-11T07:26:10+00:00",
1111
"source": "packages/sdui-parser/src",
1212
"files": [
1313
"packages/sdui-parser/src/body-dialect.ts",
@@ -21,7 +21,7 @@
2121
"packages/sdui-parser/src/validate.ts"
2222
]
2323
},
24-
"recordedAgainstPin": "20c6d351ad74d2b14a93becdc134d51b91b2d2e6",
24+
"recordedAgainstPin": "0df67f237c5ab46cbc65252c5f6bd05f2be44c48",
2525
"grammarRegion": {
2626
"file": "packages/sdui-parser/src/parse.ts",
2727
"delimiter": "/* ---------------------- the JS literal subset (#6614) ---------------------- */",

0 commit comments

Comments
 (0)