Skip to content

Commit fbc12be

Browse files
chore(objectui): bump the console pin to 87af769 with 27 re-measured citations, and fold in the two-code sdui-parser port (#17645) (#19398)
Fixes #17429 Part of #17645 — that card's deliverable (the two-code port) lands here; the director seat ends card 17645 with the landing record after the merge (a seat-written record, not a closing reference). The card's take-over from the offline `domain:devx` seat is the maintainer's instruction (「18723 os-try-charles 已下班,你也接手」), recorded on the card; the carrier reader's cross-author row (C9) cannot be cleared without the offline holder's own `Release:`, so the card is carried as `Part of`, not as a closing reference. Clause-②: yes Corrected from `no` under ruling batch #201 item 1 (maintainer 「201 A」, record 5753263180 on #17645): this PR now also carries #17645's two-code sdui-parser port, so the save gate's diagnostic set grows (`inert-quick-add`, `member-type-mismatch`); the pin bump and the 27 re-measured citations alone moved no accept set. Both landed on this branch: the fold-in commit `6ef8344645` and the citation-spelling fix `fc25a5925d` (the head); the lockstep record needed no re-recording (see the fold-in section). (Pin-bump half, as originally declared:) Declared from the diff, not from the card: nothing in the pin bump adds, removes or renames an authorable key. The two `packages/spec` edits with a published face are `.describe()` SENTENCES (`Dataset` measure `format`, `FormField.span`); `check:authorable-surface` and `check:api-surface` both report their artefacts current with no regeneration, and `pnpm --filter @objectstack/spec check:generated` reports all 15 artefacts up to date after `gen:docs` and `gen:migration-registry` ran. The same authored metadata is accepted and refused as before, so neither arm of the closed pair applies. ## What moved `.objectui-sha`: `53ded82bf7a494f54e344e19099dbf00854b8694` → `87af769e9a3ee28ace099fdd653d3ebd79fe82e2` (objectui `origin/main` tip read 2026-09-20; `cfcc17d9dd04` — the revision PR #18723 ported from — is an ancestor of it, `git merge-base --is-ancestor` exit 0). Produced by `scripts/bump-objectui.sh --no-commit 87af769`, never by hand. Everything the pin travels with: | Artefact | How | |---|---| | `.changeset/console-87af769e9a3e.md` | the bump script's own digest — 584 releasing changesets of 891 added across 1156 non-merge commits, `@objectstack/console: minor`, 98 declared-breaking entries listed | | `sdui.manifest.json` + `scripts/sdui-manifest.record.json` | `node scripts/gen-sdui-manifest-node.mjs`. The manifest is BYTE-IDENTICAL (sha256 `49211fee7792…`, 57 components): the pinned commit declares the same published `@object-ui` `17.6.0` the old pin did, so only the provenance record moves. `check:sdui-manifest` exit 0 | | `packages/sdui-parser/objectui-lockstep.json` | `pnpm gen:sdui-lockstep` against a worktree parked at the new pin (`--update` refuses off the pin). See the RED below | | 27 `.objectui-sha` citations under `packages/spec/src/**` | each re-MEASURED against the new pin's tree — see the table | | `content/docs/references/ui/{dataset,view}.mdx` | `gen:docs`, from the two corrected describes | | `.changeset/17429-pin-bump-describe-corrections.md` | `@objectstack/spec: patch` for those two sentences | Lockfile / override state: `pnpm install` in this worktree produced no `pnpm-lock.yaml` change, and the bump script writes none — the console SPA is vendored as a built `dist/`, not as a dependency, so this bump moves no dependency edge in this repo. ## Fold-in: the two-code sdui-parser port (ruling batch #201 item 1, maintainer 「201 A」) Commit `6ef8344645` brings PR #18723's port onto this branch **verbatim**. Eight files, each byte-identical to the blob on `claude/issue-17645-sdui-lockstep-port` (`git hash-object` here vs `git rev-parse claude/issue-17645-sdui-lockstep-port:PATH` there — all eight SAME, no hunk rewritten): | path | blob | |---|---| | `packages/sdui-parser/src/kanban-quick-add.ts` | `20f9f74b9f05` | | `packages/sdui-parser/src/validate.ts` | `156a264073f7` | | `packages/sdui-parser/src/types.ts` | `567bc1259bea` | | `packages/sdui-parser/src/index.ts` | `2ea35795b9cf` | | `packages/sdui-parser/src/codegen.ts` | `76a7d654f1fd` | | `packages/sdui-parser/src/__tests__/inert-quick-add.test.ts` | `723cad21333a` | | `packages/sdui-parser/src/__tests__/member-type-mismatch.test.ts` | `4b87cadaa067` | | `.changeset/17645-sdui-parser-lockstep-port.md` | `7c171fddfc43` | Deliberately NOT brought from that branch: `.objectui-sha`, `scripts/sdui-manifest.record.json` (both already this branch's, at `87af769e9a3e`) and `packages/sdui-parser/objectui-lockstep.json`. ### The lockstep record was neither text-merged nor re-recorded — and needed neither This branch already carries the record **taken at the live pin** in the pin-bump round: `objectui.rev` = `recordedAgainstPin` = `87af769e9a3ee28ace099fdd653d3ebd79fe82e2`, 26 diagnostic codes including `inert-quick-add` and `member-type-mismatch`. `--update` re-reads objectui's side only, so a re-record here would have rewritten the same bytes. Attempted anyway, and it REFUSED, which is the generator working: `pnpm gen:sdui-lockstep` exit 1, `[head-off-pin] the objectui checkout is at c2f0f48, and .objectui-sha names 87af769`; record file byte-unchanged across the attempt (`e0a6988b1c9a` before and after). The remedy it prints — parking the sibling checkout on the pin — was not taken: that is a git write inside a read-only checkout this container shares with other agents, and the record it would produce is the one already committed. **Result — `check:sdui-lockstep` exit 0** on the head: `OK — this copy is byte-identical to objectui@87af769e9a3e over 214 grammar line(s) [blob 0131f27cf86d] and agrees on all 26 diagnostic code(s), across 8 non-test source(s)`. `--self-test` exit 0 alongside. `check:sdui-manifest` exit 0 (manifest intact, sha256 `49211fee7792`, recorded at the live pin). ### The type-check red PR #18723 carried is closed by the pin, not by a code change The red was `check:objectui-pin-citations` inside the `Type Check · source gates` job. It reds exactly on the two heads of #18723 that claimed `.objectui-sha` = `cfcc17d9dd04`; on this branch, with the live pin, the gate is exit 0 (27 asserting citations match, 48 historical recorded and not checked, 7 anchor content assertions verified). Reverse-verified here through `scripts/ablation-replace.mjs`: rewriting `.objectui-sha` to `cfcc17d9dd04` turns the gate RED with five anchor-content mismatches; restored and proven (blob back to `035b6937d641`, `git diff HEAD` empty). So the fix is the fold direction itself: the port lands on the branch whose citations are already re-measured at the pin. No edit was made inside `packages/sdui-parser/**` for it, and no `@ts-ignore` or `any` was added anywhere; `tsc --listFiles` confirms both new test files are inside the package program. ### Ported from `cfcc17d9`, re-verified against the LIVE pin objectui DID move `packages/sdui-parser` between `cfcc17d9dd04` and `87af769e9a3e`: one unrelated feature, objectui#6771's retired `body` child-list dialect (`body-dialect.ts` +99, `index.ts` +1, `validate.ts` +31/−7, its own test). It touches neither ported code and stamps only `not-a-container` and `unknown-prop`, both already in the 26-code set — which is why `26 = 26` holds at the live pin with it unported. Against objectui at `87af769e9a3e` the whole non-comment divergence of the five ported sources is four items, three pre-existing (`ValidationResult` vs `ManifestValidationResult`; the `code: 'inert-quick-add'` inline literal forced by `check:dispatcher-error-vocabulary`, pinned equal to the constant by a test row; `provenance.ts` and `assertFullyLoaded` / `RegistryConfigLike.lazy` absent here) and one new since `cfcc17d9` (`body-dialect.ts` absent here — see Acceptance notes). The port strictly REDUCES divergence in every file it touches: `validate.ts` 146 → 73, `index.ts` 114 → 92, `codegen.ts` 30 → 3, `types.ts` 96 → 85 diff lines vs objectui at the live pin. ### Ablations — re-run on this tree Three, each through `scripts/ablation-replace.mjs` (anchor ×1, mutation proven on disk by anchor count and blob change, restore proven by `blob == HEAD` AND an empty `git diff HEAD`): (1) `checkKanbanQuickAdd` stamps nothing — **5 failed / 8 passed** of 13; (2) the validator's member check reads no declared arms — **7 failed / 14 passed** of 21; (3) the codegen narrows no member type — **3 failed / 18 passed** of 21. Baselines 13 and 21 passed; in each leg the failures are the SUBJECT rows and every control row stays green. Both suites import `../index.js`, a relative intra-package specifier, so no rebuild is in the resolution path. ## Citation spelling fix (`fc25a5925d`) CI's `Lint & Repo Gates` went red on `check-issue-citations` at `6ef8344645`: two issue-number citations on docblock lines this branch rewrote. `packages/spec/src/ui/view.zod.ts` — `objectstack#17328` respelled bare `#17328` (the issue exists, closed completed by merged PR #17671; the gate probes only unqualified citations, so the this-repo-qualified spelling was judged against a board never asked for it). `packages/spec/src/ui/component.zod.ts` — `#10274` measured **deleted** by `--probe-cause` (gone from the board and 404 on the web endpoint, not transferred); no replacement guessed — the sentence now states in prose that the number no longer resolves and names the live record (that block plus `check:objectui-pin-citations`). `node scripts/check-issue-citations.mjs` exit 0 at the head (31 judged, 0 findings); `check:generated` unchanged (TSDoc, not `.describe()`). ## Post-landing smoke evidence (triage's condition, issue comment 5690507317) ``` bash scripts/pm/os-verify-lock.sh -c 'bash scripts/build-console.sh' os-verify-lock: VERDICT command-exit 0 · held the lock 653s (10m53s) · waited 0s ✓ 8786 modules transformed. ✓ Bundle canary 'import/jobs' present — framework client is in the bundle. ✓ Console bundle carries THIS tree's @objectstack/spec, and only it. ✓ @objectstack/console dist ready (60228 KB) from objectui@87af769e9a3e ``` | Reading | Value | |---|---| | exit code | 0 | | `packages/console/dist` size | 60228 KB — 51,702,779 bytes, 3,285 files | | content hash | `sha256 259d2dfecaa12507fd3166a3f91c66c52581990e5ccac3899757027fa6ac108d` over `find … -type f \| sort \| xargs sha256sum \| sha256sum` | | provenance stamp | `packages/console/dist/.objectui-sha` = `87af769e9a3ee28ace099fdd653d3ebd79fe82e2` | | `pnpm check:console-sha` | exit 0 — "Console dist matches the objectui pin" | The console build is GREEN at the new pin. 584 commits of objectui change came with it and none of them broke it. ## The citations — re-MEASURED, never re-pointed 27 asserting citations, all of them stale at the new pin. Each was re-derived by reading objectui at BOTH shas and comparing content, not by arithmetic on a line number. `pnpm --filter @objectstack/spec check:objectui-pin-citations` exit 0; `--verify-anchors` exit 0 with 7 of 7 content assertions verified against objectui at `87af769e9`. ### Corpus-absence records (7 citations + 6 generated copies) These cite a zero-hit count over the pinned tree, not a file:line. Re-counted with `git grep -F -o` at both shas; the METHOD was calibrated first by reproducing the old pin's own numbers exactly (6409 tracked files, `useState` 2304). | Record | Cited | Reads at `87af769e9` | Verdict | |---|---|---|---| | `18.kernel-health-check-and-hot-reload-durations-unit-in-key.ts:48` | 13 exports of `plugin-lifecycle-advanced.zod.ts` + `debounceDelay` = 0 / 6409 files; controls `objectstack` 10171, `@objectstack/spec` 3479 | all still 0 / **8228** files; controls **12966**, **4997** | unchanged verdict, counts re-measured | | `18.kernel-runtime-config-timeout-unit-in-key.ts:45` | `resourceLimits.timeout` 0; controls `timeout` 832, `RuntimeConfig` 236, `resourceLimits` 2 | 0; **1075**, **240**, 2 — and both `resourceLimits` hits are still prose in `packages/app-shell` | unchanged | | `18.logging-durations-unit-in-key.ts:48` | 4 names 0; controls `useState` 2304, `timeout` **702** | 0; **2383**, **1075** | unchanged — ⚠️ but `timeout` 702 was WRONG AT THE PIN IT NAMED: that corpus reads 832. An error since written, found only by re-measuring, corrected here | | `18.system-metrics-jsdoc-durations-unit-in-key.ts:70` | 6 def names + 2 keys 0; controls `window` 2710, `timeout` 832, `period` 160, `interval` 156, `metrics` 301 | all 0; **3464**, **1075**, **170**, **170**, **324** | unchanged | | `18.system-tracing-otel-exporter-durations-unit-in-key.ts:66` | 37 exports of `tracing.zod.ts` + 4 key names 0; `Span` 404 / `SpanSchema` 40 unrelated; controls 10171, 3479 | all 0; **486** / **53**; **12966**, **4997** | unchanged | | `18.tenant-schema-cache-ttl-unit-in-key.ts:31` | `schemaCacheTTL` 0; controls `TTL` 112, `tenant` 819 | 0; **156**, **976** | unchanged | | `migrations/registry.ts` ×6 | the generated concatenation of the six above | regenerated with `pnpm --filter @objectstack/spec gen:migration-registry` | follows its entries | ### Read-point records (20 citations + 7 content assertions) | Record | Anchor, as cited | At `87af769e9` | Verdict | |---|---|---|---| | `data/api-methods-batch-conformance.test.ts:64` | `ObjectGrid.tsx:3538-3553` | `:3940-3955` | MOVED, span byte-identical (`git hash-object` `6133933199…` both sides) | | | `hooks/useBulkExecutor.ts:284-289` | `:298-303` | MOVED, span byte-identical (`0108334833…`); ⚠️ the FILE is no longer byte-identical (+36/-22), so the record's old identity argument is gone and the span was re-read | | `ui/component.zod.ts` tab-item `icon` + `ui/component.test.ts:376` | `containers.tsx:730-736` | `:853-859` | MOVED, 7 lines byte-identical | | | `containers.tsx:789` (registration `items` input) | `:912` | MOVED **and the LINE CHANGED** — it lost `label: 'Tabs'`, gained `of: 'object'` and a longer description; the member list the record cites is unchanged | | `ui/component.zod.ts` accordion-item `icon` + `component.test.ts:286` | `containers.tsx:919-925` | `:1069-1075` | MOVED, byte-identical | | | `containers.tsx:966` | `:1116` | MOVED **and the LINE CHANGED**, same way | | `ui/component.zod.ts` button `icon` + `component.test.ts:3489` | `form/button.tsx:43`, `:72`, `:74` | unchanged | UNCHANGED | | | `form/button.tsx:85-102` (inputs), `:103-107` (defaultProps) | `:85-97`, `:98-102` | MOVED **and SHRANK** — every input dropped its `label` and `defaultValue`; the four input names and the ABSENCE of an `icon` input, which is what the record asserts, both hold | | | `action/resolve-icon.ts:129-132` (`resolveIcon`) | `:322-328` | MOVED **and REWRITTEN** — the tail no longer indexes `lucide-react`'s `icons` record; it asks `recordIconName` and hands the pair to `lazyIconComponent`. Accept/reject behaviour unchanged | | | `resolve-icon.ts:117-120`, `:100-105`, `:90-92` | `:302-305`, `:153-158`, `:143-145` | MOVED, byte-identical | | | `lib/lazy-icon.tsx:66-92` | `:98-124` | MOVED, byte-identical | | `ui/component.zod.ts` object-metric `icon` | `plugin-dashboard/src/index.tsx:204` | `:237` (registration now opens at `:227`) | MOVED **and the LINE CHANGED** — the input's `label: 'Icon (Lucide name)'` is GONE; the key is still published, now as a bare `{ name: 'icon', type: 'string' }` | | | `ObjectMetricWidget.tsx:142` / `:474`; `MetricWidget.tsx:312-321` / `:373-382`; `lazy-icon.tsx:66-80` | `:174` / `:483`; `:351-360` / `:412-421`; `:98-112` | MOVED, byte-identical | | `ui/component.zod.ts` kanban `limit` ×2 + `component.test.ts:3360` | `ObjectKanban.tsx:264` (`$top: schema.limit ?? DEFAULT_KANBAN_LIMIT`) | `:676` (`$top: resolveRowLimit(schema.limit, DEFAULT_KANBAN_LIMIT)`) | MOVED **and REWRITTEN** — objectui#9925 put a refusal in front of it (a contract-refused cap is dropped and reported at `:553`). The pinned fact, that `limit` lowers into the query's top-level `$top`, holds | | | `ObjectKanban.tsx:71`; `plugin-kanban/src/index.tsx:395-398` | `:84`; `:447-450` | MOVED, byte-identical | | | `ObjectKanban.tsx:143` + `plugin-kanban/src/types.ts:134` (`KanbanSchema.limit?: number`) | ⚠️ **VANISHED** | `KanbanSchema` was RETIRED at this pin (maintainer ruling 2026-09-09) and `types.ts` declares the member no more. Re-derived rather than re-pointed: the published twin is `ObjectKanbanSchema`, imported at `ObjectKanban.tsx:10`, declaring `limit?: number` at `packages/types/src/objectql.ts:3735` | | | `ElementDataSourceGate.tsx:236-241` | `:316-331` | MOVED **and EXTENDED** — the branch gained objectui#9899's presence-is-not-authorship test and a `describeDisplacedRowLimit` report | | `ui/component.zod.ts` kanban `quickAdd` + `component.test.ts:3427` | `ObjectKanban.tsx:931`; `plugin-kanban/src/index.tsx:196`; `KanbanImpl.tsx:355` / `:368` | `:1563`; `:313`; `:621` / `:634` | MOVED, byte-identical. The absence re-counted at this pin: `quickAdd` / `onQuickAdd` 0 each in `ObjectKanban.tsx`, against 11 (was 6) for the sibling `onCardClick` | | `ui/dataset.zod.ts:207` measure `format` | `dataset-format.ts:185-198`, `date-display.ts:131-164` / `:117`, `:195` | `:229-264` (routed at `:370`), `:198-233` / `:152`, `:260-262` | ⚠️ **SUBSTANCE REVERSED** — see below | | `ui/view.zod.ts:2945` `FormField.span` | the widest-tier-only class claim at `53ded82bf7` | `spanLadderFor`, `form/form.tsx:204-231` | ⚠️ **SUBSTANCE REVERSED** — see below | | `ui/view.zod.ts` `ListMapConfig`, 7 content assertions | `ListView.tsx:113` / `:67`; `ObjectView.tsx:1381`; `objectql.zod.ts:562` / `:313`; `ObjectMap.tsx:373` / `:378` | `:146` / `:85`; `:1764`; `:1574` / `:734`; `:385` / `:390` | all 7 MOVED; ⚠️ one LOST ITS SYMBOL — `FLAT_MAP_CONFIG_KEYS` became the total `FLAT_MAP_CONFIG_SPELLING` map (objectui#9950), so `style` now DOES reach the flat product, as `mapStyle`. The quote was re-read, not re-pointed | ### The two records whose SUBSTANCE the range reverses Both are claims about what the SHIPPED renderer does, so the pin is what dates them, and both were re-stated from the new tree. Each also carried a published `.describe()` saying the same now-false thing, which this bump is what falsifies — so both sentences are corrected here and `content/docs/references/ui/{dataset,view}.mdx` regenerated from them. That is the `@objectstack/spec: patch` changeset in this PR. - **`Dataset` measure `format`** said "a datetime value ignores it". objectui#8352 is inside the range: `formatMeasureDate`'s datetime arm now SELECTS a formatter — `relative` to `formatRelativeDate` (`:260`), `short` to `formatDateTime(v, { locale, style: 'compact' })` (`:261`), everything else to the bare `formatDateTime(v, { locale })` (`:262`). A date PATTERN is still ignored on both arms, which is the half that survives. - **`FormField.span`** said only the widest container-query tier's class is emitted, so a `'full'` field was one cell of two at 720px (#17328). objectui#9244 / objectui#9253 (`bd09957380`) are inside the range: `spanLadderFor` emits one clamped col-span class per multi-column tier. ⭐ The previous revision of this block asked in writing to be re-read at the bump that absorbed it; this is that re-read. The `'auto'` half — textarea, markdown, html, richtext and repeater — re-measured UNCHANGED. ## Gates Derived with `node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack` (122 commands for this 19-path, 757-line change set). Run locally, exit codes captured before any pipe: ``` pnpm check:sdui-lockstep EXIT 0 (after the fold-in: 26 = 26 codes, grammar region byte-identical) pnpm --filter @objectstack/spec check:objectui-pin-citations EXIT 0 (27 asserting citations match, 7/7 anchors verified) … --verify-anchors EXIT 0 node scripts/check-sdui-manifest.mjs EXIT 0 pnpm check:objectui-bump EXIT 0 pnpm check:objectui-changeset EXIT 0 pnpm check:console-sha EXIT 0 pnpm --filter @objectstack/spec check:generated EXIT 0 (15/15 artefacts current) MANIFEST=… check:react-declaration-parity EXIT 0 (reading unmoved: the manifest is byte-identical) node scripts/check-adr-0087-registration.mjs --base origin/main EXIT 0 node scripts/check-changeset-no-major.mjs --base origin/main EXIT 0 node scripts/check-empty-changeset.mjs --base origin/main EXIT 0 pnpm lint EXIT 0 (repo-wide, eslint . --no-inline-config) pnpm --filter @objectstack/spec test EXIT 0 (503 files, 14710 tests) pnpm --filter @objectstack/spec --filter @objectstack/sdui-parser typecheck EXIT 0 ``` plus 27 further derived families, every one exit 0: `check:nul-bytes`, `check:merge-driver`, `check:watch-hint-literal`, `check:comment-mask-adoption`, `check:comment-mask-corpus`, `check:doc-frontmatter`, `check:docs-section-name`, `check:scripts-symbol-anchors`, `check:spec-docblock-symbol-anchors`, `check:ci-filter-parity`, `check:keyed-text-bounds`, `check:undeclared-dep-imports`, `check:section-landing-index`, `check:liveness`, `check:duration-unit-keys`, `check:llms-txt`, `check:spec-changes`, `check:upgrade-guide`, `check:strictness-ledger`, `check:export-origins`, `check:api-surface`, `check:authorable-surface`, `check:docs`, `check:doc-anchors`, `check:docs-spec-enumerations`, `check:quick-reference-counts`, `check:corpus-claim-drift`, `check:changeset-gate-self-tests`, `check:pm-widening-tells`, `check:published-files`, and both changeset self-tests. The rest of the 122 are left to CI, which runs the whole farm. `origin/main` moved 7 commits while this was built and touches NONE of this diff's 19 paths, so no merge was taken; the queue's rebuilt generation is what validates the join. ## Acceptance notes - `check-issue-citations` blind spot (measured on #17328 at `6ef8344645`): a citation qualified with this repository's own name (`objectstack#N` or `owner/repo#N`) is recognised as naming THIS repo and resolved against the board, but the board is only asked for unqualified citations and `--probe-cause`'s guard is `!cite.qualifier` too — a live issue reads `allocated-but-absent` and NOT MEASURED under `--probe-cause`. Not fixed here (the gate is not this PR's surface); recorded for the next author of `scripts/check-issue-citations.mjs`. - objectui's `packages/sdui-parser/body-dialect.ts` (objectui#6771, landed between `cfcc17d9dd04` and the live pin) has no counterpart in this copy: for an authored `body` key the two copies stamp different codes (`not-a-container` under a non-container there, the bare `unknown-prop` here), invisible to `check:sdui-lockstep`'s code-SET comparison because both codes are already in the 26-set. Both severities are `warning`, so `compile().ok` and the save verdict are unchanged. A third code path the ruling does not name; carrier: the next sdui-parser port round. - `provenance.ts` and `assertFullyLoaded` / `RegistryConfigLike.lazy` remain absent from this copy (zero diagnostic codes; #18723's acceptance notes already record `provenance.ts`). `pnpm gen:sdui-lockstep` is unrunnable in this container because the shared sibling checkout sits off the pin and the generator's remedy is a git write in someone else's tree; it cost nothing this round and will bite the next pin bump, which must park its own checkout. - `.changeset/18516-span-auto-wide-types.md` (pending, not yet released) describes the `FormField.span` describe text this PR corrects, including "At this pin only the widest tier's class is emitted". `check:empty-changeset` refuses any diff that MODIFIES a changeset present at the merge base, so it is deliberately left untouched here and reported instead. - The `element:button` `icon` `.describe()` still says the renderer resolves through `lucide-react`'s `icons` map. At the new pin that is one hop indirect (`recordIconName` + `lazyIconComponent`) but the glyph set and the accepted spellings are unchanged, so it was left as written rather than churned. Original author: the director seat's `os-dev` rounds (pin bump; fold-in `6ef8344645`; citation fix `fc25a5925d`), session_012GcsUbuqFGBibkEDMRC1eE; body maintained by the director seat, `session_012GcsUbuqFGBibkEDMRC1eE`. --- _Generated by [Claude Code](https://claude.ai/code)_ --------- Co-authored-by: Claude <noreply@anthropic.com>
1 parent 72eeabd commit fbc12be

27 files changed

Lines changed: 1340 additions & 219 deletions
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
---
2+
'@objectstack/spec': patch
3+
---
4+
5+
Two published `describe` sentences that the `.objectui-sha` bump to objectui `87af769e9a3e` makes false are corrected against the new pin (#17429).
6+
7+
`Clause-②: no`
8+
9+
Both are claims about what the SHIPPED console renderer does, so the pin is what dates them — and both were re-read by executing the pinned tree, not by refreshing a sha.
10+
11+
- `Dataset` measure `format`: the clause said "a datetime value ignores it". objectui#8352 lands inside the `53ded82bf7a4...87af769e9a3e` range and makes the datetime arm of `formatMeasureDate` honour the same two words the date arm does — `relative` through `formatRelativeDate`, `short` through `formatDateTime(v, { locale, style: 'compact' })`. A date PATTERN is still ignored on both arms, which is the half of the sentence that survives.
12+
- `FormField.span`: the clause said only the widest container-query tier's class is emitted, so a `'full'` field took one cell of two at the 720px modal width (objectstack#17328). objectui#9244 / objectui#9253 (objectui `bd09957380`) are also inside the range: `spanLadderFor` now emits one clamped col-span class per multi-column tier, so `'full'` is the whole row at every multi-column tier. The `'auto'` half — textarea, markdown, html, richtext and repeater — re-measured unchanged at the new pin.
13+
14+
No key, default, enum member or export moves: the same authored metadata is accepted and refused as before, and `content/docs/references/ui/{dataset,view}.mdx` are regenerated from these two sentences.
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
---
2+
"@objectstack/sdui-parser": minor
3+
---
4+
5+
The save gate now stamps `inert-quick-add` and `member-type-mismatch`, the two diagnostics that existed only in objectui's copy of this parser — so a page no longer saves clean here and renders with a different verdict there (#17645).
6+
7+
The two copies of this parser owe each other one thing: byte agreement on the accepted grammar and on diagnostic codes. This copy runs the **save gate** and objectui's runs the **renderer**, so a code on one side only is a dialect — the author gets one reading when they save and another when the page draws, which is surface-dependent and therefore reaches them as intermittent. Measured at the ported revision: objectui stamped 26 codes, this copy stamped 24, and the missing two were exactly these.
8+
9+
- **`inert-quick-add`** (warning) — `quickAdd` on `<object-kanban>` reaches no control. The Quick Add button is gated on **both** `quickAdd` and an `onQuickAdd` handler, and `onQuickAdd` takes a function, which no page on this tier can write (this tier parses, it never executes) and which the board substitutes none of its own for. It **replaces** the `unknown-prop` this copy used to emit for the key, which was false against the contract: `ComponentPropsMap['object-kanban']` publishes `quickAdd`, so an author who checked the spec found the warning contradicted and kept a key that will never do anything. Asked ahead of the declaration lookup on purpose — the claim is about the render path, so declaring the key must not silently disarm it. A falsy value and an unevaluated braced expression are deliberately untouched.
10+
- **`member-type-mismatch`** (warning; `error` when an `enum` arm is present) — the coarse type check one level down, over the member kind an input declares. This brings the `ManifestInput.of` key and its three readers with it: the validator, the serializer's canonicalization, and the codegen's element type. `of: 'string'` on an array input now types the members `string[]` in the generated `.d.ts` instead of `unknown[]`, and a member no declared arm accepts draws **one** diagnostic naming every offending position rather than one per member.
11+
12+
**Nothing published changes shape for an input that declares no `of`.** The key is absent-means-undeclared: the validator checks no member, the codegen emits the unnarrowed element type, and `manifestFromConfigs` publishes no `of` at all, so an entry written before the key existed serializes byte-identically. Measured on the tracked `sdui.manifest.json`: 0 of 339 inputs declare `of`, and the artefact regenerates to the same sha256 across this change.
13+
14+
⚠️ **Both new codes are diagnostics, not a new red gate.** Each is a warning, so `compile().ok` — the save gate's pass/fail — is unchanged, and a page that saves today still saves. Escalating an inert authored key to `error` is a separate question and belongs at the save gate, not here.

0 commit comments

Comments
 (0)