diff --git a/.changeset/20029-pin-bump-describe-correction.md b/.changeset/20029-pin-bump-describe-correction.md new file mode 100644 index 00000000000..3aec0183ce0 --- /dev/null +++ b/.changeset/20029-pin-bump-describe-correction.md @@ -0,0 +1,11 @@ +--- +'@objectstack/spec': patch +--- + +One published `describe` sentence that dates itself to the `.objectui-sha` pin is re-pointed to the pin this release builds against, objectui `f8a9d0fb0596`, after being re-read there (#20029). + +`Clause-②: no` + +- `FormField.span`: the `'auto'` clause says that at the pin this repo builds against, only textarea, markdown, html, richtext and repeater resolve to the full column count. It named `62597c588`. Re-read at `f8a9d0fb0596`, the claim still holds: `plugin-form`'s `autoLayout.ts` (`WIDE_FIELD_TYPES`, `resolveColSpan`) is byte-identical, and `form.tsx` changed only in its registration's input list (a `children` slot input), with `spanLadderFor` byte-identical, so `'full'` is still the whole row at every multi-column tier. Only the pin the sentence names moves. + +No key, default, enum member or export moves: the same authored metadata is accepted and refused as before, and `content/docs/references/ui/view.mdx` is regenerated from the sentence. diff --git a/.changeset/console-f8a9d0fb0596.md b/.changeset/console-f8a9d0fb0596.md new file mode 100644 index 00000000000..4f8bc0550a7 --- /dev/null +++ b/.changeset/console-f8a9d0fb0596.md @@ -0,0 +1,122 @@ +--- +"@objectstack/console": minor +--- + +Console (objectui) refreshed to `f8a9d0fb0596`. Frontend changes in this range: + +Derived from the changesets objectui declared over the range — 86 releasing of 91 changesets added across 92 non-merge commits; omitted: 5 release-nothing changesets, 3 commits carrying no changeset (they ship no package code). + +- **minor** — `aggregate()` reads the analytics answer in ONE spelling: `rows` on the `AnalyticsResult` that `client.analytics.query` resolves to (objectui#7028). The `{ success, data: { rows }… (objectui `512bc9049`) +- **minor** — **BREAKING** — Retire `carousel` from `AIRecommendationsSchema.layout` and from the `ai-recommendations` designer enum (objectui#10330, ADR-0049 enforce-or-remove). (objectui `f98eddf63`) +- **minor** — **BREAKING** — feat(types)!: `DetailViewFieldSchema.options` is the spec's authoring `SelectOptionSchema` (objectui#10296) (objectui `6096f20b3`) +- **minor** — Honour `filter` and the platform row ceiling on a tree's inline (`provider: 'value'`) data (objectui#9136) — the fourth surface of the objectui#8769 repair, after objectui#9061 po… (objectui `9c08dc6b2`) +- **minor** — feat(core): export `declaredNameField`, the one spelling of the ADR-0079 declared name pointer (objectui#9436) (objectui `ba0b61a60`) +- **minor** — fix(plugin-detail): `DetailView`'s header and the `record:details` H1 dedupe rank the declared `nameField` above `titleFormat`, the ADR-0079 order (objectui `ba0b61a60`) +- **minor** — fix(components): the record page H1 ranks the declared `nameField` above `titleFormat`, the ADR-0079 order (objectui `ba0b61a60`) +- **minor** — The grid summary footer and the dashboard metric tile take a currency amount's decimal places from the currency, never from `scale`, and the field designer no longer offers `Scale… (objectui `0651e7ab4`) +- **minor** — fix(react): a data object in a node's `properties` / `props` bag reaches the renderer whole, even when it carries a `source` field (objectui `2b5f509bf`) +- **minor** — `CalendarSchema.defaultValue` / `.value` cross the JSON/TS boundary once (objectui#10293, objectui#7759 ruling D1-(iii)). (objectui `8c10f4f71`) +- **minor** — fix(core): a dashboard `dateRange` that omits `defaultRange` now takes the spec's declared default preset (objectui#10339). (objectui `86982ace0`) +- **minor** — **BREAKING** — feat(types): `TooltipSchema.content` is text only, on both faces (objectui#10295) (objectui `90dac98fa`) +- **minor** — fix(auth,app-shell,console): a browser that changes hands no longer keeps the previous account's UI language (objectui `b57107d46`) +- **minor** — **BREAKING** — `UIEventHandler` and `EventableSchema` are RETIRED from `@object-ui/types`, and `APISchema` loses its `EventableSchema` arm (objectui#6497, ADR-0049 enforce-or-remo… (objectui `cb55718a9`) +- **minor** — **BREAKING** — `record:related_list`'s top-level `filter` is declared as the protocol's rule array on the authoring face, not as `any` (objectui#10199). (objectui `e3ea4f97b`) +- **minor** — On `tree` and `chart` list views, the toolbar's Filter control and the `UserFilters` chips now narrow the view, and on a `gantt` list view the toolbar's Search box now narrows the… (objectui `af243c1fd`) +- **minor** — Refuse the four remaining function-valued mirror keys by name (objectui#7759 group E, the objectui#6124 shape). (objectui `d05fe17f6`) +- **minor** — `ObjectView` opens a Cmd/Ctrl/middle-clicked row in a new browser tab (objectui#9806). (objectui `687353f4e`) +- **minor** — `CurrencyField` takes its fraction digits from the currency, never from the field-level `precision` (objectui#10276). (objectui `31938f01d`) +- **minor** — `object-form`: one rule for section divider rows on the default, modal and drawer layouts, and there a section's own settings apply whether or not it has a heading (objectui#9849… (objectui `8813335bd`) +- **minor** — `CommandItem` and `CommandGroup` are now named exports of `@object-ui/types` itself, not only of `@object-ui/types/form` (objectui#9526). They are the element types of `CommandSch… (objectui `3be720ef8`) +- **minor** — **BREAKING** — BREAKING (`@object-ui/types`, `@object-ui/plugin-chatbot`): the authoring `ChatToolInvocation.state` union sheds the AI SDK's three runtime-only approval states — `approval-reques… (objectui `b46c58f34`) +- **minor** — **BREAKING** — `RecordRelatedListRenderer`'s props type refuses a misspelled key again (objectui#9963). (objectui `905913c0e`) +- **minor** — Fix: a `dependsOn` field is no longer permanently gated when it is edited inline on a record's detail page. (objectui `a33803796`) +- **minor** — fix(core): the shared date path refuses a calendar day that does not exist, with the marker it already renders for an unparsable value (objectui `ad694ac3d`) +- **minor** — fix(plugin-kanban): a kanban lane matches records by its `id` only, never by its `title` (objectui `7a564e004`) +- **minor** — feat(plugin-detail): row caps on `record:activity`, `record:history`, `record:chatter` and `record:discussion` admit only a positive integer number, and a refused one warns (objectui `879ecac78`) +- **minor** — feat(types): `slider` and `tooltip` single-or-list keys follow their read sites (objectui#10280, objectui#7759 group B) (objectui `f3f4e4c9a`) +- **minor** — **BREAKING** — `NamedListView` (one entry of `ObjectViewSchema.listViews`) retires sixteen members on its TypeScript authoring face (objectui#7924). Each is now a `?: never` tombs… (objectui `aa083cd69`) +- **minor** — feat(types): `AppComponentSchema`, `DashboardComponentSchema` and `PageNodeSchema` take the spec by reference, like their zod mirrors (objectui `1bbaa163a`) +- **minor** — **BREAKING: the unimplemented async export-job path is removed from `@object-ui/types` and `@object-ui/components`** (objectui `8b1f06619`) +- **minor** — fix(sdui-parser,components,layout,types): containment is the declared `children` slot, not `isContainer` (objectui#9910) (objectui `5ea623eab`) +- **minor** — feat(react): an action's `params` values are templates, evaluated where `properties` are (objectui `95bf1287a`) +- **minor** — An action param that declares the spec's `carryOver` is shown read-only and submitted verbatim (objectui#6246) (objectui `06b82b8c3`) +- **minor** — A date-only value now renders the calendar day it names, west of UTC, at four more places (objectui#10183). (objectui `4ab4f1ba2`) +- **minor** — `ObjectTreeSchema.filter` is declared on both faces, in the shape objectui#9309 settled for `ObjectGallerySchema.filter`: `QueryParams['$filter']` by indexed access on the TS inte… (objectui `d16d0e977`) +- **minor** — `object-grid`'s `rowActions` now NARROWS the row kebab's generic Edit / Delete inside the `operations` ceiling — the second half of the ruling whose first half ("`operations` is t… (objectui `185079bdf`) +- **minor** — Dates and numbers across the console and the plugins format in the session's display locale instead of the machine's (objectui#9909). (objectui `a78cd378c`) +- **patch** — fix(fields): a lookup's candidate queries expand the reference columns they display (objectui `65f1e8dc6`) +- **patch** — fix(plugin-list): a list view whose every authored column is denied by field-level security still sends a `$select` (objectui `fb7f38bdf`) +- **patch** — fix(plugin-detail): feed diagnostics name the block that carries the bad value (objectui `462bafb9e`) +- **patch** — docs(types): the `WidgetInput` divergence docblock lists the serializer's key list with `of` (objectui#10337) (objectui `a5b08c9ce`) +- **patch** — fix(console): `FormPage`'s required `*` no longer lands in the control's accessible name (objectui `069ce12b4`) +- **patch** — fix(charts): a cartesian chart that declares no series at all now says so instead of drawing an empty frame (objectui#4695) (objectui `f82f85756`) +- **patch** — fix(plugin-list): gallery cards now pass a field's declared `scale` to the shared cell renderer, so a number or percent field declaring `scale` renders padded (`25.00%`) exactly a… (objectui `a883ec21a`) +- **patch** — Gantt: a row that is not an object is now refused instead of drawn as an empty, unlabelled row (objectui#7364). `items: [0]`, `items: ['x']`, `items: [true]` and `items: [[]]` use… (objectui `0b6b295a1`) +- **patch** — fix(plugin-form,plugin-list,plugin-view,react): read `SchemaRendererContext` as declared, not through a cast to `any` (objectui#7209) (objectui `3ed3eec08`) +- **patch** — fix(i18n): a translation bundle with no field label is recognised as a spec payload (objectui#10235) (objectui `dc666f70d`) +- **patch** — An `action:icon` now runs an action it receives with `autoTrigger` set, the same way `action:button` and `action:menu` do (objectui#10274). (objectui `cff4b7754`) +- **patch** — Two display-locale faces now follow the session's display locale (objectui#10232). (objectui `bb5d4eea7`) +- **patch** — fix(app-shell): the metadata form's machine-name chip is judged on the field's untranslated source label, so it shows alike in every locale (objectui#8231) (objectui `78b572f60`) +- **patch** — fix(fields): a failed image upload is reported in `ImageField`, not swallowed (objectui `1f8ef0a89`) +- **patch** — fix(plugin-charts): the legend swatch carries its series colour as a custom property (objectui `a9f34df28`) +- **patch** — Saving a view's config no longer turns the view read-only (objectui#10210). (objectui `baf98cde0`) +- **patch** — fix(plugin-view): a read-only view's menus no longer open empty or on a leading separator (objectui `b07de29d1`) +- **patch** — The two declared display-locale contracts now each name the caller they govern, and each points at the other (objectui#10098). This is documentation only: no module's behaviour mo… (objectui `8cedb0dba`) +- **patch** — **The stray-`groupBy` kanban refusal no longer tells an author their view "never came through the validated path".** (objectui `89bb77a11`) +- **patch** — The package dialog judges a version with the installed `@objectstack/spec`'s own `ManifestSchema` version field instead of a hand-copied regex, so it accepts exactly what the spec… (objectui `c84221daa`) +- **patch** — fix(app-shell): the Studio dataset-filter inspector stores a `between` range as the spec's `$between`, with both bounds required (objectui#10062) (objectui `856bf0f74`) +- **patch** — A flow launched from an action that ends with `outcome: 'refused'` without ever pausing at a screen now shows its refusal instead of reporting success (objectui#9973). (objectui `7616d8935`) +- **patch** — fix(plugin-dashboard): a field's `format` is read as a date pattern only on a `date` / `datetime` field (objectui `e2bd3e400`) +- **patch** — fix(plugin-designer): the Navigation Designer has an entry for the spec's `doc` navigation item type (objectui `1dbb9933c`) +- **patch** — A master-detail form's child grid no longer offers a cell the CALLER may read but not edit (objectui#10163). (objectui `6099dd870`) +- **patch** — **Behaviour change:** an action whose own declared `visible` gate hides it is no longer run by `autoTrigger`, and the refusal is reported instead of swallowed (objectui#4191). (objectui `978507b9a`) +- **patch** — fix(plugin-detail): a related list's row fetch drops a column the principal cannot read once the permission answer has loaded (objectui `5f44cc6f4`) +- **patch** — The published `ViewNavigationConfig` docblock no longer teaches the retired `navigation.view` key (objectui#9938). Its example of `mode` being optional on the authoring side used… (objectui `32bf2d6f6`) +- **patch** — feat(types): `SliderFieldMetadata` declares `step` (objectui `5f00ff491`) +- **patch** — `object-grid`'s `rowActions` now carries a describe, and the `ObjectGridSchema.operations` / `rowActions` docblocks state how the two keys combine: `operations` is the CEILING ove… (objectui `087981282`) +- **patch** — fix(plugin-form): `DrawerForm` no longer paints an editable form before the record it edits has loaded (objectui `88a4ef616`) +- **patch** — fix(plugin-kanban): `object-kanban` honours the binding's `dataSource.sort` (objectui `c9e073ac8`) +- **patch** — fix(plugin-detail,plugin-grid): the record-grained write verdict is forgotten when its record changes, and the row kebab's memo is per principal (objectui#10184). (objectui `fa5fbd9dc`) +- **patch** — fix(plugin-form): `customFields` merges on the drawer and modal arms too (objectui `142fdfd87`) +- **patch** — On a `gantt` list view, the toolbar's Filter control and the `UserFilters` chips now narrow the chart (objectui#10037). (objectui `0427036f5`) +- **patch** — fix(app-shell): the object page no longer re-issues the identical list query on re-renders that change nothing (objectui `5b6d177b2`) +- **patch** — `ui:menubar` now draws an item's authored `icon`, and walks submenus to any depth (objectui#6326). (objectui `d7de5348a`) +- **patch** — The `dateField` alias refusal that objectui#8355 adds to a calendar binding quotes only the first clause of the calendar refusal screen, "Calendar configuration required": the cla… (objectui `6f96fca95`) +- **patch** — `useRecordSearch` no longer keys its search effect on the identity of the caller-supplied `getDisplayName` option (objectui#10044). (objectui `0aacecc08`) +- **patch** — fix(fields): a declared `scale` above 100 no longer crashes the number cell or a grid's computed column (#10071) (objectui `0361d6bd4`) +- **patch** — `record:activity`'s landmark is named after the heading it shows, not "Discussion" (objectui#9998). (objectui `6358a2d59`) +- **patch** — `object-form`: a drawer section that declares `collapsed: true` can be opened again. The drawer now resolves `collapsed` / `collapsible` the way the default layout does (objectui#… (objectui `58d65c50d`) +- **patch** — fix(app-shell): the screen-flow runner draws the app's translated flow copy (objectui#5920) (objectui `5d895c13c`) +- **patch** — A `record:line_items` grid no longer offers a cell the CALLER may read but not edit (objectui#10163). (objectui `b809375ac`) +- **patch** — fix(mobile): `usePullToRefresh` arms on a host that mounts after the first render, and one pull has one owner (objectui#10105) (objectui `6ce001a35`) +- **patch** — A wizard no longer writes a record without a file whose upload was still running when the user pressed Next (objectui#10180). (objectui `a04b06db5`) +- **patch** — `ElementDataSourceGate` now reports a saved view's refused row cap on the renderer path (objectui#10015). (objectui `7b10befe6`) +- **patch** — Full-page search results now read correctly in Russian and Arabic at every count (objectui#10024). (objectui `a507334d2`) + +⚠️ 9 of these carry a breaking change: 9 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. + +**In this console build, declared nowhere** — objectui merged 3 commits in this range with no `.changeset/*.md`. The code is inside the pin above and ships here, but nothing upstream declared them, so they appear 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. + +- _(no changeset)_ docs(changeset): the 9242 changeset says the stray-groupBy refusal covers the list-view route only (#10364) (objectui `f8a9d0fb0`) +- _(no changeset)_ docs(changeset): the manifest serializer forwards seven keys per input, not six (#10318) (objectui `c7ab34836`) +- _(no changeset)_ fix(ci): spec-main shape gate re-points the injected spec's declared dependencies (#10238) (objectui `f4f1f4552`) + + + +objectui range: `62597c588072...f8a9d0fb0596` diff --git a/.objectui-sha b/.objectui-sha index 010114f9c1a..edf15bbbc13 100644 --- a/.objectui-sha +++ b/.objectui-sha @@ -1 +1 @@ -62597c588072636e9c30ea35b3d89b1e46fd765d +f8a9d0fb0596f4521076628e2bbfe27e6ce67d52 diff --git a/content/docs/references/ui/view.mdx b/content/docs/references/ui/view.mdx index bb5d974e18f..32431716657 100644 --- a/content/docs/references/ui/view.mdx +++ b/content/docs/references/ui/view.mdx @@ -199,7 +199,7 @@ Column footer summary configuration | **required** | `boolean` | optional | Required override | | **hidden** | `boolean` | optional | Hidden override | | **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. | -| **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` = `62597c588`), 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. | +| **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` = `f8a9d0fb0596`), 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. | | **widget** | `string` | optional | Custom widget/component name (overrides type-based inference) | | **language** | `string` | optional | Code editor language (for type=code) | | **keyField** | `{ field?: string; label?: string \| Record; placeholder?: string \| Record; helpText?: string \| Record; … }` | optional | Key column config for record-typed fields | @@ -364,7 +364,7 @@ View filter rule | **required** | `boolean` | optional | Required override | | **hidden** | `boolean` | optional | Hidden override | | **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. | -| **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` = `62597c588`), 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. | +| **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` = `f8a9d0fb0596`), 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. | | **widget** | `string` | optional | Custom widget/component name (overrides type-based inference) | | **language** | `string` | optional | Code editor language (for type=code) | | **keyField** | `{ field?: string; label?: string \| Record; placeholder?: string \| Record; helpText?: string \| Record; … }` | optional | Key column config for record-typed fields | diff --git a/packages/sdui-parser/objectui-lockstep.json b/packages/sdui-parser/objectui-lockstep.json index 5c72e4dcf8e..e1110df6dc4 100644 --- a/packages/sdui-parser/objectui-lockstep.json +++ b/packages/sdui-parser/objectui-lockstep.json @@ -6,8 +6,8 @@ ], "objectui": { "repo": "https://github.com/objectstack-ai/objectui.git", - "rev": "62597c588072636e9c30ea35b3d89b1e46fd765d", - "revDate": "2026-09-23T02:43:52+00:00", + "rev": "f8a9d0fb0596f4521076628e2bbfe27e6ce67d52", + "revDate": "2026-09-24T20:41:09+00:00", "source": "packages/sdui-parser/src", "files": [ "packages/sdui-parser/src/body-dialect.ts", @@ -22,7 +22,7 @@ "packages/sdui-parser/src/validate.ts" ] }, - "recordedAgainstPin": "62597c588072636e9c30ea35b3d89b1e46fd765d", + "recordedAgainstPin": "f8a9d0fb0596f4521076628e2bbfe27e6ce67d52", "grammarRegion": { "file": "packages/sdui-parser/src/parse.ts", "delimiter": "/* ---------------------- the JS literal subset (#6614) ---------------------- */", diff --git a/packages/spec/src/data/api-methods-batch-conformance.test.ts b/packages/spec/src/data/api-methods-batch-conformance.test.ts index 3c8541cca6d..d045bd13f6f 100644 --- a/packages/spec/src/data/api-methods-batch-conformance.test.ts +++ b/packages/spec/src/data/api-methods-batch-conformance.test.ts @@ -61,17 +61,22 @@ const SINGLE_RECORD_WRITE_ONLY: Record = { // `revoked` on ONE key. The multi-select surface this rule protects does not // exist for API keys, and the shape a future one would take does not need // `bulk` either — both read off the console build this release pins - // (`.objectui-sha` = `62597c588`, `packages/plugin-grid`; re-measured at - // that pin, 2026-09-23 — previously measured at `87af769e9`, `53ded82bf`, - // `a472b0716`, `00d3f09c5`, `67dadd602`, before that at `d8ec8d6d4`, - // `9602dc820`, `190fbd01d`, `9a3daf8d3`, originally at `6314e87f2`. - // `ObjectGrid.tsx` changed again across the move off `87af769e9` (119 - // insertions, 9 deletions), and THIS time the selection block's CONTENT + // (`.objectui-sha` = `f8a9d0fb0`, `packages/plugin-grid`; re-measured at + // that pin, 2026-09-24 — previously measured at `62597c588`, `87af769e9`, + // `53ded82bf`, `a472b0716`, `00d3f09c5`, `67dadd602`, before that at + // `d8ec8d6d4`, `9602dc820`, `190fbd01d`, `9a3daf8d3`, originally at + // `6314e87f2`. On the hop off `62597c588`, `ObjectGrid.tsx` changed again + // (18 insertions, 5 deletions: objectui#10083's `rowActionsDeclared` row-menu + // signal and objectui#9909's currency display locale), none of it inside the + // selection block, which only MOVED: `ObjectGrid.tsx:4032-4059` here, still + // hashing to `c88443302d40c2db739ddb235470bafa29056e2e`, re-READ with the + // same reading below. `ObjectGrid.tsx` changed across the move off + // `87af769e9` too (119 insertions, 9 deletions), and THAT time the selection block's CONTENT // moved, not only its position: objectui#10218 (`62597c588` itself) // rewrote the `selection` arm to "presence enables; an explicit off wins", // so an authored `selection` object with no `type` now selects // (`DEFAULT_SELECTION_TYPE`, `'multiple'`) where it used to fall through. - // The block is `ObjectGrid.tsx:4024-4051` here — `3940-3955` at `87af769e9`, + // The block was `ObjectGrid.tsx:4024-4051` at `62597c588` — `3940-3955` at `87af769e9`, // `3538-3553` at `53ded82bf` — and no longer hashes to the // `6133933199230670e29d8c7f51c558d86a0af1d2` the previous three hops // recorded (`c88443302d40c2db739ddb235470bafa29056e2e` now). Re-READ, the @@ -86,7 +91,7 @@ const SINGLE_RECORD_WRITE_ONLY: Record = { // numbers — arithmetic on a wrong anchor produces a fresh-looking span still // describing the wrong function. The second claim, // `hooks/useBulkExecutor.ts:298-303`, sits in a file that is byte-identical - // to `87af769e9` on this hop (it last changed on the hop off `53ded82bf`, 36 + // to `62597c588` and to `87af769e9` on the last two hops (it last changed on the hop off `53ded82bf`, 36 // insertions, 22 deletions, when it was re-READ rather than carried on file // identity): the six lines hash to // `01083348330f10a201cdf1078b4c21c236402b6a` at every one of those pins and diff --git a/packages/spec/src/kernel/functional-completeness.ts b/packages/spec/src/kernel/functional-completeness.ts index 1ed119bb7fb..7142de4432b 100644 --- a/packages/spec/src/kernel/functional-completeness.ts +++ b/packages/spec/src/kernel/functional-completeness.ts @@ -283,16 +283,23 @@ export function checkFieldCompleteness(def: unknown): CompletenessFinding[] { * English sentence. So the loss is total rather than partial — every * record, on every object — and the author is told at render time as well * as here. Both reads hold at the pin this repo builds against - * (`.objectui-sha` = `62597c588`, re-read 2026-09-23: `ListView.tsx` is - * byte-identical to `87af769e9`, and `ObjectCalendar.tsx` changed there only - * in its copy), so this describes the console this repo SHIPS and not only + * (`.objectui-sha` = `f8a9d0fb0`, re-read 2026-09-24: `ObjectCalendar.tsx` + * is byte-identical to `62597c588`, where it had changed only in its copy; + * `ListView.tsx` changed on this hop — objectui#10275's `$select` and the + * self-querying `gantt` / `tree` / `chart` filter and search of + * objectui#10037 / objectui#10250 — with its `case 'calendar'` arm + * untouched), so this describes the console this repo SHIPS and not only * objectui's head. * This repo already records the same deletion one door over: the #13817 * check in `../ui/view.zod.ts` names objectui#7029 as its runtime half. * - `gantt` → NO fallback, and no silence [#19630]. Measured at the pin - * this repo builds against (`.objectui-sha` = `62597c588`; `ListView.tsx` - * and `ObjectGantt.tsx` are byte-identical to `87af769e9`, where this was - * first measured, re-checked 2026-09-23). ① `ListView.tsx`'s + * this repo builds against (`.objectui-sha` = `f8a9d0fb0`, re-read + * 2026-09-24; first measured at `87af769e9`, and both files were + * byte-identical to it at `62597c588`). On this hop `ListView.tsx`'s + * `case 'gantt'` gained the EFFECTIVE `filter` and the toolbar `search` / + * `searchableFields` (objectui#10037, objectui#10250) and `ObjectGantt.tsx` + * sends them as `$search` / `$searchFields`; neither touches the date + * bindings or the config gate read below. ① `ListView.tsx`'s * `case 'gantt'` spreads `startDateField` / `endDateField` / `titleField` * only when the view DECLARED them — the `'start_date'` / `'end_date'` * floors were deleted by objectui#7070, and the `'progress'` / @@ -305,7 +312,8 @@ export function checkFieldCompleteness(def: unknown): CompletenessFinding[] { * requires. So the view does not draw a blank chart: it refuses, by name. * - `timeline` → date axis: NO fallback [#19630]; title: `titleField || 'name'`, * which still stands. Measured at the same pin (`.objectui-sha` = - * `62597c588`; `ObjectTimeline.tsx` is byte-identical to `87af769e9` too). + * `f8a9d0fb0`; `ObjectTimeline.tsx` is byte-identical to `87af769e9` and + * `62597c588` too, and `ListView.tsx`'s `case 'timeline'` did not move). * ① `ListView.tsx`'s `case 'timeline'` resolves the axis * through `resolveTimelineDateBinding` and spreads it only when one was * declared — the `startDateField || 'created_at'` floor was deleted by @@ -321,9 +329,11 @@ export function checkFieldCompleteness(def: unknown): CompletenessFinding[] { * block does render; the warning still fires there, because the block the * view TYPE names is the one that is missing. Unchanged by this row. * - `map` → NO fallback, and no silence [#19630]. Measured at the same - * pin (`.objectui-sha` = `62597c588`; `ObjectMap.tsx` changed on the hop - * from `87af769e9` only in a docblock and a dev-warning string, objectui - * `2252653d0`, and every read named below re-reads unchanged), both faces + * pin (`.objectui-sha` = `f8a9d0fb0`; `ObjectMap.tsx` is byte-identical to + * `62597c588`, and changed on the hop before that, from `87af769e9`, only + * in a docblock and a dev-warning string, objectui `2252653d0`; + * `ListView.tsx`'s `case 'map'` did not move, and every read named below + * re-reads unchanged), both faces * moved together in * objectui#8169. ① `ListView.tsx`'s `case 'map'` forwards * `resolveListMapConfig(schema)` and carries no `locationField || 'location'` diff --git a/packages/spec/src/migrations/entries/semantic/18.kernel-health-check-and-hot-reload-durations-unit-in-key.ts b/packages/spec/src/migrations/entries/semantic/18.kernel-health-check-and-hot-reload-durations-unit-in-key.ts index fadbe60609e..45e408cc326 100644 --- a/packages/spec/src/migrations/entries/semantic/18.kernel-health-check-and-hot-reload-durations-unit-in-key.ts +++ b/packages/spec/src/migrations/entries/semantic/18.kernel-health-check-and-hot-reload-durations-unit-in-key.ts @@ -45,12 +45,13 @@ export const entry: SemanticMigration = { + 'the audience that does not parse. Measured on 884e8347d: the only in-repo readers are ' + 'packages/core/src/health-monitor.ts and packages/core/src/hot-reload.ts, both moved in ' + 'this same change; and the pinned objectui checkout — the pin this repo builds ' - + 'against, `.objectui-sha` = `62597c588072636e9c30ea35b3d89b1e46fd765d` — names ' + + 'against, `.objectui-sha` = `f8a9d0fb0596f4521076628e2bbfe27e6ce67d52` — names ' + 'neither def and neither key: all thirteen exports of plugin-lifecycle-advanced.zod.ts and ' - + 'the string debounceDelay each occur 0 times across its 8303 tracked files, against lit ' + + 'the string debounceDelay each occur 0 times across its 8512 tracked files (0 across the ' + + '8303 at 62597c588 too), against lit ' + 'controls objectstack 12966 and @objectstack/spec 4997 on the same corpus at 87af769e9, ' - + 'which re-count at this pin to 13125 and 5043 respectively (git grep -o -F, the method ' - + 'that reproduces every earlier count).', + + 'which re-count to 13125 and 5043 respectively at 62597c588 and to 13347 and 5123 at ' + + 'this pin (git grep -o -F, the method that reproduces every earlier count).', acceptanceCriteria: 'Every producer and reader of a PluginHealthCheck spells intervalMs and timeoutMs, and every ' + 'one of a HotReloadConfig spells debounceDelayMs — concretely ' diff --git a/packages/spec/src/migrations/entries/semantic/18.kernel-runtime-config-timeout-unit-in-key.ts b/packages/spec/src/migrations/entries/semantic/18.kernel-runtime-config-timeout-unit-in-key.ts index 7feb9519649..beacd0723ba 100644 --- a/packages/spec/src/migrations/entries/semantic/18.kernel-runtime-config-timeout-unit-in-key.ts +++ b/packages/spec/src/migrations/entries/semantic/18.kernel-runtime-config-timeout-unit-in-key.ts @@ -42,10 +42,10 @@ export const entry: SemanticMigration = { + 'spells timeout 0 times; outside the zod file and its test the only live occurrences are the ' + 'generated rows in content/docs/references/kernel/plugin-security-advanced.mdx, which this ' + 'rename regenerates. The pinned objectui checkout — this is the pin we build against, ' - + '`.objectui-sha` = `62597c588072636e9c30ea35b3d89b1e46fd765d`, re-read from this tree — ' + + '`.objectui-sha` = `f8a9d0fb0596f4521076628e2bbfe27e6ce67d52`, re-read from this tree — ' + 'spells resourceLimits.timeout 0 times across ' - + '8303 tracked files, against lit controls timeout 1086, RuntimeConfig 240 and resourceLimits ' - + '2 on the same corpus; both resourceLimits hits are prose in packages/app-shell recording ' + + '8512 tracked files, against lit controls timeout 1096, RuntimeConfig 245 and resourceLimits ' + + '2 on the same corpus (0 across 8303, and 1086 / 240 / 2, at 62597c588); both resourceLimits hits are prose in packages/app-shell recording ' + 'that objectui\'s own AppShellRuntimeConfig shares not one key with the spec\'s ' + 'RuntimeConfig, so nothing there authors this key and no pin bump is owed. #15939, #15678, ' + '#14478, ADR-0087.', diff --git a/packages/spec/src/migrations/entries/semantic/18.logging-durations-unit-in-key.ts b/packages/spec/src/migrations/entries/semantic/18.logging-durations-unit-in-key.ts index 1b08780a39a..80f5a7bed4b 100644 --- a/packages/spec/src/migrations/entries/semantic/18.logging-durations-unit-in-key.ts +++ b/packages/spec/src/migrations/entries/semantic/18.logging-durations-unit-in-key.ts @@ -45,10 +45,10 @@ export const entry: SemanticMigration = { + 'no in-repo runtime reads any of the four — outside `packages/spec/src/system/logging.zod.ts` ' + 'and its test the only occurrences are the generated rows in ' + '`content/docs/references/system/logging.mdx`, which this rename regenerates; and the pinned ' - + 'objectui checkout — `.objectui-sha` = `62597c588072636e9c30ea35b3d89b1e46fd765d` — spells ' + + 'objectui checkout — `.objectui-sha` = `f8a9d0fb0596f4521076628e2bbfe27e6ce67d52` — spells ' + '`flushInterval` 0 times, `initialDelay` 0, `HttpDestinationConfig` 0 and `LoggingConfig` 0 ' - + 'across its 8303 tracked files, against lit controls `useState` 2389 and `timeout` 1086 on ' - + 'the same corpus.', + + 'across its 8512 tracked files, against lit controls `useState` 2391 and `timeout` 1096 on ' + + 'the same corpus (all four 0 across 8303, against 2389 and 1086, at 62597c588).', acceptanceCriteria: 'Every HTTP log destination spells `batch.flushIntervalMs`, `retry.initialDelayMs` and ' + '`timeoutMs`, and every logging buffer spells `buffer.flushIntervalMs`; authoring any of the ' diff --git a/packages/spec/src/migrations/entries/semantic/18.system-metrics-jsdoc-durations-unit-in-key.ts b/packages/spec/src/migrations/entries/semantic/18.system-metrics-jsdoc-durations-unit-in-key.ts index 746b74cf2d5..721d5eda0c2 100644 --- a/packages/spec/src/migrations/entries/semantic/18.system-metrics-jsdoc-durations-unit-in-key.ts +++ b/packages/spec/src/migrations/entries/semantic/18.system-metrics-jsdoc-durations-unit-in-key.ts @@ -67,10 +67,11 @@ export const entry: SemanticMigration = { + 'against a lit control of 1195 defineStack occurrences on that same corpus at fc28c1d38 ' + '(1195 again at 9b62f54671); and the objectui ' + 'checkout this repo builds against — this is the pin, ' - + '`.objectui-sha` = `62597c588072636e9c30ea35b3d89b1e46fd765d`, re-read from this tree — ' - + 'spells all six metrics def names and both distinctive keys 0 times across 8303 tracked ' - + 'files at that sha, against lit controls window 3526, timeout 1086, period 170, ' - + 'interval 179 and metrics 324 on that same corpus and sha, so no pin bump is owed. ' + + '`.objectui-sha` = `f8a9d0fb0596f4521076628e2bbfe27e6ce67d52`, re-read from this tree — ' + + 'spells all six metrics def names and both distinctive keys 0 times across 8512 tracked ' + + 'files at that sha, against lit controls window 3581, timeout 1096, period 171, ' + + 'interval 179 and metrics 326 on that same corpus and sha (0 across 8303, against 3526 / ' + + '1086 / 170 / 179 / 324, at 62597c588), so no pin bump is owed. ' + '#15939, #15679, #14478, ADR-0087.', acceptanceCriteria: 'Every metric definition spells summary.maxAgeSeconds, every error-budget burn rate window ' diff --git a/packages/spec/src/migrations/entries/semantic/18.system-tracing-otel-exporter-durations-unit-in-key.ts b/packages/spec/src/migrations/entries/semantic/18.system-tracing-otel-exporter-durations-unit-in-key.ts index 473907c1b49..bbbcc66c1dc 100644 --- a/packages/spec/src/migrations/entries/semantic/18.system-tracing-otel-exporter-durations-unit-in-key.ts +++ b/packages/spec/src/migrations/entries/semantic/18.system-tracing-otel-exporter-durations-unit-in-key.ts @@ -63,12 +63,13 @@ export const entry: SemanticMigration = { + 'dark control of 0; inside packages/spec the ' + 'only occurrences are tracing.zod.ts, its test, and the generated rows in ' + 'content/docs/references/system/tracing.mdx, which this rename regenerates. And the ' - + 'pinned objectui checkout — `.objectui-sha` = `62597c588072636e9c30ea35b3d89b1e46fd765d` — names none of it: all 37 exports of ' - + 'tracing.zod.ts and each of the four key names occur 0 times across the 8303 files ' - + 'tracked at that sha (the 486 Span and 53 SpanSchema hits are objectui\'s own HTML ' - + 'text-span component, TextSpanSchema, an unrelated name), against two lit controls on ' - + 'that same corpus and sha: 13125 hits for the bare token objectstack, and 5043 for the ' - + 'package specifier @objectstack/spec.', + + 'pinned objectui checkout — `.objectui-sha` = `f8a9d0fb0596f4521076628e2bbfe27e6ce67d52` — names none of it: all 37 exports of ' + + 'tracing.zod.ts and each of the four key names occur 0 times across the 8512 files ' + + 'tracked at that sha (the 488 Span and 53 SpanSchema hits are objectui\'s own HTML ' + + 'text-span component, TextSpanSchema, an unrelated name, plus colSpan and prose), against ' + + 'two lit controls on that same corpus and sha: 13347 hits for the bare token objectstack, ' + + 'and 5123 for the package specifier @objectstack/spec (at 62597c588: 0 across 8303, ' + + 'Span 486, 13125 and 5043).', acceptanceCriteria: 'Every author and reader of an OpenTelemetryCompatibility spells exporter.timeoutMs, ' + 'exporter.batch.exportTimeoutMs and exporter.batch.scheduledDelayMs, and every one of a ' diff --git a/packages/spec/src/migrations/entries/semantic/18.tenant-schema-cache-ttl-unit-in-key.ts b/packages/spec/src/migrations/entries/semantic/18.tenant-schema-cache-ttl-unit-in-key.ts index 366730da971..34050f4c7e9 100644 --- a/packages/spec/src/migrations/entries/semantic/18.tenant-schema-cache-ttl-unit-in-key.ts +++ b/packages/spec/src/migrations/entries/semantic/18.tenant-schema-cache-ttl-unit-in-key.ts @@ -28,9 +28,9 @@ export const entry: SemanticMigration = { + 'bd25e897dc: no in-repo runtime reads the key — outside `packages/spec/src/system/tenant.zod.ts` ' + 'and its test the only occurrences are the four generated rows in ' + '`content/docs/references/system/tenant.mdx`, which this rename regenerates; and the pinned ' - + 'objectui checkout — `.objectui-sha` = `62597c588072636e9c30ea35b3d89b1e46fd765d` — spells it 0 ' - + 'times across 8303 tracked files, against lit controls `TTL` 156 and `tenant` 987 on the ' - + 'same corpus.', + + 'objectui checkout — `.objectui-sha` = `f8a9d0fb0596f4521076628e2bbfe27e6ce67d52` — spells it 0 ' + + 'times across 8512 tracked files, against lit controls `TTL` 156 and `tenant` 1034 on the ' + + 'same corpus (0 across 8303, against 156 and 987, at 62597c588).', acceptanceCriteria: 'Every schema-level tenant isolation source spells `performance.schemaCacheTtlSeconds`; ' + 'authoring `performance.schemaCacheTTL` fails to compile and fails to parse with the rename ' diff --git a/packages/spec/src/migrations/registry.ts b/packages/spec/src/migrations/registry.ts index 30cf33582d0..a2c85e400a2 100644 --- a/packages/spec/src/migrations/registry.ts +++ b/packages/spec/src/migrations/registry.ts @@ -9764,12 +9764,13 @@ const step18: MigrationStep = { + 'the audience that does not parse. Measured on 884e8347d: the only in-repo readers are ' + 'packages/core/src/health-monitor.ts and packages/core/src/hot-reload.ts, both moved in ' + 'this same change; and the pinned objectui checkout — the pin this repo builds ' - + 'against, `.objectui-sha` = `62597c588072636e9c30ea35b3d89b1e46fd765d` — names ' + + 'against, `.objectui-sha` = `f8a9d0fb0596f4521076628e2bbfe27e6ce67d52` — names ' + 'neither def and neither key: all thirteen exports of plugin-lifecycle-advanced.zod.ts and ' - + 'the string debounceDelay each occur 0 times across its 8303 tracked files, against lit ' + + 'the string debounceDelay each occur 0 times across its 8512 tracked files (0 across the ' + + '8303 at 62597c588 too), against lit ' + 'controls objectstack 12966 and @objectstack/spec 4997 on the same corpus at 87af769e9, ' - + 'which re-count at this pin to 13125 and 5043 respectively (git grep -o -F, the method ' - + 'that reproduces every earlier count).', + + 'which re-count to 13125 and 5043 respectively at 62597c588 and to 13347 and 5123 at ' + + 'this pin (git grep -o -F, the method that reproduces every earlier count).', acceptanceCriteria: 'Every producer and reader of a PluginHealthCheck spells intervalMs and timeoutMs, and every ' + 'one of a HotReloadConfig spells debounceDelayMs — concretely ' @@ -9955,10 +9956,10 @@ const step18: MigrationStep = { + 'spells timeout 0 times; outside the zod file and its test the only live occurrences are the ' + 'generated rows in content/docs/references/kernel/plugin-security-advanced.mdx, which this ' + 'rename regenerates. The pinned objectui checkout — this is the pin we build against, ' - + '`.objectui-sha` = `62597c588072636e9c30ea35b3d89b1e46fd765d`, re-read from this tree — ' + + '`.objectui-sha` = `f8a9d0fb0596f4521076628e2bbfe27e6ce67d52`, re-read from this tree — ' + 'spells resourceLimits.timeout 0 times across ' - + '8303 tracked files, against lit controls timeout 1086, RuntimeConfig 240 and resourceLimits ' - + '2 on the same corpus; both resourceLimits hits are prose in packages/app-shell recording ' + + '8512 tracked files, against lit controls timeout 1096, RuntimeConfig 245 and resourceLimits ' + + '2 on the same corpus (0 across 8303, and 1086 / 240 / 2, at 62597c588); both resourceLimits hits are prose in packages/app-shell recording ' + 'that objectui\'s own AppShellRuntimeConfig shares not one key with the spec\'s ' + 'RuntimeConfig, so nothing there authors this key and no pin bump is owed. #15939, #15678, ' + '#14478, ADR-0087.', @@ -10099,10 +10100,10 @@ const step18: MigrationStep = { + 'no in-repo runtime reads any of the four — outside `packages/spec/src/system/logging.zod.ts` ' + 'and its test the only occurrences are the generated rows in ' + '`content/docs/references/system/logging.mdx`, which this rename regenerates; and the pinned ' - + 'objectui checkout — `.objectui-sha` = `62597c588072636e9c30ea35b3d89b1e46fd765d` — spells ' + + 'objectui checkout — `.objectui-sha` = `f8a9d0fb0596f4521076628e2bbfe27e6ce67d52` — spells ' + '`flushInterval` 0 times, `initialDelay` 0, `HttpDestinationConfig` 0 and `LoggingConfig` 0 ' - + 'across its 8303 tracked files, against lit controls `useState` 2389 and `timeout` 1086 on ' - + 'the same corpus.', + + 'across its 8512 tracked files, against lit controls `useState` 2391 and `timeout` 1096 on ' + + 'the same corpus (all four 0 across 8303, against 2389 and 1086, at 62597c588).', acceptanceCriteria: 'Every HTTP log destination spells `batch.flushIntervalMs`, `retry.initialDelayMs` and ' + '`timeoutMs`, and every logging buffer spells `buffer.flushIntervalMs`; authoring any of the ' @@ -12593,10 +12594,11 @@ const step18: MigrationStep = { + 'against a lit control of 1195 defineStack occurrences on that same corpus at fc28c1d38 ' + '(1195 again at 9b62f54671); and the objectui ' + 'checkout this repo builds against — this is the pin, ' - + '`.objectui-sha` = `62597c588072636e9c30ea35b3d89b1e46fd765d`, re-read from this tree — ' - + 'spells all six metrics def names and both distinctive keys 0 times across 8303 tracked ' - + 'files at that sha, against lit controls window 3526, timeout 1086, period 170, ' - + 'interval 179 and metrics 324 on that same corpus and sha, so no pin bump is owed. ' + + '`.objectui-sha` = `f8a9d0fb0596f4521076628e2bbfe27e6ce67d52`, re-read from this tree — ' + + 'spells all six metrics def names and both distinctive keys 0 times across 8512 tracked ' + + 'files at that sha, against lit controls window 3581, timeout 1096, period 171, ' + + 'interval 179 and metrics 326 on that same corpus and sha (0 across 8303, against 3526 / ' + + '1086 / 170 / 179 / 324, at 62597c588), so no pin bump is owed. ' + '#15939, #15679, #14478, ADR-0087.', acceptanceCriteria: 'Every metric definition spells summary.maxAgeSeconds, every error-budget burn rate window ' @@ -12788,12 +12790,13 @@ const step18: MigrationStep = { + 'dark control of 0; inside packages/spec the ' + 'only occurrences are tracing.zod.ts, its test, and the generated rows in ' + 'content/docs/references/system/tracing.mdx, which this rename regenerates. And the ' - + 'pinned objectui checkout — `.objectui-sha` = `62597c588072636e9c30ea35b3d89b1e46fd765d` — names none of it: all 37 exports of ' - + 'tracing.zod.ts and each of the four key names occur 0 times across the 8303 files ' - + 'tracked at that sha (the 486 Span and 53 SpanSchema hits are objectui\'s own HTML ' - + 'text-span component, TextSpanSchema, an unrelated name), against two lit controls on ' - + 'that same corpus and sha: 13125 hits for the bare token objectstack, and 5043 for the ' - + 'package specifier @objectstack/spec.', + + 'pinned objectui checkout — `.objectui-sha` = `f8a9d0fb0596f4521076628e2bbfe27e6ce67d52` — names none of it: all 37 exports of ' + + 'tracing.zod.ts and each of the four key names occur 0 times across the 8512 files ' + + 'tracked at that sha (the 488 Span and 53 SpanSchema hits are objectui\'s own HTML ' + + 'text-span component, TextSpanSchema, an unrelated name, plus colSpan and prose), against ' + + 'two lit controls on that same corpus and sha: 13347 hits for the bare token objectstack, ' + + 'and 5123 for the package specifier @objectstack/spec (at 62597c588: 0 across 8303, ' + + 'Span 486, 13125 and 5043).', acceptanceCriteria: 'Every author and reader of an OpenTelemetryCompatibility spells exporter.timeoutMs, ' + 'exporter.batch.exportTimeoutMs and exporter.batch.scheduledDelayMs, and every one of a ' @@ -12888,9 +12891,9 @@ const step18: MigrationStep = { + 'bd25e897dc: no in-repo runtime reads the key — outside `packages/spec/src/system/tenant.zod.ts` ' + 'and its test the only occurrences are the four generated rows in ' + '`content/docs/references/system/tenant.mdx`, which this rename regenerates; and the pinned ' - + 'objectui checkout — `.objectui-sha` = `62597c588072636e9c30ea35b3d89b1e46fd765d` — spells it 0 ' - + 'times across 8303 tracked files, against lit controls `TTL` 156 and `tenant` 987 on the ' - + 'same corpus.', + + 'objectui checkout — `.objectui-sha` = `f8a9d0fb0596f4521076628e2bbfe27e6ce67d52` — spells it 0 ' + + 'times across 8512 tracked files, against lit controls `TTL` 156 and `tenant` 1034 on the ' + + 'same corpus (0 across 8303, against 156 and 987, at 62597c588).', acceptanceCriteria: 'Every schema-level tenant isolation source spells `performance.schemaCacheTtlSeconds`; ' + 'authoring `performance.schemaCacheTTL` fails to compile and fails to parse with the rename ' diff --git a/packages/spec/src/ui/component.test.ts b/packages/spec/src/ui/component.test.ts index 9394b69c540..dbea5c52674 100644 --- a/packages/spec/src/ui/component.test.ts +++ b/packages/spec/src/ui/component.test.ts @@ -286,12 +286,14 @@ describe('PageAccordionProps variant (#6776)', () => { // same file's `ComponentRegistry.register('accordion', …)` publishes the key to // the Studio block designer at `:1116` (the `items` input, documented as // `[{ label, icon?, collapsed?, children }]`). Measured at the pin this repo -// builds against — `.objectui-sha` = `62597c588`. Re-derived at that pin -// 2026-09-23: `containers.tsx` changed again across the hop from `87af769e9` -// (74 insertions, 16 deletions, objectui `4c6f549ef`, the `page:header` -// title), so both anchors were re-READ rather than carried — and NEITHER -// moved: the icon block is still `1069-1075` and the input still `1116`, each -// byte-identical to its `87af769e9` text. (The hop before, off `53ded82bf`, +// builds against — `.objectui-sha` = `f8a9d0fb0`. Re-derived at that pin +// 2026-09-24: `containers.tsx` changed again across the hop from `62597c588` +// (36 insertions, 7 deletions, objectui `ba0b61a60`: an import line and the +// `page:header` title), so both anchors were re-READ rather than carried — +// and NEITHER moved: the icon block is still `1069-1075` and the input still +// `1116`, each byte-identical to its `62597c588` and `87af769e9` text. The +// hop onto `62597c588` (74 insertions, 16 deletions, objectui `4c6f549ef`) +// read the same. (The hop before, off `53ded82bf`, // moved them from `919-925` and `966` and rewrote the input LINE — it now // declares `of: 'object'`, carries a longer description and no `label` — // while the member list this pin cites stayed unchanged.) Identity preserves a @@ -379,12 +381,13 @@ describe('PageTabsProps items[].value / items[].count (#5775)', () => { // same file's `ComponentRegistry.register('tabs', …)` publishes the key to the // Studio block designer at `:912` (the `items` input, documented as // `[{ label, value?, icon?, count?, visibleWhen?, children }]`). Measured at -// the pin this repo builds against — `.objectui-sha` = `62597c588`. Re-derived -// at that pin 2026-09-23: `containers.tsx` changed again across the hop from -// `87af769e9` (74 insertions, 16 deletions, objectui `4c6f549ef`), so both +// the pin this repo builds against — `.objectui-sha` = `f8a9d0fb0`. Re-derived +// at that pin 2026-09-24: `containers.tsx` changed again across the hop from +// `62597c588` (36 insertions, 7 deletions, objectui `ba0b61a60`), so both // anchors were re-READ rather than carried — and NEITHER moved: the icon block // is still `853-859` and the input still `912`, each byte-identical to its -// `87af769e9` text. (The hop before, off `53ded82bf`, moved them from +// `62597c588` and `87af769e9` text; the hop onto `62597c588` (74 insertions, +// 16 deletions, objectui `4c6f549ef`) read the same. (The hop before, off `53ded82bf`, moved them from // `730-736` and `789` and rewrote the input LINE — `of: 'object'`, a longer // description, no `label` — while the member list this pin cites stayed // unchanged.) Never inferred (#10274). @@ -3385,19 +3388,24 @@ describe('#7751 — object-* block props schemas', () => { // #16503 — the spec half of objectui#8172 (decision batch #68, 2026-09-07, // option A: the contract declares the capability that already ships, is // documented and is in use). Measured at the objectui pin this repo builds -// against (`.objectui-sha` = `62597c588`; re-measured there 2026-09-23 — all -// five objectui files this block cites are byte-identical to `87af769e9` -// (`git diff --quiet`), so the four anchors hold unmoved; they were last -// re-READ at `87af769e9` 2026-09-20, the hop that moved every one of them and -// renamed one face outright): `plugin-kanban/src/ObjectKanban.tsx:676` +// against (`.objectui-sha` = `f8a9d0fb0`; re-measured there 2026-09-24 — +// `plugin-kanban/src/types.ts` and `plugin-kanban.mdx` are byte-identical to +// `62597c588`; `ObjectKanban.tsx`, `index.tsx` and `objectql.ts` changed, so +// their anchors were re-READ: `676` -> `687` and `:84` -> `:85` moved with +// their text byte-identical, the mapping gained `sort: true` beside the +// `limit` it cites (objectui#10068, `447-450` -> `507-511`), and the +// `limit?: number` member moved `3735` -> `3832`. All five files were +// byte-identical across the hop onto `62597c588`, and were last re-READ at +// `87af769e9` 2026-09-20, the hop that moved every anchor and renamed one +// face outright): `plugin-kanban/src/ObjectKanban.tsx:687` // queries `$top: resolveRowLimit(schema.limit, DEFAULT_KANBAN_LIMIT)` (100, -// `:84`; the bare `??` became `resolveRowLimit` in objectui#9925, which drops +// `:85`; the bare `??` became `resolveRowLimit` in objectui#9925, which drops // and reports a cap the contract refuses), -// `plugin-kanban/src/index.tsx:447-450` maps `limit: 'limit'` in +// `plugin-kanban/src/index.tsx:507-511` maps `limit: 'limit'` in // `OBJECT_KANBAN_DATA_SOURCE`, ⚠️ `KanbanSchema` is RETIRED at this pin and // `plugin-kanban/src/types.ts` declares the member no more — the published // twin is `ObjectKanbanSchema`, declaring `limit?: number` at -// `packages/types/src/objectql.ts:3735` — and `content/docs/plugins/plugin-kanban.mdx` +// `packages/types/src/objectql.ts:3832` — and `content/docs/plugins/plugin-kanban.mdx` // teaches `limit: 250` with a Properties row. The strict map refused the key by // name — the same `unrecognized_keys` verdict as the `bogusProp` control — so an // author following the published docs wrote a node the save gate rejected. @@ -3458,10 +3466,12 @@ describe('ObjectKanbanPropsSchema limit — the row cap four objectui faces alre // on the React-host `kanban-ui` block). Unlike `limit` above — a key four // objectui faces already implemented, so the spec was the half that was wrong // — `quickAdd` was FORWARDED and never read: at the pin this repo builds -// against (`.objectui-sha` = `62597c588`; re-measured there 2026-09-23 — -// `ObjectKanban.tsx` and `KanbanImpl.tsx` are byte-identical to `87af769e9`, -// where every anchor was re-READ 2026-09-20 and MOVED with its cited text -// byte-identical, so none moved on this hop) `ObjectKanban.tsx:1563` +// against (`.objectui-sha` = `f8a9d0fb0`; re-measured there 2026-09-24 — +// `KanbanImpl.tsx` is byte-identical to `62597c588`, and `ObjectKanban.tsx` +// changed above the spread only (objectui#10068's `$orderby`), which MOVED +// `1563` -> `1578` with its text byte-identical; both files were +// byte-identical across the hop onto `62597c588`, and every anchor was +// re-READ at `87af769e9` 2026-09-20) `ObjectKanban.tsx:1578` // spreads the // authored bag into `KanbanRenderer` and `KanbanImpl` gates the affordance on // `quickAdd && onQuickAdd` (`KanbanImpl.tsx:621`, `:634` — the file is spelled @@ -3526,9 +3536,12 @@ describe('ObjectKanbanPropsSchema quickAdd is retired (#17260)', () => { // #9881 and #9972 recorded the accordion and tab items; these two close the set. // // The button record re-measured at the pin this repo builds against — -// `.objectui-sha` = `62597c588`, re-derived there 2026-09-23: `resolve-icon.ts`, -// `button.tsx` and `lazy-icon.tsx` are all byte-identical to `87af769e9` -// (`git diff --quiet`), so no anchor moved on this hop. The hop before it, +// `.objectui-sha` = `f8a9d0fb0`, re-derived there 2026-09-24: `resolve-icon.ts` +// and `lazy-icon.tsx` are byte-identical to `62597c588` and `87af769e9` +// (`git diff --quiet`), and `button.tsx` changed only inside its +// registration's input list (objectui#9910 added a `children` slot input, no +// `icon` one), so the `:43` / `:72` / `:74` anchors below did not move; all +// three files were byte-identical across the hop onto `62597c588`. The hop before that, // onto `87af769e9` (re-derived 2026-09-20), moved both files in this chain — // `resolve-icon.ts` +203/-7 and `button.tsx` +6/-11 against `53ded82bf` — so // no anchor below was carried there and every one was re-READ (#10274). ⚠️ `resolveIcon` itself was rewritten: its tail no @@ -3648,10 +3661,15 @@ describe('ObjectMetricPropsSchema icon liveness (#10053)', () => { // // The acceptance the card names, pinned: each row's KEY SET is the one the // renderer's read points support at the pin this repo builds against -// (`.objectui-sha` = `62597c588`; re-measured there 2026-09-23 — the gantt and -// tree renderers are byte-identical to `87af769e9`, and the map's -// `ObjectMap.tsx` changed only in a docblock and a dev-warning string -// (objectui `2252653d0`), so its anchors MOVED with their cited text +// (`.objectui-sha` = `f8a9d0fb0`; re-measured there 2026-09-24 — the map's +// `ObjectMap.tsx` is byte-identical to `62597c588`, and the gantt and tree +// renderers changed on this hop, so their anchors were re-READ: no declared +// key set moved (the gantt's new host-generated `search` / `searchableFields` +// reads, objectui#10250, stay undeclared and are recorded in its header; the +// tree's `filter.tree` stash read was deleted, objectui#9549). At `62597c588` +// the gantt and tree renderers were byte-identical to `87af769e9`, and the +// map's `ObjectMap.tsx` had changed only in a docblock and a dev-warning +// string (objectui `2252653d0`), so its anchors MOVED with their cited text // byte-identical and no key set moved. They were re-READ at `87af769e9` // 2026-09-22 — all three renderers moved hard on the hop from `53ded82bf`, // so NO anchor in this block was carried and every one was re-derived. Four diff --git a/packages/spec/src/ui/component.zod.ts b/packages/spec/src/ui/component.zod.ts index 012616c0f37..3b788891c78 100644 --- a/packages/spec/src/ui/component.zod.ts +++ b/packages/spec/src/ui/component.zod.ts @@ -692,11 +692,13 @@ export const PageTabsProps = strictObject({ * false candidate a component over). * * The key is LIVE at the objectui pin this repo builds against - * (`.objectui-sha` = `62597c588`; re-derived at that pin 2026-09-23 — - * `containers.tsx` changed again across the hop from `87af769e9` (74 - * insertions, 16 deletions, objectui `4c6f549ef`), so both anchors were - * re-READ rather than carried, and NEITHER moved: `853-859` and `912` are - * byte-identical to their `87af769e9` text. The hop before, off + * (`.objectui-sha` = `f8a9d0fb0`; re-derived at that pin 2026-09-24 — + * `containers.tsx` changed again across the hop from `62597c588` (36 + * insertions, 7 deletions, objectui `ba0b61a60`: one import line and the + * `page:header` title), so both anchors were re-READ rather than carried, + * and NEITHER moved: `853-859` and `912` are byte-identical to their + * `62597c588` and `87af769e9` text. The same held on the hop onto + * `62597c588` (74 insertions, 16 deletions, objectui `4c6f549ef`). The hop before, off * `53ded82bf`, moved the icon block `730-736` -> `853-859` with its seven * lines byte-identical and the registration input `789` -> `912` with its * LINE rewritten — it declares `of: 'object'` and carries a longer @@ -1866,11 +1868,13 @@ export const PageAccordionProps = strictObject({ * re-derive the same false candidate). * * The key is LIVE at the objectui pin this repo builds against - * (`.objectui-sha` = `62597c588`; re-derived at that pin 2026-09-23 — - * `containers.tsx` changed again across the hop from `87af769e9` (74 - * insertions, 16 deletions, objectui `4c6f549ef`), so both anchors were - * re-READ rather than carried, and NEITHER moved: `1069-1075` and `1116` - * are byte-identical to their `87af769e9` text. The hop before, off + * (`.objectui-sha` = `f8a9d0fb0`; re-derived at that pin 2026-09-24 — + * `containers.tsx` changed again across the hop from `62597c588` (36 + * insertions, 7 deletions, objectui `ba0b61a60`: one import line and the + * `page:header` title), so both anchors were re-READ rather than carried, + * and NEITHER moved: `1069-1075` and `1116` are byte-identical to their + * `62597c588` and `87af769e9` text. The same held on the hop onto + * `62597c588` (74 insertions, 16 deletions, objectui `4c6f549ef`). The hop before, off * `53ded82bf`, moved the icon block `919-925` -> `1069-1075` with its seven * lines byte-identical and the registration input `966` -> `1116` with its * LINE rewritten — it declares `of: 'object'` and carries a longer @@ -2127,10 +2131,13 @@ export const ElementButtonPropsSchema = lazySchema(() => strictObject({ * the button. * * The key is LIVE at the objectui pin this repo builds against - * (`.objectui-sha` = `62597c588`; re-derived at that pin 2026-09-23 — - * `resolve-icon.ts`, `button.tsx` and `lib/lazy-icon.tsx` are all - * byte-identical to `87af769e9` (`git diff --quiet`), so no anchor below - * moved on this hop. The hop onto `87af769e9` (re-derived 2026-09-20) is the + * (`.objectui-sha` = `f8a9d0fb0`; re-derived at that pin 2026-09-24 — + * `resolve-icon.ts` and `lib/lazy-icon.tsx` are byte-identical to + * `62597c588` and `87af769e9` (`git diff --quiet`), and `button.tsx` + * changed on this hop only inside its registration's input list (objectui + * `5ea623eab`, objectui#9910, below), so the render-path anchors did not + * move; `button.tsx` too was byte-identical across the hop onto + * `62597c588`. The hop onto `87af769e9` (re-derived 2026-09-20) is the * one that moved both files: `resolve-icon.ts` +203/-7 and * `button.tsx` +6/-11 against `53ded82bf`, so NO anchor below was carried * there and every one was re-READ. Four moved with their cited text byte-identical @@ -2190,9 +2197,13 @@ export const ElementButtonPropsSchema = lazySchema(() => strictObject({ * behaviour promised above is the same on both sides of that move. * * Also measured at the same pin: the renderer's registration publishes no - * `icon` input (`button.tsx:85-97` lists `label`, `variant`, `size`, - * `className`; `:98-102` is `defaultProps`), so the Studio block designer - * does not offer the key. Both ranges SHRANK on the hop onto `87af769e9` — the inputs went + * `icon` input (`button.tsx:85-105` lists `label`, `variant`, `size`, + * `className` and `children`; `:106-110` is `defaultProps`), so the Studio + * block designer does not offer the key. The inputs GREW on the hop onto + * `f8a9d0fb0` — `85-97` -> `85-105`, `defaultProps` `98-102` -> `106-110` — + * because objectui#9910 declared the label slot's rich form as a + * `{ name: 'children', type: 'slot' }` input; re-read, it is still not an + * `icon` input, so the absence holds. Both ranges SHRANK on the hop onto `87af769e9` — the inputs went * `85-102` -> `85-97` and `defaultProps` `103-107` -> `98-102`, because each * input dropped its `label` and `defaultValue` members; the four input names * and the absence of an `icon` input are what was re-read, and both hold. @@ -2960,9 +2971,13 @@ export const ObjectMetricPropsSchema = lazySchema(() => strictObject({ * same record for the metric tile. * * The key is LIVE at the objectui pin this repo builds against - * (`.objectui-sha` = `62597c588`; re-derived at that pin 2026-09-23 — all - * four objectui files in the chain below are byte-identical to `87af769e9` - * (`git diff --quiet`), so no anchor moved on this hop. On the hop onto + * (`.objectui-sha` = `f8a9d0fb0`; re-derived at that pin 2026-09-24 — + * `plugin-dashboard/src/index.tsx`, `MetricWidget.tsx` and `lazy-icon.tsx` + * are byte-identical to `62597c588` and `87af769e9` (`git diff --quiet`); + * `ObjectMetricWidget.tsx` changed on this hop (objectui `0651e7ab4`, the + * currency tile's decimals, objectui#10221), and its two anchors MOVED with + * their cited text byte-identical: the destructure `174` -> `181`, the + * forward `483` -> `528`. On the hop onto * `87af769e9` (re-derived 2026-09-20) EVERY file in the chain moved, so no * anchor was carried there and each was re-READ: the `object-metric` * registration now begins at `:227` @@ -2975,7 +2990,7 @@ export const ObjectMetricPropsSchema = lazySchema(() => strictObject({ * runs three files: * `plugin-dashboard/src/index.tsx:237` publishes it as a designer input * on the registered `object-metric` block; - * `ObjectMetricWidget.tsx:174` destructures it and forwards it at `:483` to + * `ObjectMetricWidget.tsx:181` destructures it and forwards it at `:528` to * `MetricWidget`; `MetricWidget.tsx:351-360` resolves it via * `getLazyIcon(icon)` — guarded on `typeof icon === 'string'`, because the * React prop also accepts a ready-made node — and `:412-421` draws it in the @@ -3064,17 +3079,20 @@ export type ObjectMetricPropsParsed = z.infer; * DESIGNER's spelling with * zero read points (#7973 class) — aliased to the `groupBy` the board reads. * `limit` (#16503) was measured later, at the pin this repo builds against - * (`.objectui-sha` = `62597c588`; re-measured there 2026-09-23 — - * `ObjectKanban.tsx` is byte-identical to `87af769e9`, where it was re-READ - * 2026-09-20: the file moved hard on that hop, +708/-79 against `53ded82bf`, + * (`.objectui-sha` = `f8a9d0fb0`; re-measured there 2026-09-24 — + * `ObjectKanban.tsx` changed on this hop, +16/-1 (objectui#10068 added the + * binding's `sort` as the query's `$orderby`), so the anchor was re-READ and + * MOVED `676` -> `687` with its text byte-identical; the file was + * byte-identical across the hop onto `62597c588`, and was re-READ at + * `87af769e9` 2026-09-20: it moved hard on that hop, +708/-79 against `53ded82bf`, * and this anchor is one the * numbers alone would have mis-carried: the read was a bare * `$top: schema.limit ?? DEFAULT_KANBAN_LIMIT` at `:264` and is now * `$top: resolveRowLimit(schema.limit, DEFAULT_KANBAN_LIMIT)`, objectui#9925 * having put a refusal in front of it — a contract-refused row cap is dropped - * and reported at `:553` instead of being sent. The pinned fact is unchanged: + * and reported at `:554` instead of being sent. The pinned fact is unchanged: * `schema.limit` still lowers into the query's top-level `$top`): - * `ObjectKanban.tsx:676`, the `$top` of the + * `ObjectKanban.tsx:687`, the `$top` of the * board's one query — its docblock below carries the four-face record. */ export const ObjectKanbanPropsSchema = lazySchema(() => strictObject({ @@ -3115,27 +3133,37 @@ export const ObjectKanbanPropsSchema = lazySchema(() => strictObject({ * Row cap (#16503 — the spec half of objectui#8172; decision batch #68, * 2026-09-07, option A: the contract declares the capability that already * ships, is documented and is in use). Measured at the objectui pin this - * repo builds against (`.objectui-sha` = `62597c588`; re-measured there - * 2026-09-23 — every objectui file this block cites, `ElementDataSourceGate`, - * `element-data-source.ts`, `ListView.tsx` and `ObjectView.tsx` included, is - * byte-identical to `87af769e9`, so no anchor moved on this hop. All four + * repo builds against (`.objectui-sha` = `f8a9d0fb0`; re-measured there + * 2026-09-24 — `element-data-source.ts`, `plugin-kanban/src/types.ts` and + * `plugin-kanban.mdx` are byte-identical to `62597c588`; every other file + * this block cites changed on this hop, and each anchor was re-READ: the + * board's query GAINED a member (objectui#10068's `$orderby` from the + * binding's `sort`, between `$filter` and `$top`, `674-679` -> `680-690`) + * and the data-source mapping gained `sort: true` (`447-450` -> `507-511`); + * every other anchor MOVED with its cited text byte-identical — `:84` -> + * `:85`, `:553` -> `:554`, `:559` -> `:565`, `:676` -> `:687`, + * `objectql.ts:3735` -> `:3832`, `ElementDataSourceGate.tsx:316-331` -> + * `:373-388` and `:192-194` -> `:200-202`, `ListView.tsx:2979` -> `:3067` and + * `:2952` -> `:3040`, `ObjectView.tsx:1638` -> `:1666` and `:1579` -> + * `:1607` — and `ObjectKanban.tsx:10` did not move. Every file here was + * byte-identical across the hop onto `62597c588`. All four * anchors were re-READ at `87af769e9` 2026-09-20 — the hop that moved every * one of them, and RENAMED one face rather than shifting it), four * faces agree * while this map refused the key by name: the board's one query is - * `dataSource.find(objectName, { $filter: schema.filter, $top: + * `dataSource.find(objectName, { $filter: schema.filter, $orderby: …, $top: * resolveRowLimit(schema.limit, DEFAULT_KANBAN_LIMIT) })` - * (`plugin-kanban/src/ObjectKanban.tsx:674-679`, - * the default `100` at `:84` — a REAL top-level `$top` since objectui#4025; + * (`plugin-kanban/src/ObjectKanban.tsx:680-690`, + * the default `100` at `:85` — a REAL top-level `$top` since objectui#4025; * before that the cap sat under a `options` key no adapter read, and the * bare `??` became `resolveRowLimit` in objectui#9925, which drops and * reports a cap the contract refuses instead of sending it), * `OBJECT_KANBAN_DATA_SOURCE` maps `limit: 'limit'` - * (`plugin-kanban/src/index.tsx:447-450`), the type the board reads `schema` + * (`plugin-kanban/src/index.tsx:507-511`), the type the board reads `schema` * through is `ObjectKanbanSchema` — ⚠️ `KanbanSchema` was RETIRED on this hop * (maintainer ruling 2026-09-09) and `plugin-kanban/src/types.ts` no longer * declares the member at all — imported at `ObjectKanban.tsx:10` and - * declaring `limit?: number` at `packages/types/src/objectql.ts:3735`, + * declaring `limit?: number` at `packages/types/src/objectql.ts:3832`, * and `content/docs/plugins/plugin-kanban.mdx` * teaches it with a typed snippet (`limit: 250`) plus a Properties row. So * an author following the published docs wrote a node the save gate @@ -3146,7 +3174,7 @@ export const ObjectKanbanPropsSchema = lazySchema(() => strictObject({ * table, not this key's. The component-level `dataSource.limit` overrides * this key unconditionally; a bound named view's `pagination.pageSize` is * LOWERED INTO it through the `limit: 'limit'` mapping only when this key is - * unset (`react/src/element-data-source/ElementDataSourceGate.tsx:316-331`, + * unset (`react/src/element-data-source/ElementDataSourceGate.tsx:373-388`, * `readLimit`/`writeLimit` keyed by `ElementDataSourceLimitKey`; the branch * gained objectui#9899's presence-is-not-authorship test and a * `describeDisplacedRowLimit` report on this hop). @@ -3156,7 +3184,7 @@ export const ObjectKanbanPropsSchema = lazySchema(() => strictObject({ * 2026-09-21T10:20Z. The branch is * `if (!fromView || !isUsableRowLimit(authored))`, and * `isUsableRowLimit` is `typeof v === 'number' && Number.isInteger(v) && v > 0` - * (`ElementDataSourceGate.tsx:192-194`), and this key's accept set + * (`ElementDataSourceGate.tsx:200-202`), and this key's accept set * (`z.number().int().positive()`) is a SUBSET of it — ⛔ not the same set, * and the difference is reachable: `2^53 + 2` is refused here (zod 4's * `.int()` is safe-integer, `too_big`) and `Number.isInteger` calls it @@ -3189,14 +3217,14 @@ export const ObjectKanbanPropsSchema = lazySchema(() => strictObject({ * `ListViewSchema` document's `kanban` block) and THIS `limit` is the * ELEMENT-FACE key on the node; the third door is the one that turns the * first into the second. The ADAPTERS spread the view's kanban block FLAT - * onto the generated node — `plugin-list/src/ListView.tsx:2979` and - * `plugin-view/src/ObjectView.tsx:1638`, both `...restKanban`, and neither - * destructure (`ListView.tsx:2952`, `ObjectView.tsx:1579`) strips `limit`. + * onto the generated node — `plugin-list/src/ListView.tsx:3067` and + * `plugin-view/src/ObjectView.tsx:1666`, both `...restKanban`, and neither + * destructure (`ListView.tsx:3040`, `ObjectView.tsx:1607`) strips `limit`. * So a view's `kanban.limit`, INCLUDING the 100 its applied default - * materializes, lands on THIS key, and `ObjectKanban.tsx:553` reads it - * (`describeRefusedRowLimit`, unconditional). The `$top` at `:676` is not + * materializes, lands on THIS key, and `ObjectKanban.tsx:554` reads it + * (`describeRefusedRowLimit`, unconditional). The `$top` at `:687` is not * issued on either route today — both hosts pass rows down as a React `data` - * prop and the board short-circuits at `:559` — so it governs no query + * prop and the board short-circuits at `:565` — so it governs no query * there, which is ⛔ NOT the same claim as 「no consumer reads it」. A * spread carries a key without spelling it, so a property-access sweep * cannot see this and returns a confident zero. @@ -3231,20 +3259,24 @@ export const ObjectKanbanPropsSchema = lazySchema(() => strictObject({ * React-host `kanban-ui` block). * * Measured at the objectui pin this repo builds against - * (`.objectui-sha` = `62597c588`; re-measured there 2026-09-23 — the three - * plugin-kanban files cited are byte-identical to `87af769e9`, where all four - * anchors were re-READ 2026-09-20 and each MOVED with its cited text - * byte-identical, so none moved on this hop): the board + * (`.objectui-sha` = `f8a9d0fb0`; re-measured there 2026-09-24 — + * `KanbanImpl.tsx` is byte-identical to `62597c588`, while `ObjectKanban.tsx` + * (objectui#10068's `$orderby`) and `index.tsx` (objectui#10069's lane + * matching, the `sort` mapping) changed, and both of their anchors MOVED + * with the cited text byte-identical: `1563` -> `1578`, `313` -> `363`. All + * three files were byte-identical across the hop onto `62597c588`, and all + * four anchors were re-READ at `87af769e9` 2026-09-20, where each MOVED with + * its cited text byte-identical): the board * forwards the key — - * `ObjectKanban.tsx:1563` spreads the authored bag into `KanbanRenderer`, + * `ObjectKanban.tsx:1578` spreads the authored bag into `KanbanRenderer`, * which passes * `quickAdd={schema.quickAdd}` and `onQuickAdd={schema.onQuickAdd}` - * (`plugin-kanban/src/index.tsx:313`) — but the affordance is gated on + * (`plugin-kanban/src/index.tsx:363-364`) — but the affordance is gated on * BOTH (`KanbanImpl.tsx:621` and `:634`), and `onQuickAdd` is a * host-supplied FUNCTION that JSON cannot carry and no producer puts on an * `object-kanban` node. `ObjectKanban.tsx` names neither half of the pair * (0 occurrences each, against 11 for the sibling `onCardClick` in the same - * file — re-counted at `62597c588`; this record said 6, which the identical + * file — re-counted at `f8a9d0fb0` and `62597c588`; this record said 6, which the identical * file at `87af769e9` does not reproduce either, so the control was * miscounted rather than moved, and the verdict rests on the 0). So the gate was permanently false and authoring the key was a * parse-clean no-op — the accepted-and-dropped class. @@ -3280,16 +3312,19 @@ export const ObjectKanbanPropsSchema = lazySchema(() => strictObject({ * element schemas). * * Measured at the pin this repo builds against (`.objectui-sha` = - * `62597c588`; re-measured there 2026-09-23 — `ObjectKanban.tsx` is - * byte-identical to `87af769e9`, so no anchor moved on this hop. They were + * `f8a9d0fb0`; re-measured there 2026-09-24 — `ObjectKanban.tsx` changed on + * this hop, +16/-1 (objectui#10068's `$orderby`), all of it above these + * anchors, so each MOVED by 15 with its cited text byte-identical and is + * cited below at its new number; the file was byte-identical across the hop + * onto `62597c588`. They were * re-READ at `87af769e9` 2026-09-22 — every anchor re-derived from that * tree rather than carried, none of them at its `53ded82bf` number and one * of them no longer spelled the way this record quoted it): - * `ObjectKanban.tsx:1210` + * `ObjectKanban.tsx:1225` * reads `schema.navigation ?? { mode: 'drawer' }` and hands it to - * `useNavigationOverlay` (`:1218-1219`), whose result drives the card click - * (`:1587`) and the detail overlay (`:1468`, whose `NavigationOverlay` is - * `:1484-1497`) — on a STANDALONE board, with no enclosing view to resolve + * `useNavigationOverlay` (`:1233-1234`), whose result drives the card click + * (`:1602`) and the detail overlay (`:1483`, whose `NavigationOverlay` is + * `:1499-1512`) — on a STANDALONE board, with no enclosing view to resolve * a mode from. ⚠️ The `(schema as any)` cast this record used to quote is * GONE at this pin: the read is spelled `schema.navigation` and compiles * through `BaseSchema`'s index signature, which the comment above it @@ -3411,8 +3446,10 @@ export const ObjectCalendarPropsSchema = lazySchema(() => strictObject({ * `object-kanban`'s above. * * Measured at the pin this repo builds against (`.objectui-sha` = - * `62597c588`; re-READ there 2026-09-23 — `ObjectCalendar.tsx` changed - * across the hop from `87af769e9` (objectui `afb228418`, the calendar's + * `f8a9d0fb0`; re-checked there 2026-09-24 — `ObjectCalendar.tsx` is + * byte-identical to `62597c588` (`git diff --quiet`), so every anchor below + * holds unmoved from the re-READ taken at `62597c588` 2026-09-23. That file + * changed across the hop from `87af769e9` (objectui `afb228418`, the calendar's * copy routed through the locale packs, +43/-17), so every anchor was * re-derived rather than carried: `:921-935`, `:936` and `:938-939` did not * move, and the three after the change MOVED with their cited text @@ -3637,7 +3674,10 @@ const OBJECT_MAP_FLAT_CONFIG_GUIDANCE: readonly KeySetGuidance[] = [ /** * `object-map` (objectui `plugin-map/src/ObjectMap.tsx` plus the registry shell * `plugin-map/src/index.tsx`, read at the pin this repo builds against — - * `.objectui-sha` = `62597c588`, re-READ there 2026-09-23. `ObjectMap.tsx` + * `.objectui-sha` = `f8a9d0fb0`, re-checked there 2026-09-24: `ObjectMap.tsx`, + * `index.tsx` and `core/src/utils/record-source.ts` are byte-identical to + * `62597c588` (`git diff --quiet`), so every anchor below holds unmoved from + * the re-READ taken there 2026-09-23. `ObjectMap.tsx` * changed across the hop from `87af769e9` only in `warnOnTopLevelStyleUrl`'s * docblock and dev-warning text (objectui `2252653d0`, +27/-8, which names * the flat `mapStyle` spelling the flatten really carries), so no read point @@ -3723,9 +3763,10 @@ export const ObjectMapPropsSchema = lazySchema(() => strictObject({ * Base query filter — the `ViewFilterRule` ARRAY form, the one filter * orthography every `filter` door in this map shares (ui#6206-B reaching the * `object-*` family: #15449, decision batch #55, option A). Measured at the - * pin this repo builds against (`.objectui-sha` = `62597c588`, re-READ + * pin this repo builds against (`.objectui-sha` = `f8a9d0fb0`, where + * `ObjectMap.tsx` is byte-identical to `62597c588`; re-READ at `62597c588` * 2026-09-23 — both anchors MOVED 19 lines from `:814` / `:895` with their - * text byte-identical, the hop changing only a docblock and a dev warning + * text byte-identical, that hop changing only a docblock and a dev warning * above them): `ObjectMap.tsx:833` and `:914` hand `schema.filter` verbatim * to `$filter` on the inline and the object fetch, where the adapter lowers a * rule array exactly as it does for the kanban and the calendar. The record @@ -3742,8 +3783,10 @@ export const ObjectMapPropsSchema = lazySchema(() => strictObject({ * Marker order — the `SortItem` ARRAY form, the one sort orthography every * DECLARED `sort` door on this platform carries (objectui#8221, decision batch * #77, option B). Measured at the pin this repo builds against - * (`.objectui-sha` = `62597c588`, re-READ 2026-09-23 — both anchors MOVED - * 19 lines from `:815` / `:896` with their text byte-identical): + * (`.objectui-sha` = `f8a9d0fb0`, where `ObjectMap.tsx` and + * `plugin-map/src/index.tsx` are byte-identical to `62597c588`; re-READ at + * `62597c588` 2026-09-23 — both anchors MOVED 19 lines from `:815` / `:896` + * with their text byte-identical): * `ObjectMap.tsx:834` and `:915` * hand `schema.sort` to the shared `convertSortToQueryParams` sink as the * fetch's `$orderby` — the same sink `object-grid` and `object-calendar` @@ -3821,38 +3864,49 @@ const OBJECT_GANTT_FLAT_CONFIG_GUIDANCE: readonly KeySetGuidance[] = [ /** * `object-gantt` (objectui `plugin-gantt/src/ObjectGantt.tsx` plus the registry * shell `plugin-gantt/src/index.tsx`, read at the pin this repo builds against - * — `.objectui-sha` = `62597c588`, re-measured there 2026-09-23: both files, - * and `core/src/utils/record-source.ts`, are byte-identical to `87af769e9` - * (`git diff --quiet`), so no anchor moved on this hop. At `87af769e9` + * — `.objectui-sha` = `f8a9d0fb0`, re-measured there 2026-09-24: + * `plugin-gantt/src/index.tsx` and `core/src/utils/record-source.ts` are + * byte-identical to `62597c588` (`git diff --quiet`); `ObjectGantt.tsx` + * changed on this hop (+29/-2, objectui#10250: the toolbar Search term, below), + * so every anchor in it was re-mapped through the diff and re-read — those + * above the insertion (`:501-503`, `:613`) did not move, and every later one + * MOVED 21 or 29 lines with its cited text byte-identical (the retired `:1849` + * reading is a blank line at its new `:1878` too). All three files were + * byte-identical across the hop onto `62597c588`. At `87af769e9` * (re-READ 2026-09-22) not one anchor below was carried from `53ded82bf`; * every number was re-derived from that tree, and the `label` one moved far * enough that the retired reading now lands in an unrelated callback.) * Read points per key: `data` (`resolveRecordSourceConfig` at * `:613` — rung 1, `core/src/utils/record-source.ts:292`), `staticData` (rung 2, - * `record-source.ts:296`), `objectName` (rung 3; also `:1487` and `:1682` here), - * `filter` (`:844`, verbatim to `$filter`), `sort` (`:845`, through + * `record-source.ts:296`), `objectName` (rung 3; also `:1516` and `:1711` here), + * `filter` (`:865`, verbatim to `$filter`), `sort` (`:866`, through * `convertSortToQueryParams` to `$orderby`), `gantt` (`:501-503` — * `getGanttConfig` branch 1, the author face and the registration's declared * `{ name: 'gantt', type: 'object' }` input (`plugin-gantt/src/index.tsx:121`), * validated there against this - * repo's own {@link GanttConfigSchema}), `navigation` (`:1615`), `label` - * (`:2181`, resolved through `resolveI18nLabel` for the export file name — + * repo's own {@link GanttConfigSchema}), `navigation` (`:1644`), `label` + * (`:2210`, resolved through `resolveI18nLabel` for the export file name — * ⚠️ the retired reading `:1849` was the comment ABOVE that chain and at this * pin is a BLANK line, two above a dependency-delete callback's own comment, * so it is re-READ here, not re-pointed), - * `skipWeekends` (`:1333`), `holidays` (`:1334`), `persistLayout` (`:1485`), - * `viewName` (`:1487`), `markers` (`:2136`), `criticalPath` (`:2139`), - * `showBaselines` (`:2142`), `readOnly` (`:1985` and `:2143`) and - * `mobileReadOnly` (`:2144`). + * `skipWeekends` (`:1362`), `holidays` (`:1363`), `persistLayout` (`:1514`), + * `viewName` (`:1516`), `markers` (`:2165`), `criticalPath` (`:2168`), + * `showBaselines` (`:2171`), `readOnly` (`:2014` and `:2172`) and + * `mobileReadOnly` (`:2173`). * * Measured and deliberately NOT declared: the flat `GanttConfig` spellings (the * flatten product — {@link OBJECT_GANTT_FLAT_CONFIG_GUIDANCE}); `title`, which * this renderer never reads (the export-name chain is `gantt.exportFileName` → - * `label` → the OBJECT's label → `objectName`, `:2179-2185`); a row cap — the - * reload's `$top` is the platform ceiling `NON_GRID_ROW_CEILING_TOP` (`:855`) - * and the renderer's own comment marks it "⛔ Not authorable" (`:853`); and + * `label` → the OBJECT's label → `objectName`, `:2208-2214`); a row cap — the + * reload's `$top` is the platform ceiling `NON_GRID_ROW_CEILING_TOP` (`:876`) + * and the renderer's own comment marks it "⛔ Not authorable" (`:874`); and * the `onTaskClick` / `onRowClick` / `onBeforeTaskUpdate` callbacks, which are - * host props. + * host props. ⚠️ New at this pin and recorded, not ruled: objectui#10250 + * gave the renderer two more reads, `search` and `searchableFields` + * (`:776-779`, sent as `$search` / `$searchFields` at `:880-885`), which + * `ListView.tsx` writes onto the node it generates from its toolbar Search + * box — a host-generated key pair in the same position as the flatten + * product, and not declared here. * * VALUE posture: `gantt` is the one config block in this family whose value * contract is already the SPEC's — `ObjectGantt.tsx:503` validates it against @@ -3929,12 +3983,15 @@ export type ObjectGanttPropsParsed = z.infer; /** * The flat `TreeConfig` spellings `getTreeConfig` reads ahead of the `tree` - * block (`ObjectTree.tsx:235-248`) and that `ObjectView` / `ListView` EMIT when - * they flatten `options.tree` (`ListView.tsx:3261-3275`, `case 'tree'`: the - * product carries these keys and NO `tree` key). Both halves re-READ at the - * pin this repo builds against (`.objectui-sha` = `62597c588`) on - * 2026-09-23 — `ObjectTree.tsx` and `ListView.tsx` are byte-identical to - * `87af769e9`, where both were re-READ 2026-09-22 (this record carried no pin + * block (`ObjectTree.tsx:246-259`) and that `ObjectView` / `ListView` EMIT when + * they flatten `options.tree` (`ListView.tsx:3366-3385`, `case 'tree'`: the + * product carries these keys, the EFFECTIVE `filter` objectui#10250 added, and + * NO `tree` key). Both halves re-READ at the + * pin this repo builds against (`.objectui-sha` = `f8a9d0fb0`) on + * 2026-09-24 — both files changed on this hop (`getTreeConfig` lost its + * `filter.tree` arm, objectui#9549; the flatten gained `filter`), and the + * flat key set each reads or emits did not move. At `62597c588` both were + * byte-identical to `87af769e9`, where both were re-READ 2026-09-22 (this record carried no pin * at all before that, so nothing re-checked it when the pin moved). Read, but NOT authorable — * one composition key per concept (Prime Directive #12), the ruling the map and * the gantt carry from objectui#5018 / #6469 and the channel `object-calendar` @@ -3943,7 +4000,7 @@ export type ObjectGanttPropsParsed = z.infer; * * `titleField` is in the set although no `tree` block key is spelled that way: * `ListView`'s flatten resolves `treeCfg.titleField` into `labelField` before - * emitting (`ListView.tsx:3270`, `labelField: treeCfg.labelField || + * emitting (`ListView.tsx:3380`, `labelField: treeCfg.labelField || * treeCfg.titleField || 'name'`), so the author's intent is always the block's * `labelField`, and the prescription below says so. * @@ -3951,7 +4008,7 @@ export type ObjectGanttPropsParsed = z.infer; * read rather than a moved one: `getTreeConfig`'s `?? schema.titleField` rung * — the `:117` this record used to cite — was removed on objectui#8841 * because it read the FLATTENED NODE and never the block, and the docblock at - * `ObjectTree.tsx:197-218` records the three measurements that retired it. + * `ObjectTree.tsx:198-219` records the three measurements that retired it. * The flatten half above is what keeps the key in this set; ⛔ do not restore * the renderer half from this record's history. */ @@ -3972,57 +4029,70 @@ const OBJECT_TREE_FLAT_CONFIG_GUIDANCE: readonly KeySetGuidance[] = [ /** * `object-tree` (objectui `plugin-tree/src/ObjectTree.tsx` plus the registry * shell `plugin-tree/src/index.tsx`, read at the pin this repo builds against - * — `.objectui-sha` = `62597c588`, re-measured there 2026-09-23: both files, - * and `core/src/utils/record-source.ts`, are byte-identical to `87af769e9` - * (`git diff --quiet`), so no anchor moved on this hop. At `87af769e9` + * — `.objectui-sha` = `f8a9d0fb0`, re-measured there 2026-09-24: + * `plugin-tree/src/index.tsx` and `core/src/utils/record-source.ts` are + * byte-identical to `62597c588` (`git diff --quiet`); `ObjectTree.tsx` + * changed (+69/-3: objectui#9549 deleted `getTreeConfig`'s `filter.tree` + * arm, and objectui#9136 routed the inline `value` provider through a + * `ValueDataSource` query that honours `filter` and the row ceiling), so + * every anchor in it was re-READ: two changed CONTENT and say so where they + * are cited, and every other one MOVED with its cited text byte-identical. + * All three files were byte-identical across the hop onto `62597c588`. At `87af769e9` * (re-READ 2026-09-22) no anchor below was carried from `53ded82bf`; every * one was re-derived from that tree, and the ladder call changed in CONTENT * as well as position.) * Read points per key: `data` (`resolveRecordSourceConfig` at - * `:582` — rung 1, `core/src/utils/record-source.ts:292`, which returns the + * `:593` — rung 1, `core/src/utils/record-source.ts:292`, which returns the * authored value VERBATIM; that ONE site is the whole support * for the arm this row declares. ⚠️ The ARM this renderer passes is * `'undeclared'`, not the `'view-data'` its siblings pass, so rung 1 honours * any truthy value there — WIDER than this row, which is the harmless * direction: the bare array this door refuses is one the renderer would have * taken, never the reverse), `staticData` (rung 2, - * `record-source.ts:296`), `objectName` (rung 3; also `:871`, `:922` and - * `:985` here, each behind `resolveRecordSourceObjectName`, plus the - * parent-field detection at `:813-814`), - * `filter` (`:742`, verbatim to `$filter`), `tree` (`:236`, the - * nested config block `getTreeConfig` (`:235-248`) reads, and the + * `record-source.ts:296`), `objectName` (rung 3; also `:937`, `:988` and + * `:1051` here, each behind `resolveRecordSourceObjectName`, plus the + * parent-field detection at `:879-880`), + * `filter` (`:753`, verbatim to `$filter` on the object fetch, and — new at + * this pin, objectui#9136 — `:837`, the same key on the inline `value` + * provider's `ValueDataSource` query), `tree` (`:247`, the + * nested config block `getTreeConfig` (`:246-259`) reads, and the * registration's declared `{ name: 'tree', type: 'object' }` input - * (`plugin-tree/src/index.tsx:27-31`)) and `navigation` (`:908`, handed to - * `useNavigationOverlay` at `:891`). + * (`plugin-tree/src/index.tsx:27-31`)) and `navigation` (`:974`, handed to + * `useNavigationOverlay` at `:957`). * * ⚠️ `data` IS declared here, and that is the measurement, not a family * symmetry. objectui#9234 left this block's rung-1 read marked `undeclared` * because neither published face carried the key: `ObjectTreeSchema` on - * `@object-ui/types` declares no `data`, no `staticData`, no `filter` and no - * `navigation` at all, and requires `objectName`. The renderer reads all four + * `@object-ui/types` declared no `data`, no `staticData`, no `filter` and no + * `navigation` at all, and requires `objectName` (⚠️ at this pin it declares + * `filter`, in the `QueryParams['$filter']` shape, objectui#9549; the other + * three are still absent). The renderer reads all four * — so the protocol row follows the READ POINTS, which is what 「以协议为准」 * resolving for this block means, and the mirror is the face that has to * follow. * - * ⛔ `:775` is NOT a second site for the object arm, and citing it as one would + * ⛔ `:786` is NOT a second site for the object arm, and citing it as one would * be citing a read of the opposite SHAPE: `(rest as any).data ?? schema.data` * (the cast on `schema` went away with objectui#8655; the one on `rest` stays) * is gated by `Array.isArray(passed)` on the very next line, so it * honours only the bare-ARRAY shorthand this row REFUSES — the same shorthand * `object-map` measures and declines one section up. One ladder site is - * sufficient, and `:582` is it. + * sufficient, and `:593` is it. * * Measured and deliberately NOT declared: the flat `TreeConfig` spellings * ({@link OBJECT_TREE_FLAT_CONFIG_GUIDANCE}); the bare-array `data` shorthand - * `:775-776` accepts, which `ViewData` cannot publish (a discriminated union + * `:786-787` accepts, which `ViewData` cannot publish (a discriminated union * over OBJECT variants) and for which `staticData` is this block's declared * door; `sort` — this renderer's fetch - * (`:741-753`) carries `$filter`, `$top` and `$expand` and NO `$orderby`, and + * (`:752-764`) carries `$filter`, `$top` and `$expand` and NO `$orderby`, the + * inline query (`:836-845`) carries `$filter` and `$top` only, and * nothing else reads an order, so declaring one would publish a key with no read * site; a row cap, for the same reason `object-gantt` declares none (the `$top` - * is the platform ceiling at `:751`, marked "⛔ Not authorable" at `:750`); and - * `filter.tree`, the legacy stash `:236` still reads, which is a shape to stop - * writing rather than a key to declare. + * is the platform ceiling at `:762` and again at `:844`, marked "⛔ Not + * authorable" at `:761`); and `filter.tree`, the legacy stash — ⚠️ no longer + * read at this pin: objectui#9549 deleted that arm, so `getTreeConfig` + * (`:247`) takes the block from `tree` alone — which was a shape to stop + * writing and is not a key to declare. * * This is also the one block of the three whose type is absent from the tracked * `sdui.manifest.json`, so `check:react-declaration-parity` reports it as @@ -4050,13 +4120,13 @@ export const ObjectTreePropsSchema = lazySchema(() => strictObject({ * holds for them because each registers through `ElementDataSourceGate`, * which lowers the spec binding onto `objectName` before the renderer sees * the node. `plugin-tree/src/index.tsx` does NOT: at the pin this repo - * builds against (`.objectui-sha` = `62597c588`, re-COUNTED there - * 2026-09-23) its registry shell has ZERO hits for that wiring, against 3 + * builds against (`.objectui-sha` = `f8a9d0fb0`, re-COUNTED there + * 2026-09-24) its registry shell has ZERO hits for that wiring, against 3 * each in `plugin-map`, `plugin-gantt`, `plugin-grid` and `plugin-calendar` * — four controls, so the zero discriminates. ⚠️ Re-counted at every end * with ONE method (occurrences of that identifier in each `src/index.tsx`): - * `87af769e9` and `53ded82bf` both read 3 each and 0 for the tree as well — - * `plugin-grid/src/index.tsx` changed on this hop and still reads 3 — so + * `62597c588`, `87af769e9` and `53ded82bf` all read 3 each and 0 for the tree as well — + * `plugin-grid/src/index.tsx` changed on the hop onto `62597c588` and still reads 3 — so * nothing about this reading moved. The `7 each` this record used to carry is * reproducible at neither pin by that method, nor by a whole-package count * (7 / 5 / 11 / 5, not 7 each). ⛔ A count is a reading only with its METHOD @@ -4139,9 +4209,14 @@ const OBJECT_TIMELINE_FLAT_CONFIG_GUIDANCE: readonly KeySetGuidance[] = [ * `object-timeline` (objectui `plugin-timeline/src/ObjectTimeline.tsx`, the * presentational `plugin-timeline/src/renderer.tsx` it composes into, and the * registry shell `plugin-timeline/src/index.tsx` — all read at the pin this - * repo builds against (`.objectui-sha` = `62597c588`), re-measured there - * 2026-09-23: all three files are byte-identical to `87af769e9`, where they - * were re-READ 2026-09-22, so no anchor below moved on this hop. + * repo builds against (`.objectui-sha` = `f8a9d0fb0`), re-measured there + * 2026-09-24: `ObjectTimeline.tsx` and `index.tsx` are byte-identical to + * `62597c588` (`git diff --quiet`), and `renderer.tsx` changed (+46/-20, + * objectui `0b6b295a1`: a gantt row that is not an object is refused), so + * its three anchors were re-READ — each MOVED with its cited text + * byte-identical, `1215` -> `1240`, `1505` -> `1531`, `1442-1457` -> + * `1468-1483`. All three files were byte-identical to `87af769e9` at + * `62597c588`, and were re-READ there 2026-09-22. * * ⛔ This record used to be MIXED, and the historical spelling is what let it * be: its `limit` clause was re-read at this pin on 2026-09-21 while every @@ -4183,11 +4258,11 @@ const OBJECT_TIMELINE_FLAT_CONFIG_GUIDANCE: readonly KeySetGuidance[] = [ * `variant` (`:706`) and `navigation` (`:650-653` → `:785` → `:840-841`). * Four more are read by the presentational renderer off the schema this * component spreads into it (`effectiveSchema`, `:769-788`): `dateFormat` - * (`plugin-timeline/src/renderer.tsx:1215`, every variant — its number is the - * same at both pins, as `plugin-timeline/src/index.tsx:333`'s also is, which is - * why the number alone is never the reading) and the gantt trio `rowLabel` - * (`plugin-timeline/src/renderer.tsx:1505`), `minDate` / `maxDate` - * (`plugin-timeline/src/renderer.tsx:1442-1457`). ⚠️ All three name their + * (`plugin-timeline/src/renderer.tsx:1240`, every variant — its number was the + * same at `53ded82bf` and `87af769e9`, as `plugin-timeline/src/index.tsx:333`'s + * also was, which is why the number alone is never the reading) and the gantt + * trio `rowLabel` (`plugin-timeline/src/renderer.tsx:1531`), `minDate` / + * `maxDate` (`plugin-timeline/src/renderer.tsx:1468-1483`). ⚠️ All three name their * package because objectui has a second `renderer.tsx` (in `plugin-chatbot`): * a suffix that matches two files names neither, and the gate drops it from * the population rather than guessing. @@ -4314,8 +4389,8 @@ export const ObjectTimelinePropsSchema = lazySchema(() => strictObject({ * first publishes a refusal for a key the renderer honours. * * Read points at the pin this repo builds against (`.objectui-sha` = - * `62597c588`; the file is byte-identical to `87af769e9`, where they were - * re-READ 2026-09-22), all in + * `f8a9d0fb0`; the file is byte-identical to `62597c588` and `87af769e9`, + * where they were re-READ 2026-09-22), all in * `ObjectTimeline.tsx`: `:255` seeds the loading state off it, `:420` * SKIPS the object query when it is present, `:442` tracks it, and `:444` * is the row source itself — `(props as any).data || boundData || @@ -4523,10 +4598,13 @@ export const ComponentPropsMap = { // authority for map and gantt while tree's rung-1 `data` read stayed // undeclared on every face. Key sets measured from the renderers' read // points at the pin this repo builds against (`.objectui-sha` = - // `62597c588`), all three re-measured there 2026-09-23 (gantt and tree - // byte-identical to `87af769e9`, where all three were re-READ 2026-09-22; - // the map's anchors moved with their text byte-identical and no key set - // moved) — per-block citations in + // `f8a9d0fb0`), all three re-measured there 2026-09-24 (the map + // byte-identical to `62597c588`; the gantt and tree renderers changed and + // were re-READ — no declared key set moved, the gantt's new `search` / + // `searchableFields` reads are recorded in its header as host-generated and + // undeclared, and the tree lost its `filter.tree` stash read; at `62597c588` + // gantt and tree were byte-identical to `87af769e9`, where all three were + // re-READ 2026-09-22) — per-block citations in // each schema's header, including what each block reads and deliberately // does NOT declare, and what the hop from `53ded82bf` deleted rather than // moved. @@ -4540,8 +4618,10 @@ export const ComponentPropsMap = { // it — so `object-timeline` was unjudged in both directions, a real key and // a typo riding through alike. Key set measured from the renderer's read // points at the pin this repo builds against (`.objectui-sha` = - // `62597c588`), re-measured there 2026-09-23 (byte-identical to `87af769e9`, - // where it was re-READ 2026-09-22); the schema's own header + // `f8a9d0fb0`), re-measured there 2026-09-24 (`ObjectTimeline.tsx` and + // `index.tsx` byte-identical to `62597c588` and `87af769e9`, where it was + // re-READ 2026-09-22; `renderer.tsx`'s three anchors moved with their text + // byte-identical); the schema's own header // carries the per-key citations and what it deliberately does NOT declare. 'object-timeline': ObjectTimelinePropsSchema, } as const; diff --git a/packages/spec/src/ui/dataset.zod.ts b/packages/spec/src/ui/dataset.zod.ts index f764608b21e..3e9fb04033f 100644 --- a/packages/spec/src/ui/dataset.zod.ts +++ b/packages/spec/src/ui/dataset.zod.ts @@ -209,13 +209,19 @@ export const DatasetMeasureSchema = lazySchema(() => strictObject({ * and this docblock and the `describe` beneath it both said so. * * Measured at the pin this repo builds against (`.objectui-sha` = - * `62597c588`; re-derived at that pin 2026-09-23 — `dataset-format.ts` is - * byte-identical to `87af769e9`, and `date-display.ts` moved (objectui - * `516583b54`, +77/-4): `formatDate` now parses through `toDisplayDate`, so a - * date-only value renders the calendar day it names in every timezone, - * while the style handling this record cites re-reads unchanged; its two - * anchors MOVED `198-233` -> `271-306` and `152` -> `225`, the second - * byte-identical. At `87af769e9` (2026-09-20) every anchor below MOVED and + * `f8a9d0fb0`; re-derived at that pin 2026-09-24 — both files moved on this + * hop (objectui `ad694ac3d`, objectui#10026: the shared date path refuses a + * date-only calendar day that does not exist, with the dash it renders for + * any unparsable value, and `dataset-format.ts` rewrote + * `formatMeasureDate`'s comment on that case), while the style handling + * this record cites re-reads unchanged: `formatDate` `271-306` -> `355-390` + * and the ±7-day fallback `225` -> `309` MOVED byte-identical, and + * `formatMeasureDate` is `:229-263` (one comment line shorter), its call at + * `:369` and its datetime arm at `:259`-`:261`. At `62597c588` (2026-09-23) + * `dataset-format.ts` was byte-identical to `87af769e9`, and `date-display.ts` + * had moved (objectui `516583b54`, +77/-4): `formatDate` parses through + * `toDisplayDate`, so a date-only value renders the calendar day it names in + * every timezone. At `87af769e9` (2026-09-20) every anchor below MOVED and * one of them changed SUBSTANCE, so nothing here was carried there either: * `formatMeasureDate`'s datetime arm no longer calls * `formatDateTime(v, { locale })` unconditionally, it SELECTS a formatter, @@ -223,17 +229,17 @@ export const DatasetMeasureSchema = lazySchema(() => strictObject({ * into and widening that published signature was refused) in * objectui * `packages/core/src/utils/dataset-format.ts`: `formatMeasure` routes a - * non-numeric value through `formatMeasureDate` (`:229-264`, was `:185-198`) - * at `:370`, + * non-numeric value through `formatMeasureDate` (`:229-263`, was `:229-264` + * and before that `:185-198`) at `:369`, * whose date-only arm threads `format` into the STYLE parameter of - * `formatDate` (`utils/date-display.ts:271-306`, was `:198-233` and before - * that `:131-164`, whose `relative` branch falls back to the absolute form - * beyond ±7 days at `:225`, was `:152` and `:117` — the fallback strips the style through + * `formatDate` (`utils/date-display.ts:355-390`, was `:271-306`, `:198-233` + * and before that `:131-164`, whose `relative` branch falls back to the absolute form + * beyond ±7 days at `:309`, was `:225`, `:152` and `:117` — the fallback strips the style through * `absoluteFallbackOptions`), while its datetime arm answers `relative` with - * `formatRelativeDate` (`:260`), `short` with - * `formatDateTime(v, { locale, style: 'compact' })` (`:261`) and everything + * `formatRelativeDate` (`:259`), `short` with + * `formatDateTime(v, { locale, style: 'compact' })` (`:260`) and everything * else — a date PATTERN included — with the bare - * `formatDateTime(v, { locale })` (`:262`). + * `formatDateTime(v, { locale })` (`:261`). * Teaching * the shared path a pattern grammar would change every list cell that reads * it, so that gap is still DOCUMENTED here rather than closed (objectui#7178 diff --git a/packages/spec/src/ui/view.zod.ts b/packages/spec/src/ui/view.zod.ts index d82029734eb..12c6c0b953b 100644 --- a/packages/spec/src/ui/view.zod.ts +++ b/packages/spec/src/ui/view.zod.ts @@ -1463,12 +1463,18 @@ type RowLimitView = keyof typeof ROW_LIMIT_SUBJECT; * * ⚠️ WHAT THIS VIEW-FACE KEY REACHES TODAY — recorded, not repaired (#19228). * Measured first-hand at the pin this repo builds against (`.objectui-sha` = - * `62597c588`), with TWO instruments, because one was not enough and the + * `f8a9d0fb0`), with TWO instruments, because one was not enough and the * first one's answer was wrong. First taken at `87af769e9` 2026-09-21T09:15Z; - * re-taken at `62597c588` 2026-09-23, where instrument 1 returns the SAME hit - * set line for line (probe 0; control 13 lines, 6 files) and all nine - * objectui files cited below are byte-identical to `87af769e9`, so every - * anchor and both verdicts stand unmoved: + * re-taken at `62597c588` 2026-09-23, where instrument 1 returned the SAME + * hit set line for line (probe 0; control 13 lines, 6 files) and all nine + * objectui files cited below were byte-identical to `87af769e9`; re-taken + * again at `f8a9d0fb0` 2026-09-24, where the probe is still 0, the control + * gains ONE line in a seventh file (a test, below), instrument 2 returns the + * same four flattening spreads and the same exclusions, and every anchor in + * the six cited files that changed (both `ObjectView.tsx`, `ListView.tsx`, + * `ObjectKanban.tsx`, `ObjectGallery.tsx`; `ObjectTimeline.tsx` and the + * three cited tests are byte-identical) MOVED with its cited text + * byte-identical — so both verdicts stand unmoved, at the numbers below: * * 1. PROPERTY-ACCESS spellings. ⛔ Published as its EXPRESSION, not as a * number — this card exists because a confident count was wrong once, so @@ -1476,21 +1482,23 @@ type RowLimitView = keyof typeof ROW_LIMIT_SUBJECT; * an objectui checkout, over every tracked file: * probe: git grep -nIE '\.(kanban|gallery|timeline)(\?)?\.limit\b' * control: git grep -nIE '\.(kanban|gallery|timeline)(\?)?\.(groupByField|scale|coverField)\b' - * Probe: **0** lines, 0 files. Control: **13** lines across **6** files — + * Probe: **0** lines, 0 files. Control: **14** lines across **7** files — * `app-shell/src/views/ObjectView.galleryBinding-7547.test.tsx:41`, - * `app-shell/src/views/ObjectView.tsx:450`, - * `plugin-list/src/ListView.tsx:2538`, `:2540`, `:2547`, `:3057`, `:3114`, - * `:3116`, + * `app-shell/src/views/ObjectView.tsx:451`, + * `plugin-detail/src/__tests__/RelatedList.selectFls-10186.test.tsx:314` + * (new at this pin, an executable test line), + * `plugin-list/src/ListView.tsx:2551`, `:2553`, `:2560`, `:3145`, `:3202`, + * `:3204`, * `plugin-list/src/__tests__/ListView.kanbanOptionsBagCanonical-8193.test.tsx:42`, - * `:99`, `plugin-view/src/ObjectView.tsx:1695`, and + * `:99`, `plugin-view/src/ObjectView.tsx:1723`, and * `types/src/__tests__/object-kanban-group-by-limit-7322.test.ts:146`, `:148`. * ⚠️ Filtering changes that number and the filter must be stated with it. - * Of the 13: **2 are COMMENTS** (`ObjectView.galleryBinding-7547.test.tsx:41`, + * Of the 14: **2 are COMMENTS** (`ObjectView.galleryBinding-7547.test.tsx:41`, * `ListView.kanbanOptionsBagCanonical-8193.test.tsx:42`), **1 is an * `it()` TITLE string** (same file, `:99` — ⛔ not a comment), and **2 are * lines inside a QUOTED source-text pin** * (`object-kanban-group-by-limit-7322.test.ts:146`, `:148`). So a reader - * counting executable reads only gets **8**. All three readings are of one + * counting executable reads only gets **9** (8 at `62597c588`). All three readings are of one * hit set. A live instrument — and a WRONG answer. * 2. ⭐ SPREADS — a spread carries a key without ever spelling it, so it is * the hole instrument 1 cannot see by construction. ⛔ Re-take it by its @@ -1501,46 +1509,46 @@ type RowLimitView = keyof typeof ROW_LIMIT_SUBJECT; * excludes). A grep broad enough to find these also returns the nested * merges, so the rule, not the number, is what makes it reproducible. * ⛔ And name what the predicate EXCLUDES, or the next reader re-finds - * it and wonders: `app-shell/src/views/ObjectView.tsx:206` and `:342` - * ARE spreads of a view block, inside `timelineViewOptions` (`:201`) and - * `galleryViewOptions` (`:334`). They build an OPTIONS BAG that feeds + * it and wonders: `app-shell/src/views/ObjectView.tsx:207` and `:343` + * ARE spreads of a view block, inside `timelineViewOptions` (`:202`) and + * `galleryViewOptions` (`:335`). They build an OPTIONS BAG that feeds * `ListView`'s nested forward, not the object literal an adapter returns * as the node, so the predicate excludes them — deliberately, not by * oversight. Two more the predicate excludes for their own reasons: - * `plugin-list/src/ListView.tsx:3044-3046` (`mergedGallery`) builds a + * `plugin-list/src/ListView.tsx:3132-3134` (`mergedGallery`) builds a * NESTED gallery prop, the `...mergedTimeline` family; and - * `app-shell/src/views/ObjectView.tsx:1284` + * `app-shell/src/views/ObjectView.tsx:1406` * (`spec.kanban = { ...(spec.kanban || {}), columns }`) writes back into a * VIEW document's own block — a metadata write, not a node build. * Under that predicate, at that pin, the VIEW-face per-kind blocks give: - * `plugin-list/src/ListView.tsx:2979` `...restKanban` - * `plugin-view/src/ObjectView.tsx:1638` `...restKanban` - * `plugin-view/src/ObjectView.tsx:1697` `...(viewOptions.gallery || {})` - * `plugin-view/src/ObjectView.tsx:1725` `...(viewOptions.timeline || {})` - * Neither `restKanban` destructure strips `limit` (`ListView.tsx:2952`, - * `ObjectView.tsx:1579`), so a VIEW's per-kind `limit` — INCLUDING the 100 + * `plugin-list/src/ListView.tsx:3067` `...restKanban` + * `plugin-view/src/ObjectView.tsx:1666` `...restKanban` + * `plugin-view/src/ObjectView.tsx:1725` `...(viewOptions.gallery || {})` + * `plugin-view/src/ObjectView.tsx:1753` `...(viewOptions.timeline || {})` + * Neither `restKanban` destructure strips `limit` (`ListView.tsx:3040`, + * `ObjectView.tsx:1607`), so a VIEW's per-kind `limit` — INCLUDING the 100 * this applied default materializes — becomes the generated node's * ELEMENT-face flat `limit`, which is the key the renderers read. * * ⇒ **A view's `kanban.limit`: flattened on BOTH adapter routes, and read.** - * `ObjectKanban.tsx:553` runs `describeRefusedRowLimit(schema.limit, …)` + * `ObjectKanban.tsx:554` runs `describeRefusedRowLimit(schema.limit, …)` * unconditionally. * ⇒ **A view's `timeline.limit`: ROUTE-DEPENDENT.** `plugin-view` flattens it - * (`ObjectView.tsx:1725`) and the node it returns carries no `timeline` + * (`ObjectView.tsx:1753`) and the node it returns carries no `timeline` * block at all, so the value arrives as the node's flat `limit` and * `ObjectTimeline.tsx:279` reads it. `plugin-list` instead forwards the - * block NESTED (`ListView.tsx:3084`), where nothing reads it. - * ⇒ **A view's `gallery.limit`: flattened by `ObjectView.tsx:1697` and read by + * block NESTED (`ListView.tsx:3172`), where nothing reads it. + * ⇒ **A view's `gallery.limit`: flattened by `ObjectView.tsx:1725` and read by * NOBODY** — `ObjectGallery.tsx` contains no `limit` at all (0 occurrences, * case-insensitive, against a lit control `schema.imageField` / * `schema.titleField` at `:340` / `:348`). ⛔ Do not generalise that * asymmetry to the other two; it is gallery's alone. * - * ⚠️ Where it IS read, the `$top` it would govern (`ObjectKanban.tsx:676`, + * ⚠️ Where it IS read, the `$top` it would govern (`ObjectKanban.tsx:687`, * `ObjectTimeline.tsx:407`) is still not issued on either adapter route today: - * both hosts hand rows down as a React `data` prop (`ListView.tsx:4702`, - * `ObjectView.tsx:2319`) and both children short-circuit their own fetch on it - * (`ObjectKanban.tsx:559`, `ObjectTimeline.tsx:420`). ⛔ That is a statement + * both hosts hand rows down as a React `data` prop (`ListView.tsx:4815`, + * `ObjectView.tsx:2347`) and both children short-circuit their own fetch on it + * (`ObjectKanban.tsx:565`, `ObjectTimeline.tsx:420`). ⛔ That is a statement * about the QUERY, not about the key being unread. * * ⚠️ A consequence of APPLIED that the open decision needs: through those @@ -2193,14 +2201,20 @@ export const TreeConfigSchema = lazySchema(() => strictObject({ * `map: { style }`, which the flatten whitelist carries out as `mapStyle`), * while `getMapConfig` itself is byte-identical, so both read points moved 19 * lines and neither changed what it does; the other five anchors sit in files - * byte-identical to `87af769e9`. Each anchor quotes the line it was read at, + * byte-identical to `87af769e9`. RE-READ again at pin `f8a9d0fb0` on + * 2026-09-24: that bump redded three anchors, and each MOVED with the block it + * opens byte-identical — `ObjectView.tsx`'s `case 'map':` `1764` -> `1792` + * (17 lines), `ObjectMapConfigSchema` `1574` -> `1589` (the whole 47-line + * declaration) and `LIST_VIEW_LOCAL_OVERRIDES` `734` -> `741` (the whole + * list, still without `map`); `ObjectMap.tsx` and the `ListView.tsx` anchors + * did not move. Each anchor quotes the line it was read at, * so the next pin bump reds instead of rotting * (`check:objectui-pin-citations`): * * - **The block this face feeds is FLATTENED, not forwarded.** `ListView` * (`packages/plugin-list/src/ListView.tsx:146` first line * `function resolveListMapConfig(schema: { map?: unknown; options?: { map?: unknown } }): Record {`) - * and `ObjectView` (`packages/plugin-view/src/ObjectView.tsx:1764` first line + * and `ObjectView` (`packages/plugin-view/src/ObjectView.tsx:1792` first line * `case 'map':`) copy it through a HAND-LISTED whitelist * (`packages/plugin-list/src/ListView.tsx:85` first line * `export const FLAT_MAP_CONFIG_SPELLING = {`) — ⚠️ re-read at the new pin: @@ -2212,7 +2226,7 @@ export const TreeConfigSchema = lazySchema(() => strictObject({ * there, but by a whitelist and in SILENCE: no parse, no warning, no * diagnostic of any kind. * - **The renderer's own zod schema does not close the set.** - * `packages/types/src/zod/objectql.zod.ts:1574` first line + * `packages/types/src/zod/objectql.zod.ts:1589` first line * `export const ObjectMapConfigSchema = z.object({` — a plain `z.object`, * NOT strict, so an undeclared key parses clean there: zero issues, no * warning. `getMapConfig` consults that `safeParse` @@ -2228,7 +2242,7 @@ export const TreeConfigSchema = lazySchema(() => strictObject({ * checker at all: it dies in the whitelist without a word, and the one schema * that could have reported it is open and warn-only. And this parse is the only * place an author is told ANYWHERE: `map` is not in objectui's - * `LIST_VIEW_LOCAL_OVERRIDES` (`packages/types/src/zod/objectql.zod.ts:734` + * `LIST_VIEW_LOCAL_OVERRIDES` (`packages/types/src/zod/objectql.zod.ts:741` * first line `const LIST_VIEW_LOCAL_OVERRIDES = [`), so objectui's own * `ListViewSchema` imports THIS block by reference and the document check on * that side is this same schema. The two key sets MIRROR each other, key for @@ -2242,8 +2256,10 @@ export const TreeConfigSchema = lazySchema(() => strictObject({ * (2026-09-23: `objectql.zod.ts` and `plugin-map.mdx` are byte-identical to * `87af769e9`, and the `ObjectMap.tsx` read MOVED `377` -> `396` with its line * byte-identical; at `87af769e9`, 2026-09-20, each of these three had moved - * and each was re-READ): - * `packages/types/src/zod/objectql.zod.ts:1574` declares the eight keys, + * and each was re-READ; at `f8a9d0fb0`, 2026-09-24, `ObjectMap.tsx` and + * `plugin-map.mdx` are byte-identical to `62597c588` and the declaration MOVED + * `1574` -> `1589` byte-identical): + * `packages/types/src/zod/objectql.zod.ts:1589` declares the eight keys, * `packages/plugin-map/src/ObjectMap.tsx:396` reads * `schema.mapStyle || schema.map?.style`, and objectui's own * `content/docs/plugins/plugin-map.mdx:143` documents `style` in the block — @@ -3367,10 +3383,13 @@ const FormFieldBaseSchema = lazySchema(() => { * inside the `53ded82bf7...87af769e9` range, so the widest-tier-only * under-span this block used to record (#17328: one cell of two at * 720px) no longer reproduces at the pin this repo builds against - * (`.objectui-sha` = `62597c588`, re-read 2026-09-23: `form.tsx` is - * byte-identical to `87af769e9`, so `spanLadderFor` still emits the ladder). + * (`.objectui-sha` = `f8a9d0fb0`, re-read 2026-09-24: `form.tsx` changed on + * this hop only in its registration's input list, objectui#9910's + * `children` slot, and `spanLadderFor` at `:204-231` is byte-identical, so it + * still emits the ladder; `plugin-form`'s `autoLayout.ts` is byte-identical + * to `62597c588`, where `form.tsx` was byte-identical to `87af769e9`). */ - span: z.enum(['auto', 'full']).default('auto').describe("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` = `62597c588`), 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."), + span: z.enum(['auto', 'full']).default('auto').describe("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` = `f8a9d0fb0596`), 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."), /** Custom widget override — only needed when auto-inference is insufficient */ widget: z.string().optional().describe('Custom widget/component name (overrides type-based inference)'), diff --git a/scripts/sdui-manifest.record.json b/scripts/sdui-manifest.record.json index 4848a786387..a737f58b1cd 100644 --- a/scripts/sdui-manifest.record.json +++ b/scripts/sdui-manifest.record.json @@ -11,12 +11,12 @@ "a pin bump without regeneration goes RED there — that is the anti-rot half of the freshness gate.", "Regenerate + re-record: pnpm objectui:build && node scripts/gen-sdui-manifest-node.mjs" ], - "objectuiSha": "62597c588072636e9c30ea35b3d89b1e46fd765d", + "objectuiSha": "f8a9d0fb0596f4521076628e2bbfe27e6ce67d52", "source": "built-tree", - "modulesRoot": ".cache/objectui-62597c588072/apps/console", + "modulesRoot": ".cache/objectui-f8a9d0fb0596/apps/console", "objectuiWorkspaceVersion": "17.6.0", "generator": "scripts/gen-sdui-manifest-node.mjs", - "generatedAt": "2026-09-23", - "sha256": "22c83c9ec70163559c2bd8f7b1613174d8660ad9949d15ed483a4189b7857c9a", + "generatedAt": "2026-09-24", + "sha256": "12dd4f8fbf455c6e6fd5503edbbc19799d5b635f341286255bfeda6e75875360", "components": 59 } diff --git a/sdui.manifest.json b/sdui.manifest.json index 32492523bc2..4628135d925 100644 --- a/sdui.manifest.json +++ b/sdui.manifest.json @@ -2110,6 +2110,10 @@ { "name": "className", "type": "string" + }, + { + "name": "children", + "type": "slot" } ] }, @@ -2151,6 +2155,10 @@ { "name": "className", "type": "string" + }, + { + "name": "children", + "type": "slot" } ] }, @@ -2199,6 +2207,10 @@ { "name": "className", "type": "string" + }, + { + "name": "children", + "type": "slot" } ] }, @@ -2218,6 +2230,10 @@ { "name": "className", "type": "string" + }, + { + "name": "children", + "type": "slot" } ] }, @@ -2342,6 +2358,10 @@ { "name": "className", "type": "string" + }, + { + "name": "children", + "type": "slot" } ] }, @@ -2353,6 +2373,10 @@ { "name": "className", "type": "string" + }, + { + "name": "children", + "type": "slot" } ] }, @@ -2528,6 +2552,11 @@ { "name": "className", "type": "string" + }, + { + "name": "children", + "type": "slot", + "description": "Rich label content, rendered when `label` is not set" } ] }, @@ -2555,6 +2584,11 @@ { "name": "className", "type": "string" + }, + { + "name": "children", + "type": "slot", + "description": "Rich description content, rendered when `description` is not set" } ] }, @@ -2591,6 +2625,11 @@ { "name": "className", "type": "string" + }, + { + "name": "children", + "type": "slot", + "description": "Rich label content, rendered when `label` is not set" } ] },