diff --git a/.changeset/22682-position-form-permission-sets-picker.md b/.changeset/22682-position-form-permission-sets-picker.md new file mode 100644 index 00000000000..9350216a605 --- /dev/null +++ b/.changeset/22682-position-form-permission-sets-picker.md @@ -0,0 +1,11 @@ +--- +"@objectstack/spec": patch +--- + +`positionForm`: the `permissionSets` row now declares `widget: 'ref-multi:permission'` in place of `type: 'tags'`. ADR-0131 D4 resolves a reference to a declared item by machine name, registry-first, so the row names the permission-set registry (metadata type `permission`) for the designer to offer the declared sets and commit their names, instead of a free-text tag box where a name that does not exist can be typed. + +Clause-②: no + +- **The key.** `ref-multi:` followed by a metadata type is the list form of the forms' `ref:` pickers (`ref:object`, `ref:dataset`, `ref:component`, all single-valued). A distinct key, as `field-ref` / `field-multi` already are, because a single `ref:` picker writes one string and the widget registry declares one labelling per key. +- **Which renderer honours it.** A console whose metadata-admin widget registry has no `ref-multi:permission` entry renders this row as its announced fallback: a JSON editor with the note that no custom renderer is registered. The stored value is the same list of names either way. +- ⛔ Only this one form row changes. No schema, parse, export or accept-set change: `PositionSchema.permissionSets` stays a list of snake_case names, and `FormField.widget` stays a free string. diff --git a/.changeset/console-4997995022f8.md b/.changeset/console-4997995022f8.md new file mode 100644 index 00000000000..941118841d6 --- /dev/null +++ b/.changeset/console-4997995022f8.md @@ -0,0 +1,20 @@ +--- +"@objectstack/console": minor +--- + +Console (objectui) refreshed to `4997995022f8`. Frontend changes in this range: + +Derived from the changesets objectui declared over the range — 5 releasing of 5 changesets added across 7 non-merge commits; omitted: 2 commits carrying no changeset (they ship no package code). + +- **minor** — A Studio form field that declares the `ref-multi:permission` widget now renders a picker of the declared permission sets instead of the JSON editor fallback (objectui#12126). (objectui `499799502`) +- **minor** — The Marketplace's install answers now say what the runtime served (objectui#12098). (objectui `107139379`) +- **minor** — A paged grid's column footer reads the whole matched set, or says it reads the page (objectui#12081 item 3). (objectui `69bca0af6`) +- **patch** — A boolean field whose `defaultValue` is a CEL expression or a runtime token now gets that default on create (objectui#12121). (objectui `c9fc10b1e`) +- **patch** — More write affordances read the affordance-to-grant map, so a caller without the grant is no longer offered a write the server then refuses (objectui#12082, leg A of the write-cen… (objectui `752504520`) + +**In this console build, declared nowhere** — objectui merged 2 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: stop teaching keys the strict authoring face refuses (objectui#12131, phase 1) (#12134) (objectui `66eb5604e`) +- _(no changeset)_ fix(examples): repair the class (i) keys the strict authoring face refuses (objectui#5250 slice C) (#12128) (objectui `802f0bc41`) + +objectui range: `0df67f237c5a...4997995022f8` diff --git a/.changeset/objectui-pin-citations-4997995022f8.md b/.changeset/objectui-pin-citations-4997995022f8.md new file mode 100644 index 00000000000..11d1d3c5128 --- /dev/null +++ b/.changeset/objectui-pin-citations-4997995022f8.md @@ -0,0 +1,18 @@ +--- +'@objectstack/spec': patch +--- + +The spec's objectui citations, and the shipped description text that names the `.objectui-sha` pin (the `FormField.span` describe and six migration-entry descriptions), are re-measured against the new console pin, objectui `4997995022f8`. + +Clause-②: no + +Every anchor was mapped through the objectui diff `0df67f237c5a..4997995022f8`: 80 paths over 7 commits, none deleted and one renamed (a schema-catalog example, which no record cites). Three files a record cites changed on the hop, plus the `en` / `zh` / `de` packs (whose `calendar.configRequired` strings did not change): `ObjectGrid.tsx` (objectui#12081 item 3 and objectui#12082), `ObjectGantt.tsx` (objectui#12082) and `form.tsx` (objectui#12121). Every cited line in them moved or held with its text byte-identical, and each record that cites one is re-pointed with a hop sentence that says by how much. The records that cite only byte-identical files gain a hop sentence that says so. + +Two readings sit beside a cited read, and each hop sentence says what it found: + +- `ObjectGrid.tsx`: a bulk `update` def is now withheld unless the edit verdict allows it (objectui#12082), which narrows the declared defs and adds no implicit one, so the `sys_api_key` reading holds. The selection block still hashes to `c88443302d40`. +- `ObjectGantt.tsx`: the chart's in-chart write handlers are withheld from a caller without the grant (objectui#12082). No `schema.*` read moved; the renderer reads the same 49 names at both pins. + +The six migration entries' corpus counts were re-taken with `git grep -o -F`, the method that reproduces every `0df67f237c5a` number. The corpus is now 8441 tracked files. Every token an entry counts as zero still reads zero (96 tokens; `Span` and `SpanSchema` read 517 and 57 at both pins, as the tracing entry records). The controls moved with the corpus, for example `objectstack` from 18248 to 18271 and `timeout` from 1705 to 1704. + +No key, default, enum member or export moves. diff --git a/.objectui-sha b/.objectui-sha index 8341ee8b200..97325989491 100644 --- a/.objectui-sha +++ b/.objectui-sha @@ -1 +1 @@ -0df67f237c5ab46cbc65252c5f6bd05f2be44c48 +4997995022f8e65946f6362b7434685539cc72b7 diff --git a/content/docs/references/ui/view.mdx b/content/docs/references/ui/view.mdx index 8fd7765ea6c..11812a8b1a2 100644 --- a/content/docs/references/ui/view.mdx +++ b/content/docs/references/ui/view.mdx @@ -213,7 +213,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` = `0df67f237c5a`), only textarea, markdown, html, richtext and repeater resolve to the full column count (repeater reaches it through the wide `field:grid` widget it maps to). 'full': resolves to the form grid's full column count. How far down the container-query tiers that span is emitted is the renderer's, not this key's: at that same pin the renderer emits one clamped col-span class per multi-column tier (`@md:col-span-2 @2xl:col-span-3` for a 3-column grid), so the field takes the whole row at every multi-column tier, not just the widest. | +| **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` = `4997995022f8`), 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 | @@ -343,7 +343,7 @@ Form-view select option — the object-field option shape minus the per-option ` | **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` = `0df67f237c5a`), only textarea, markdown, html, richtext and repeater resolve to the full column count (repeater reaches it through the wide `field:grid` widget it maps to). 'full': resolves to the form grid's full column count. How far down the container-query tiers that span is emitted is the renderer's, not this key's: at that same pin the renderer emits one clamped col-span class per multi-column tier (`@md:col-span-2 @2xl:col-span-3` for a 3-column grid), so the field takes the whole row at every multi-column tier, not just the widest. | +| **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` = `4997995022f8`), 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 d5b9b0c7bae..9ff6726ea5b 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": "0df67f237c5ab46cbc65252c5f6bd05f2be44c48", - "revDate": "2026-10-11T07:26:10+00:00", + "rev": "4997995022f8e65946f6362b7434685539cc72b7", + "revDate": "2026-10-11T10:56:33+00:00", "source": "packages/sdui-parser/src", "files": [ "packages/sdui-parser/src/body-dialect.ts", @@ -21,7 +21,7 @@ "packages/sdui-parser/src/validate.ts" ] }, - "recordedAgainstPin": "0df67f237c5ab46cbc65252c5f6bd05f2be44c48", + "recordedAgainstPin": "4997995022f8e65946f6362b7434685539cc72b7", "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 d4ce1410d85..05043cc6ba0 100644 --- a/packages/spec/src/data/api-methods-batch-conformance.test.ts +++ b/packages/spec/src/data/api-methods-batch-conformance.test.ts @@ -61,7 +61,24 @@ 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` = `0df67f237`, re-read there 2026-10-11: + // (`.objectui-sha` = `499799502`, re-read there 2026-10-11: + // in `packages/plugin-grid`, on the hop off `0df67f237`, `ObjectGrid.tsx` + // changed again (89 insertions, 44 deletions: objectui#12081 item 3's + // whole-set footer and objectui#12082 leg A), none of it inside the + // selection block, which only MOVED by +84: `ObjectGrid.tsx:4981-5008` here + // (`4897-4924` at `0df67f237`), still hashing to + // `c88443302d40c2db739ddb235470bafa29056e2e` (hash-object of the block), + // re-READ with the same reading below. Two hunks sit beside that reading and + // were re-READ as well: objectui#12081 item 3 moved the `bulkFanoutParams` + // and `resolvedTotalMatching` declarations, their code byte-identical, above + // the footer's hook; and objectui#12082 now also withholds a bulk `update` + // def unless the edit verdict (`rowEditVerdict`) allows it, which narrows the + // declared defs and adds no implicit one. The `delete` verdict line MOVED + // `:1786` -> `:1787` and the promoted def's params `:5097-5116` -> + // `:5165-5184` (called at `:5132` -> `:5200`), each byte-identical. + // `hooks/useBulkExecutor.ts` is byte-identical to `0df67f237` and its + // `:298-303` still hashes to `01083348330f10a201cdf1078b4c21c236402b6a`. At + // `0df67f237`, re-read there 2026-10-11: // in `packages/plugin-grid`, on the hop off `20c6d351a`, `ObjectGrid.tsx` // changed again (82 insertions, 32 deletions: objectui#12082's // affordance-to-grant map, objectui#12103's per-column write grant and diff --git a/packages/spec/src/identity/position.form.ts b/packages/spec/src/identity/position.form.ts index b103938a0ae..62270c8d238 100644 --- a/packages/spec/src/identity/position.form.ts +++ b/packages/spec/src/identity/position.form.ts @@ -25,7 +25,13 @@ export const positionForm = defineForm({ { field: 'description', colSpan: 2 }, // [ADR-0131 D3/D4] The sets a holder of this position holds, by name — // what the authorization resolver reads (the junction rows grant nothing). - { field: 'permissionSets', type: 'tags', colSpan: 2, helpText: 'Permission sets this position distributes, by name (snake_case).' }, + // D4 resolves a reference registry-first, so the row binds the + // permission-set registry (metadata type `permission`) rather than a + // free-text tag box: `ref-multi:` is the list form of the + // `ref:` pickers (`ref:object`, `ref:dataset`), offering the + // declared names and committing each pick's name. An explicit widget + // outranks type inference, so the row declares no `type`. + { field: 'permissionSets', widget: 'ref-multi:permission', colSpan: 2, helpText: 'Permission sets this position distributes, by name (snake_case).' }, // #19331 — `delegatable` is declared by PositionSchema and was offered by // no control, so the only door to an ADR-0091 D3 self-service delegation // was the Source tab's free-text JSON. A boolean node takes the boolean diff --git a/packages/spec/src/identity/position.test.ts b/packages/spec/src/identity/position.test.ts index c29e37402c2..56b95c311aa 100644 --- a/packages/spec/src/identity/position.test.ts +++ b/packages/spec/src/identity/position.test.ts @@ -1,5 +1,8 @@ import { describe, it, expect } from 'vitest'; import { PositionSchema, type Position } from './position.zod'; +import { getMetadataTypeSchema } from '../kernel/metadata-type-schemas'; +import { PermissionSetSchema } from '../security/permission.zod'; +import { METADATA_FORM_REGISTRY } from '../system/metadata-form-registry'; describe('PositionSchema', () => { describe('Basic Properties', () => { @@ -285,3 +288,42 @@ describe('unknown keys are rejected, not stripped', () => { expect(parsed._lock).toBe('full'); }); }); + +// [ADR-0131 D4] "References to declared items are by machine name, resolved +// registry-first." The position form is the one authoring surface for the +// position → permission-set binding, so its `permissionSets` row names the +// permission-set registry picker rather than a free-text tag box. The form is +// read through the registry `/meta/types` serves, so a parse that dropped +// `widget` would turn this red too. +describe('the position form picks `permissionSets` from the permission-set registry', () => { + type Row = { field?: string; widget?: string; type?: string }; + const rows = (): Row[] => + ((METADATA_FORM_REGISTRY.position?.sections ?? []) as Array<{ fields?: Row[] }>) + .flatMap((s) => s.fields ?? []); + const rowFor = (key: string) => rows().filter((r) => r.field === key); + + it('CONTROLS: the row probe finds a known row and reports a known absence', () => { + expect(rowFor('name'), 'lit control: the position form has always offered `name`').toHaveLength(1); + expect(rowFor('noSuchKeyAtAll'), 'dark control: a key the form does not offer').toHaveLength(0); + }); + + it('offers `permissionSets` once, as the `ref-multi:permission` picker', () => { + const [row, ...extra] = rowFor('permissionSets'); + expect(extra, 'one row only').toEqual([]); + expect(row?.widget).toBe('ref-multi:permission'); + }); + + it('the registry type the row names is the permission-set catalog', () => { + const [row] = rowFor('permissionSets'); + const registryType = row?.widget?.split(':')[1]; + expect(registryType).toBe('permission'); + expect(getMetadataTypeSchema(registryType!)).toBe(PermissionSetSchema); + }); + + it('the multi-value key sits on a list: `permissionSets` refuses a bare name', () => { + const result = PositionSchema.safeParse({ name: 'auditor', label: 'Auditor', permissionSets: 'read_all' }); + expect(result.success).toBe(false); + const issue = result.error!.issues.find((i) => i.path.join('.') === 'permissionSets'); + expect(issue?.code).toBe('invalid_type'); + }); +}); diff --git a/packages/spec/src/kernel/functional-completeness.ts b/packages/spec/src/kernel/functional-completeness.ts index fac7035d786..b9d740f225c 100644 --- a/packages/spec/src/kernel/functional-completeness.ts +++ b/packages/spec/src/kernel/functional-completeness.ts @@ -298,7 +298,14 @@ 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` = `0df67f237`, re-read there 2026-10-11: + * (`.objectui-sha` = `499799502`, re-read there 2026-10-11: + * on the hop off `0df67f237` `ObjectCalendar.tsx` and `ListView.tsx` are + * byte-identical (`git diff --quiet`), so `getCalendarConfig` `:311`, the + * `if (!calendarConfig)` arm `:1354` with its `tt(…)` lines `:1361-1362` and + * the `case 'calendar'` at `3813` did not move; and the `en` / `zh` / `de` + * packs changed (two commits: objectui#12081 item 3 and objectui#12098) but + * not their `calendar.configRequired` strings. At `0df67f237`, re-read there + * 2026-10-11: * on the hop off `20c6d351a` `ObjectCalendar.tsx` changed (+75/-19: * objectui#12081 item 2's windowed fetch and objectui#12082's write * affordances), no hunk inside a cited read, so `getCalendarConfig` moved @@ -418,7 +425,14 @@ export function checkFieldCompleteness(def: unknown): CompletenessFinding[] { * 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` = `0df67f237`, re-read there 2026-10-11: + * this repo builds against (`.objectui-sha` = `499799502`, re-read there 2026-10-11: + * on the hop off `0df67f237` `ObjectGantt.tsx` changed (+27/-4, + * objectui#12082, objectui `752504520`: the chart's in-chart writes read the + * affordance-to-grant map), none of it in `getGanttConfig` or the refusal arm, + * which are byte-identical and moved `:610` -> `:612` and `:2307` -> `:2330`, + * and `ListView.tsx` is byte-identical (`git diff --quiet`), so its + * `case 'gantt'` did not move from `3959`. At `0df67f237`, re-read there + * 2026-10-11: * on the hop off `20c6d351a` `ObjectGantt.tsx` is byte-identical (`git diff * --quiet`), so `getGanttConfig` `:610` and the `if (!ganttConfig)` arm `:2307` * did not move, and `ListView.tsx` changed (+229/-57, as above) with its @@ -510,6 +524,9 @@ 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` = + * `499799502`, re-read there 2026-10-11: + * every objectui file this record cites is byte-identical across the hop from + * `0df67f237` (`git diff --quiet`), so every anchor held unmoved. At * `0df67f237`, re-read there 2026-10-11: * on the hop off `20c6d351a` `ObjectTimeline.tsx` changed (+42/-20, * objectui#12104, objectui `206505c34`: an explicit `groupByField` groups by @@ -603,7 +620,10 @@ 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` = `0df67f237`, re-read there 2026-10-11: + * pin (`.objectui-sha` = `499799502`, re-read there 2026-10-11: + * every objectui file this record cites is byte-identical across the hop from + * `0df67f237` (`git diff --quiet`), so every anchor held unmoved. At + * `0df67f237`, re-read there 2026-10-11: * on the hop off `20c6d351a` `ObjectMap.tsx` is byte-identical (`git diff * --quiet`), so `getMapConfig` `:421`, `hasCoordinateBinding` `:527` and the * refusal arm `:1337` did not move; and `ListView.tsx` changed (+229/-57) with 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 7210dfb14ee..a84ca1a448c 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 @@ -52,13 +52,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` = `0df67f237c5ab46cbc65252c5f6bd05f2be44c48` — names ' + + 'against, `.objectui-sha` = `4997995022f8e65946f6362b7434685539cc72b7` — 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 8424 tracked files (0 across the 8351 at 20c6d351a, the 8281 at 47b1f0bb7, the 8234 at f0268ad78, the 7754 at a58626c88, the 7650 at 0abd4f9f8, the 7632 at 9dfaca654, the 7579 at 2e818d0b5, the 10267 at ab1879721, the 10071 at 89cad75d5, the 9912 at 31971ff1e, the 9800 at e420df310, the 9546 at db11afd49, the 9283 at dd3f7e1be, the ' + + 'the string debounceDelay each occur 0 times across its 8441 tracked files (0 across the 8424 at 0df67f237, the 8351 at 20c6d351a, the 8281 at 47b1f0bb7, the 8234 at f0268ad78, the 7754 at a58626c88, the 7650 at 0abd4f9f8, the 7632 at 9dfaca654, the 7579 at 2e818d0b5, the 10267 at ab1879721, the 10071 at 89cad75d5, the 9912 at 31971ff1e, the 9800 at e420df310, the 9546 at db11afd49, the 9283 at dd3f7e1be, the ' + '8512 at f8a9d0fb0 and the 8303 at 62597c588 too), against lit ' + 'controls objectstack 12966 and @objectstack/spec 4997 on the same corpus at 87af769e9, ' + 'which re-count to 13125 and 5043 respectively at 62597c588, to 13347 and 5123 at ' - + 'f8a9d0fb0, to 13745 and 5466 at dd3f7e1be, to 14704 and 5545 at db11afd49, to 15352 and 6024 at e420df310, to 15691 and 6206 at 31971ff1e, to 16044 and 6461 at 89cad75d5, to 16377 and 6665 at ab1879721, to 17227 and 7134 at 2e818d0b5, to 17313 and 7186 at 9dfaca654, to 17390 and 7209 at 0abd4f9f8, to 17468 and 7246 at a58626c88, to 17956 and 7522 at f0268ad78, to 17980 and 7523 at 47b1f0bb7, to 18047 and 7545 at 20c6d351a and to 18248 and 7582 at this pin (git grep -o -F, the method that reproduces ' + + 'f8a9d0fb0, to 13745 and 5466 at dd3f7e1be, to 14704 and 5545 at db11afd49, to 15352 and 6024 at e420df310, to 15691 and 6206 at 31971ff1e, to 16044 and 6461 at 89cad75d5, to 16377 and 6665 at ab1879721, to 17227 and 7134 at 2e818d0b5, to 17313 and 7186 at 9dfaca654, to 17390 and 7209 at 0abd4f9f8, to 17468 and 7246 at a58626c88, to 17956 and 7522 at f0268ad78, to 17980 and 7523 at 47b1f0bb7, to 18047 and 7545 at 20c6d351a, to 18248 and 7582 at 0df67f237 and to 18271 and 7587 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 ' 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 19ac1e2b8e0..d3729356a49 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 @@ -46,10 +46,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` = `0df67f237c5ab46cbc65252c5f6bd05f2be44c48`, re-read from this tree — ' + + '`.objectui-sha` = `4997995022f8e65946f6362b7434685539cc72b7`, re-read from this tree — ' + 'spells resourceLimits.timeout 0 times across ' - + '8424 tracked files, against lit controls timeout 1705, RuntimeConfig 347 and resourceLimits ' - + '2 on the same corpus (0 across 8351, and 1694 / 337 / 2, at 20c6d351a; 0 across 8281, and 1674 / 337 / 2, at 47b1f0bb7; 0 across 8234, and 1658 / 337 / 2, at f0268ad78; 0 across 7754, and 1431 / 299 / 2, at a58626c88; 0 across 7650, and 1360 / 293 / 2, at 0abd4f9f8; 0 across 7632, and 1360 / 293 / 2, at 9dfaca654; 0 across 7579, and 1351 / 276 / 2, at 2e818d0b5; 0 across 10267, and 1348 / 273 / 2, at ab1879721; 0 across 10071, and 1331 / 273 / 2, at 89cad75d5; 0 across 9912, and 1303 / 273 / 2, at 31971ff1e; 0 across 9800, and 1293 / 273 / 2, at e420df310; 0 across 9546, and 1197 / 273 / 2, at db11afd49; 0 across 9283, and 1172 / 263 / 2, at dd3f7e1be; 0 across 8512, and 1096 / 245 / 2, at f8a9d0fb0; 0 across 8303, and ' + + '8441 tracked files, against lit controls timeout 1704, RuntimeConfig 352 and resourceLimits ' + + '2 on the same corpus (0 across 8424, and 1705 / 347 / 2, at 0df67f237; 0 across 8351, and 1694 / 337 / 2, at 20c6d351a; 0 across 8281, and 1674 / 337 / 2, at 47b1f0bb7; 0 across 8234, and 1658 / 337 / 2, at f0268ad78; 0 across 7754, and 1431 / 299 / 2, at a58626c88; 0 across 7650, and 1360 / 293 / 2, at 0abd4f9f8; 0 across 7632, and 1360 / 293 / 2, at 9dfaca654; 0 across 7579, and 1351 / 276 / 2, at 2e818d0b5; 0 across 10267, and 1348 / 273 / 2, at ab1879721; 0 across 10071, and 1331 / 273 / 2, at 89cad75d5; 0 across 9912, and 1303 / 273 / 2, at 31971ff1e; 0 across 9800, and 1293 / 273 / 2, at e420df310; 0 across 9546, and 1197 / 273 / 2, at db11afd49; 0 across 9283, and 1172 / 263 / 2, at dd3f7e1be; 0 across 8512, and 1096 / 245 / 2, at f8a9d0fb0; 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. 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 81f0d711245..9f6fd13981e 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 @@ -47,10 +47,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` = `0df67f237c5ab46cbc65252c5f6bd05f2be44c48` — spells ' + + 'objectui checkout — `.objectui-sha` = `4997995022f8e65946f6362b7434685539cc72b7` — spells ' + '`flushInterval` 0 times, `initialDelay` 0, `HttpDestinationConfig` 0 and `LoggingConfig` 0 ' - + 'across its 8424 tracked files, against lit controls `useState` 2645 and `timeout` 1705 on ' - + 'the same corpus (all four 0 across 8351, against 2630 and 1694, at 20c6d351a, 0 across 8281, against 2630 and 1674, at 47b1f0bb7, 0 across 8234, against 2622 and 1658, at f0268ad78, 0 across 7754, against 2491 and 1431, at a58626c88, 0 across 7650, against 2478 and 1360, at 0abd4f9f8, 0 across 7632, against 2477 and 1360, at 9dfaca654, 0 across 7579, against 2477 and 1351, at 2e818d0b5, 0 across 10267, against 2476 and 1348, at ab1879721, 0 across 10071, against 2470 and 1331, at 89cad75d5, 0 across 9912, against 2469 and 1303, at 31971ff1e, 0 across 9800, against 2464 and 1293, at e420df310, 0 across 9546, against 2449 and 1197, at db11afd49, 0 across 9283, against 2435 and 1172, at dd3f7e1be, 0 across 8512, ' + + 'across its 8441 tracked files, against lit controls `useState` 2648 and `timeout` 1704 on ' + + 'the same corpus (all four 0 across 8424, against 2645 and 1705, at 0df67f237, 0 across 8351, against 2630 and 1694, at 20c6d351a, 0 across 8281, against 2630 and 1674, at 47b1f0bb7, 0 across 8234, against 2622 and 1658, at f0268ad78, 0 across 7754, against 2491 and 1431, at a58626c88, 0 across 7650, against 2478 and 1360, at 0abd4f9f8, 0 across 7632, against 2477 and 1360, at 9dfaca654, 0 across 7579, against 2477 and 1351, at 2e818d0b5, 0 across 10267, against 2476 and 1348, at ab1879721, 0 across 10071, against 2470 and 1331, at 89cad75d5, 0 across 9912, against 2469 and 1303, at 31971ff1e, 0 across 9800, against 2464 and 1293, at e420df310, 0 across 9546, against 2449 and 1197, at db11afd49, 0 across 9283, against 2435 and 1172, at dd3f7e1be, 0 across 8512, ' + 'against 2391 and 1096, at f8a9d0fb0, and 0 across ' + '8303, against 2389 and 1086, at 62597c588).', acceptanceCriteria: 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 43c66424172..5c7b5f1613a 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 @@ -73,10 +73,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` = `0df67f237c5ab46cbc65252c5f6bd05f2be44c48`, re-read from this tree — ' - + 'spells all six metrics def names and both distinctive keys 0 times across 8424 tracked ' - + 'files at that sha, against lit controls window 4596, timeout 1705, period 251, ' - + 'interval 233 and metrics 456 on that same corpus and sha (0 across 8351, against 4470 / ' + + '`.objectui-sha` = `4997995022f8e65946f6362b7434685539cc72b7`, re-read from this tree — ' + + 'spells all six metrics def names and both distinctive keys 0 times across 8441 tracked ' + + 'files at that sha, against lit controls window 4604, timeout 1704, period 251, ' + + 'interval 238 and metrics 456 on that same corpus and sha (0 across 8424, against 4596 / ' + + '1705 / 251 / 233 / 456, at 0df67f237, 0 across 8351, against 4470 / ' + '1694 / 249 / 213 / 456, at 20c6d351a, 0 across 8281, against 4449 / ' + '1674 / 249 / 213 / 455, at 47b1f0bb7, 0 across 8234, against 4430 / ' + '1658 / 249 / 213 / 404, at f0268ad78, 0 across 7754, against 4255 / ' 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 19891d0d191..319dc12f085 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 @@ -69,12 +69,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` = `0df67f237c5ab46cbc65252c5f6bd05f2be44c48` — names none of it: all 37 exports of ' - + 'tracing.zod.ts and each of the four key names occur 0 times across the 8424 files ' + + 'pinned objectui checkout — `.objectui-sha` = `4997995022f8e65946f6362b7434685539cc72b7` — names none of it: all 37 exports of ' + + 'tracing.zod.ts and each of the four key names occur 0 times across the 8441 files ' + 'tracked at that sha (the 517 Span and 57 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: 18248 hits for the bare token objectstack, ' - + 'and 7582 for the package specifier @objectstack/spec (at 20c6d351a: 0 across 8351, Span 517, ' + + 'two lit controls on that same corpus and sha: 18271 hits for the bare token objectstack, ' + + 'and 7587 for the package specifier @objectstack/spec (at 0df67f237: 0 across 8424, Span 517, ' + + '18248 and 7582; at 20c6d351a: 0 across 8351, Span 517, ' + '18047 and 7545; at 47b1f0bb7: 0 across 8281, Span 517, ' + '17980 and 7523; at f0268ad78: 0 across 8234, Span 517, ' + '17956 and 7522; at a58626c88: 0 across 7754, Span 509, ' 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 b85eb98b1c0..1bc6e935bae 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 @@ -31,9 +31,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` = `0df67f237c5ab46cbc65252c5f6bd05f2be44c48` — spells it 0 ' - + 'times across 8424 tracked files, against lit controls `TTL` 184 and `tenant` 1357 on the ' - + 'same corpus (0 across 8351, against 184 and 1340, at 20c6d351a; 0 across 8281, against 184 and 1338, at 47b1f0bb7; 0 across 8234, against 184 and 1338, at f0268ad78; 0 across 7754, against 184 and 1319, at a58626c88; 0 across 7650, against 182 and 1318, at 0abd4f9f8; 0 across 7632, against 182 and 1318, at 9dfaca654; 0 across 7579, against 182 and 1317, at 2e818d0b5; 0 across 10267, against 180 and 1238, at ab1879721; 0 across 10071, against 181 and 1237, at 89cad75d5; 0 across 9912, against 181 and 1237, at 31971ff1e; 0 across 9800, against 181 and 1235, at e420df310; 0 across 9546, against 181 and 1200, at db11afd49; 0 across 9283, against 181 and 1185, at dd3f7e1be; 0 across 8512, against 156 and 1034, at f8a9d0fb0; 0 across 8303, against 156 ' + + 'objectui checkout — `.objectui-sha` = `4997995022f8e65946f6362b7434685539cc72b7` — spells it 0 ' + + 'times across 8441 tracked files, against lit controls `TTL` 184 and `tenant` 1362 on the ' + + 'same corpus (0 across 8424, against 184 and 1357, at 0df67f237; 0 across 8351, against 184 and 1340, at 20c6d351a; 0 across 8281, against 184 and 1338, at 47b1f0bb7; 0 across 8234, against 184 and 1338, at f0268ad78; 0 across 7754, against 184 and 1319, at a58626c88; 0 across 7650, against 182 and 1318, at 0abd4f9f8; 0 across 7632, against 182 and 1318, at 9dfaca654; 0 across 7579, against 182 and 1317, at 2e818d0b5; 0 across 10267, against 180 and 1238, at ab1879721; 0 across 10071, against 181 and 1237, at 89cad75d5; 0 across 9912, against 181 and 1237, at 31971ff1e; 0 across 9800, against 181 and 1235, at e420df310; 0 across 9546, against 181 and 1200, at db11afd49; 0 across 9283, against 181 and 1185, at dd3f7e1be; 0 across 8512, against 156 and 1034, at f8a9d0fb0; 0 across 8303, against 156 ' + 'and 987, at 62597c588).', acceptanceCriteria: 'Every schema-level tenant isolation source spells `performance.schemaCacheTtlSeconds`; ' diff --git a/packages/spec/src/ui/action-outcome-messages.test.ts b/packages/spec/src/ui/action-outcome-messages.test.ts index 30da4bd021e..8d020f59c83 100644 --- a/packages/spec/src/ui/action-outcome-messages.test.ts +++ b/packages/spec/src/ui/action-outcome-messages.test.ts @@ -12,6 +12,9 @@ * runner default) and the `${result.*}` INTERPOLATION are the console's — the * reader is objectstack-ai/objectui#11344, a later link of the same ruling, * carried from the pin this repo builds against (`.objectui-sha` = + * `499799502`, re-read there 2026-10-11: + * every objectui file this record cites is byte-identical across the hop from + * `0df67f237` (`git diff --quiet`), so every anchor held unmoved. At * `0df67f237`, re-read there 2026-10-11: * every objectui file this record cites is byte-identical across the hop from * `20c6d351a` (`git diff --quiet`), so every anchor held unmoved. At diff --git a/packages/spec/src/ui/action.zod.ts b/packages/spec/src/ui/action.zod.ts index b2676a757ed..6ed83465a72 100644 --- a/packages/spec/src/ui/action.zod.ts +++ b/packages/spec/src/ui/action.zod.ts @@ -1364,6 +1364,9 @@ const actionObject = () => strictObject({ * * Liveness: the ledger row was `planned` until the console reader landed, * and it is `live` from the pin this repo builds against (`.objectui-sha` = + * `499799502`, re-read there 2026-10-11: + * every objectui file this record cites is byte-identical across the hop from + * `0df67f237` (`git diff --quiet`), so every anchor held unmoved. At * `0df67f237`, re-read there 2026-10-11: * every objectui file this record cites is byte-identical across the hop from * `20c6d351a` (`git diff --quiet`), so every anchor held unmoved. At diff --git a/packages/spec/src/ui/component.test.ts b/packages/spec/src/ui/component.test.ts index b66c78759e6..4b3a11fdcd9 100644 --- a/packages/spec/src/ui/component.test.ts +++ b/packages/spec/src/ui/component.test.ts @@ -288,7 +288,10 @@ describe('PageAccordionProps variant — declared because the accordion renderer // same file's `ComponentRegistry.register('accordion', …)` publishes the key to // the Studio block designer at `:1222` (the `items` input, documented as // `[{ label, icon?, collapsed?, children }]`). Measured at the pin this repo -// builds against — `.objectui-sha` = `0df67f237`, re-read there 2026-10-11: +// builds against — `.objectui-sha` = `499799502`, re-read there 2026-10-11: +// every objectui file this record cites is byte-identical across the hop from +// `0df67f237` (`git diff --quiet`), so every anchor held unmoved. At +// `0df67f237`, re-read there 2026-10-11: // every objectui file this record cites is byte-identical across the hop from // `20c6d351a` (`git diff --quiet`), so every anchor held unmoved. At // `20c6d351a`, re-read there 2026-10-10: @@ -454,7 +457,10 @@ describe('PageTabsProps items[].value / items[].count — declared because the t // same file's `ComponentRegistry.register('tabs', …)` publishes the key to the // Studio block designer at `:1007` (the `items` input, documented as // `[{ label, value?, icon?, count?, visibleWhen?, children }]`). Measured at -// the pin this repo builds against — `.objectui-sha` = `0df67f237`, re-read there 2026-10-11: +// the pin this repo builds against — `.objectui-sha` = `499799502`, re-read there 2026-10-11: +// every objectui file this record cites is byte-identical across the hop from +// `0df67f237` (`git diff --quiet`), so every anchor held unmoved. At +// `0df67f237`, re-read there 2026-10-11: // every objectui file this record cites is byte-identical across the hop from // `20c6d351a` (`git diff --quiet`), so every anchor held unmoved. At // `20c6d351a`, re-read there 2026-10-10: @@ -3493,7 +3499,10 @@ describe('object-* block props schemas — declared, so the props gate has a sch // #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` = `0df67f237`, re-read there 2026-10-11: +// against (`.objectui-sha` = `499799502`, re-read there 2026-10-11: +// every objectui file this record cites is byte-identical across the hop from +// `0df67f237` (`git diff --quiet`), so every anchor held unmoved. At +// `0df67f237`, re-read there 2026-10-11: // `plugin-kanban/src/index.tsx`, `plugin-kanban/src/types.ts` and // `objectql.ts` are byte-identical across the hop from `20c6d351a` (`git diff // --quiet`), so the mapping `488-492` and the member `4838` did not move; @@ -3704,7 +3713,10 @@ describe('ObjectKanbanPropsSchema limit — the row cap four objectui faces alre // since retired that block, objectui#8257). 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` = `0df67f237`, re-read there 2026-10-11: +// against (`.objectui-sha` = `499799502`, re-read there 2026-10-11: +// every objectui file this record cites is byte-identical across the hop from +// `0df67f237` (`git diff --quiet`), so every anchor held unmoved. At +// `0df67f237`, re-read there 2026-10-11: // all three files changed across the hop from `20c6d351a` for one commit, // objectui#12082 (objectui `5af42dbbd`: a card is draggable only for a caller // the `kanbanCardMove` row of the affordance-to-grant map allows), no hunk on @@ -3904,7 +3916,10 @@ describe('ObjectKanbanPropsSchema quickAdd is retired', () => { // #9881 and commit 60e0f900a 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` = `0df67f237`, re-read there 2026-10-11: +// `.objectui-sha` = `499799502`, re-read there 2026-10-11: +// every objectui file this record cites is byte-identical across the hop from +// `0df67f237` (`git diff --quiet`), so every anchor held unmoved. At +// `0df67f237`, re-read there 2026-10-11: // every objectui file this record cites is byte-identical across the hop from // `20c6d351a` (`git diff --quiet`), so every anchor held unmoved. At // `20c6d351a`, re-read there 2026-10-10: @@ -4087,7 +4102,15 @@ describe('ObjectMetricPropsSchema icon liveness', () => { // // 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` = `0df67f237`, re-read there 2026-10-11: +// (`.objectui-sha` = `499799502`, re-read there 2026-10-11: +// `ObjectTree.tsx`, `ObjectMap.tsx` and `record-source.ts` are byte-identical +// across the hop from `0df67f237` (`git diff --quiet`), so every anchor in them +// held unmoved; `ObjectGantt.tsx` +27/-4 changed for objectui#12082 (objectui +// `752504520`: the chart's in-chart writes read the affordance-to-grant map, +// so a bar's drag, its links and the row Delete are handlers withheld from a +// caller without the grant), no hunk on a `schema.*` read, and the set of +// `schema.*` keys it reads is the same at both pins (49 names). At +// `0df67f237`, re-read there 2026-10-11: // every objectui file this record cites is byte-identical across the hop from // `20c6d351a` (`git diff --quiet`), so every anchor held unmoved. At // `20c6d351a`, re-read there 2026-10-10: diff --git a/packages/spec/src/ui/component.zod.ts b/packages/spec/src/ui/component.zod.ts index 2b2da0d90ab..5628b3f3b91 100644 --- a/packages/spec/src/ui/component.zod.ts +++ b/packages/spec/src/ui/component.zod.ts @@ -840,7 +840,10 @@ export const PageTabsProps = strictObject({ * false candidate a component over). * * The key is LIVE at the objectui pin this repo builds against - * (`.objectui-sha` = `0df67f237`, re-read there 2026-10-11: + * (`.objectui-sha` = `499799502`, re-read there 2026-10-11: + * every objectui file this record cites is byte-identical across the hop from + * `0df67f237` (`git diff --quiet`), so every anchor held unmoved. At + * `0df67f237`, re-read there 2026-10-11: * every objectui file this record cites is byte-identical across the hop from * `20c6d351a` (`git diff --quiet`), so every anchor held unmoved. At * `20c6d351a`, re-read there 2026-10-10: @@ -1080,7 +1083,10 @@ export const PageCardProps = strictObject({ * declarations identical. * * Each clause is read off the objectui pin this repo builds against - * (`.objectui-sha` = `0df67f237c5a`, re-read there 2026-10-11: + * (`.objectui-sha` = `4997995022f8`, re-read there 2026-10-11: + * every objectui file this record cites is byte-identical across the hop from + * `0df67f237c5a` (`git diff --quiet`), so every anchor held unmoved. At + * `0df67f237c5a`, re-read there 2026-10-11: * across the hop from `20c6d351ad74` `record-highlights.tsx`, * `record-related-list.tsx`, `record-quick-actions.tsx` and `usePermissions.ts` * are byte-identical (`git diff --quiet`), so NO anchor in those four moved; @@ -2471,7 +2477,10 @@ export const PageAccordionProps = strictObject({ * re-derive the same false candidate). * * The key is LIVE at the objectui pin this repo builds against - * (`.objectui-sha` = `0df67f237`, re-read there 2026-10-11: + * (`.objectui-sha` = `499799502`, re-read there 2026-10-11: + * every objectui file this record cites is byte-identical across the hop from + * `0df67f237` (`git diff --quiet`), so every anchor held unmoved. At + * `0df67f237`, re-read there 2026-10-11: * every objectui file this record cites is byte-identical across the hop from * `20c6d351a` (`git diff --quiet`), so every anchor held unmoved. At * `20c6d351a`, re-read there 2026-10-10: @@ -2902,7 +2911,10 @@ export const ElementButtonPropsSchema = lazySchema(() => strictObject({ * the button. * * The key is LIVE at the objectui pin this repo builds against - * (`.objectui-sha` = `0df67f237`, re-read there 2026-10-11: + * (`.objectui-sha` = `499799502`, re-read there 2026-10-11: + * every objectui file this record cites is byte-identical across the hop from + * `0df67f237` (`git diff --quiet`), so every anchor held unmoved. At + * `0df67f237`, re-read there 2026-10-11: * every objectui file this record cites is byte-identical across the hop from * `20c6d351a` (`git diff --quiet`), so every anchor held unmoved. At * `20c6d351a`, re-read there 2026-10-10: @@ -3374,7 +3386,10 @@ export const ElementTextInputPropsSchema = lazySchema(() => strictObject({ * had no row for — `action:button`, `action:group`, `action:menu`, * `action:icon`, `element:definition-list`, `element:repeater` * (`core/src/registry/public-blocks.ts:117-122` at the pin this repo builds - * against, `.objectui-sha` = `0df67f237`, re-read there 2026-10-11: + * against, `.objectui-sha` = `499799502`, re-read there 2026-10-11: + * every objectui file this record cites is byte-identical across the hop from + * `0df67f237` (`git diff --quiet`), so every anchor held unmoved. At + * `0df67f237`, re-read there 2026-10-11: * `public-blocks.ts`, `auto-trigger.ts`, `static-params.ts`, `ui/button.tsx`, * the four `action-*.tsx` renderers and `previews/block-config.ts` are * byte-identical across the hop from `20c6d351a` (`git diff --quiet`), so @@ -3941,7 +3956,10 @@ export type ActionIconPropsParsed = z.infer; * inventory. A member's `params` is its `ActionParam[]` input list: both * containers forward an array as `actionParams` (group `:346-348`, menu * `:270-272`, re-read at the pin this repo builds against, `.objectui-sha` = - * `0df67f237`, 2026-10-11: `action-group.tsx`, `action-menu.tsx` and + * `499799502`, 2026-10-11: `action-group.tsx`, `action-menu.tsx` and + * `static-params.ts` are byte-identical across the hop from `0df67f237` (`git + * diff --quiet`), so both held unmoved; at `0df67f237`, 2026-10-11: + * `action-group.tsx`, `action-menu.tsx` and * `static-params.ts` are byte-identical across the hop from `20c6d351a` (`git * diff --quiet`), so both held unmoved; at `20c6d351a`, 2026-10-10: * `action-group.tsx`, `action-menu.tsx` and @@ -4632,7 +4650,13 @@ const GridOperationsSchema = lazySchema(() => strictObject({ * control `schema.editable` in `ObjectGrid.tsx`. It was declared ahead of its * reader on purpose (the BUILD objectui#11068 chose), and its describe carried * the `[EXPERIMENTAL — not enforced]` marker that said so. Re-measured at the - * pin this repo builds against (`.objectui-sha` = `0df67f237`, re-read there 2026-10-11: + * pin this repo builds against (`.objectui-sha` = `499799502`, re-read there 2026-10-11: + * `ObjectGrid.tsx` changed across the hop from `0df67f237` (+89/-44: + * objectui#12081 item 3, objectui `69bca0af6`, and objectui#12082, objectui + * `752504520`) and `data-table.tsx` is byte-identical (`git diff --quiet`); the + * read MOVED `5570` -> `5615` with its line byte-identical, and the same method + * still finds 15 hit lines against 3 for the control. At `0df67f237`, re-read + * there 2026-10-11: * `ObjectGrid.tsx` changed across the hop from `20c6d351a` (+82/-32: * objectui#12082, objectui#12103 and objectui#12105) and `data-table.tsx` is * byte-identical (`git diff --quiet`); the read MOVED `5520` -> `5570` with its @@ -4672,7 +4696,7 @@ const GridOperationsSchema = lazySchema(() => strictObject({ * `ab1879721`): the BUILD landed — objectui `154075ab1` (objectui#11068), inside * `89cad75d5570..ab1879721595` — and the grid reads the key. The same method * finds 0 hit lines at `89cad75d5570` and 15 at `ab1879721595`, at `2e818d0b51ec` and at this pin, against 3 for the - * control `schema.editable` in `ObjectGrid.tsx` at each: `ObjectGrid.tsx:5570` + * control `schema.editable` in `ObjectGrid.tsx` at each: `ObjectGrid.tsx:5615` * hands `schema.keyboardNavigation ?? inlineEditable` to the `data-table` it * renders, and `components/src/renderers/complex/data-table.tsx` acts on it. * So the marker is gone, as the member's record prescribed; see the member. @@ -4751,7 +4775,12 @@ export const ObjectGridPropsSchema = lazySchema(() => strictObject({ * same members, and objectui's grid follows this declaration. * * ⚠️ That gap is closed at the pin this repo builds against (`.objectui-sha` - * = `0df67f237`, re-read there 2026-10-11: + * = `499799502`, re-read there 2026-10-11: + * `ObjectGrid.tsx` changed across the hop from `0df67f237` (+89/-44: + * objectui#12081 item 3 and objectui#12082), every hunk above both reads + * (the last at `:5321-5343`), so both MOVED by 45 with their lines + * byte-identical: `6587-6588` -> `6632-6633`, `6604-6605` -> `6649-6650`. At + * `0df67f237`, re-read there 2026-10-11: * `ObjectGrid.tsx` changed across the hop from `20c6d351a` (+82/-32: * objectui#12082, objectui#12103 and objectui#12105), every hunk above both * reads (the last at `:5609`), so both MOVED by 50 with their lines @@ -4785,7 +4814,7 @@ export const ObjectGridPropsSchema = lazySchema(() => strictObject({ * `6158e4c93`) resolves both members against the display locale before they * reach `DataEmptyState` — * `resolveInlineI18nLabel(authoredEmptyState?.title, displayLocale)` and the - * same for `message` (`ObjectGrid.tsx:6587-6588`, drawn at `:6604-6605`) — so + * same for `message` (`ObjectGrid.tsx:6632-6633`, drawn at `:6649-6650`) — so * both `I18nLabel` forms draw, and a locale map with no usable entry keeps * that member's default. At `89cad75d5570` the two still reached * `DataEmptyState` raw. @@ -5149,7 +5178,15 @@ export const ObjectGridPropsSchema = lazySchema(() => strictObject({ * `ComponentPropsMap` key. This record said to drop the marker in the change * that lands the BUILD at the pin, and it is dropped here. * - * Read at the pin this repo builds against (`.objectui-sha` = `0df67f237`, re-read there 2026-10-11: + * Read at the pin this repo builds against (`.objectui-sha` = `499799502`, re-read there 2026-10-11: + * `ObjectGrid.tsx` changed across the hop from `0df67f237` (+89/-44: + * objectui#12081 item 3 and objectui#12082) and `data-table.tsx` is + * byte-identical (`git diff --quiet`), so the five `data-table.tsx` anchors + * held unmoved and the two grid anchors MOVED with their lines + * byte-identical — `5570` -> `5615`, `1850` -> `1851`; no hunk lands between + * the viewer's write verdict `objectInlineEditable` and `:1851`, so + * `inlineEditable` is still the authored `editable` AND that verdict. At + * `0df67f237`, re-read there 2026-10-11: * `ObjectGrid.tsx` changed across the hop from `20c6d351a` (+82/-32: * objectui#12082, objectui#12103 and objectui#12105) and `data-table.tsx` is * byte-identical (`git diff --quiet`), so the five `data-table.tsx` anchors @@ -5196,9 +5233,9 @@ export const ObjectGridPropsSchema = lazySchema(() => strictObject({ * and `data-table.tsx` were * byte-identical across the hop from `ab1879721`, where they were measured * 2026-10-03; the BUILD is objectui `154075ab1`, objectui#11068): - * `plugin-grid/src/ObjectGrid.tsx:5570` hands the data table + * `plugin-grid/src/ObjectGrid.tsx:5615` hands the data table * `keyboardNavigation: schema.keyboardNavigation ?? inlineEditable`, where - * `inlineEditable` (`:1850`) is the authored `editable` AND the viewer's + * `inlineEditable` (`:1851`) is the authored `editable` AND the viewer's * write verdict — so an absent key follows whether the grid RENDERS * editable, `true` turns the navigation on for a read-only grid, and `false` * turns it off on an editable one. `components/src/renderers/complex/data-table.tsx` @@ -5582,7 +5619,10 @@ 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` = `0df67f237`, re-read there 2026-10-11: + * (`.objectui-sha` = `499799502`, re-read there 2026-10-11: + * every objectui file this record cites is byte-identical across the hop from + * `0df67f237` (`git diff --quiet`), so every anchor held unmoved. At + * `0df67f237`, re-read there 2026-10-11: * every objectui file this record cites is byte-identical across the hop from * `20c6d351a` (`git diff --quiet`), so every anchor held unmoved. At * `20c6d351a`, re-read there 2026-10-10: @@ -5839,7 +5879,10 @@ const ObjectKanbanLaneSchema = lazySchema(() => strictObject({ * 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` = `0df67f237`, re-read there 2026-10-11: + * (`.objectui-sha` = `499799502`, re-read there 2026-10-11: + * every objectui file this record cites is byte-identical across the hop from + * `0df67f237` (`git diff --quiet`), so every anchor held unmoved. At + * `0df67f237`, re-read there 2026-10-11: * `ObjectKanban.tsx` changed across the hop from `20c6d351a`, +21/-1 * (objectui#12082, objectui `5af42dbbd`: the card move reads the * affordance-to-grant map), two import lines above the anchor and every other @@ -5957,7 +6000,10 @@ 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` = `0df67f237`, re-read there 2026-10-11: + * repo builds against (`.objectui-sha` = `499799502`, re-read there 2026-10-11: + * every objectui file this record cites is byte-identical across the hop from + * `0df67f237` (`git diff --quiet`), so every anchor held unmoved. At + * `0df67f237`, re-read there 2026-10-11: * `plugin-kanban/src/types.ts` (still no row-cap member), * `plugin-kanban/src/index.tsx`, `element-data-source.ts`, * `ElementDataSourceGate.tsx` and `objectql.ts` are byte-identical across the @@ -6247,7 +6293,12 @@ export const ObjectKanbanPropsSchema = lazySchema(() => strictObject({ * quick-add control and no block a document can name offers one either). * * Measured at the objectui pin this repo builds against - * (`.objectui-sha` = `0df67f237`, re-read there 2026-10-11: + * (`.objectui-sha` = `499799502`, re-read there 2026-10-11: + * every objectui file this record cites is byte-identical across the hop from + * `0df67f237` (`git diff --quiet`), so every anchor held unmoved; + * `ObjectKanban.tsx` still names `quickAdd` and `onQuickAdd` 2 times each + * against 11 for `onCardClick`, and objectui still registers no `kanban-ui` + * block. At `0df67f237`, re-read there 2026-10-11: * `plugin-kanban/src/index.tsx` is byte-identical across the hop from * `20c6d351a` (`git diff --quiet`), so `345-346` did not move; * `KanbanBoardCore.tsx` (+9/-0), `ObjectKanban.tsx` (+21/-1) and @@ -6464,6 +6515,9 @@ export const ObjectKanbanPropsSchema = lazySchema(() => strictObject({ * element schemas). * * Measured at the pin this repo builds against (`.objectui-sha` = + * `499799502`, re-read there 2026-10-11: + * every objectui file this record cites is byte-identical across the hop from + * `0df67f237` (`git diff --quiet`), so every anchor held unmoved. At * `0df67f237`, re-read there 2026-10-11: * `useNavigationOverlay.ts` is byte-identical to `20c6d351a` (`git diff * --quiet`), and `ObjectKanban.tsx` changed above and between the anchors @@ -6690,6 +6744,9 @@ export const ObjectCalendarPropsSchema = lazySchema(() => strictObject({ * `object-kanban`'s above. * * Measured at the pin this repo builds against (`.objectui-sha` = + * `499799502`, re-read there 2026-10-11: + * every objectui file this record cites is byte-identical across the hop from + * `0df67f237` (`git diff --quiet`), so every anchor held unmoved. At * `0df67f237`, re-read there 2026-10-11: * `useNavigationOverlay.ts` is byte-identical to `20c6d351a` (`git diff * --quiet`), and `ObjectCalendar.tsx` changed above and between the anchors @@ -7913,7 +7970,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` = `0df67f237`, re-read there 2026-10-11: + * `.objectui-sha` = `499799502`, re-read there 2026-10-11: + * every objectui file this record cites is byte-identical across the hop from + * `0df67f237` (`git diff --quiet`), so every anchor held unmoved. At + * `0df67f237`, re-read there 2026-10-11: * every objectui file this record cites is byte-identical across the hop from * `20c6d351a` (`git diff --quiet`), so every anchor held unmoved. At * `20c6d351a`, re-read there 2026-10-10: @@ -8111,7 +8171,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` = `0df67f237`, re-read there 2026-10-11: + * pin this repo builds against (`.objectui-sha` = `499799502`, re-read there 2026-10-11: + * every objectui file this record cites is byte-identical across the hop from + * `0df67f237` (`git diff --quiet`), so every anchor held unmoved. At + * `0df67f237`, re-read there 2026-10-11: * every objectui file this record cites is byte-identical across the hop from * `20c6d351a` (`git diff --quiet`), so every anchor held unmoved. At * `20c6d351a`, re-read there 2026-10-10: @@ -8188,7 +8251,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` = `0df67f237`, re-read there 2026-10-11: + * (`.objectui-sha` = `499799502`, re-read there 2026-10-11: + * every objectui file this record cites is byte-identical across the hop from + * `0df67f237` (`git diff --quiet`), so every anchor held unmoved. At + * `0df67f237`, re-read there 2026-10-11: * every objectui file this record cites is byte-identical across the hop from * `20c6d351a` (`git diff --quiet`), so every anchor held unmoved. At * `20c6d351a`, re-read there 2026-10-10: @@ -8387,7 +8453,23 @@ function objectGanttMarker() { /** * `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` = `0df67f237`, re-read there 2026-10-11: + * — `.objectui-sha` = `499799502`, re-read there 2026-10-11: + * `record-source.ts`, `plugin-gantt/src/index.tsx` and `ListView.tsx` are + * byte-identical across the hop from `0df67f237` (`git diff --quiet`), so every + * anchor in them held unmoved; `ObjectGantt.tsx` +27/-4 changed for + * objectui#12082 (objectui `752504520`: the chart's in-chart writes read the + * affordance-to-grant map) — two import lines above `getGanttConfig`, a + * 21-line block of grant reads below the reload, and four handler props whose + * handlers are now withheld without the grant — no hunk on a cited read, so + * every anchor MOVED with its cited text byte-identical, by 2 above the block + * (`:613-615` -> `:615-617`, `:725` -> `:727`, `:921` -> `:923`, + * `:1066`/`:1067` -> `:1068`/`:1069`, `:888-891` -> `:890-893`, + * `:1081-1086` -> `:1083-1088`, `:1075`/`:1077` -> `:1077`/`:1079`, + * `:1679`/`:1680` -> `:1681`/`:1682`, `:1831`/`:1833` -> `:1833`/`:1835`, + * `:1969` -> `:1971`, `:2036` -> `:2038`) and by 23 below it (`:2348` -> + * `:2371`, `:2506`-`:2514` -> `:2529`-`:2537`, `:2549-2555` -> `:2572-2578`), + * and each is cited below at this pin. At `0df67f237`, re-read there + * 2026-10-11: * `ObjectGantt.tsx`, `record-source.ts` and `plugin-gantt/src/index.tsx` are * byte-identical across the hop from `20c6d351a` (`git diff --quiet`), so every * anchor in them held unmoved; `ListView.tsx` changed (+229/-57), and its @@ -8513,46 +8595,46 @@ function objectGanttMarker() { * 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 - * `:725` — rung 1, `core/src/utils/record-source.ts:307`), `staticData` (rung 2, - * `record-source.ts:311`), `objectName` (rung 3; also `:1833` and `:2036` here), - * `filter` (`:921`, read once through `useResolvedFilter`, which resolves its - * context tokens — objectui#10666 — and `:1066` sends the held result to - * `$filter`; at `f8a9d0fb0` it was sent verbatim), `sort` (`:1067`, through - * `convertSortToQueryParams` to `$orderby`), `gantt` (`:613-615` — + * `:727` — rung 1, `core/src/utils/record-source.ts:307`), `staticData` (rung 2, + * `record-source.ts:311`), `objectName` (rung 3; also `:1835` and `:2038` here), + * `filter` (`:923`, read once through `useResolvedFilter`, which resolves its + * context tokens — objectui#10666 — and `:1068` sends the held result to + * `$filter`; at `f8a9d0fb0` it was sent verbatim), `sort` (`:1069`, through + * `convertSortToQueryParams` to `$orderby`), `gantt` (`:615-617` — * `getGanttConfig` branch 1, the author face and the registration's declared * `{ name: 'gantt', type: 'object' }` input (`plugin-gantt/src/index.tsx:179`), * validated there against this - * repo's own {@link GanttConfigSchema}), `navigation` (`:1969`), `label` - * (`:2551`, resolved through `resolveInlineI18nLabel` for the export file + * repo's own {@link GanttConfigSchema}), `navigation` (`:1971`), `label` + * (`:2574`, resolved through `resolveInlineI18nLabel` for the export file * name — this record said `resolveI18nLabel`, which the line did not read at * `f8a9d0fb0` either — * ⚠️ the retired reading `:1849` was the comment ABOVE that chain and at this * pin `87af769e9` was a BLANK line (nothing cites `:1849` now), two above a dependency-delete callback's own comment, * so it is re-READ here, not re-pointed), - * `skipWeekends` (`:1679`), `holidays` (`:1680`), `persistLayout` (`:1831`), - * `viewName` (`:1833`), `markers` (`:2506`), `criticalPath` (`:2509`), - * `showBaselines` (`:2512`), `readOnly` (`:2348` and `:2513`) and - * `mobileReadOnly` (`:2514`). + * `skipWeekends` (`:1681`), `holidays` (`:1682`), `persistLayout` (`:1833`), + * `viewName` (`:1835`), `markers` (`:2529`), `criticalPath` (`:2532`), + * `showBaselines` (`:2535`), `readOnly` (`:2371` and `:2536`) and + * `mobileReadOnly` (`:2537`). * * 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`, `:2549-2555`); a row cap — the + * `label` → the OBJECT's label → `objectName`, `:2572-2578`); a row cap — the * reload's `$top` is the platform ceiling, spread in as core's - * `nonGridRowCeilingQuery()` (`:1077`: one probe row past the ceiling, which + * `nonGridRowCeilingQuery()` (`:1079`: one probe row past the ceiling, which * `applyNonGridRowCeiling` slices back off; at `f8a9d0fb0` a bare * `$top: NON_GRID_ROW_CEILING_TOP`, until objectui#7508 homed the ceiling in - * core) and the renderer's own comment marks it "⛔ Not authorable" (`:1075`); and + * core) and the renderer's own comment marks it "⛔ Not authorable" (`:1077`); and * the `onTaskClick` / `onRowClick` / `onBeforeTaskUpdate` callbacks, which are * host props. ⚠️ New at `f8a9d0fb0` and recorded, not ruled: objectui#10250 * gave the renderer two more reads, `search` and `searchableFields` - * (`:888-891`, sent as `$search` / `$searchFields` at `:1081-1086`), which + * (`:890-893`, sent as `$search` / `$searchFields` at `:1083-1088`), 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:615` validates it against + * contract is already the SPEC's — `ObjectGantt.tsx:617` validates it against * `GanttConfigSchema` imported from `@objectstack/spec/ui` — so the read point * names the schema and this door takes it rather than `z.unknown()`. The * scalars below are read as their coercions say: `!!schema.readOnly`, @@ -8645,7 +8727,10 @@ export type ObjectGanttPropsParsed = z.infer; * they flatten `options.tree` (`ListView.tsx:4120-4144`, `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` = `0df67f237`, re-read there 2026-10-11: + * pin this repo builds against (`.objectui-sha` = `499799502`, re-read there 2026-10-11: + * every objectui file this record cites is byte-identical across the hop from + * `0df67f237` (`git diff --quiet`), so every anchor held unmoved. At + * `0df67f237`, re-read there 2026-10-11: * `ObjectTree.tsx` and `plugin-tree/src/index.tsx` are byte-identical to * `20c6d351a` (`git diff --quiet`), so `289-302` and `240-261` did not move; * `ListView.tsx` changed above and below its `case 'tree'` arm (+229/-57: @@ -8790,7 +8875,10 @@ 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` = `0df67f237`, re-read there 2026-10-11: + * — `.objectui-sha` = `499799502`, re-read there 2026-10-11: + * every objectui file this record cites is byte-identical across the hop from + * `0df67f237` (`git diff --quiet`), so every anchor held unmoved. At + * `0df67f237`, re-read there 2026-10-11: * every objectui file this record cites is byte-identical across the hop from * `20c6d351a` (`git diff --quiet`), so every anchor held unmoved. At * `20c6d351a`, re-read there 2026-10-10: @@ -8986,7 +9074,11 @@ 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` = `0df67f237`, re-read there 2026-10-11: + * builds against (`.objectui-sha` = `499799502`, re-read there 2026-10-11: + * re-COUNTED by the same method, 0 for the tree, 3 each for `plugin-gantt`, + * `plugin-grid` and `plugin-calendar` and 4 for `plugin-map`, all five + * shells byte-identical across the hop from `0df67f237` (`git diff + * --quiet`). At `0df67f237`, re-read there 2026-10-11: * re-COUNTED by the same method, 0 for the tree, 3 each for `plugin-gantt` * and `plugin-grid` and 4 for `plugin-map`, those four shells byte-identical * across the hop from `20c6d351a` (`git diff --quiet`), and 3 for @@ -9393,7 +9485,10 @@ function objectTimelineItemsFitVariant() { * `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` = `0df67f237`, re-read there 2026-10-11: + * repo builds against (`.objectui-sha` = `499799502`, re-read there 2026-10-11: + * every objectui file this record cites is byte-identical across the hop from + * `0df67f237` (`git diff --quiet`), so every anchor held unmoved. At + * `0df67f237`, re-read there 2026-10-11: * `index.tsx` is byte-identical to `20c6d351a` (`git diff --quiet`), so its * anchors held unmoved; `ObjectTimeline.tsx` (+42/-20) and `renderer.tsx` * (+28/-8) changed for objectui#12104 (objectui `206505c34`: an explicit @@ -9650,6 +9745,9 @@ 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` = + * `499799502`, re-read there 2026-10-11: + * every objectui file this record cites is byte-identical across the hop from + * `0df67f237` (`git diff --quiet`), so every anchor held unmoved. At * `0df67f237`, re-read there 2026-10-11: * `record-source.ts` and `SchemaRenderer.tsx` are byte-identical across the hop * from `20c6d351a` (`git diff --quiet`), so the prop channel above still @@ -10013,6 +10111,9 @@ export const ComponentPropsMap = { // set from this map's keys), on the three-part evidence that vocabulary's // string-arm ledger asks of a type admitted without an enum member — all // measured at the pin this repo builds against (`.objectui-sha` = + // `499799502`, re-read there 2026-10-11: + // every objectui file this record cites is byte-identical across the hop from + // `0df67f237` (`git diff --quiet`), so every anchor held unmoved. At // `0df67f237`, re-read there 2026-10-11: // `public-blocks.ts`, `block-types.ts` and `block-config.ts` are // byte-identical across the hop from `20c6d351a` (`git diff --quiet`), so @@ -10119,7 +10220,14 @@ 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` = - // `0df67f237`, re-read there 2026-10-11: + // `499799502`, re-read there 2026-10-11: + // `ObjectTree.tsx` and `ObjectMap.tsx` are byte-identical to `0df67f237` + // (`git diff --quiet`); `ObjectGantt.tsx` (+27/-4) changed for objectui#12082 + // (objectui `752504520`: the chart's in-chart writes read the + // affordance-to-grant map) and was re-READ: its anchors MOVED byte-identical + // and its `schema.*` read set is unchanged (the same 49 names at both pins), + // so no declared key set moved and no read point died. At `0df67f237`, + // re-read there 2026-10-11: // every objectui file this record cites is byte-identical across the hop from // `20c6d351a` (`git diff --quiet`), so every anchor held unmoved. At // `20c6d351a`, re-read there 2026-10-10: @@ -10202,6 +10310,9 @@ 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` = + // `499799502`, re-read there 2026-10-11: + // every objectui file this record cites is byte-identical across the hop from + // `0df67f237` (`git diff --quiet`), so every anchor held unmoved. At // `0df67f237`, re-read there 2026-10-11: // `index.tsx` is byte-identical to `20c6d351a` (`git diff --quiet`); // `ObjectTimeline.tsx` (+42/-20) and `renderer.tsx` (+28/-8) changed for diff --git a/packages/spec/src/ui/dataset.zod.ts b/packages/spec/src/ui/dataset.zod.ts index e3fff6a576a..72928729c88 100644 --- a/packages/spec/src/ui/dataset.zod.ts +++ b/packages/spec/src/ui/dataset.zod.ts @@ -283,6 +283,9 @@ 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` = + * `499799502`, re-read there 2026-10-11: + * every objectui file this record cites is byte-identical across the hop from + * `0df67f237` (`git diff --quiet`), so every anchor held unmoved. At * `0df67f237`, re-read there 2026-10-11: * every objectui file this record cites is byte-identical across the hop from * `20c6d351a` (`git diff --quiet`), so every anchor held unmoved. At diff --git a/packages/spec/src/ui/view.zod.ts b/packages/spec/src/ui/view.zod.ts index 7bd5c6125a1..2fe8f9026c3 100644 --- a/packages/spec/src/ui/view.zod.ts +++ b/packages/spec/src/ui/view.zod.ts @@ -3429,7 +3429,16 @@ 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` = `0df67f237`, re-read there 2026-10-11: + * (`.objectui-sha` = `499799502`, re-read there 2026-10-11: + * `autoLayout.ts` and `fields`' `field-type-alias.ts` are byte-identical to + * `0df67f237` (`git diff --quiet`), so `resolveColSpan` `:154`, + * `WIDE_FIELD_TYPES` `:58-69` and the `repeater` -> `field:grid` mapping held + * unmoved, and `form.tsx` changed on this hop — 37 insertions, 25 deletions: + * objectui#12121 (objectui `c9fc10b1e`), a boolean whose default the server + * resolves is left unseeded on create — none of it inside `spanLadderFor`, + * which held at `:274-301` byte-identical, and its one call site MOVED + * `:3246` -> `:3258` with the call byte-identical, so it still emits the + * ladder. At `0df67f237`, re-read there 2026-10-11: * `autoLayout.ts` and `fields`' `field-type-alias.ts` are byte-identical to * `20c6d351a` (`git diff --quiet`), so `resolveColSpan` `:154`, * `WIDE_FIELD_TYPES` `:58-69` and the `repeater` -> `field:grid` mapping held @@ -3523,7 +3532,7 @@ const FormFieldBaseSchema = lazySchema(() => { * had changed only in its registration's input list, objectui#9910's * `children` slot; at `62597c588` it 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` = `0df67f237c5a`), only textarea, markdown, html, richtext and repeater resolve to the full column count (repeater reaches it through the wide `field:grid` widget it maps to). 'full': resolves to the form grid's full column count. How far down the container-query tiers that span is emitted is the renderer's, not this key's: at that same pin the renderer emits one clamped col-span class per multi-column tier (`@md:col-span-2 @2xl:col-span-3` for a 3-column grid), so the field takes the whole row at every multi-column tier, not just the widest."), + 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` = `4997995022f8`), 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 a1d2707b818..9089e121ea0 100644 --- a/scripts/sdui-manifest.record.json +++ b/scripts/sdui-manifest.record.json @@ -11,9 +11,9 @@ "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": "0df67f237c5ab46cbc65252c5f6bd05f2be44c48", + "objectuiSha": "4997995022f8e65946f6362b7434685539cc72b7", "source": "built-tree", - "modulesRoot": ".cache/objectui-0df67f237c5a/apps/console", + "modulesRoot": ".cache/objectui-4997995022f8/apps/console", "objectuiWorkspaceVersion": "17.7.0", "generator": "scripts/gen-sdui-manifest-node.mjs", "generatedAt": "2026-10-11",