Commit 8832655
Fixes #21807
Clause-②: no
This moves the bundled Console's objectui pin from `9dfaca654311`
(#21772, PR #21800) to `0abd4f9f8769fc4c19ad2f96707684876f74c09f`, which
was objectui `main` at write time and is past `39a3e91fad`. The Console
now carries objectui#11636, the fix for objectui#11092: the screen-flow
runner names the flow by its served label, translated. That merge is
what #20318 waits on. The range also carries objectui#11637
(objectui#11170), objectui#11635 (objectui#11095), objectui#11624
(objectui#11396) and objectui#11640 (objectui#11628).
⛔ This is not a release act. Version PR #21352 is untouched, and no tag,
publish or Release was made.
## Range
- objectui `git ls-remote origin refs/heads/main` read
`0abd4f9f8769fc4c19ad2f96707684876f74c09f` at 2026-10-05T04:53:29Z, just
before the bump.
- Re-read at 05:37:53Z, it reads `59917c4b2` (objectui#11639, a served
view's toolbar change written inside `config`), one commit past the pin.
This PR does not carry it.
- The objectui clone is full (`--is-shallow-repository`: false). `git
merge-base --is-ancestor` exits 0 against `0abd4f9f8` for `39a3e91fa`,
`c4c506b9e`, `22ddcd5c5` and `1c2e2c46c`.
- `9dfaca654311..0abd4f9f8769` has 5 commits and 0 merges.
- objectui declared 5 changesets over the range: 3 release and 2 release
nothing. Every commit carries a changeset. None declares `major`, and
none carries the breaking annotation. The highest declared level is
`minor`, so the console changeset is `minor`. These counts come from the
bump's own digest and were re-read from the changeset blobs.
- **No commit subject in the range carries `!`.** `git log --format='%h
%s' 9dfaca654..0abd4f9f8 | grep -E '^[0-9a-f]+ [a-z]+(\([^)]*\))?!:'`
matches nothing (exit 1).
| objectui commit | landing | changeset | note |
|---|---|---|---|
| `1c2e2c46c` | objectui#11624 (objectui#11396):
`MasterDetailDetailConfig` is derived from the spec's `details` entry by
reference, member for member the same | release-nothing | moves the
manifest (below) |
| `22ddcd5c5` | objectui#11635 (objectui#11095): a dataset-bound KPI
tile's re-read on the data-invalidation bus gets a pin; tests and a doc
comment only | release-nothing | |
| `39a3e91fa` | objectui#11636 (objectui#11092): the flow runner names
the flow by `flows.FLOW.label`, then the served `flowLabel`, then the
API name | minor (`Clause-②: yes (widening)`) | smoke below; unlocks
#20318 |
| `c4c506b9e` | objectui#11637 (objectui#11170): one declaration of
per-type NODE SLOTS; `objectui check`, core `validateSchema`, the SDUI
parser's `validateTree` and the `kind:'html'` compile walk them | minor
(`Clause-②: yes (narrowing)`) | answered below |
| `0abd4f9f8` | objectui#11640 (objectui#11628): the External Datasource
panel unwraps the `{ success, data }` envelope | patch | smoke below |
## Declared-breaking entries and the ADR-0087 disposition
**There are none to dispose of.** No commit subject carries `!`, no
changeset declares `major` or the breaking annotation, and the bump
wrote no `adr-0087: TODO` placeholder. `check-adr-0087-registration
--base origin/main` reports "this PR adds no declared-breaking
changeset". `check-changeset-no-major --base origin/main` reports "This
diff introduces no `major` bump".
One entry narrows by its own declaration, so here is how this repo
answers it. **objectui#11170 (`c4c506b9e`, `Clause-②: yes
(narrowing)`)** widens the reach of four objectui validators: each now
judges nodes held in a renderer's declared slots, not only in
`children`. It adds, removes or renames no ObjectStack-authorable key,
and no Zod schema or stored `sys_metadata` shape moves. Its sdui-parser
half only takes effect when a manifest is built with `slotsFor`. This
repo's `scripts/gen-sdui-manifest-node.mjs` calls
`manifestFromConfigs(configs)` without that option, and the regenerated
`sdui.manifest.json` carries 0 `slots` keys. So the save gate's walk
does not move with this bump. The lockstep reading is in Acceptance
notes.
## What changed here (22 files, +255 / -93)
- **`.objectui-sha` and `.changeset/console-0abd4f9f8769.md`.**
`scripts/bump-objectui.sh 0abd4f9f8769fc4c19ad2f96707684876f74c09f
--no-commit` wrote both, with `OBJECTUI_ROOT` set to a read-only
objectui clone in the scratchpad. The range walked completely and the
level was auto-set to `minor`.
- The digest rendered objectui#11170's bullet as its first line, the
bare `**Clause-②: yes (narrowing)**`. That bullet is rewritten to say
what landed.
- A closing paragraph states the range has no declared-breaking entry
and names the release-nothing pair.
- **`sdui.manifest.json` and `scripts/sdui-manifest.record.json`.**
`node scripts/gen-sdui-manifest-node.mjs` regenerated them over the tree
that `pnpm objectui:build` built at the pin. It still has 107
components, and the sha256 moves from `6f921896ffac…` to
`f95d406a584e…`.
- One input moved: `object-master-detail-form`'s `details` gains `of:
"object"` and a description of the spec's closed entry (objectui#11396).
`"of": "object"` occurrences go from 12 to 13.
- The record moves its pin and `modulesRoot`. objectui's workspace
version stays 17.7.0, confirmed against the pin by `check-sdui-manifest
--require-objectui`.
- **`packages/sdui-parser/objectui-lockstep.json`.** `gen:sdui-lockstep`
re-recorded it from the clone at the pin. It records 214 grammar lines
(blob `0131f27cf86d`), 25 diagnostic codes and containment predicate
`76c18fb95d1f`, all unchanged, so no port is owed by that gate.
- **The 54 asserting pin citations in `packages/spec/src`, re-measured,
not restamped.**
- **Method.** The range changes 50 paths. Each asserting record's cited
objectui paths were resolved against the tree at `9dfaca654`. Ambiguous
bare names were disambiguated by the record's own directory. Each
`index.tsx` and `types.ts` cited is a `plugin-kanban`,
`plugin-dashboard`, `plugin-map`, `plugin-gantt`, `plugin-grid`,
`plugin-tree` or `plugin-timeline` file. None is
`plugin-form/src/index.tsx` or `sdui-parser/src/types.ts`, the two
same-named files the range touches.
- **Result.** No asserting record cites a changed path. So every cited
file is byte-identical across the hop, and every anchor held unmoved.
- **Records.** Each of the 41 hand-written records gains a dated
2026-10-05 hop sentence and keeps its earlier history.
- **Counts.** Three records carry a count, and each was re-taken by its
own method; all three read the same at `2e818d0b5`, `9dfaca654` and
`0abd4f9f8`:
- the `keyboardNavigation` hit lines: 15, against 3 for the
`schema.editable` control;
- `ObjectKanban.tsx`'s `quickAdd` / `onQuickAdd`: 2 each, against 11 for
`onCardClick`;
- the `ElementDataSourceGate` occurrences in the five `src/index.tsx`
shells: 0, 3, 3, 3 and 4.
- **Corpus counts.** The six migration entries' counts were re-taken
with `git grep -o -F`. That method first reproduced every `9dfaca654`
number: 7632 files, `objectstack` 17313, `@objectstack/spec` 7186,
`timeout` 1360, `useState` 2477, `TTL` 182, `tenant` 1318,
`RuntimeConfig` 293, `resourceLimits` 2, `window` 4193, `period` 238,
`interval` 195, `metrics` 401 and `Span` 508.
- The new readings are 7650 files, `objectstack` 17390,
`@objectstack/spec` 7209 and `useState` 2478. `window` reads 4194. Every
other control is unchanged.
- All 98 checked tokens (the export lists of
`plugin-lifecycle-advanced.zod.ts`, `tracing.zod.ts` and
`metrics.zod.ts`, plus every named key) read the same at both pins:
every zero is still zero, and `Span` / `SpanSchema` read 508 / 57.
- `packages/spec/src/migrations/registry.ts` was regenerated with
`gen:migration-registry`.
- **`.changeset/objectui-pin-citations-0abd4f9f8769.md`** is a
`@objectstack/spec` patch, because the `FormField.span` describe and six
migration descriptions name the pin.
`content/docs/references/ui/view.mdx` was regenerated by
`check:generated --fix`.
No example, test or gate needed adapting, and no code changed outside
generated records, citations and changesets.
## Console build (the local Console Pin Gate equivalent)
`turbo run build --filter=@objectstack/client...
--filter=@objectstack/spec...` and then `pnpm objectui:build` ran as one
command under the verify lock. That is a clean build: mode 3
shallow-cloned objectui at the pin into `.cache/objectui-0abd4f9f8769`.
Exit 0, 10m51s on the shared box. The build log reports:
- "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"**: the spec-injection check passes.
- "@objectstack/console dist ready (64232 KB) from
objectui@0abd4f9f8769".
`check:console-sha` and `check:console-injection` (self-test 67
assertions, then the dist check) exit 0 against that dist.
## Browser smoke: `examples/app-showcase` with the Console built at
`0abd4f9f8769`
The server ran `pnpm dev -- --fresh --ui --no-watch -p 41907` with
`OS_PORT=41907`, on its own ephemeral DB with the seeded admin. Headless
Chromium (`/opt/pw-browsers/chromium`) drove it, signing in through the
console's login form. Page errors, console errors and every 4xx/5xx
response were captured. Only the PIDs this run started were stopped.
**Flow label (objectui#11636 / objectui#11092).** The launch was Tasks
list, select a row, then the toolbar's "Reassign…"
(`showcase_bulk_reassign`, which targets the screen flow
`showcase_reassign_wizard`, label "Reassign Task").
| leg | trigger answer | runner header line | dialog title (accessible
name) | API name shown | completion toast |
|---|---|---|---|---|---|
| `en` | 200, `status: paused`, `flowLabel: "Reassign Task"` | `Reassign
Task` | `New Assignee` (the screen's own title) | no | `Flow "Reassign
Task" completed` |
| `zh-CN`, with a bundle entry `flows.showcase_reassign_wizard.label` |
200, `flowLabel: "Reassign Task"` | `重新分配任务` | `New Assignee` | no |
`流程「重新分配任务」已完成` |
- The resume answered 200 with `flowLabel` on both legs.
- **The showcase bundle declares no `flows` translations** (`git grep`
finds none), so the `zh-CN` leg needed one to exist. It was made by a
temporary local edit, as #21800's smoke did for `imageField`:
- `node scripts/ablation-replace.mjs --hold` added `flows: {
showcase_reassign_wizard: { label: '重新分配任务' } }` to the `zh-CN` block of
`examples/app-showcase/src/system/translations/index.ts`.
- The server booted with `--compile`.
- The file was restored at once with `--restore`. The tool reports the
blob back to HEAD's `f0517049b565` and `git diff HEAD` empty, and `git
status --porcelain` is empty.
- `GET /api/v1/i18n/translations/zh-CN` served the entry, and the
session's `html[lang]` read `zh-CN`.
- The showcase `dist/` was rebuilt afterwards (`turbo run build
--filter=@objectstack/example-showcase --force`), and the held string
has 0 hits in `dist/objectstack.json`. Nothing of the edit is in this
diff.
- **Verdict:** at this pin the runner header and the completion toast
name the flow by the active language's `flows.FLOW.label`, then the
served label, and never by the API name. The launcher button still reads
the ACTION's label ("Reassign…"), which is the action's own string and
not the flow's.
**The range's other landings.**
| landing | surface | observed |
|---|---|---|
| objectui#11640 (objectui#11628) | Setup →
`metadata/datasource/showcase_external` | The External Datasource panel
lists the remote tables `customers` (7 columns) and `orders` (7), each
with Import. "Refresh catalog" (`POST …/external/refresh-catalog` 200)
shows `snapshot 10/5/2026, 5:25:23 AM`. "Run validation" (`POST
…/external/validate` 200) renders "All 2 objects match the remote
schema." with `showcase_ext_customer` and `showcase_ext_order`, and no
render error. |
| objectui#11624 (objectui#11396) | `page/showcase_project_workspace`
(`object-master-detail-form`, `details: [{ title: 'Tasks', childObject:
'showcase_task', addLabel: 'Add task' }]`) | The master form draws its 6
fields. The Tasks section draws, and "Add task" opens the child's inline
form with 14 more fields (Title*, Assignee, Priority, …). 0 page errors.
|
| objectui#11637 (objectui#11170) | the three `kind:'html'` pages:
`showcase_start_here`, `showcase_capability_map`,
`showcase_command_center_jsx` | All three render (1563 / 2426 / 882
characters of text), with no compile or validation text and 0 page
errors. |
| objectui#11635 (objectui#11095) | `dashboard/showcase_ops_dashboard`,
`showcase_revenue_pulse`, `showcase_chart_gallery` | The ops tiles read
Active Projects 2, At-Risk (Red) 1, Awaiting Review 2 and Total Budget
1,090,000, matching #21710's REST cross-check. All three dashboards have
0 page errors. This landing changes no executable code (its changeset:
tests and one doc comment). An out-of-band REST `PATCH` of a task to
`in_review` did not re-read the open tile: it stayed 2 with 0 dataset
queries in 6s, and read 3 after a reload. That mutation never travels
the console's own invalidation bus, so this is no reading of
objectui#11095's pin. **NOT MEASURED** there. |
**Console messages across the run:** 0 page errors. The failed loads are
the pre-login `401 GET /api/v1/auth/get-session`, one `404` per page
load that the response listener did not attribute (`/favicon.ico`
answers 404 on this server, as #21800 recorded), and `404 GET
/api/v1/meta/datasource/showcase_external?state=draft`, the panel's
draft probe for a datasource that has no draft.
## Gates and tests (head `e40526e564`)
- `node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack
--commands` derived 127 commands from the 22-path diff, and all 127 were
run at `e40526e564` and exited 0. `--ran` reports "127 derived, 127 run,
0 NOT-MEASURED, 0 UNRUN", with every exit code recorded. The full
workspace build (`turbo run build --filter=!@objectstack/docs`) ran
first, so no dist-reading gate met a missing prerequisite.
- Also exit 0:
- `check:objectui-pin-citations --verify-anchors` with `OBJECTUI_ROOT`
at the pin: "54 asserting objectui pin citation(s) match .objectui-sha
(0abd4f9f8)", and "7 anchor content assertion(s) verified against
objectui at 0abd4f9f8".
- `check:objectui-bump` (20 assertions across 5 cases),
`check:sdui-lockstep`, `check-sdui-manifest --require-objectui`,
`check:console-sha`, `check:console-injection`.
- `check-adr-0087-registration --base origin/main` and
`check-changeset-no-major --base origin/main`.
- `@objectstack/spec check:generated`: all 15 artifacts current after
the `--fix`.
- `pnpm --filter @objectstack/spec exec vitest run`: 668 files, 19261
passed, 1 todo. `pnpm --filter @objectstack/spec typecheck`: exit 0.
- `@objectstack/sdui-parser` test (14 files, 225 passed) and typecheck:
exit 0.
- These suites read the regenerated manifest:
- `@objectstack/lint` (119 files, 5627 passed);
- `@objectstack/metadata-protocol`
`src/protocol.runtime-authoring-gate.test.ts` (70 passed);
- `@objectstack/cli` unit tier `src/utils/sdui-manifest.test.ts` and
`test/validate-build-gate-parity.test.ts` (2 files, 79 passed).
- The CLI integration tier is declared to CI.
- `eslint --no-inline-config --format json` on the 15 changed TS files:
15 files, 0 errors and 0 warnings.
- The lint population is `**/*.{ts,tsx,mts,cts,js,jsx,mjs,cjs}`
(`eslint.config.mjs:971`).
- The config enables no type-aware linting (`:328`), so this diff cannot
move a verdict on an untouched file.
- Repo-wide `pnpm lint` is left to CI.
## Acceptance notes
- **Lockstep, a reading and not a gate result.** objectui#11170 gives
objectui's `validateTree` a slot walk: `slotElements` plus the
`comp?.slots` loop in `packages/sdui-parser/src/validate.ts`. This
repo's port has none (`git grep -n slots packages/sdui-parser/src`: 0).
- The walk only fires for a manifest built with `slotsFor`, and this
repo's committed manifest carries no `slots`. So the save gate and
objectui's runtime parser still agree on that manifest.
- objectui's `kind:'html'` compile (`getJsxManifest`) is now built with
`slotsFor`. A slot-held node that fails validation could fail the
renderer's compile while this repo's save gate accepts it.
- `check:sdui-lockstep` compares the grammar region, the codes and the
containment predicate, so it cannot see a walk-depth change. That class
is outside its reach by its own header ("CANNOT see … WHEN a code fires"
beyond the predicate).
- Not measured through a public door here, so it is noted rather than
filed. Carrier: none.
- `main` moved three commits past this branch's base (#21810, #21808,
#21809). `git merge-tree --write-tree HEAD origin/main` is clean. Two of
them touch files this diff touches:
`api-methods-batch-conformance.test.ts` (test titles) and
`component.test.ts` (#21808 re-points a non-asserting anchor). The
merged tree still carries 1 and 6 citations at the new pin and 0 at the
old one. No merge was made; the merge queue rebuilds on the current
`main`.
- objectui `main` reached `59917c4b2` (objectui#11639) after the pin was
read. It is not in this range.
- Writes: one draft PR through the relay and the report comment on
#21807. No label, PR assignee, ready flag or auto-merge was written;
this dispatch's write budget names none of them.
---
_Generated by [Claude
Code](https://claude.ai/code/session_01VDtqoecgES7ScQYGbFVDRv)_
---------
Co-authored-by: Claude <noreply@anthropic.com>
1 parent 6fb7115 commit 8832655
22 files changed
Lines changed: 255 additions & 93 deletions
File tree
- .changeset
- content/docs/references/ui
- packages
- sdui-parser
- spec/src
- data
- kernel
- migrations
- entries/semantic
- ui
- scripts
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | | - | |
| 1 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
213 | 213 | | |
214 | 214 | | |
215 | 215 | | |
216 | | - | |
| 216 | + | |
217 | 217 | | |
218 | 218 | | |
219 | 219 | | |
| |||
343 | 343 | | |
344 | 344 | | |
345 | 345 | | |
346 | | - | |
| 346 | + | |
347 | 347 | | |
348 | 348 | | |
349 | 349 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
6 | 6 | | |
7 | 7 | | |
8 | 8 | | |
9 | | - | |
10 | | - | |
| 9 | + | |
| 10 | + | |
11 | 11 | | |
12 | 12 | | |
13 | 13 | | |
| |||
21 | 21 | | |
22 | 22 | | |
23 | 23 | | |
24 | | - | |
| 24 | + | |
25 | 25 | | |
26 | 26 | | |
27 | 27 | | |
| |||
Lines changed: 4 additions & 1 deletion
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
61 | 61 | | |
62 | 62 | | |
63 | 63 | | |
64 | | - | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
65 | 68 | | |
66 | 69 | | |
67 | 70 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
287 | 287 | | |
288 | 288 | | |
289 | 289 | | |
290 | | - | |
| 290 | + | |
| 291 | + | |
| 292 | + | |
| 293 | + | |
291 | 294 | | |
292 | 295 | | |
293 | 296 | | |
| |||
355 | 358 | | |
356 | 359 | | |
357 | 360 | | |
358 | | - | |
| 361 | + | |
| 362 | + | |
| 363 | + | |
| 364 | + | |
359 | 365 | | |
360 | 366 | | |
361 | 367 | | |
| |||
417 | 423 | | |
418 | 424 | | |
419 | 425 | | |
420 | | - | |
| 426 | + | |
| 427 | + | |
| 428 | + | |
| 429 | + | |
421 | 430 | | |
422 | 431 | | |
423 | 432 | | |
| |||
467 | 476 | | |
468 | 477 | | |
469 | 478 | | |
470 | | - | |
| 479 | + | |
| 480 | + | |
| 481 | + | |
| 482 | + | |
471 | 483 | | |
472 | 484 | | |
473 | 485 | | |
| |||
Lines changed: 3 additions & 3 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
52 | 52 | | |
53 | 53 | | |
54 | 54 | | |
55 | | - | |
| 55 | + | |
56 | 56 | | |
57 | | - | |
| 57 | + | |
58 | 58 | | |
59 | 59 | | |
60 | 60 | | |
61 | | - | |
| 61 | + | |
62 | 62 | | |
63 | 63 | | |
64 | 64 | | |
| |||
Lines changed: 3 additions & 3 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
46 | 46 | | |
47 | 47 | | |
48 | 48 | | |
49 | | - | |
| 49 | + | |
50 | 50 | | |
51 | | - | |
52 | | - | |
| 51 | + | |
| 52 | + | |
53 | 53 | | |
54 | 54 | | |
55 | 55 | | |
| |||
Lines changed: 3 additions & 3 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
47 | 47 | | |
48 | 48 | | |
49 | 49 | | |
50 | | - | |
| 50 | + | |
51 | 51 | | |
52 | | - | |
53 | | - | |
| 52 | + | |
| 53 | + | |
54 | 54 | | |
55 | 55 | | |
56 | 56 | | |
| |||
0 commit comments