diff --git a/.changeset/10803-dead-citation-sweep-third-batch.md b/.changeset/10803-dead-citation-sweep-third-batch.md new file mode 100644 index 0000000000..033b46563e --- /dev/null +++ b/.changeset/10803-dead-citation-sweep-third-batch.md @@ -0,0 +1,20 @@ +--- +--- + +Comment-only in `@object-ui/app-shell`, `@object-ui/components`, `@object-ui/core`, +`@object-ui/data-objectstack`, `@object-ui/i18n`, `@object-ui/layout`, +`@object-ui/plugin-charts`, `@object-ui/plugin-dashboard`, `@object-ui/plugin-detail`, +`@object-ui/react`, `@object-ui/sdui-parser` and `@object-ui/types`: docblocks and code +comments that cited objectui issues which answer 404 now cite the commit that landed each +change, as a 9-character sha, the ruling by its date where the sentence cites a ruling, or +a live successor, and where nothing answers they name the card by role (objectui#10803, +the third batch). Some of these docblocks reach the +emitted `.d.ts` and `.js`; none of them moves a claim, and none of these comment edits +changes a code or type token. No published behaviour changes through them, so this +declares no release. The runtime text the sweep touches, four tombstone guidance strings +and two zod `.describe()` strings in `@object-ui/types` and one CEL authoring advisory in +`@object-ui/app-shell`, is declared on its own as a patch in +`10803-third-batch-runtime-strings.md`. + +The same repair in the pending changesets that carried these citations is prose-only, and +their frontmatter is byte-identical. diff --git a/.changeset/10803-third-batch-runtime-strings.md b/.changeset/10803-third-batch-runtime-strings.md new file mode 100644 index 0000000000..cc3a2de328 --- /dev/null +++ b/.changeset/10803-third-batch-runtime-strings.md @@ -0,0 +1,30 @@ +--- +'@object-ui/types': patch +'@object-ui/app-shell': patch +--- + +fix(types,app-shell): runtime strings no longer point at objectui issues that answer 404 + +Four ADR-0049 retirement tombstones in the published zod mirrors, two runtime descriptions +and the Studio CEL authoring advisory carried a pointer to an objectui issue that answers +404. A reader of a parse error, a zod `description` or an editor warning has no repository +to resolve a commit against, so no dead pointer becomes a commit: tombstones cite +`ADR-0049` in its place, and every other pointer is simply dropped (objectui#10803). + +- **The tombstone guidance.** Each tombstone's guidance feeds both the parse error an + author reads and the `.describe()` text, and now opens `RETIRED (ADR-0049) —` in + place of the dead card: `TreeViewSchema.data`, `TextSchema.value`, + `ChartDataSeriesSchema.data`, and `DashboardConfigSchema.aria` (its error and its + describe text, two strings). Everything after the dash is unchanged, so the remedy + each message gives is word for word what it was. +- **Two descriptions.** `TreeViewSchema.nodes` loses the pointer in two places: its + parenthesis now ends "no presence rule exists", and its history clause reads "the + `data` fallback spelling was retired". `TextSchema.content` likewise ends "its `value` + fallback spelling was retired". +- **The advisory** that tells an author a row predicate binds the row as `record` and + nothing else ends that clause at "nothing else". + +Nothing else in any string moves, and no key, path, issue code, accept set, refusal or +severity changes: every document that parsed before parses the same way and is refused +at the same path with the same code, and the advisory still fires on exactly the same +predicates. diff --git a/.changeset/5291-api-console-storage-slot.md b/.changeset/5291-api-console-storage-slot.md index a764660e97..861dd36c3a 100644 --- a/.changeset/5291-api-console-storage-slot.md +++ b/.changeset/5291-api-console-storage-slot.md @@ -6,7 +6,7 @@ API Console's endpoint catalog is keyed by the canonical `storage` service slot, only that slot (objectui#5291, framework#9683). `useApiDiscovery`'s `SERVICE_ENDPOINT_CATALOG` looks its keys up directly in `/discovery`'s -`services` map, and that lookup is deliberately fail-closed (ADR-0076 D12). objectui#5286 +`services` map, and that lookup is deliberately fail-closed (ADR-0076 D12). `38ba3ddf3` had kept the Storage entry keyed by the deprecated `file-storage` spelling, with a small alias table that read `services.storage` first and fell back to `services['file-storage']`, because the installed `@objectstack/spec` did not list `storage` in `CoreServiceName` yet. diff --git a/.changeset/5859-retire-orphaned-object-exports.md b/.changeset/5859-retire-orphaned-object-exports.md index 7e460424ea..4590fdae3b 100644 --- a/.changeset/5859-retire-orphaned-object-exports.md +++ b/.changeset/5859-retire-orphaned-object-exports.md @@ -4,7 +4,7 @@ `ObjectTrigger` and `ObjectRelationship` are removed from `@object-ui/types` — two hand-written interfaces orphaned by the `ObjectSchemaMetadata` derivation -(objectui#5859, triage adjudication 2026-08-24; the derivation itself was +(triage adjudication 2026-08-24; the derivation itself was objectui#5362). **Breaking for anyone importing either name.** The two symbols are, verbatim: diff --git a/.changeset/5926-empty-action-visible-when.md b/.changeset/5926-empty-action-visible-when.md index 4599bf9b70..6bd8255259 100644 --- a/.changeset/5926-empty-action-visible-when.md +++ b/.changeset/5926-empty-action-visible-when.md @@ -17,7 +17,7 @@ result itself, so the node never passed through `SchemaRenderer` and its `visibl **never evaluated**. `@objectstack/spec` accepts the key (`SchemaNodeSchema` carries `visibleWhen`, and `data-display.zod.ts` types `emptyAction` as a `SchemaNode`), so an author wrote a gate, the platform took it, and nothing enforced it — declared-not-enforced, -the same class objectui#5401 / #5505 closed for `record:alert`, one level down. +the same class `c86185eb5` closed for `record:alert`, one level down. Measured on the branch point, mounting a `data-table` with no rows so the empty state is actually reached: an `emptyAction` carrying diff --git a/.changeset/6150-undeclared-but-consumed-keys.md b/.changeset/6150-undeclared-but-consumed-keys.md index 659da5b5c8..c7f0f1f24d 100644 --- a/.changeset/6150-undeclared-but-consumed-keys.md +++ b/.changeset/6150-undeclared-but-consumed-keys.md @@ -90,7 +90,7 @@ either face: optional, so the `nodes` spelling the renderer reads FIRST stands on its own (`6939-tree-view-nodes-mirror.md`, published beside this note). `bind` is read before either and is unchanged. -- **`data` is not required — it is REFUSED BY NAME.** objectui#6951 retired it +- **`data` is not required — it is REFUSED BY NAME.** `16a725f96` retired it under ADR-0049 on both faces: the TypeScript member is a `?: never` tombstone and the zod arm is a `retirementTombstone(...)` whose guidance points the author at `nodes` (`6951-tree-view-data-retired.md`, also published beside this note). diff --git a/.changeset/6293-conditionbuilder-reference-value.md b/.changeset/6293-conditionbuilder-reference-value.md index 1bee446a33..5204c92458 100644 --- a/.changeset/6293-conditionbuilder-reference-value.md +++ b/.changeset/6293-conditionbuilder-reference-value.md @@ -22,7 +22,7 @@ validation evaluators, and `current_user` is the ADR-0068 spelling of the same i `vars`, `page`) are deliberately excluded: `data.csv` is a plausible literal and `data` *is* bound, so capturing it would trade one silently-false predicate for another rather than for a loud one. Declaring which roots a mounting surface actually binds is caller-supplied -vocabulary and belongs to objectui#6296. +vocabulary, which `88b15fddc` added. The test is "a dotted path under a declared root", not "contains a dot" — a version string (`1.2.3`), a filename, and a path under an unbound root all stay literal text. The literal and diff --git a/.changeset/6296-conditionbuilder-subject-vocabulary.md b/.changeset/6296-conditionbuilder-subject-vocabulary.md index 77b92ba6e0..267e341d6f 100644 --- a/.changeset/6296-conditionbuilder-subject-vocabulary.md +++ b/.changeset/6296-conditionbuilder-subject-vocabulary.md @@ -3,7 +3,7 @@ --- `ConditionBuilder` now takes a caller-supplied **subject vocabulary** instead of hardcoding a -record-scoped one (objectui#6296). +record-scoped one. The builder built every row subject as `record.` + field name, plus a fixed `record.id` / `user.*` / `org.*` context list. That is correct for all five files that mount it today — six diff --git a/.changeset/6464-recall-submitter-gate.md b/.changeset/6464-recall-submitter-gate.md index 541e31c934..e334e15549 100644 --- a/.changeset/6464-recall-submitter-gate.md +++ b/.changeset/6464-recall-submitter-gate.md @@ -5,7 +5,7 @@ --- The record page's approval band offers its **Recall** button to the approval's submitter -only (objectui#6464). +only. Field report on `@objectstack/*@17.2.0`: user A submits a record into a 4-level approval; user B — not the submitter, read access, not an admin — opens the record and the band still diff --git a/.changeset/6598-inert-expression-warning.md b/.changeset/6598-inert-expression-warning.md index 84ebbeb9f2..526300d808 100644 --- a/.changeset/6598-inert-expression-warning.md +++ b/.changeset/6598-inert-expression-warning.md @@ -19,7 +19,7 @@ state. `validateTree` now emits a warning-severity `inert-expression` diagnostic when a declared input's value is the `$expr` marker, with the fix in the message: write the value as JSON (double-quoted strings and keys). Warning, not error, per the -objectui#5709 posture for inert authored keys — pages keep compiling and +`8d58f46b4` posture for inert authored keys — pages keep compiling and rendering exactly as before; the silence is what changed. Escalating the severity, widening the accepted literal grammar (e.g. materializing single-quoted strings), and covering base props like `style` are contract diff --git a/.changeset/6661-app-launcher-nav-menu-renderers.md b/.changeset/6661-app-launcher-nav-menu-renderers.md index cb069799f7..aaa11c84df 100644 --- a/.changeset/6661-app-launcher-nav-menu-renderers.md +++ b/.changeset/6661-app-launcher-nav-menu-renderers.md @@ -4,11 +4,11 @@ '@object-ui/i18n': minor --- -Renderers for the `app:launcher` and `nav:menu` page blocks (objectui#6661). +Renderers for the `app:launcher` and `nav:menu` page blocks. Phase 1 of the 2026-08-26 maintainer ruling on objectstack#12183 — the two `PageComponentType` members that are purely metadata-driven, so nothing had to ship before their renderers could. Phase 2 (`global:search` / -`global:notifications`) landed in objectui#6757 and set the pattern this +`global:notifications`) landed in `f99932a42` and set the pattern this follows. A page that declared either member drew a dashed box. The two symptoms were not diff --git a/.changeset/6740-flex-is-container.md b/.changeset/6740-flex-is-container.md index c151c0f144..e66425da03 100644 --- a/.changeset/6740-flex-is-container.md +++ b/.changeset/6740-flex-is-container.md @@ -2,7 +2,7 @@ '@object-ui/components': patch --- -`flex` declares the containment it renders (objectui#6740). +`flex` declares the containment it renders. `flex` has always rendered `schema.children`, but its registration omitted `isContainer` while `grid`, `card`, `container` and `stack` — same directory, diff --git a/.changeset/6757-global-search-notifications-renderers.md b/.changeset/6757-global-search-notifications-renderers.md index 5be1aca0ca..49bc2a8ec1 100644 --- a/.changeset/6757-global-search-notifications-renderers.md +++ b/.changeset/6757-global-search-notifications-renderers.md @@ -2,8 +2,8 @@ '@object-ui/app-shell': minor --- -Renderers for the `global:search` and `global:notifications` page blocks -(objectui#6757). A page that declared either member drew the literal "Component +Renderers for the `global:search` and `global:notifications` page blocks. +A page that declared either member drew the literal "Component Placeholder" scaffold: both are first-class `PageComponentType` members that the 2026-08-26 maintainer ruling on objectstack#12183 kept declared once the readiness read in objectstack#13117 evidenced both data sources shipped, and diff --git a/.changeset/6764-container-declaration-census.md b/.changeset/6764-container-declaration-census.md index 8c82181367..5e425b1605 100644 --- a/.changeset/6764-container-declaration-census.md +++ b/.changeset/6764-container-declaration-census.md @@ -15,7 +15,7 @@ rendered — what the omission did was make `validateTree` warn `not-a-container on a child list it then rendered, on the tier built to accept AI-authored pages. A warning that lies trains authors to discount the true ones. -Same reasoning as objectui#3900 (`page-header`) and objectui#6740 (`flex`): +Same reasoning as objectui#3900 (`page-header`) and `7c9b044f4` (`flex`): `children` is a base property of every node in the JSON protocol, not a per-component authoring key, so the flag widens no spec surface. diff --git a/.changeset/6854-layout-renderer-retired-onclick.md b/.changeset/6854-layout-renderer-retired-onclick.md index ee542966aa..bd581e449d 100644 --- a/.changeset/6854-layout-renderer-retired-onclick.md +++ b/.changeset/6854-layout-renderer-retired-onclick.md @@ -4,7 +4,7 @@ --- The standalone runner renders `AppAction.items` from its declared type only, which -makes `AppActionSchema.onClick`'s retirement message true again (objectui#6854, +makes `AppActionSchema.onClick`'s retirement message true again (the maintainer ruling of 2026-09-05, option B2). `AppAction.items` is `AppMenuItem[]`, and the zod mirror parses it with the legacy diff --git a/.changeset/6859-injected-editor-commit-comment.md b/.changeset/6859-injected-editor-commit-comment.md index b0c39c2eb5..d5edc5f04f 100644 --- a/.changeset/6859-injected-editor-commit-comment.md +++ b/.changeset/6859-injected-editor-commit-comment.md @@ -2,7 +2,7 @@ --- No behaviour change, and deliberately so: this is the record being corrected, not the -renderer (objectui#6859). +renderer. The data table's document-level `pointerdown` listener — the one that exits a host-injected inline cell editor when you click away — justified itself with "the injected widgets (text, diff --git a/.changeset/6864-aggregate-spec-shape-analytics-keys.md b/.changeset/6864-aggregate-spec-shape-analytics-keys.md index d129da605e..e691d2b0cb 100644 --- a/.changeset/6864-aggregate-spec-shape-analytics-keys.md +++ b/.changeset/6864-aggregate-spec-shape-analytics-keys.md @@ -3,7 +3,7 @@ --- `aggregate()`'s spec-shape branch now REFUSES the analytics branch's `filter` / -`field` / `function` instead of dropping them (objectui#6864, extending the +`field` / `function` instead of dropping them (extending the maintainer ruling of 2026-08-30 on objectui#6825 — option A, refuse at the producer). diff --git a/.changeset/6896-retire-chart-inline-data.md b/.changeset/6896-retire-chart-inline-data.md index 835f5cade4..f57353292e 100644 --- a/.changeset/6896-retire-chart-inline-data.md +++ b/.changeset/6896-retire-chart-inline-data.md @@ -3,7 +3,7 @@ --- Retire `ChartDataSeries.data`, and correct `ChartSchema.categories`' prose to the read it -has always had (objectui#6896, ADR-0049 enforce-or-remove; maintainer ruling 2026-08-31). +has always had (ADR-0049 enforce-or-remove; maintainer ruling 2026-08-31). ⚠️ **BREAKING for anyone authoring a static `ChartSchema` node**, shipped as `minor` because this repository's `major` is a cross-repo pin to `@objectstack`'s major rather than diff --git a/.changeset/6951-text-value-retired.md b/.changeset/6951-text-value-retired.md index 2aebdb2f93..4bdecf53e1 100644 --- a/.changeset/6951-text-value-retired.md +++ b/.changeset/6951-text-value-retired.md @@ -4,8 +4,8 @@ '@object-ui/plugin-dashboard': patch --- -**Breaking for authored metadata:** `TextSchema.value` is RETIRED (objectui#6951, -maintainer ruling A1 of 2026-09-04; objectui#7016; ADR-0049 enforce-or-remove). +**Breaking for authored metadata:** `TextSchema.value` is RETIRED +(maintainer ruling A1 of 2026-09-04; objectui#7016; ADR-0049 enforce-or-remove). A `text` node that authors `value` no longer validates: the parse fails loudly on the `value` path with the explanation in the message, the TS member is a `?: never` tombstone so the same document is refused at compile time, and the @@ -34,7 +34,7 @@ nodes, and were excluded by kind.) now fails validation with: -> RETIRED (objectui#6951) — `value` is no longer part of TextSchema; write +> RETIRED (ADR-0049) — `value` is no longer part of TextSchema; write > `content`. It was a second spelling of the one content slot, read only as the > fallback limb of `schema.content || schema.value`, and was retired under > ADR-0049 enforce-or-remove with no deprecation window (maintainer ruling A1, diff --git a/.changeset/6951-tree-view-data-retired.md b/.changeset/6951-tree-view-data-retired.md index d1d4c40f81..f9ee6a833d 100644 --- a/.changeset/6951-tree-view-data-retired.md +++ b/.changeset/6951-tree-view-data-retired.md @@ -3,8 +3,8 @@ '@object-ui/components': minor --- -**Breaking for authored metadata:** `TreeViewSchema.data` is RETIRED (objectui#6951, -maintainer ruling B1 of 2026-09-04; ADR-0049 enforce-or-remove). A `tree-view` +**Breaking for authored metadata:** `TreeViewSchema.data` is RETIRED +(maintainer ruling B1 of 2026-09-04; ADR-0049 enforce-or-remove). A `tree-view` node that authors `data` no longer validates: the parse fails loudly on the `data` path with the explanation in the message, the TS member is a `?: never` tombstone so the same document is refused at compile time, and the renderer no @@ -32,7 +32,7 @@ authored either spelling. now fails validation with: -> RETIRED (objectui#6951) — `data` is no longer part of TreeViewSchema; write +> RETIRED (ADR-0049) — `data` is no longer part of TreeViewSchema; write > `nodes` (or bind the tree with `bind`). It was the second spelling of the one > inline-nodes slot, read only as the last limb of > `boundData || schema.nodes || schema.data || []`, and was retired under diff --git a/.changeset/7092-launcher-exclusion-reason.md b/.changeset/7092-launcher-exclusion-reason.md index 19513e04b1..61dc7b07b1 100644 --- a/.changeset/7092-launcher-exclusion-reason.md +++ b/.changeset/7092-launcher-exclusion-reason.md @@ -6,7 +6,7 @@ page-palette ledger. It read "shell singleton — the app shell renders it, not and objectui#7091 registered a real `app:launcher` renderer, so a page can now render it and the "not a page" clause became false. The reason now reads "shell singleton — lives in the app shell chrome", mirroring the neutral form its sibling `global:notifications` -has carried since objectui#6757 shipped that type a renderer without its wording rotting: +has carried since `f99932a42` shipped that type a renderer without its wording rotting: the entry describes WHERE the thing lives, not whether a renderer exists, so a later renderer cannot falsify it. diff --git a/.changeset/7113-chart-data-model.md b/.changeset/7113-chart-data-model.md index 2d314e79b6..f302a73c40 100644 --- a/.changeset/7113-chart-data-model.md +++ b/.changeset/7113-chart-data-model.md @@ -10,7 +10,7 @@ independently instructed declaring these two keys, so they land as one change). ⚠️ Shipped as `minor`, not `patch`, because two document classes that validated before now REFUSE. The 2026-09-02 ruling grades this class "patch where the accept set only widens toward what -already renders"; this change is not a pure widening, so it takes the level objectui#6896 +already renders"; this change is not a pure widening, so it takes the level `b0d308da9` set for the same transition in this same file — the mirror starting to refuse — and for the same reason: this repository's `major` is a cross-repo pin to `@objectstack`'s major rather than a severity dial, so the break is announced here, which is the channel that carries it. @@ -96,7 +96,7 @@ would discard them. ## Not done, deliberately The 2026-09-02 ruling's `chart` row also says "`series[].data` stops being required". On this base -it already is not: objectui#6896 replaced it with `retirementTombstone(...)` — +it already is not: `b0d308da9` replaced it with `retirementTombstone(...)` — `z.never({ error }).optional()` — which is optional AND refuses any authored value by name. Implementing the clause literally would re-widen a retired key and reverse a landed ruling, so it is not done. diff --git a/.changeset/7469-app-actions-retired.md b/.changeset/7469-app-actions-retired.md index 439ddb808b..e85321cf11 100644 --- a/.changeset/7469-app-actions-retired.md +++ b/.changeset/7469-app-actions-retired.md @@ -40,7 +40,7 @@ draws no toolbar button per `'button'` entry and no avatar menu per `'user'` entry. The notification Bell is now always drawn. Before, it was hidden when a `'button'` action was authored. -Changeset entries from objectui#6854, objectui#7344, objectui#7719 and +Changeset entries from `adb2a86db`, objectui#7344, objectui#7719 and objectui#7721 describe `AppAction` as it stood before this retirement. The `shortcut` refusal from objectui#7719 still applies to the legacy `menu` items. Pinned in `packages/types/src/__tests__/app-actions-retired-7469.test.ts` and `packages/runner/src/__tests__/LayoutRenderer.chrome-7469.test.tsx`. diff --git a/.changeset/7546-chart-series-keys-declared.md b/.changeset/7546-chart-series-keys-declared.md index a184bfe906..a35c2471c5 100644 --- a/.changeset/7546-chart-series-keys-declared.md +++ b/.changeset/7546-chart-series-keys-declared.md @@ -16,7 +16,7 @@ renderer does NOT drop: the normalizer keeps that renderer-internal spelling and `primary`, but it is not a member of the published pair, so it now refuses at `variant` (below). Such a document draws a chart today — the normalizer ignores the bad value, or honours `current` — so this is a narrowing away from something that renders, which is the -distinction the 2026-09-02 ruling's grading language turns on, and it takes the level objectui#6896 and +distinction the 2026-09-02 ruling's grading language turns on, and it takes the level `b0d308da9` and objectui#7113 set for the same transition in this same file. This repository's `major` is a cross-repo pin to `@objectstack`'s major, not a severity dial; the change is announced here. @@ -78,7 +78,7 @@ is unchanged; objectui#7682 owns that decision. The object stays non-strict — a truly undeclared key is still stripped, exactly as `chart-inline-data-retired.test.ts` pins; this change declares what is read, it does not close -the object. The `data` tombstone (objectui#6896) and the at-least-one-binding refinement +the object. The `data` tombstone (`b0d308da9`) and the at-least-one-binding refinement (`5f789538d`, objectui#7113) are untouched. No reader changed. Pinned in `packages/types/src/__tests__/chart-series-keys-7546.test.ts` — the card's fixture diff --git a/.changeset/7690-chart-axis-config-declared.md b/.changeset/7690-chart-axis-config-declared.md index 47fef2230f..a69c899861 100644 --- a/.changeset/7690-chart-axis-config-declared.md +++ b/.changeset/7690-chart-axis-config-declared.md @@ -18,7 +18,7 @@ TS side — instead of letting both ride `BaseSchema`'s passthrough unchecked (o `Did you mean grid → showGridLines?`) instead of a bare `Invalid input`. ⚠️ Shipped as `minor`, not `patch`: documents that validated before now **refuse**, and each of them -draws a chart today — a narrowing away from something that renders, the transition objectui#6896, +draws a chart today — a narrowing away from something that renders, the transition `b0d308da9`, objectui#7113 and objectui#7546 graded `minor` in this same file. - An axis object with a malformed value (`min: 'zero'`, `position: 'middle'`), an undeclared key diff --git a/.changeset/7694-chart-series-chart-type-alias-refusal.md b/.changeset/7694-chart-series-chart-type-alias-refusal.md index 6b31e0bfd9..1300855b0c 100644 --- a/.changeset/7694-chart-series-chart-type-alias-refusal.md +++ b/.changeset/7694-chart-series-chart-type-alias-refusal.md @@ -83,7 +83,7 @@ mode gains is the NAMED refusal and its guidance, not a narrower accept set. The object stays non-strict — a truly undeclared key is still stripped, exactly as `chart-inline-data-retired.test.ts` pins. The six keys objectui#7546 declared, the `data` tombstone -(objectui#6896) and the at-least-one-binding refinement (`5f789538d`, objectui#7113) are untouched. +(`b0d308da9`) and the at-least-one-binding refinement (`5f789538d`, objectui#7113) are untouched. **No reader changed:** `normalizeSeries` still reads `chartType` first on the internal-shape arrays its producers hand it; that limb is a reader decision, not this declaration's. diff --git a/.changeset/7719-app-menu-item-shortcut-named-refusal.md b/.changeset/7719-app-menu-item-shortcut-named-refusal.md index 0d2f24595c..483b1f2344 100644 --- a/.changeset/7719-app-menu-item-shortcut-named-refusal.md +++ b/.changeset/7719-app-menu-item-shortcut-named-refusal.md @@ -9,7 +9,7 @@ issue 指向 `NavigationItem`。TS 面同步收窄:`AppMenuItem.shortcut?: never`,在编写处就被 `tsc` 拒掉。 零迁移面:本仓**零作者**写过这个键,且 `@object-ui/runner` 不发布库入口,没有绕过校验器塞进来的 -路径。⛔ 这里刻意不冻结任何总数 —— objectui#6854 当初普查的那个 JSON 总体此后已经变动,冻进散文 +路径。⛔ 这里刻意不冻结任何总数 —— `adb2a86db` 当初普查的那个 JSON 总体此后已经变动,冻进散文 的数字没有东西会去重新求值。判据写成可复跑的规则:**结构化**地 `JSON.parse` 每一个 tracked `*.json`,无限深度遍历,报出「经由字面名为 `items` 的键抵达的数组、其元素对象自带 `shortcut`」者; 在本次改动的头上跑出 0 命中,注入 fixture 的正控制会开火(含一处嵌套命中),且不会把 action 层的 `shortcut` @@ -23,7 +23,7 @@ issue 指向 `NavigationItem`。TS 面同步收窄:`AppMenuItem.shortcut?: nev - zod 面 —— `MenuItemSchema.shortcut` 走 `retirementTombstone()`,一条 guidance 同时喂 parse 消息与 `.describe()`(即已发布的 JSON-Schema 描述)。 -⛔ `LayoutRenderer` 未恢复任何读点,objectui#6854 的那枚 pin 断言原样保留;本次只修了它与 +⛔ `LayoutRenderer` 未恢复任何读点,`adb2a86db` 的那枚 pin 断言原样保留;本次只修了它与 `LayoutRenderer.tsx` 里已经过期的散文(两处都在把一个已裁决的问题描述成悬而未决)。 `@object-ui/runner` 的改动**仅为注释**,无任何已发布行为变化。 diff --git a/.changeset/7727-conditional-formatting-record-scope.md b/.changeset/7727-conditional-formatting-record-scope.md index ad80a39279..1f55ca62a7 100644 --- a/.changeset/7727-conditional-formatting-record-scope.md +++ b/.changeset/7727-conditional-formatting-record-scope.md @@ -20,7 +20,7 @@ is migrated automatically and nothing at runtime changes: those conditions were dead (see below), the editor just stops hiding it. Rewrite `status == 'overdue'` as `record.status == 'overdue'`. -The editor was teaching a spelling the runtime had already retired. objectui#5741 +The editor was teaching a spelling the runtime had already retired. `83fe6e741` (Phase 2 of the objectui#5330 canon, ruled 2026-09-02 and amended 2026-09-05) unbound the bare shorthand and `data.*` on runtime record surfaces: `evalRowPredicate` binds the row as `record.*` and nothing else, so `status == 'overdue'` faults with @@ -115,7 +115,7 @@ the engine's `introspectScope` returns byte-identical `fields` for `record` and `fields` hint rather than deriving one per scope). The `flattened` default at the shared authoring seam is **untouched**: RLS predicates -and flow conditions are not row surfaces (objectui#5738 stand-down 3) and stay +and flow conditions are not row surfaces (stand-down 3 on the corpus-sweep card behind `702c48a62`) and stay flattened. **What this does NOT close — one half is left open, and it is filed.** diff --git a/.changeset/8166-record-scope-data-root.md b/.changeset/8166-record-scope-data-root.md index d42c721453..0719b68a96 100644 --- a/.changeset/8166-record-scope-data-root.md +++ b/.changeset/8166-record-scope-data-root.md @@ -14,7 +14,7 @@ lives in `@objectstack/formula`'s `SCOPE_ROOTS`, which still contains `data`, an scope is the producer-side half and is not this repo's to make. What changes is what the runtime does with such a predicate once it is saved. -**What was wrong.** objectui#5741 (Phase 2 of the objectui#5330 canon) retired `data.*` +**What was wrong.** `83fe6e741` (Phase 2 of the objectui#5330 canon) retired `data.*` on runtime record surfaces — the row is bound as `record.*` and nothing else. But `@object-ui/app-shell`'s `buildExpressionScope` kept binding an ambient `data`, so a predicate the linter had waved through also *resolved* at runtime, against that bag @@ -44,7 +44,7 @@ question, not this change's). So a record form renders exactly as before except console now names the root. Nothing throws. **Migration.** Rewrite `data.foo` as `record.foo` on any runtime record surface — the -canonical spelling since objectui#5741, and the only one that reaches the row. The +canonical spelling since `83fe6e741`, and the only one that reaches the row. The metadata-admin designer is unaffected: its `data` is the DRAFT under edit (ADR-0089 D3, `CANONICAL_ROOT_BY_LAYER` = `{ runtime: 'record', metadata: 'data' }`), bound by `views/metadata-admin/predicate.ts` through its own builder, which takes only the diff --git a/.changeset/8167-conditionbuilder-mount-scope.md b/.changeset/8167-conditionbuilder-mount-scope.md index 12c8f618a6..f1e1af3879 100644 --- a/.changeset/8167-conditionbuilder-mount-scope.md +++ b/.changeset/8167-conditionbuilder-mount-scope.md @@ -9,7 +9,7 @@ declare `record` (objectui#8167). mount fell through to `celAuthoring`'s own default — spelled `hint.scope ?? 'flattened'` — and no caller could override it. A bare `status == 'done'` typed into an action's **Visible when** therefore linted CLEAN and then never matched: `usePredicateRecordContext` -binds `record` and nothing else, and objectui#5741 Phase 2 retired the bare shorthand +binds `record` and nothing else, and Phase 2 (`83fe6e741`) retired the bare shorthand on runtime record surfaces. This is objectui#7727's defect at a component objectui#7727 does not touch; PR #8164 turned the same defect at the conditional-formatting mount. diff --git a/.changeset/8613-metric-structured-groupby.md b/.changeset/8613-metric-structured-groupby.md index a0c780cba9..555e6c81c0 100644 --- a/.changeset/8613-metric-structured-groupby.md +++ b/.changeset/8613-metric-structured-groupby.md @@ -38,5 +38,5 @@ author asked for one question and the platform answered another (objectui#8613). Unchanged, and pinned as controls: a plain string `groupBy` and an absent one (floored at the single `'_all'` bucket) still take the legacy query byte for byte, and an ARRAY `groupBy` still travels there too — it is not this union's -object arm, and it must keep reaching the producer-side refusal objectui#6864 +object arm, and it must keep reaching the producer-side refusal `503cd8b89` landed in the adapter. diff --git a/.changeset/8650-chart-foreign-dialect-retired.md b/.changeset/8650-chart-foreign-dialect-retired.md index 687df21814..2bef42073c 100644 --- a/.changeset/8650-chart-foreign-dialect-retired.md +++ b/.changeset/8650-chart-foreign-dialect-retired.md @@ -24,7 +24,7 @@ share one verdict: - `categories` is **not retired and is unaffected**. It is a declared member of the published `ChartSchema` and of its zod mirror, is documented in the schema reference as an alternative series list, and was ruled live by - objectui#6896. `normalizeChartSchema` — the single translation point + the maintainer ruling of 2026-08-31. `normalizeChartSchema` — the single translation point (objectui#2880 S1) — already consumed it, so `ChartRenderer`'s own branch was a second, un-normalized read that no well-formed chart could reach. Removing it changes nothing for a well-formed chart and removes two wrong answers for diff --git a/.changeset/8972-cel-authoring-data-root-advisory.md b/.changeset/8972-cel-authoring-data-root-advisory.md index 0516466ad9..6cdcd17487 100644 --- a/.changeset/8972-cel-authoring-data-root-advisory.md +++ b/.changeset/8972-cel-authoring-data-root-advisory.md @@ -8,7 +8,7 @@ Warn at typing time when a record-scope CEL predicate is rooted on `data`. `visibleWhen` / `readonlyWhen` / `requiredWhen`, a formula `expression` or a conditional-formatting `condition` written as `data.status == 'x'` used to lint green and then fault at runtime with `Unknown variable: data`, because the row -is bound as `record.*` and nothing else (objectui#5741, objectui#8166). The +is bound as `record.*` and nothing else (`83fe6e741`, objectui#8166). The metadata editors now surface `@object-ui/core`'s `detectNonCanonicalRowSpelling` as an inline warning naming `record` as the fix. diff --git a/.changeset/action-onsuccess-forward-5493.md b/.changeset/action-onsuccess-forward-5493.md index b74a69cef5..252fcebad2 100644 --- a/.changeset/action-onsuccess-forward-5493.md +++ b/.changeset/action-onsuccess-forward-5493.md @@ -8,7 +8,7 @@ actually happens on those four surfaces (objectui#5493). `onSuccess` — spec's closed strict `{ navigate, openIn }` object — became authorable on `ActionSchema` with the `@objectstack/spec` 17.1.0 pin bump (objectui#5328), and the -runner has read it off the **forwarded** def since objectui#5221: +runner has read it off the **forwarded** def since `053fdc8f9`: `ActionRunner.handlePostExecution` → `readOnSuccessNavigation` → `navigateOnSuccess`, which hops through the app's own `navigationHandler` (a real SPA route change, immune to popup blocking). Between those two halves sat these four forward whitelists, which never diff --git a/.changeset/approver-display-name-5414.md b/.changeset/approver-display-name-5414.md index f441983851..9238b98a41 100644 --- a/.changeset/approver-display-name-5414.md +++ b/.changeset/approver-display-name-5414.md @@ -11,7 +11,7 @@ formatter's 14-character truncation arm and middle-truncated to fit its chip. Th step names beside it were human prose; the one line answering *who is holding this record* was an internal identifier, and not even a complete one. The same reference reached the admin-override confirm dialog un-truncated, so a paragraph -of plain governance prose ended `— position:sales_manager` (objectui#5414). +of plain governance prose ended `— position:sales_manager`. Both surfaces now resolve the reference before rendering, in three tiers, most authoritative first. The server's own `pending_approver_names` wins whenever it diff --git a/.changeset/button-container-exception-reason-6804.md b/.changeset/button-container-exception-reason-6804.md index 5dda128717..10e38da96a 100644 --- a/.changeset/button-container-exception-reason-6804.md +++ b/.changeset/button-container-exception-reason-6804.md @@ -17,7 +17,7 @@ it), with the provenance kept in the reason. This matters because an exception with no recorded ground is indistinguishable from a missed one, and that indistinguishability is the mechanism behind this defect class's three -independent rediscoveries (objectui#3900 / objectui#6740 / objectui#6764). +independent rediscoveries (objectui#3900 / `7c9b044f4` / objectui#6764). Also records a measurement the note previously implied away: `button` is the only public tag among the 45 violations listed, but not the only public tag in the containment story — diff --git a/.changeset/dashboard-config-aria-retired-5852.md b/.changeset/dashboard-config-aria-retired-5852.md index 9ce2a42a1a..0a0fa79537 100644 --- a/.changeset/dashboard-config-aria-retired-5852.md +++ b/.changeset/dashboard-config-aria-retired-5852.md @@ -2,7 +2,7 @@ '@object-ui/types': minor --- -**Retired the designer-surface dashboard `aria` pair — `DashboardConfig.aria` and `DashboardConfigSchema.aria`** (objectui#5852). +**Retired the designer-surface dashboard `aria` pair — `DashboardConfig.aria` and `DashboardConfigSchema.aria`**. Both spellings are named verbatim above so a host can grep its own sources: the retired member is `aria`, on the TypeScript interface `DashboardConfig` diff --git a/.changeset/dashboard-table-header-one-spelling-5425.md b/.changeset/dashboard-table-header-one-spelling-5425.md index 8a0de721b2..7903c8f937 100644 --- a/.changeset/dashboard-table-header-one-spelling-5425.md +++ b/.changeset/dashboard-table-header-one-spelling-5425.md @@ -22,7 +22,7 @@ static `data-table`, no columns Close Date Needs Analysis ``` One dashboard can hold all three widgets over one object, so a single field key -rendered under two spellings — the defect class objectui#5425 rules out. The odd +rendered under two spellings — the defect class this change rules out. The odd path adopts the shared convention rather than the convention gaining a fourth dialect. camelCase keys are unaffected (`unitPrice` read `Unit Price` before and after — the coincidence that kept the snake_case divergence unnoticed), and a diff --git a/.changeset/flow-resume-result-5417.md b/.changeset/flow-resume-result-5417.md index 5de2804350..f56375658e 100644 --- a/.changeset/flow-resume-result-5417.md +++ b/.changeset/flow-resume-result-5417.md @@ -3,7 +3,7 @@ '@object-ui/i18n': minor --- -A screen flow's resume result reaches the user — on both outcomes (objectui#5417). +A screen flow's resume result reaches the user — on both outcomes. A dogfood walkthrough reported that a refused `resume` and a successful one "render identically: the dialog closes and the page is unchanged", leaving no diff --git a/.changeset/gate-listlocalinstalls-marketplace-5620.md b/.changeset/gate-listlocalinstalls-marketplace-5620.md index cb6c4165c2..262db83f8b 100644 --- a/.changeset/gate-listlocalinstalls-marketplace-5620.md +++ b/.changeset/gate-listlocalinstalls-marketplace-5620.md @@ -10,11 +10,11 @@ effects already check, in addition to (not instead of) its existing `listLocalInstalls`'s only consumer is `localInstalls.find(...)` in the content branch, which is unreachable whenever the page has already returned `MarketplaceDisabled` (no marketplace on this runtime) or `MarketplaceAccessDenied` (a refused viewer) — both -decided ahead of the content branch since objectui#5533 and objectui#5583. Before this +decided ahead of the content branch since `2573ff434` and objectui#5583. Before this fix, a runtime with `features.installLocal: true` still fired the request — and discarded its answer — on a marketplace-off runtime and for a non-admin, the same -wasted-round-trip class objectui#5533 established the fix for on this page, on the flag -that card was not about. +wasted-round-trip class `2573ff434` established the fix for on this page, on the flag +that change was not about. `features.installLocal` remains its own axis: a runtime can mount a local kernel install path with no marketplace proxy at all, so the fix adds the two predicates as a diff --git a/.changeset/issue-5709-unconsumed-widget-option-warning.md b/.changeset/issue-5709-unconsumed-widget-option-warning.md index c4a5485748..74e9a5d72f 100644 --- a/.changeset/issue-5709-unconsumed-widget-option-warning.md +++ b/.changeset/issue-5709-unconsumed-widget-option-warning.md @@ -4,7 +4,7 @@ `validateTree` now reports a dashboard widget `options` key that no renderer consumes as a `unconsumed-widget-option` **warning** naming the consumed set -(objectui#5709 ruling). The census behind the accepted set — the spec's five +(maintainer ruling 2026-08-23). The census behind the accepted set — the spec's five declared query keys (`dateGranularity`, `sortBy`, `sortOrder`, `limit`, `stageOrder`) plus the `description` sub-caption convention key — is re-measured on every test run against `@objectstack/spec` and the diff --git a/.changeset/marketplace-catalog-runtime-before-admin-5557.md b/.changeset/marketplace-catalog-runtime-before-admin-5557.md index 69a66da580..845815e7fe 100644 --- a/.changeset/marketplace-catalog-runtime-before-admin-5557.md +++ b/.changeset/marketplace-catalog-runtime-before-admin-5557.md @@ -15,7 +15,7 @@ non-admin. The runtime check now answers first, because "this deployment has no marketplace" is true regardless of who is asking. This restores the sibling-page invariant for the one class of viewer it still -failed for: `MarketplacePackagePage` was reordered the same way in objectui#5533, +failed for: `MarketplacePackagePage` was reordered the same way in `2573ff434`, so on a marketplace-off runtime the catalog page and the package detail page now give a non-admin the same kind of answer. diff --git a/.changeset/marketplace-detail-admin-guard-order-5583.md b/.changeset/marketplace-detail-admin-guard-order-5583.md index b50d522485..4b2afaa4af 100644 --- a/.changeset/marketplace-detail-admin-guard-order-5583.md +++ b/.changeset/marketplace-detail-admin-guard-order-5583.md @@ -17,7 +17,7 @@ to whether an unrelated request happened to succeed. The guard now sits ahead of both branches, and `getMarketplacePackage` and `getCloudInstallationInfo` are gated on `isAdmin` as well, so the page stops issuing requests on behalf of a viewer it has already decided to turn away. That is the -discipline objectui#5533 established on this same page for `features.marketplace`, +discipline `2573ff434` established on this same page for `features.marketplace`, applied to the other predicate that decides the same thing. It is also the ordering `MarketplacePage` carries after objectui#5557, so the two sibling pages now answer one runtime the same way for every viewer. The server remains the authority on what a diff --git a/.changeset/marketplace-detail-disabled-state-5533.md b/.changeset/marketplace-detail-disabled-state-5533.md index 672d7f993a..c8884f232e 100644 --- a/.changeset/marketplace-detail-disabled-state-5533.md +++ b/.changeset/marketplace-detail-disabled-state-5533.md @@ -3,7 +3,7 @@ --- The marketplace **package detail** page now states that the marketplace is turned -off, instead of red-erroring, on a runtime that has none (objectui#5533). +off, instead of red-erroring, on a runtime that has none. `MarketplacePackagePage` takes the same `isMarketplaceEnabled()` early return its sibling catalog page took in objectui#5504, rendering the informational diff --git a/.changeset/page-source-tailwind-framing-5461.md b/.changeset/page-source-tailwind-framing-5461.md index 4762675119..1ed41bcef3 100644 --- a/.changeset/page-source-tailwind-framing-5461.md +++ b/.changeset/page-source-tailwind-framing-5461.md @@ -7,7 +7,7 @@ This is a published type surface: the TSDoc ships in `@object-ui/types`'s built `.d.ts` and is what an author reads on hover over `kind`. It said a `kind:'html'` page is "constrained JSX/HTML + Tailwind" — and it links -`content/docs/guide/react-pages.md`, which objectui#5413 has already corrected to +`content/docs/guide/react-pages.md`, which `688cb93ad` has already corrected to say the opposite. Shipped type documentation was contradicting the guide it points readers to. diff --git a/.changeset/row-predicate-phase2-record-only-5741.md b/.changeset/row-predicate-phase2-record-only-5741.md index 2ce7fefa07..c06d8816fd 100644 --- a/.changeset/row-predicate-phase2-record-only-5741.md +++ b/.changeset/row-predicate-phase2-record-only-5741.md @@ -6,7 +6,7 @@ row predicates on runtime record surfaces resolve `record.*` only; the bare-field and `data.*` spellings are no longer bound Phase 2 of the row-predicate canon (objectui#5330, ruled 2026-08-20, option B; -Phase 2 ruled 2026-09-02 and amended 2026-09-05 on objectui#5741). Until now a +Phase 2 ruled 2026-09-02 and amended 2026-09-05). Until now a row predicate — `visible` / `disabled` / `enabled` on an action renderer, a row action, a `record:alert`, a `page:header` action, a conditional-formatting `condition` — bound the row three ways: canonical `record.status`, bare diff --git a/.changeset/sparse-predicate-warning-cause-5399.md b/.changeset/sparse-predicate-warning-cause-5399.md index adebbd2ba1..5581b73656 100644 --- a/.changeset/sparse-predicate-warning-cause-5399.md +++ b/.changeset/sparse-predicate-warning-cause-5399.md @@ -3,7 +3,7 @@ --- The `[page:header]` sparse-predicate warning no longer blames `hidden: true` — it -states what it actually measured (objectui#5399). +states what it actually measured. When an action's `visible` predicate references a `record.` the bound payload does not carry, the warner names the missing key and then explained the cause: diff --git a/.changeset/studio-metadata-form-ux-5416.md b/.changeset/studio-metadata-form-ux-5416.md index 551450b9e7..3ecbeaadd9 100644 --- a/.changeset/studio-metadata-form-ux-5416.md +++ b/.changeset/studio-metadata-form-ux-5416.md @@ -4,7 +4,7 @@ Studio's metadata authoring path stops greeting the author with errors they did not cause, English help text in a Chinese console, and a toast on top of the publish button. -Three defects measured on a 17.1.0 dogfood walkthrough (objectui#5416), all on +Three defects measured on a 17.1.0 dogfood walkthrough, all on the first surfaces a new author sees. **Validation no longer runs on mount.** `新建软件包` opened with both required diff --git a/.changeset/surface-deeplink-live-channel-5476.md b/.changeset/surface-deeplink-live-channel-5476.md index 9515eb71b3..fa20ed87db 100644 --- a/.changeset/surface-deeplink-live-channel-5476.md +++ b/.changeset/surface-deeplink-live-channel-5476.md @@ -30,7 +30,7 @@ still ignores every URL change after mount, and a live request never moves it. The sheet's other home is the Home / draft-preview bar, where the Studio object editor is not a reachable destination at all. Reachability is answered structurally — the producer hook returns `null` when no host published the channel — so off-Studio the -item name stays the prose #5418 shipped rather than becoming a link to nowhere. Both +item name stays the prose `7a90afdf9` shipped rather than becoming a link to nowhere. Both directions are assertions in `DraftChangesPanel.securityLink.test`, not a comment. Nothing the other three pillars observe changed: `useSurfaceDeepLink` keeps its diff --git a/content/docs/components/basic/text.mdx b/content/docs/components/basic/text.mdx index 186de9149f..c1842368ce 100644 --- a/content/docs/components/basic/text.mdx +++ b/content/docs/components/basic/text.mdx @@ -45,7 +45,7 @@ interface TextSchema { > fallback of `content || value` — and it is no longer part of `TextSchema` on > either face. A `text` node that authors `value` now fails validation with: > -> > RETIRED (objectui#6951) — `value` is no longer part of TextSchema; write +> > RETIRED (ADR-0049) — `value` is no longer part of TextSchema; write > > `content`. … > > Rename the key to `content`; the string is unchanged. Measured before the diff --git a/content/docs/components/data-display/tree-view.mdx b/content/docs/components/data-display/tree-view.mdx index 4486dafd8e..db8c438ff6 100644 --- a/content/docs/components/data-display/tree-view.mdx +++ b/content/docs/components/data-display/tree-view.mdx @@ -62,7 +62,7 @@ interface TreeViewSchema { > `TreeViewSchema` on either face. A `tree-view` node that authors `data` now > fails validation with: > -> > RETIRED (objectui#6951) — `data` is no longer part of TreeViewSchema; write +> > RETIRED (ADR-0049) — `data` is no longer part of TreeViewSchema; write > > `nodes` (or bind the tree with `bind`). … > > Rename the key to `nodes`; the array is unchanged. `bind` is unchanged and is diff --git a/packages/app-shell/src/console/AppContent.tsx b/packages/app-shell/src/console/AppContent.tsx index bf64c1dee3..7c41a615fa 100644 --- a/packages/app-shell/src/console/AppContent.tsx +++ b/packages/app-shell/src/console/AppContent.tsx @@ -700,7 +700,7 @@ export function AppContent({ extraRoutes, extraRoutesNoApp }: AppContentProps = // predicate on the SAME modal's per-field rules (form.tsx, over the // provider's `data={{}}`) faulted, and the same predicate in CREATE mode // (`editingRecord` null) faulted too. One authored string, three answers, - // none of them the row's canonical `record.*` binding (objectui#5741). + // none of them the row's canonical `record.*` binding (`83fe6e741`). // The row reaches field predicates as `record`, from the form's own // `ruleRecord` — not from this bag, which is why nothing is lost here. () => createExpressionEvaluator({ diff --git a/packages/app-shell/src/console/marketplace/MarketplacePackagePage.tsx b/packages/app-shell/src/console/marketplace/MarketplacePackagePage.tsx index 6eec8a80f4..48b50343ee 100644 --- a/packages/app-shell/src/console/marketplace/MarketplacePackagePage.tsx +++ b/packages/app-shell/src/console/marketplace/MarketplacePackagePage.tsx @@ -168,8 +168,8 @@ export function MarketplacePackagePage() { // Its only consumer is `localInstalls.find(...)` in the content branch // below, which is unreachable whenever the page has already returned // `MarketplaceDisabled` or (post-objectui#5583) `MarketplaceAccessDenied`. - // Firing anyway would be the same discarded-request class objectui#5533 - // closed for this page, on the flag that card was not about + // Firing anyway would be the same discarded-request class `2573ff434` + // closed for this page, on the flag that change was not about // (objectui#5620). if (!marketplaceEnabled) return; if (!isAdmin) return; @@ -218,7 +218,7 @@ export function MarketplacePackagePage() { // No marketplace on this runtime -> no request. Fetching anyway and // discarding the result would still put a 404/403 on the server and can // race the destructive card onto the screen before the disabled state - // settles (objectui#5533). + // settles (`2573ff434`). if (!marketplaceEnabled) return; // Nor on behalf of a viewer this page refuses (objectui#5583). // Authorization is not a function of whether the fetch succeeded, so it @@ -556,7 +556,7 @@ export function MarketplacePackagePage() { // A CONFIGURATION CONCLUSION, not a load failure -- the same informational // state the catalog page renders, so the two pages stop disagreeing about the - // same runtime (objectui#5533). Reached by a pasted or bookmarked package URL, + // same runtime (`2573ff434`). Reached by a pasted or bookmarked package URL, // the only way in once the catalog and both Home entries are gated. // // Ahead of the `!isAdmin` branch below deliberately: on a runtime that mounts @@ -574,7 +574,7 @@ export function MarketplacePackagePage() { // allowed to use -- and reached the refusal only on the paths where the load // happened to work. Both fetch effects above are gated on the same predicate, // so the refusal also stops the page requesting on behalf of a viewer it has - // already decided to turn away: the discipline objectui#5533 established on + // already decided to turn away: the discipline `2573ff434` established on // this page for `features.marketplace`, applied to the other predicate that // decides the same thing. // @@ -587,7 +587,7 @@ export function MarketplacePackagePage() { // read. The verdict has a third state ("not resolved yet") and this guard is // the reason it exists. Ordered AFTER `!marketplaceEnabled` deliberately — // that answer is true of every viewer on this runtime and needs no verdict, - // so the ordering objectui#5557/#5533 established is untouched — and BEFORE + // so the ordering objectui#5557 and `2573ff434` established is untouched — and BEFORE // `!isAdmin`, which is the branch that must not fire on a guess. // // This is NOT the incidental skeleton objectui#5621 removed: that one hid the diff --git a/packages/app-shell/src/console/marketplace/MarketplacePage.tsx b/packages/app-shell/src/console/marketplace/MarketplacePage.tsx index d01379567c..c1256f1327 100644 --- a/packages/app-shell/src/console/marketplace/MarketplacePage.tsx +++ b/packages/app-shell/src/console/marketplace/MarketplacePage.tsx @@ -211,7 +211,7 @@ export function MarketplacePage() { // misdirected. Telling an unprivileged member they lack PERMISSION for a // surface that exists for nobody sends them to ask an administrator for a // grant that would not help them. This is the ordering - // `MarketplacePackagePage` landed under objectui#5533; the sibling pages now + // `MarketplacePackagePage` landed in `2573ff434`; the sibling pages now // answer one runtime the same way. if (!marketplaceEnabled) return ; @@ -223,7 +223,7 @@ export function MarketplacePage() { // read. The verdict has a third state ("not resolved yet") and this guard is // the reason it exists. Ordered AFTER `!marketplaceEnabled` deliberately — // that answer is true of every viewer on this runtime and needs no verdict, - // so the ordering objectui#5557/#5533 established is untouched — and BEFORE + // so the ordering objectui#5557 and `2573ff434` established is untouched — and BEFORE // `!isAdmin`, which is the branch that must not fire on a guess. // // This is NOT the incidental skeleton objectui#5621 removed: that one hid the diff --git a/packages/app-shell/src/hooks/useApproverDirectory.ts b/packages/app-shell/src/hooks/useApproverDirectory.ts index 197e135113..dec02df79d 100644 --- a/packages/app-shell/src/hooks/useApproverDirectory.ts +++ b/packages/app-shell/src/hooks/useApproverDirectory.ts @@ -9,7 +9,7 @@ /** * useApproverDirectory — resolve `:` approver references against * the system directory objects, for the surfaces that must NAME an approver - * (objectui#5414). + * (`77f846a8b`). * * ## Server-first, and inert by default * @@ -27,7 +27,7 @@ * values — the label leg; * - for `position` refs only, `sys_user_position` -> `sys_user` — the staffing * leg, which answers "who actually sits in this seat" and, when it comes - * back empty, the unstaffed state objectui#5414 asks to surface. + * back empty, the unstaffed state `77f846a8b` surfaces. * * The two legs fail INDEPENDENTLY. A business-app reader may hold list access to * `sys_position` and none to `sys_user_position`; `find` rejects that with diff --git a/packages/app-shell/src/hooks/useInboxBell.ts b/packages/app-shell/src/hooks/useInboxBell.ts index 1533ae2c73..0872d022e0 100644 --- a/packages/app-shell/src/hooks/useInboxBell.ts +++ b/packages/app-shell/src/hooks/useInboxBell.ts @@ -12,7 +12,7 @@ * The rows, the badge number and the three mark-read paths used to live inline * in `AppHeader`, which was fine while the header held the only bell. It no * longer does: `global:notifications` is a spec `PageComponentType` member an - * author may declare on a page (objectui#6757), and its renderer has to reach + * author may declare on a page (`f99932a42`), and its renderer has to reach * the SAME inbox — the one ADR-0012/ADR-0030 defines and `sharedUserFeeds` * already serves to the header and to Home's action centre. * diff --git a/packages/app-shell/src/hooks/useRecordApprovals.ts b/packages/app-shell/src/hooks/useRecordApprovals.ts index 725ba6bcbc..9acb280581 100644 --- a/packages/app-shell/src/hooks/useRecordApprovals.ts +++ b/packages/app-shell/src/hooks/useRecordApprovals.ts @@ -203,7 +203,7 @@ export function recordLockedByApproval(request: ApprovalRequestLite | null | und * Did the current viewer submit this approval request? * * The submitter's levers — Remind on the approvals panel, Recall on the record - * band (objectui#6464) — are the ones the server authorizes on submitter + * band (`830ed5803`) — are the ones the server authorizes on submitter * identity and refuses to anyone else. This is the ONE place that answer is * derived, so the two surfaces cannot drift into disagreeing about who the * submitter is (the identical hazard `utils/approverIdentity` exists for on the diff --git a/packages/app-shell/src/index.ts b/packages/app-shell/src/index.ts index 38934b9be5..95c8fe0578 100644 --- a/packages/app-shell/src/index.ts +++ b/packages/app-shell/src/index.ts @@ -323,7 +323,7 @@ import './views/record-attachments-renderer.js'; import './views/record-approvals-renderer.js'; // `global:search` / `global:notifications` — the two spec `PageComponentType` // members the 2026-08-26 ruling on objectstack#12183 kept declared because both -// data sources shipped (objectui#6757). Registered here, not in +// data sources shipped (`f99932a42`). Registered here, not in // `@object-ui/components`, because they read this package's providers and feeds; // without these two imports an authored page draws the "Component Placeholder" // scaffold for `global:search` and a red unknown-type panel for @@ -331,7 +331,7 @@ import './views/record-approvals-renderer.js'; import './views/global-search-renderer.js'; import './views/global-notifications-renderer.js'; // `app:launcher` / `nav:menu` — Phase 1 of that same 2026-08-26 ruling -// (objectui#6661): the two `PageComponentType` members that are purely +// (`969ba84f4`): the two `PageComponentType` members that are purely // metadata-driven, so nothing had to ship before their renderers could. // Registered here, not in `@object-ui/components`, because they read this // package's providers (the metadata app registry, the expression / permission / diff --git a/packages/app-shell/src/layout/AppHeader.tsx b/packages/app-shell/src/layout/AppHeader.tsx index 76eccb3d28..75bf715e21 100644 --- a/packages/app-shell/src/layout/AppHeader.tsx +++ b/packages/app-shell/src/layout/AppHeader.tsx @@ -218,7 +218,7 @@ export function AppHeader({ * The bell's inbox — rows, badge addends and the three mark-read paths — now * comes from `useInboxBell`, the ONE wiring of `sharedUserFeeds` onto an * `InboxPopover` (#4225 / #4316). The `global:notifications` page block - * (objectui#6757) mounts the SAME hook, so a bell in the header and a bell an + * (`f99932a42`) mounts the SAME hook, so a bell in the header and a bell an * author declared on a page cannot disagree about a row's read-state: there * is no second read and no second optimistic overlay left to drift. * diff --git a/packages/app-shell/src/layout/UnifiedSidebar.tsx b/packages/app-shell/src/layout/UnifiedSidebar.tsx index 0ef580a5b1..08eafebbd2 100644 --- a/packages/app-shell/src/layout/UnifiedSidebar.tsx +++ b/packages/app-shell/src/layout/UnifiedSidebar.tsx @@ -678,7 +678,7 @@ export function UnifiedSidebar({ activeAppName }: UnifiedSidebarProps) { order. A pinned section would also land directly above this arm's own "Starred" group. Separate product decisions, not part of unflattening a group. - (Until objectui#5197 this list also named `resolveGroupLabel` / + (Until `9c60144b5` this list also named `resolveGroupLabel` / `resolveItemLabel`. Those props are gone from the renderer entirely — they were unreachable for every real nav entry, and app-nav localization belongs to the server `/meta` boundary.) */} diff --git a/packages/app-shell/src/preview/DraftChangesPanel.tsx b/packages/app-shell/src/preview/DraftChangesPanel.tsx index 0526051f6f..d2e594bedd 100644 --- a/packages/app-shell/src/preview/DraftChangesPanel.tsx +++ b/packages/app-shell/src/preview/DraftChangesPanel.tsx @@ -359,7 +359,7 @@ export function DraftChangesPanel({ const [error, setError] = useState(null); /** * Author-time security findings that the publish door would REFUSE - * (objectui#5418). Surfaced here, next to the button, so the refusal is + * (`7a90afdf9`). Surfaced here, next to the button, so the refusal is * something the author reads before committing rather than a toast that * arrives after the batch has already rolled back. */ @@ -435,7 +435,7 @@ export function DraftChangesPanel({ }, [open, load]); /** - * Clear the toast stack when this panel opens (objectui#5416). + * Clear the toast stack when this panel opens (`add10d8f9`). * * The console mounts its toaster bottom-right (`apps/console/src/App.tsx`) * and this sheet is `side="right"` with a `mt-auto` footer, so the stack diff --git a/packages/app-shell/src/preview/securityPostureLint.ts b/packages/app-shell/src/preview/securityPostureLint.ts index d9461d5399..17693a5af3 100644 --- a/packages/app-shell/src/preview/securityPostureLint.ts +++ b/packages/app-shell/src/preview/securityPostureLint.ts @@ -8,7 +8,7 @@ /** * Pre-publish security-posture lint (ADR-0090 D7) — the "fail early, not at - * publish" half of objectui#5418. + * publish" half of `7a90afdf9`. * * The publish door refuses an object whose record-sharing baseline was never * authored (`security-owd-unset`), and it is RIGHT to: the OWD must be a diff --git a/packages/app-shell/src/providers/ExpressionProvider.tsx b/packages/app-shell/src/providers/ExpressionProvider.tsx index 1ff5203ac9..c347bcffaf 100644 --- a/packages/app-shell/src/providers/ExpressionProvider.tsx +++ b/packages/app-shell/src/providers/ExpressionProvider.tsx @@ -118,7 +118,7 @@ export interface ExpressionScopeInput { * `app` and `data` came off the same list producing OPPOSITE failures, and the * `data` half is the nastier one. * - * objectui#5741 (Phase 2 of the objectui#5330 canon) retired `data.*` on + * `83fe6e741` (Phase 2 of the objectui#5330 canon) retired `data.*` on * runtime record surfaces: the row is bound as `record.*` and nothing else, and * `@object-ui/core`'s `evaluator/rowPredicateCanon.ts` records the server's * verdict for the retired spelling — `data.status` is `❌ Unknown variable: diff --git a/packages/app-shell/src/utils/approverIdentity.ts b/packages/app-shell/src/utils/approverIdentity.ts index 1dbf27e07f..dff62f0e2b 100644 --- a/packages/app-shell/src/utils/approverIdentity.ts +++ b/packages/app-shell/src/utils/approverIdentity.ts @@ -8,7 +8,7 @@ /** * approverIdentity — the ONE place the console turns an approver REFERENCE - * into something a person can read (objectui#5414). + * into something a person can read (`77f846a8b`). * * ## The defect this closes * @@ -173,11 +173,11 @@ export function prettifyMachineName(raw: string | null | undefined): string { * binding commits a machine NAME prettified, and opaque 16+ char ids * middle-truncated. * - * Moved here from `RecordApprovalsPanel` in objectui#5414 so the panel, the + * Moved here from `RecordApprovalsPanel` in `77f846a8b` so the panel, the * timeline and the admin-override dialog cannot format one identifier three * ways. The truncation arm is deliberately kept for the id-valued kinds: a raw * UUID wall is what objectui#3461 complained about, and a UUID has no prose to - * recover. What #5414 adds is the arm above it — `position:sales_manager` + * recover. What `77f846a8b` adds is the arm above it — `position:sales_manager` * carries a machine name, so it never had to be truncated in the first place. */ export function formatIdentity(id: string | null | undefined): string { @@ -270,7 +270,7 @@ export const MAX_INLINE_HOLDERS = 3; * `sales_manager` prettifies into real prose. The id-valued kinds * (`user`/`team`/`department`) carry opaque row ids that prettify into * nonsense — those keep the caller's existing formatting, which is the right - * treatment for an id and is not what objectui#5414 reports. + * treatment for an id and is not what `77f846a8b` fixes. */ export function approverDisplay( raw: string, diff --git a/packages/app-shell/src/utils/consoleServerAction.ts b/packages/app-shell/src/utils/consoleServerAction.ts index bffa6d396a..6fa5d8be41 100644 --- a/packages/app-shell/src/utils/consoleServerAction.ts +++ b/packages/app-shell/src/utils/consoleServerAction.ts @@ -21,7 +21,7 @@ * - the **`redirectUrl` convention**: a handler returning `{ redirectUrl }` * asks the UI to open it — into the pre-opened tab when there is one, else a * lazily opened one with a popup-blocked toast fallback. A handler may add - * `openIn: 'self'` to ask for the same-tab jump instead (objectui#5221); + * `openIn: 'self'` to ask for the same-tab jump instead (`053fdc8f9`); * WITHOUT it the shipped new-tab behavior stands, so nothing flips silently. * - **deferring to a declared `ActionSchema.onSuccess` block**: when the action * itself declares the post-success hop, the runner performs it and this @@ -235,7 +235,7 @@ export function createConsoleServerActionHandler(opts: ConsoleServerActionOption // all this branch owes is the pre-opened tab. // // ⚠️ The spec rules each surface's own default but does NOT rule this - // precedence — objectui#5221 escalates it. If the maintainer rules the + // precedence — the card behind `053fdc8f9` escalates it. If the maintainer rules the // other way, this is the line that changes. if (readOnSuccessNavigation(action.onSuccess)) { closeTab(preOpenedTab); diff --git a/packages/app-shell/src/utils/flowResponse.ts b/packages/app-shell/src/utils/flowResponse.ts index 499c41a908..ee760414e3 100644 --- a/packages/app-shell/src/utils/flowResponse.ts +++ b/packages/app-shell/src/utils/flowResponse.ts @@ -43,7 +43,7 @@ * where React expects a child and crashes the page (React #31) — the same trap * `actionErrorDetail` exists for. * - * ## A failed run does NOT always arrive as HTTP 200 (objectui#4784) + * ## A failed run does NOT always arrive as HTTP 200 (`833c90047`) * * The three shapes above describe the route as it answers today. objectstack#8684 * unifies the resume route onto real status codes — inheriting the #3962 ruling @@ -186,7 +186,7 @@ export type FlowResponseOutcome = * runner must not offer one. * * What a runner DOES with that is the runner's own decision, and it is - * not "close" (objectui#5417): `FlowRunner` keeps the dialog up so the + * not "close" (`c40f3b8ca`): `FlowRunner` keeps the dialog up so the * refusal stays beside the input that caused it, and withdraws the * submit affordance instead. This flag says the run is gone, nothing * more. diff --git a/packages/app-shell/src/utils/resolveActionParams.ts b/packages/app-shell/src/utils/resolveActionParams.ts index 00ceb543c3..10da98437c 100644 --- a/packages/app-shell/src/utils/resolveActionParams.ts +++ b/packages/app-shell/src/utils/resolveActionParams.ts @@ -72,7 +72,7 @@ export type RawActionParamOption = { value: string; /** * Everything else an option declares (`visibleWhen` / `color` / `icon` / - * `disabled`), preserved verbatim — objectui#3559. + * `disabled`), preserved verbatim — `fbc23e094`. */ [key: string]: unknown; }; @@ -106,7 +106,7 @@ export interface RawActionParam { * Option list authored inline on the param. Speaks the same vocabulary as the * resolved side ({@link ActionParamOption}): the two keys this resolver reads * plus a catch-all for whatever else an option declares (`visibleWhen`, - * `color`, `icon`, `disabled`) — objectui#3559. + * `color`, `icon`, `disabled`) — `fbc23e094`. * * One key differs, and it is the same rc.6 widening as {@link * RawActionParam.label} one level down: an option's `label` is authored as @@ -177,7 +177,7 @@ function paramName(param: RawActionParam): string | undefined { * rc.6's inline per-locale map — to the single string the dialog renders. * * Everything else is preserved by spread, for the same reason - * {@link normaliseOptions} preserves it (objectui#3559): rebuilding a fresh + * {@link normaliseOptions} preserves it (`fbc23e094`): rebuilding a fresh * `{ label, value }` silently drops `visibleWhen` / `color` / `icon` / * `disabled`. A label that resolves to nothing falls back to `value`, which is * what a bare-string option already means (`{ label: s, value: s }`). @@ -188,7 +188,7 @@ function resolveOptionLabels( ): ActionParamOption[] | undefined { if (!options) return undefined; // Identity-preserving fast path, and it is load-bearing rather than an - // optimisation: objectui#3559 pins that an INLINE option list reaches the + // optimisation: `fbc23e094` pins that an INLINE option list reaches the // dialog *verbatim* — `toBe`, not `toEqual` — because the bug it closed was a // rebuild that dropped `visibleWhen`. A list with nothing to resolve is // therefore returned untouched, so that pin stays true as written; only a @@ -403,7 +403,7 @@ export interface ResolveActionParamsContext { * `{ label, value }` and translate each label through `fieldOptionLabel`. * * Those are the only two jobs. Everything else the option declares is - * PRESERVED, not rebuilt (objectui#3559): this used to return a fresh + * PRESERVED, not rebuilt (`fbc23e094`): this used to return a fresh * `{ label, value }` per entry, which silently dropped a field's per-option * `visibleWhen` — so a select field whose options narrow by predicate in the * object form (`resolveVisibleOptions()` in `@object-ui/core`, ADR-0058 / diff --git a/packages/app-shell/src/views/DeclaredActionsBar.tsx b/packages/app-shell/src/views/DeclaredActionsBar.tsx index c4219c5973..9d2aedc7b7 100644 --- a/packages/app-shell/src/views/DeclaredActionsBar.tsx +++ b/packages/app-shell/src/views/DeclaredActionsBar.tsx @@ -199,7 +199,7 @@ const DeclaredActionButton: React.FC<{ * (the unstaffed-position rescue the override path exists for) gets its own * wording rather than an empty list. * - * objectui#5414 — and those names must be NAMES. `bypassedApproverNames` + * `77f846a8b` — and those names must be NAMES. `bypassedApproverNames` * defaults its formatter to identity, so an engine reference reached this * dialog raw: a paragraph of plain governance prose ending * `—— position:sales_manager`. Resolution is gated on `isOverride`, so an diff --git a/packages/app-shell/src/views/FlowRunner.tsx b/packages/app-shell/src/views/FlowRunner.tsx index 9c48baa8a4..83752d5270 100644 --- a/packages/app-shell/src/views/FlowRunner.tsx +++ b/packages/app-shell/src/views/FlowRunner.tsx @@ -14,7 +14,7 @@ * {@link ScreenView} — the same renderer the Studio design preview reuses, so * the two can never drift (cf. #1927). * - * ## The resume RESULT has to reach the user (objectui#5417) + * ## The resume RESULT has to reach the user (`c40f3b8ca`) * * A dogfood walkthrough reported that a `400 FLOW_FAILED` and a successful run * "render identically: the dialog closes and the page is unchanged". Half of @@ -349,7 +349,7 @@ export function FlowRunner({ state, authFetch, baseUrl, onClose, onComplete, dat // #31). See utils/flowResponse. const outcome = interpretFlowResponse(res, json, 'Resume'); if (outcome.kind === 'failed') { - // Two carriers on purpose (#5417): the toast is fixed to the viewport and + // Two carriers on purpose (`c40f3b8ca`): the toast is fixed to the viewport and // reaches a user scrolled to the bottom of a tall object-form step; the // inline Alert stays with the values that caused it. toast.error(outcome.error); diff --git a/packages/app-shell/src/views/RecordApprovalsPanel.tsx b/packages/app-shell/src/views/RecordApprovalsPanel.tsx index 403eb4519d..41543e6969 100644 --- a/packages/app-shell/src/views/RecordApprovalsPanel.tsx +++ b/packages/app-shell/src/views/RecordApprovalsPanel.tsx @@ -113,7 +113,7 @@ const ACTION_DOT: Record = { }; /** - * Identity formatting moved to `utils/approverIdentity` in objectui#5414 — the + * Identity formatting moved to `utils/approverIdentity` in `77f846a8b` — the * panel, the merged timeline and the admin-override dialog must not each own a * copy. Re-exported here because this module is where it was published. */ @@ -223,7 +223,7 @@ export const RecordApprovalsPanel: React.FC = ({ const [reminding, setReminding] = React.useState(false); /** - * Resolve the pending approvers the SERVER could not name (objectui#5414). + * Resolve the pending approvers the SERVER could not name (`77f846a8b`). * * `positi…ager` was `formatIdentity('position:sales_manager')` — the raw * engine reference, middle-truncated to fit its chip. The gate below keeps @@ -277,7 +277,7 @@ export const RecordApprovalsPanel: React.FC = ({ * server-resolved `viewer.is_submitter` from the enriched pending row and * fall back to a plain id match for backends predating framework#3310. * - * The derivation moved to `isSubmitterOf` unchanged (objectui#6464) so the + * The derivation moved to `isSubmitterOf` unchanged (`830ed5803`) so the * record band's Recall gate reads the SAME answer — two copies of it would be * two definitions of who submitted. `?? false` restates this call site's own * reading of "no pending request": there is nothing to remind about, so the @@ -517,7 +517,7 @@ export const RecordApprovalsPanel: React.FC = ({ variant="outline" className="text-[11px]" /* The raw `position:…` reference belongs on hover, not as the - primary identification — objectui#5414. */ + primary identification — `77f846a8b`. */ title={chip.title} data-testid="approver-chip" data-unstaffed={chip.unstaffed ? 'true' : undefined} diff --git a/packages/app-shell/src/views/RecordDetailView.tsx b/packages/app-shell/src/views/RecordDetailView.tsx index b935b33415..21c40f54ae 100644 --- a/packages/app-shell/src/views/RecordDetailView.tsx +++ b/packages/app-shell/src/views/RecordDetailView.tsx @@ -1135,7 +1135,7 @@ export function RecordDetailView({ dataSource, objects, onEdit, objectNameOverri // whether their click closes the step. Server-computed; `first_response` // nodes carry none and the band then shows nothing extra. const approvalProgress = approvals.pendingRequest?.decision_progress; - // Who may RECALL the pending approval (objectui#6464). Recall is the + // Who may RECALL the pending approval (`830ed5803`). Recall is the // submitter's lever and the server refuses everyone else, so a non-submitter // reading a pending record was being offered a button whose click could only // fail. Same source order the approvals panel's Remind gate uses — one @@ -1145,7 +1145,7 @@ export function RecordDetailView({ dataSource, objects, onEdit, objectNameOverri // `undefined` when there is no pending request to consult: the band is then // running off the record's `approval_status` mirror alone (a backend with no // approvals API), the host has resolved no identity, and the DetailView keeps - // its pre-#6464 behaviour rather than hiding on absent information. + // its pre-`830ed5803` behaviour rather than hiding on absent information. // // This gates the AFFORDANCE only. `canEdit` / `approvalLocked` below are // untouched by it, and the recall endpoint authorizes the recall itself. diff --git a/packages/app-shell/src/views/app-launcher-renderer.tsx b/packages/app-shell/src/views/app-launcher-renderer.tsx index a7057d95c9..e23fba7e0a 100644 --- a/packages/app-shell/src/views/app-launcher-renderer.tsx +++ b/packages/app-shell/src/views/app-launcher-renderer.tsx @@ -8,7 +8,7 @@ /** * `app:launcher` — the app launcher grid, addressable from a page schema - * (objectui#6661). + * (`969ba84f4`). * * ## Why this exists * @@ -66,7 +66,7 @@ * address, describe or disable. * * Registered in app-shell rather than `@object-ui/components` for the same - * reason `global:search` is (objectui#6757): the providers are here. + * reason `global:search` is (`f99932a42`): the providers are here. * `@object-ui/components` depends on neither `@object-ui/layout` nor * `react-router-dom` (measured against its `package.json` on `592acafbe`), and * this block needs the router to open an app. The eager palette placeholder in @@ -78,7 +78,7 @@ * This does NOT put the block in the Studio page palette: `PALETTE_EXCLUSIONS` * still records `app:launcher` as a shell singleton, and that is a palette * decision about authoring ergonomics, independent of whether a declared type - * renders — exactly as objectui#6757 left `global:notifications`. + * renders — exactly as `f99932a42` left `global:notifications`. */ import * as React from 'react'; diff --git a/packages/app-shell/src/views/global-notifications-renderer.tsx b/packages/app-shell/src/views/global-notifications-renderer.tsx index e960379b2c..9ef5add641 100644 --- a/packages/app-shell/src/views/global-notifications-renderer.tsx +++ b/packages/app-shell/src/views/global-notifications-renderer.tsx @@ -8,7 +8,7 @@ /** * `global:notifications` — the notification bell, addressable from a page - * schema (objectui#6757). + * schema (`f99932a42`). * * ## Why this exists * diff --git a/packages/app-shell/src/views/global-search-renderer.tsx b/packages/app-shell/src/views/global-search-renderer.tsx index 61812022a7..4f8fd52f48 100644 --- a/packages/app-shell/src/views/global-search-renderer.tsx +++ b/packages/app-shell/src/views/global-search-renderer.tsx @@ -8,7 +8,7 @@ /** * `global:search` — the cross-object search box, addressable from a page - * schema (objectui#6757). + * schema (`f99932a42`). * * ## Why this exists * diff --git a/packages/app-shell/src/views/metadata-admin/ConditionalFormattingEditor.tsx b/packages/app-shell/src/views/metadata-admin/ConditionalFormattingEditor.tsx index 3df1a1c49c..fd93e1fc87 100644 --- a/packages/app-shell/src/views/metadata-admin/ConditionalFormattingEditor.tsx +++ b/packages/app-shell/src/views/metadata-admin/ConditionalFormattingEditor.tsx @@ -42,7 +42,7 @@ import type { CelLintIssue } from './celAuthoring.js'; * ## What changed, and why this list lost a member (objectui#7727) * * It used to bind the row THREE ways: bare fields, `record.*` and `data.*`. - * Phase 2 of the objectui#5330 canon (objectui#5741, ruled 2026-09-02, amended + * Phase 2 of the objectui#5330 canon (`83fe6e741`, ruled 2026-09-02, amended * 2026-09-05) RETIRED the other two — see `@object-ui/core`'s * `evaluator/rowPredicateCanon.ts`. Neither `status` nor `data.status` names * this row any more; both fault as unknown variables, exactly as they always @@ -378,7 +378,7 @@ export function ConditionalFormattingEditor({ objectName={objectName} fieldNames={fieldNames} // Row predicates bind the row as `record.*` and nothing else at - // runtime — objectui#5741 (Phase 2 of the objectui#5330 canon) + // runtime — `83fe6e741` (Phase 2 of the objectui#5330 canon) // retired the bare shorthand and `data.*`. So this lints in the // RECORD scope, the same one the field conditional rules // `visibleWhen` / `readonlyWhen` / `requiredWhen` use: a bare diff --git a/packages/app-shell/src/views/metadata-admin/SchemaForm.tsx b/packages/app-shell/src/views/metadata-admin/SchemaForm.tsx index a1c784a0ae..8eb231acbe 100644 --- a/packages/app-shell/src/views/metadata-admin/SchemaForm.tsx +++ b/packages/app-shell/src/views/metadata-admin/SchemaForm.tsx @@ -1172,7 +1172,7 @@ const SchemaFormNestingContext = React.createContext(false); /** * Defer validation DISPLAY until the author has touched the field - * (objectui#5416). + * (`add10d8f9`). * * A CREATE form opens on an empty draft, so every required field already * fails `safeParse` before a single keystroke: `新建软件包` used to open with @@ -1247,7 +1247,7 @@ export function SchemaForm(props: SchemaFormProps) { const nested = React.useContext(SchemaFormNestingContext); const inheritedDefer = React.useContext(DeferIssueDisplayContext); useDuplicateFieldHostIdCheck(!nested); - // objectui#5416 — a create form defers issue DISPLAY to first touch; a + // `add10d8f9` — a create form defers issue DISPLAY to first touch; a // nested form inherits whatever the form hosting it decided. const deferIssues = props.createMode === true || inheritedDefer; return ( @@ -1543,7 +1543,7 @@ function FieldRow({ onChange: (v: unknown) => void; }) { const locale = useMetadataLocale(); - // objectui#5416 — validation-display timing. `touched` flips on the first + // `add10d8f9` — validation-display timing. `touched` flips on the first // focusout anywhere in this row (React's onBlur IS focusout, so it bubbles // out of every widget, including the composite ones that never emit a DOM // change event) and on this field's own first edit. While a create form is diff --git a/packages/app-shell/src/views/metadata-admin/celAuthoring.ts b/packages/app-shell/src/views/metadata-admin/celAuthoring.ts index b1d0b79f50..e74a56b520 100644 --- a/packages/app-shell/src/views/metadata-admin/celAuthoring.ts +++ b/packages/app-shell/src/views/metadata-admin/celAuthoring.ts @@ -324,13 +324,13 @@ function loadRowCanon(): Promise { * * `@objectstack/formula`'s `SCOPE_ROOTS` carries `data`, so at `scope: 'record'` * the engine lint ACCEPTS `data.status == 'x'` with zero findings (measured on - * `@objectstack/formula@17.4.0`). objectui#5741 retired that spelling on runtime + * `@objectstack/formula@17.4.0`). `83fe6e741` retired that spelling on runtime * record surfaces and objectui#8166 stopped this tier binding an ambient `data`, * so the predicate now faults at runtime with `Unknown variable: data` — but the * author still gets a GREEN lint while typing it. That gap is the whole card: * the diagnostic arrives at misbehaviour time instead of at typing time. * - * ## Why this is not a re-run of the warning objectui#5741 deleted + * ## Why this is not a re-run of the warning Phase 2 (`83fe6e741`) deleted * * That ruling removed the Phase-1 warning from the runtime hot path and kept * the export, in its own words, "as the offline instrument". `listConditional.ts` @@ -459,7 +459,7 @@ async function rowCanonAdvisory(source: string, slot: string | undefined): Promi severity: 'warning', message: `\`${finding.identifier}\` is not the row on this surface: a row predicate binds the ` + - `record as \`${finding.canonical}\` and nothing else (objectui#5741). The CEL scope ` + + `record as \`${finding.canonical}\` and nothing else. The CEL scope ` + `vocabulary still accepts \`${finding.identifier}\`, so nothing here blocks the save, but ` + `at runtime the expression faults with \`Unknown variable: ${finding.identifier}\` and the ` + `rule never fires. Re-root the reference on \`${finding.canonical}\`.`, diff --git a/packages/app-shell/src/views/metadata-admin/conditionScope.ts b/packages/app-shell/src/views/metadata-admin/conditionScope.ts index f34b0f48f5..464cf4002c 100644 --- a/packages/app-shell/src/views/metadata-admin/conditionScope.ts +++ b/packages/app-shell/src/views/metadata-admin/conditionScope.ts @@ -24,7 +24,7 @@ import { * The widget's surface is whatever the host schema points it at, so no single * scope is right for it: `record` is right where the evaluator binds a row, and * refusing the bare shorthand on the flow / RLS tiers — which are NOT row - * surfaces (objectui#5738 stand-down 3) — would narrow a surface with no defect. + * surfaces (stand-down 3 on the corpus-sweep card behind `702c48a62`) — would narrow a surface with no defect. * The one place that knows which tier is on screen is the host that is editing * a metadata type, so the scope originates there and rides * {@link WidgetContext.conditionScope}, required at construction. @@ -119,7 +119,7 @@ export const CONDITION_SCOPE_BY_METADATA_TYPE = { flow: 'flattened', permission: 'flattened', /** Row-level security: a rule condition, evaluated per row but bound flat — - * the objectui#5738 stand-down 3 surface, the same as `permission`. */ + * a stand-down 3 surface of the corpus-sweep card behind `702c48a62`, the same as `permission`. */ sharing_rule: 'flattened', /* ── `none` — no lint claim this editor may honestly make ────────────── */ diff --git a/packages/app-shell/src/views/metadata-admin/i18n.ts b/packages/app-shell/src/views/metadata-admin/i18n.ts index 7711f1fe35..d0dcc809a5 100644 --- a/packages/app-shell/src/views/metadata-admin/i18n.ts +++ b/packages/app-shell/src/views/metadata-admin/i18n.ts @@ -2423,7 +2423,7 @@ const ENGINE_STRINGS_EN: Record = { 'engine.studio.data.noObjects': 'No objects yet — create one below to start', 'engine.studio.data.labelPlaceholder': 'Display name (e.g. Repair Ticket)', 'engine.studio.data.idPlaceholder': 'Identifier (e.g. repair_ticket)', - // [objectui#5418] The create dialog's third field. `新建对象` used to ask for + // [`7a90afdf9`] The create dialog's third field. `新建对象` used to ask for // exactly two things and produce an object the publish door refuses. 'engine.studio.data.owdLabel': 'Record sharing (OWD) — who can see records another user owns', 'engine.studio.data.owdHint': @@ -3601,7 +3601,7 @@ const ENGINE_STRINGS_ZH: Record = { 'engine.flowNode.try_catch.hint': '用错误处理与重试保护步骤', 'engine.flowNode.approval.label': '审批', 'engine.flowNode.approval.hint': '暂停等待人工决策', - // objectui#5416 — `approval_revise` was the ONE palette entry with no zh + // `add10d8f9` — `approval_revise` was the ONE palette entry with no zh // row, so it alone rendered the server descriptor: an English name and the // descriptor's three-line English paragraph in a list where every other node // is a Chinese name and a short Chinese phrase. @@ -4044,7 +4044,7 @@ const ENGINE_STRINGS_ZH: Record = { 'engine.packages.form.scope': '范围', 'engine.packages.form.dependencies': '依赖', - // objectui#5416 — help text for the package manifest form. + // `add10d8f9` — help text for the package manifest form. // // The LABELS above have always been translated while the help line under // each one stayed English, so `新建软件包` rendered 显示名称 over @@ -4787,7 +4787,7 @@ const ENGINE_STRINGS_ZH: Record = { 'engine.studio.data.noObjects': '还没有对象 — 在下方新建一个开始', 'engine.studio.data.labelPlaceholder': '显示名(如:报修工单)', 'engine.studio.data.idPlaceholder': '标识符(如:repair_ticket)', - // [objectui#5418] 新建对象对话框的第三项。此前只问两项,产出的对象会被发布门拒绝。 + // [`7a90afdf9`] 新建对象对话框的第三项。此前只问两项,产出的对象会被发布门拒绝。 'engine.studio.data.owdLabel': '记录共享模型(OWD)—— 谁能看到他人拥有的记录', 'engine.studio.data.owdHint': '发布必填,之后可在“设置 → 记录共享模型”中修改。Private 与未设置时运行时的实际行为一致。', @@ -5620,7 +5620,7 @@ export function t(key: string, locale?: SupportedLocale | string): string { * Like {@link t}, but returns `undefined` when the active locale's table has * no entry — instead of echoing the key back as if it were a translation. * - * For strings this console does not OWN (objectui#5416). The package form's + * For strings this console does not OWN (`add10d8f9`). The package form's * help text is `@objectstack/spec`'s `ManifestSchema` `.describe()`, produced * in the framework repo and already reaching the form through the * spec-derived JSONSchema; only the zh rendering lives here. A caller uses diff --git a/packages/app-shell/src/views/metadata-admin/inspectors/ConditionBuilder.tsx b/packages/app-shell/src/views/metadata-admin/inspectors/ConditionBuilder.tsx index ffe8bf3000..5b509a0134 100644 --- a/packages/app-shell/src/views/metadata-admin/inspectors/ConditionBuilder.tsx +++ b/packages/app-shell/src/views/metadata-admin/inspectors/ConditionBuilder.tsx @@ -30,7 +30,7 @@ type Op = '==' | '!=' | '>' | '<' | '>=' | '<=' | 'truthy' | 'falsy'; /** The quote character a string literal was authored with. Remembered per row * so the builder re-emits the author's own spelling instead of normalising it - * (objectui#6296) — see {@link fmtValue}. */ + * (`88b15fddc`) — see {@link fmtValue}. */ type Quote = '"' | "'"; interface Row { subject: string; op: Op; value: string; quote?: Quote } @@ -101,7 +101,7 @@ const CONTEXT_SUBJECTS = [ const norm = (s: string) => s.replace(/\s+/g, ' ').trim(); /** - * The subject vocabulary a mount site binds (objectui#6296). + * The subject vocabulary a mount site binds (`88b15fddc`). * * The builder used to hardcode one: `record.` + field name, plus `record.id` / * `user.*` / `org.*`. That is right for every RECORD-scoped site — which is @@ -178,7 +178,7 @@ export interface ConditionSubjectVocabulary { * a plausible literal, and `data` IS bound, so reading it as a reference would * produce another silently-false predicate instead of a loud one. Which roots * a mounting surface actually binds is caller-supplied vocabulary - * (objectui#6296) and is that card's to declare, not this one's to guess. + * (`88b15fddc`), the caller's to declare, not this list's to guess. */ export const REFERENCE_ROOTS = ['record', 'previous', 'parent', 'user', 'current_user', 'org'] as const; @@ -450,7 +450,7 @@ function fmtValue(v: string, quote: Quote = "'"): string { if (REFERENCE_RE.test(t)) return t; // `quote` defaults to the single quote this function has always emitted, so // a row the author built here — and every row parsed from single-quoted CEL - // — is byte-for-byte what it was before objectui#6296. Only a row parsed + // — is byte-for-byte what it was before `88b15fddc`. Only a row parsed // from a DOUBLE-quoted literal carries `"`, and those did not reach row mode // at all until this change. const esc = quote === "'" ? t.replace(/'/g, "\\'") : t.replace(/"/g, '\\"'); @@ -469,7 +469,7 @@ function unfmtValue(raw: string): { value: string; quote?: Quote } { // Double-quoted literals are the spelling every shipped flow-entry condition // uses, and the field's own placeholder teaches. Stripping only single // quotes while re-emitting only single quotes meant they could never - // round-trip, so they were handed to the raw editor (objectui#6296). + // round-trip, so they were handed to the raw editor (`88b15fddc`). const dq = /^"(.*)"$/.exec(t); if (dq) return { value: dq[1].replace(/\\"/g, '"'), quote: '"' }; return { value: t }; @@ -542,7 +542,7 @@ export function ConditionBuilder({ label, value, onCommit, objectName, fields: f */ onBlockingIssuesChange?: (count: number) => void; /** - * What this mount site's subjects are called (objectui#6296). Omit for the + * What this mount site's subjects are called (`88b15fddc`). Omit for the * record-scoped default every existing consumer relies on. */ subjects?: ConditionSubjectVocabulary; @@ -557,7 +557,7 @@ export function ConditionBuilder({ label, value, onCommit, objectName, fields: f * spelling is `hint.scope ?? 'flattened'`, and no caller could say otherwise * — so a bare `status == 'done'` typed into an action's **Visible when** * linted CLEAN. It never matches: `usePredicateRecordContext` binds `record` - * and nothing else, and objectui#5741 Phase 2 retired the bare shorthand on + * and nothing else, and Phase 2 (`83fe6e741`) retired the bare shorthand on * runtime record surfaces. The row-predicate canon in `@object-ui/core` * (`rowPredicateCanon.ts`) names an action renderer's `visible` / `disabled` * as such a surface in its own words. That is objectui#7727's defect, at a diff --git a/packages/app-shell/src/views/metadata-admin/inspectors/FlowReferenceField.tsx b/packages/app-shell/src/views/metadata-admin/inspectors/FlowReferenceField.tsx index e0822d6507..ef95d10984 100644 --- a/packages/app-shell/src/views/metadata-admin/inspectors/FlowReferenceField.tsx +++ b/packages/app-shell/src/views/metadata-admin/inspectors/FlowReferenceField.tsx @@ -176,7 +176,7 @@ export const KIND_TO_RECORD_LOOKUP: Partial { // // This used to justify itself with "the injected widgets (text, number, date, // lookup, …) have no such handler". That claim is no longer true and is no - // longer the reason (objectui#6859). `onBlur` is a DECLARED DOM pass-through + // longer the reason (`64d937c53`). `onBlur` is a DECLARED DOM pass-through // key — named in `FieldWidgetDomProps` (`@object-ui/fields`), named in // `SDUI_DOM_PASS_THROUGH_KEYS` (`@object-ui/core`), forwarded by // `toDomProps` — and every widget reachable as an inline editor spreads that @@ -1143,7 +1143,7 @@ const DataTableRenderer = ({ schema }: { schema: DataTableSchema }) => { // EDIT MODE, not rescuing the value: injected widgets stage on every change // (the host wires the widget's `onChange` to `stageEdit` below), so a typed // value is already in `pendingChanges` before any exit event — measured in a - // real browser on the text, date and number editors for objectui#6859. + // real browser on the text, date and number editors for `64d937c53`. // Retiring this listener would strand cells in edit mode; it would not drop // edits. const injectedEditorElRef = useRef(null); @@ -1922,7 +1922,7 @@ const DataTableRenderer = ({ schema }: { schema: DataTableSchema }) => { // Built-in `` editors commit via their own onBlur (handleEditBlur). The // widgets injected through `renderCellEditor` (text, number, date, lookup, …) // never receive one — not because they cannot deliver it (they can, and do: - // see `injectedEditorElRef` above and objectui#6859) but because nothing on + // see `injectedEditorElRef` above and `64d937c53`) but because nothing on // this seam passes it to them — so without this they stay stuck in edit mode // when the user clicks away. A capture-phase document listener (capture so a cell's // own `stopPropagation` can't hide it) commits the staged value and exits edit @@ -2255,7 +2255,7 @@ const DataTableRenderer = ({ schema }: { schema: DataTableSchema }) => { that path entirely, so an authored `visibleWhen` on an `emptyAction` was accepted by the spec and then never evaluated — declared-not-enforced (objectui#5926 gap 1), - the same class objectui#5401 / #5505 closed for + the same class `c86185eb5` closed for `record:alert`, one level down. Routing to the ONE gate rather than adding a local @@ -2613,7 +2613,7 @@ const DataTableRenderer = ({ schema }: { schema: DataTableSchema }) => { // // Tab is deliberately NOT in that list, and // tabbing out therefore does not leave edit - // mode — measured, objectui#6859. It costs + // mode — measured, `64d937c53`. It costs // nothing: the widget has already staged // every keystroke into `pendingChanges`, so // the value is safe; the cell simply stays diff --git a/packages/components/src/renderers/layout/containers.tsx b/packages/components/src/renderers/layout/containers.tsx index 19c2e94ada..3e5d220a85 100644 --- a/packages/components/src/renderers/layout/containers.tsx +++ b/packages/components/src/renderers/layout/containers.tsx @@ -1277,7 +1277,7 @@ const _warnedHeaderPredicates = new Set(); * that is present-but-null does NOT trigger this (legitimately empty field). * Skipped while the record is empty/loading to avoid false positives. * - * ⛔ Do NOT re-attribute this to `hidden: true` (objectui#5399). `hidden` is a + * ⛔ Do NOT re-attribute this to `hidden: true` (`5a07e67d9`). `hidden` is a * UI concern ("Hidden from default UI"), not a projection rule: the framework's * read path drops `internal: true` columns and the `__search` companion, and * nothing else. This surface knows only WHICH keys the bound payload lacks; it diff --git a/packages/components/src/renderers/layout/flex.tsx b/packages/components/src/renderers/layout/flex.tsx index 85253bb6e6..893a6b4e7f 100644 --- a/packages/components/src/renderers/layout/flex.tsx +++ b/packages/components/src/renderers/layout/flex.tsx @@ -166,7 +166,7 @@ ComponentRegistry.register('flex', // DECLARE that it does, while `grid`, `card`, `container` and `stack` — the // same directory, the same `ui` namespace — all do. The flag is not read by // the render path, so nothing was broken at runtime; its consumers are - // elsewhere, and the gap made them contradict the renderer (objectui#6740). + // elsewhere, and the gap made them contradict the renderer (`7c9b044f4`). // // MEASURED, not inferred. Building the manifest the way the app builds it // (`getKnownTypes()` + `getMeta()` -> `manifestFromConfigs`) and putting a diff --git a/packages/core/src/actions/ActionRunner.ts b/packages/core/src/actions/ActionRunner.ts index dc7bf353d5..d62f82a725 100644 --- a/packages/core/src/actions/ActionRunner.ts +++ b/packages/core/src/actions/ActionRunner.ts @@ -636,7 +636,7 @@ export type ResultDialogHandler = ( * `visibleWhen` (the CEL predicate `resolveVisibleOptions()` filters on — * ADR-0058 / #2284), `color`, `icon`, `disabled`. * - * The catch-all is deliberate rather than a closed key list (objectui#3559). + * The catch-all is deliberate rather than a closed key list (`fbc23e094`). * A field's option vocabulary is owned by the field metadata (`@objectstack/spec`'s * `SelectOptionSchema`) and read by the option widgets; a param's option list is * only a CONDUIT between the two. When this type restated that vocabulary as @@ -1412,7 +1412,7 @@ export class ActionRunner { // ── ActionSchema.onSuccess — post-success navigation ──────────────────── // - // objectui#5221, the console half of objectstack#9566/#9474. The spec + // `053fdc8f9`, the console half of objectstack#9566/#9474. The spec // declares `onSuccess` as a CLOSED STRICT object // `{ navigate: string, openIn: 'self' | 'newTab' }`, refine-scoped to // `type: 'api'` and `type: 'script'` — the two types whose success event diff --git a/packages/core/src/evaluator/listConditional.ts b/packages/core/src/evaluator/listConditional.ts index 1d494e6e15..837424151e 100644 --- a/packages/core/src/evaluator/listConditional.ts +++ b/packages/core/src/evaluator/listConditional.ts @@ -164,7 +164,7 @@ export interface RowPredicateOptions { * scope (`features` / `user`) a host shell provides. The row wins on * collision: a `record` key here never shadows the row. Every OTHER key — * a host's own `data` included — reaches the predicate as the host's own - * (objectui#5741: `data` no longer names the row on a record surface). */ + * (`83fe6e741`: `data` no longer names the row on a record surface). */ scope?: Record; /** When true, log a one-time warning if a *present* predicate faults. */ warnOnError?: boolean; @@ -208,7 +208,7 @@ export interface RowPredicateOptions { * Evaluate a single boolean predicate against a row record on the canonical CEL * engine (with a legacy-dialect fallback — see the module note). The row is * bound ONE way: as `record.*` — **the canon** (maintainer ruling 2026-08-20 on - * objectui#5330, option B; Phase 2 executed by objectui#5741). + * objectui#5330, option B; Phase 2 executed by `83fe6e741`). * * Until Phase 2 the row was also bound as bare fields (`status`, the row-action * shorthand) and as `data.*`, and Phase 1 (PR #5737) warned once per @@ -260,7 +260,7 @@ export function evalRowPredicate( ? {} : toPredicateRecord(row && typeof row === 'object' ? row : {}, opts.fields); // `record.*` + the host scope, all top-level. The row is bound ONE way - // (objectui#5741, Phase 2 of the objectui#5330 canon): no bare-field spread + // (`83fe6e741`, Phase 2 of the objectui#5330 canon): no bare-field spread // and no `data` — a predicate spelled either way is simply unbound here and // faults, on both dialect paths, exactly as it does on the server. // @@ -316,7 +316,7 @@ export function evalRowPredicate( } // CEL path — everything reaching here is CEL. No spelling detector runs here - // (objectui#5741 removed the Phase-1 warning with the bindings): a retired + // (`83fe6e741` removed the Phase-1 warning with the bindings): a retired // bare-field / `data.*` spelling is unbound above and faults in the engine // like any other unknown variable, and the fault report below is what names // it. `detectNonCanonicalRowSpelling` stays exported for OFFLINE sweeps of diff --git a/packages/core/src/evaluator/rowPredicateCanon.ts b/packages/core/src/evaluator/rowPredicateCanon.ts index 2dcefdf73f..706d4bd8e5 100644 --- a/packages/core/src/evaluator/rowPredicateCanon.ts +++ b/packages/core/src/evaluator/rowPredicateCanon.ts @@ -9,7 +9,7 @@ /** * The row-predicate spelling CANON: on a runtime record surface the row is bound * as `record.*` and nothing else (objectui#5330, maintainer ruling 2026-08-20, - * option B; Phase 2 executed by objectui#5741). + * option B; Phase 2 executed by `83fe6e741`). * * ## The canon * @@ -21,7 +21,7 @@ * deciding which of them was CONTRACT). The ruling decided it, in two phases: * * > **The canon is `record.*`.** Phase 1 (PR #5737) declared it and warned - * > once, in dev, on the two other spellings. Phase 2 (objectui#5741, ruled + * > once, in dev, on the two other spellings. Phase 2 (`83fe6e741`, ruled * > 2026-09-02 and amended 2026-09-05) retired them: the bare shorthand and * > `data.*` are no longer bound on runtime record surfaces, and the Phase-1 * > warning went with them. No stored-metadata survey was run (「不考虑存量」); @@ -72,8 +72,8 @@ * * {@link detectNonCanonicalRowSpelling} is the OFFLINE instrument: it classifies * an authored predicate's spelling against a row without evaluating it, so a - * sweep over stored or in-repo metadata (the objectui#5738 corpus sweep, - * PR #5758's recipe) can find the documents that still need rewriting. It is + * sweep over stored or in-repo metadata (the `702c48a62` corpus sweep's + * recipe) can find the documents that still need rewriting. It is * exported for that purpose and nothing on the hot path calls it — the runtime * warning half Phase 1 built on it (`warnNonCanonicalRowSpelling`, * `resetRowPredicateCanonWarnings`) was removed with the bindings. @@ -144,7 +144,7 @@ export type NonCanonicalRowSpelling = * @param source The predicate's CEL text. A legacy `${…}`-dialect string * is not CEL and returns `null` here (unparseable); classify * it by its own dialect's rules — on a runtime record surface - * it retired with the CEL spellings (objectui#5741), while on + * it retired with the CEL spellings (`83fe6e741`), while on * the schema/widget tier `data` is a different scope entirely. * @param row The row the predicate is bound against. * @param dataNamesRow Whether `data` is bound to that same row on this surface. diff --git a/packages/core/src/utils/object-aggregate-query.ts b/packages/core/src/utils/object-aggregate-query.ts index d93c4b2a5c..fc56582d88 100644 --- a/packages/core/src/utils/object-aggregate-query.ts +++ b/packages/core/src/utils/object-aggregate-query.ts @@ -91,7 +91,7 @@ export interface ObjectAggregateSpecQuery { * ⚠️ An ARRAY answers `false`. It is an object, but it is not this union's * object arm — neither `ChartGroupBySchema` nor `ObjectMetricPropsSchema`'s * `aggregate` admits one at this position, and `data-objectstack`'s adapter - * already refuses it at the wire (objectui#6864). Letting it through here would + * already refuses it at the wire (`503cd8b89`). Letting it through here would * wrap it into `groupBy: [[…]]` and turn a producer-side refusal into a * malformed query. */ diff --git a/packages/data-objectstack/src/index.ts b/packages/data-objectstack/src/index.ts index 8ba0378268..5fda0559cb 100644 --- a/packages/data-objectstack/src/index.ts +++ b/packages/data-objectstack/src/index.ts @@ -355,7 +355,7 @@ function specShapeSelectorReasons(params: any): string[] { * Analytics-branch params — `filter`, `field`, `function` — that reached * `aggregate()`'s SPEC-SHAPE branch, which reads none of them. * - * WHY A REFUSAL AND NOT A DROP (objectui#6864). This applies the maintainer + * WHY A REFUSAL AND NOT A DROP (`503cd8b89`). This applies the maintainer * ruling of 2026-08-30 on objectui#6825 — option A, REFUSE at the producer — to * the rest of the same branch. That ruling's reason was that a shape the spec's * own gate would reject is off-contract at the PRODUCER, so the adapter says no @@ -6027,7 +6027,7 @@ export class ObjectStackAdapter implements DataSource { assertSpecShapeWhereIsFilterAst(params.where, resource); queryAst.where = params.where; } - // The other half of the same ruling — objectui#6864. `where` above is the + // The other half of the same ruling — `503cd8b89`. `where` above is the // key this branch DOES read and refuses when unlowered; `filter`, `field` // and `function` are the analytics branch's keys, which this branch reads // not at all and used to drop without a word. Same disposition, applied to diff --git a/packages/i18n/src/locales/ar.ts b/packages/i18n/src/locales/ar.ts index 06a75f5297..3d198a3ff5 100644 --- a/packages/i18n/src/locales/ar.ts +++ b/packages/i18n/src/locales/ar.ts @@ -3553,7 +3553,7 @@ const ar = { detailChangedKeys: 'تغييرات أخرى:', confirmNote: 'النشر يُصدر كل المسودات المعلقة ({{count}}) لهذه الحزمة دفعة واحدة.', publishConfirm: 'نشر الكل', - // [objectui#5418] Pre-publish security-posture findings, shown next to + // [`7a90afdf9`] Pre-publish security-posture findings, shown next to // the confirm button so a refusal the door would issue is read BEFORE // the click rather than as a toast after the batch rolled back. securityBlockTitle: 'سيتم رفض النشر — {{count}} عنصر (عناصر) بحاجة إلى قرار أولاً', diff --git a/packages/i18n/src/locales/de.ts b/packages/i18n/src/locales/de.ts index 71775abbc3..7ed892f6fc 100644 --- a/packages/i18n/src/locales/de.ts +++ b/packages/i18n/src/locales/de.ts @@ -3523,7 +3523,7 @@ const de = { detailChangedKeys: 'Ebenfalls geändert:', confirmNote: 'Beim Veröffentlichen werden alle {{count}} ausstehenden Entwürfe dieses Pakets atomar freigegeben.', publishConfirm: 'Alle veröffentlichen', - // [objectui#5418] Pre-publish security-posture findings, shown next to + // [`7a90afdf9`] Pre-publish security-posture findings, shown next to // the confirm button so a refusal the door would issue is read BEFORE // the click rather than as a toast after the batch rolled back. securityBlockTitle: 'Veröffentlichen wird abgelehnt — {{count}} Element(e) benötigen zuerst eine Entscheidung', diff --git a/packages/i18n/src/locales/en.ts b/packages/i18n/src/locales/en.ts index 11823bce6b..94c3513e22 100644 --- a/packages/i18n/src/locales/en.ts +++ b/packages/i18n/src/locales/en.ts @@ -2979,7 +2979,7 @@ const en = { detailChangedKeys: 'Also changed:', confirmNote: 'Publishing releases all {{count}} pending drafts of this package atomically.', publishConfirm: 'Publish all', - // [objectui#5418] Pre-publish security-posture findings, shown next to + // [`7a90afdf9`] Pre-publish security-posture findings, shown next to // the confirm button so a refusal the door would issue is read BEFORE // the click rather than as a toast after the batch rolled back. securityBlockTitle: 'Publishing will be refused — {{count}} item(s) need a decision first', diff --git a/packages/i18n/src/locales/es.ts b/packages/i18n/src/locales/es.ts index f2692ba76d..f74b8249d5 100644 --- a/packages/i18n/src/locales/es.ts +++ b/packages/i18n/src/locales/es.ts @@ -3527,7 +3527,7 @@ const es = { detailChangedKeys: 'También cambió:', confirmNote: 'Publicar libera atómicamente los {{count}} borradores pendientes de este paquete.', publishConfirm: 'Publicar todo', - // [objectui#5418] Pre-publish security-posture findings, shown next to + // [`7a90afdf9`] Pre-publish security-posture findings, shown next to // the confirm button so a refusal the door would issue is read BEFORE // the click rather than as a toast after the batch rolled back. securityBlockTitle: 'La publicación será rechazada: {{count}} elemento(s) necesitan una decisión primero', diff --git a/packages/i18n/src/locales/fr.ts b/packages/i18n/src/locales/fr.ts index fb65bb4b4f..d9fb4dd1e6 100644 --- a/packages/i18n/src/locales/fr.ts +++ b/packages/i18n/src/locales/fr.ts @@ -3525,7 +3525,7 @@ const fr = { detailChangedKeys: 'Également modifié :', confirmNote: 'La publication libère atomiquement les {{count}} brouillons en attente de ce paquet.', publishConfirm: 'Tout publier', - // [objectui#5418] Pre-publish security-posture findings, shown next to + // [`7a90afdf9`] Pre-publish security-posture findings, shown next to // the confirm button so a refusal the door would issue is read BEFORE // the click rather than as a toast after the batch rolled back. securityBlockTitle: 'La publication sera refusée — {{count}} élément(s) nécessitent d’abord une décision', diff --git a/packages/i18n/src/locales/ja.ts b/packages/i18n/src/locales/ja.ts index 288b949840..b6cd2c9f37 100644 --- a/packages/i18n/src/locales/ja.ts +++ b/packages/i18n/src/locales/ja.ts @@ -3525,7 +3525,7 @@ const ja = { detailChangedKeys: 'その他の変更:', confirmNote: '公開すると、このパッケージの保留中ドラフト {{count}} 件がまとめて(アトミックに)公開されます。', publishConfirm: 'すべて公開', - // [objectui#5418] Pre-publish security-posture findings, shown next to + // [`7a90afdf9`] Pre-publish security-posture findings, shown next to // the confirm button so a refusal the door would issue is read BEFORE // the click rather than as a toast after the batch rolled back. securityBlockTitle: '公開は拒否されます — {{count}} 件の項目に先に決定が必要です', diff --git a/packages/i18n/src/locales/ko.ts b/packages/i18n/src/locales/ko.ts index c7368e0aed..799262f6d0 100644 --- a/packages/i18n/src/locales/ko.ts +++ b/packages/i18n/src/locales/ko.ts @@ -3522,7 +3522,7 @@ const ko = { detailChangedKeys: '기타 변경:', confirmNote: '게시하면 이 패키지의 대기 중인 초안 {{count}}개가 한 번에(원자적으로) 게시됩니다.', publishConfirm: '모두 게시', - // [objectui#5418] Pre-publish security-posture findings, shown next to + // [`7a90afdf9`] Pre-publish security-posture findings, shown next to // the confirm button so a refusal the door would issue is read BEFORE // the click rather than as a toast after the batch rolled back. securityBlockTitle: '게시가 거부됩니다 — {{count}}개 항목에 먼저 결정이 필요합니다', diff --git a/packages/i18n/src/locales/pt.ts b/packages/i18n/src/locales/pt.ts index ae94d399ff..98895a16b9 100644 --- a/packages/i18n/src/locales/pt.ts +++ b/packages/i18n/src/locales/pt.ts @@ -3522,7 +3522,7 @@ const pt = { detailChangedKeys: 'Também alterado:', confirmNote: 'Publicar libera atomicamente todos os {{count}} rascunhos pendentes deste pacote.', publishConfirm: 'Publicar tudo', - // [objectui#5418] Pre-publish security-posture findings, shown next to + // [`7a90afdf9`] Pre-publish security-posture findings, shown next to // the confirm button so a refusal the door would issue is read BEFORE // the click rather than as a toast after the batch rolled back. securityBlockTitle: 'A publicação será recusada — {{count}} item(ns) precisam de uma decisão primeiro', diff --git a/packages/i18n/src/locales/ru.ts b/packages/i18n/src/locales/ru.ts index 573b6aa803..e30f60ff5b 100644 --- a/packages/i18n/src/locales/ru.ts +++ b/packages/i18n/src/locales/ru.ts @@ -3553,7 +3553,7 @@ const ru = { detailChangedKeys: 'Также изменено:', confirmNote: 'Публикация атомарно выпускает все {{count}} ожидающих черновиков этого пакета.', publishConfirm: 'Опубликовать всё', - // [objectui#5418] Pre-publish security-posture findings, shown next to + // [`7a90afdf9`] Pre-publish security-posture findings, shown next to // the confirm button so a refusal the door would issue is read BEFORE // the click rather than as a toast after the batch rolled back. securityBlockTitle: 'Публикация будет отклонена — {{count}} элемент(ов) требуют решения', diff --git a/packages/i18n/src/locales/zh.ts b/packages/i18n/src/locales/zh.ts index 8e6c2e45c0..7e8a415313 100644 --- a/packages/i18n/src/locales/zh.ts +++ b/packages/i18n/src/locales/zh.ts @@ -2688,7 +2688,7 @@ const zh = { detailChangedKeys: '其他变更:', confirmNote: '发布将一次性(原子地)发布此包全部 {{count}} 个待发布草稿。', publishConfirm: '全部发布', - // [objectui#5418] Pre-publish security-posture findings, shown next to + // [`7a90afdf9`] Pre-publish security-posture findings, shown next to // the confirm button so a refusal the door would issue is read BEFORE // the click rather than as a toast after the batch rolled back. securityBlockTitle: '发布会被拒绝 —— 有 {{count}} 项需要先做出决定', diff --git a/packages/i18n/src/useObjectLabel.ts b/packages/i18n/src/useObjectLabel.ts index 0834ec2f1e..cb79c3a774 100644 --- a/packages/i18n/src/useObjectLabel.ts +++ b/packages/i18n/src/useObjectLabel.ts @@ -370,7 +370,7 @@ export function useObjectLabel() { * reaches this client — so nav labels arrive already localized. One * owner, not two. To translate a sidebar group, translate it there. * - * History (objectui#5197): until then this docstring promised + * History (`9c60144b5`): until then this docstring promised * `"Sales" → "销售"` for sidebar groups, and `NavigationRenderer` * accepted `resolveGroupLabel`/`resolveItemLabel` to wire it up. Those * props could never fire — the renderer's `isCustomized` guard compared a diff --git a/packages/layout/src/NavigationRenderer.tsx b/packages/layout/src/NavigationRenderer.tsx index 4d8579d9ca..bda3399c5f 100644 --- a/packages/layout/src/NavigationRenderer.tsx +++ b/packages/layout/src/NavigationRenderer.tsx @@ -197,7 +197,7 @@ export interface NavigationRendererProps { */ resolveViewLabel?: (objectName: string, viewName: string, fallbackLabel: string) => string; - // RETIRED (objectui#5197): `resolveGroupLabel` / `resolveItemLabel`, the two + // RETIRED (`9c60144b5`): `resolveGroupLabel` / `resolveItemLabel`, the two // id-keyed label resolvers. They were unreachable by construction — see the // note on `resolveNavItemLabel` below — and app-navigation localization is // owned solely by the server-side `/meta` boundary. Do not re-add them; a @@ -277,7 +277,7 @@ export function resolveLabel( * have it silently overridden by an `objects..label` translation. * * Deliberately NOT here: id-keyed resolution for `group` items and for - * url/page/report/custom leaves. Those two hooks existed until objectui#5197 + * url/page/report/custom leaves. Those two hooks existed until `9c60144b5` * and could never fire: the `isCustomized` guard below compares the authored * label against the branch's comparison target, and on an id-keyed branch * that target is the node's own `id` (`grp_workspace`) while the label is its @@ -291,7 +291,7 @@ export function resolveLabel( * id before the metadata reaches this renderer, so `base` is already * localized when it arrives. One owner, not two — localize nav labels there. * - * EXPORTED since objectui#6661, for the same reason {@link resolveHref} is: a + * EXPORTED since `969ba84f4`, for the same reason {@link resolveHref} is: a * second surface now renders the same `NavigationItem[]`. `nav:menu` is the * app's navigation tree as PAGE CONTENT (`app-shell/src/views/nav-menu-renderer.tsx`), * and it cannot mount `NavigationRenderer` itself — that renders through diff --git a/packages/plugin-charts/src/ChartRenderer.tsx b/packages/plugin-charts/src/ChartRenderer.tsx index e0dac80c6e..7170c77c48 100644 --- a/packages/plugin-charts/src/ChartRenderer.tsx +++ b/packages/plugin-charts/src/ChartRenderer.tsx @@ -181,7 +181,7 @@ export const ChartRenderer: React.FC = ({ schema, onChartCli // - `categories` was never a foreign spelling at all. It is a declared // member of the published `ChartSchema` and of its zod mirror, // documented in the schema reference as an ALTERNATIVE SERIES LIST, and - // ruled LIVE by objectui#6896 (maintainer ruling 2026-08-31, prose + // ruled LIVE by the maintainer ruling of 2026-08-31 (prose // follows machine). `normalizeChartSchema` -- the ONE translation point // (objectui#2880 S1) -- already consumes it, so `spec.series` above is // populated before the old branch could be reached. That branch was a diff --git a/packages/plugin-charts/src/normalizeChartSchema.ts b/packages/plugin-charts/src/normalizeChartSchema.ts index a1daaf9f10..b3c36b857d 100644 --- a/packages/plugin-charts/src/normalizeChartSchema.ts +++ b/packages/plugin-charts/src/normalizeChartSchema.ts @@ -649,7 +649,7 @@ export function normalizeChartSchema( // is resolved separately, from `xAxisKey` / `xAxis` above. // // `@object-ui/types` documented this key as "X-axis labels/categories" until - // objectui#6896; the declaration was corrected to this reading rather than + // `b0d308da9`; the declaration was corrected to this reading rather than // this reading to the declaration (maintainer ruling 2026-08-31 — prose // follows machine). Pinned in `normalizeChartSchema.test.ts`; if you change // what `categories` means here, that docblock is the other half of the edit. diff --git a/packages/plugin-dashboard/src/ObjectDataTable.tsx b/packages/plugin-dashboard/src/ObjectDataTable.tsx index fd082a1558..ca1eb5da17 100644 --- a/packages/plugin-dashboard/src/ObjectDataTable.tsx +++ b/packages/plugin-dashboard/src/ObjectDataTable.tsx @@ -870,13 +870,13 @@ export const ObjectDataTable: React.FC = ({ schema, dataSo // This line used to carry a THIRD, inline spelling that split camelCase but // never turned `_` into a space, so one field key rendered under two // spellings on one dashboard — measured, as headers over the same - // `crm_opportunity` columns (objectui#5425): + // `crm_opportunity` columns (`56f4e34c0`): // // auto-derived (here) Close_date · Needs_analysis // declared `columns: ['close_date']` Close Date · Needs Analysis // static `data-table`, no columns Close Date · Needs Analysis // - // That is the defect class objectui#5425 rules out — "a value cannot appear + // That is the defect class `56f4e34c0` rules out — "a value cannot appear // twice under two spellings" — so the odd one out adopts the convention // rather than the convention gaining a fourth dialect. The i18n wrapper is // unchanged: a bundle entry still wins, and this is only its fallback. diff --git a/packages/plugin-dashboard/src/RecordDetailDrawer.tsx b/packages/plugin-dashboard/src/RecordDetailDrawer.tsx index df9fe69599..1c3c20e1da 100644 --- a/packages/plugin-dashboard/src/RecordDetailDrawer.tsx +++ b/packages/plugin-dashboard/src/RecordDetailDrawer.tsx @@ -120,7 +120,7 @@ export const RecordDetailDrawer: React.FC = ({ // that upper-cased only the first word, so one key rendered as // `Close Date` in the column the user clicked and `Close date` in the // field this drawer opened — one key, two spellings, one uninterrupted - // interaction (objectui#9055; the class objectui#5425 ruled out). + // interaction (objectui#9055; the class `56f4e34c0` ruled out). // // The KEY prefixer stays distinct from `humanizeLabel`, the VALUE // prefixer in `@object-ui/core` — see `utils/humanize-label.ts`, whose diff --git a/packages/plugin-dashboard/src/index.tsx b/packages/plugin-dashboard/src/index.tsx index ddd36e3a78..06e5b1cf7c 100644 --- a/packages/plugin-dashboard/src/index.tsx +++ b/packages/plugin-dashboard/src/index.tsx @@ -61,7 +61,7 @@ export { // `PUBLIC_BLOCKS`), and it used to publish only `columns`/`gap`/`className` // while `DashboardRenderer` honoured far more, so `validateTree` warned // authors off keys that work — `widgets` included, the very key the -// objectui#5709 unconsumed-options warning descends into. The keys below are +// `8d58f46b4` unconsumed-options warning descends into. The keys below are // the per-key triage (#4668 / #5091 class), each declared because BOTH hold: // the renderer reads it AND `@objectstack/spec`'s strict `DashboardSchema` // accepts it, so the manifest never offers a key the save gate refuses. diff --git a/packages/plugin-dashboard/src/utils.ts b/packages/plugin-dashboard/src/utils.ts index 0e38568a31..d3552a78d5 100644 --- a/packages/plugin-dashboard/src/utils.ts +++ b/packages/plugin-dashboard/src/utils.ts @@ -49,7 +49,7 @@ export function humanizeFieldKey(key: string): string { * chart for the same widget rendered the humanized one (objectui#9172). That * card is what moved this here rather than growing a second copy of the * three-arm logic: a helper duplicated across the two relays is exactly the - * "one value, two spellings" class objectui#5425 ruled out. + * "one value, two spellings" class `56f4e34c0` ruled out. * * ⭐ THREE ARMS, and only the last two derive a display string from a FIELD * KEY: diff --git a/packages/plugin-detail/src/DetailView.tsx b/packages/plugin-detail/src/DetailView.tsx index e57c4e0973..858d0a9002 100644 --- a/packages/plugin-detail/src/DetailView.tsx +++ b/packages/plugin-detail/src/DetailView.tsx @@ -1668,7 +1668,7 @@ export const DetailView: React.FC = ({ {/* Recall belongs to the approval, not to the lock: an editable pending approval is just as recallable as a locked one. - It also belongs to the SUBMITTER (objectui#6464). The server + It also belongs to the SUBMITTER (`830ed5803`). The server authorizes recall on submitter identity and refuses everyone else, so rendering the button for every reader of a pending record offers a lever whose click must fail — the diff --git a/packages/react/src/context/InlineEditContext.tsx b/packages/react/src/context/InlineEditContext.tsx index 8457b82817..6c5dbc02cc 100644 --- a/packages/react/src/context/InlineEditContext.tsx +++ b/packages/react/src/context/InlineEditContext.tsx @@ -95,7 +95,7 @@ export interface InlineEditContextValue { approvalProgress?: ApprovalProgress; /** * Whether the viewer is the SUBMITTER of the pending approval request - * (objectui#6464). Recall is the submitter's lever and the server enforces + * (`830ed5803`). Recall is the submitter's lever and the server enforces * exactly that — a non-submitter's recall is refused — so a recall button * lit for everyone who can read the record is a button whose click must * fail. The host resolves the identity (server-resolved `viewer.is_submitter` @@ -227,7 +227,7 @@ export interface InlineEditProviderProps { approvalProgress?: ApprovalProgress; /** * Whether the viewer submitted the pending approval request - * (objectui#6464). Surfaced verbatim so the recall affordance is offered to + * (`830ed5803`). Surfaced verbatim so the recall affordance is offered to * the submitter only. Omitted ⇒ `undefined` ⇒ recall is offered exactly as * it was before this prop existed (see `InlineEditContextValue`), so a host * that resolves no approval identity is unchanged. diff --git a/packages/react/src/hooks/useExpression.ts b/packages/react/src/hooks/useExpression.ts index 458533199f..1b6778feb5 100644 --- a/packages/react/src/hooks/useExpression.ts +++ b/packages/react/src/hooks/useExpression.ts @@ -89,14 +89,14 @@ export { toPredicateInput } from '@object-ui/core'; * {@link useCondition} when the thing being gated is scoped to one record. * * The row is bound ONE way: `record.status` — the canon (objectui#5330, ruled - * 2026-08-20; Phase 2 executed by objectui#5741). This is not a dialect choice; + * 2026-08-20; Phase 2 executed by `83fe6e741`). This is not a dialect choice; * it is one rule, and it is `evalRowPredicate`'s rule * (`core/evaluator/listConditional.ts` — the record header, list rows, the row * kebab and conditional formatting all evaluate through it), restated here for * the `useCondition` tier so both tiers answer an author's `visible:` the same * way. * - * ## The two retired spellings (objectui#5741) + * ## The two retired spellings (`83fe6e741`) * * Until Phase 2 this bag also carried the row spread flat (bare `status`, the * row-action shorthand) and as `data` (legacy), and `useCondition` below warned @@ -206,7 +206,7 @@ export function useCondition( // We evaluate directly without caching the evaluator to avoid issues with context changes return useMemo( () => { - // No row-spelling detector on this tier (objectui#5741 removed the + // No row-spelling detector on this tier (`83fe6e741` removed the // Phase-1 warning with the bindings): a retired bare-field / `data.*` // spelling against a `usePredicateRecordContext` bag is simply unbound // and faults like any other unknown variable, and each leg's existing @@ -254,7 +254,7 @@ export function useCondition( * envelope is always CEL, and only a legacy-dialect string falls back to the * old engine (with a deprecation warning). The row is bound as `record.*` only * — the canon (objectui#5330; the bare-field and `data.*` spellings retired in - * objectui#5741 and fault here like any unknown variable); the ambient + * `83fe6e741` and fault here like any unknown variable); the ambient * predicate scope (`features` / `user` / …) is merged alongside so * deployment-level gates keep resolving. * diff --git a/packages/react/src/utils/visibilityDiagnostic.ts b/packages/react/src/utils/visibilityDiagnostic.ts index 46800e9ebc..0267e759af 100644 --- a/packages/react/src/utils/visibilityDiagnostic.ts +++ b/packages/react/src/utils/visibilityDiagnostic.ts @@ -589,8 +589,8 @@ const DATA_ROOT_PATH_RE = * * "a `data.*` read the bound object does not answer" — this one. On the * card's repro (`data.status` against the adapter) it fires; on * `${data.total}` against `{ total: 99 }` it does not; and it is - * STRUCTURALLY incapable of firing on the `record.*` bucket (objectui#5401 - * → #5454), which is the adjacent card with a different correct fix. + * STRUCTURALLY incapable of firing on the `record.*` bucket + * (objectui#5454), which is the adjacent card with a different correct fix. * * Residue, stated rather than hidden: deliberate absence idioms * (`data.status == null`, `!data.status`) are reported. They are not really diff --git a/packages/sdui-parser/src/dashboard-widget-options.ts b/packages/sdui-parser/src/dashboard-widget-options.ts index b38abed64f..d98396848f 100644 --- a/packages/sdui-parser/src/dashboard-widget-options.ts +++ b/packages/sdui-parser/src/dashboard-widget-options.ts @@ -1,12 +1,12 @@ /** - * ObjectUI — unconsumed dashboard-widget `options` keys (objectui#5709) + * ObjectUI — unconsumed dashboard-widget `options` keys (`8d58f46b4`) * * `@objectstack/spec`'s `DashboardWidgetOptionsSchema` ends in `.passthrough()` * ("declared query keys + open renderer extras"), so ANY key parses, validates * and lints cleanly — including one no renderer reads. That is how a showcase * dashboard shipped `options: { invert: true }` on a gauge with a comment * saying what it was believed to do, and rendered the un-inverted measure with - * no diagnostic anywhere (objectui#5709). The 2026-08-23 maintainer ruling: + * no diagnostic anywhere (`8d58f46b4`). The 2026-08-23 maintainer ruling: * open extras stay open — they just stop being SILENT. A key that reaches no * renderer draws a WARNING naming the consumed set. Not an error: no gate * weakening and no new red gates were ruled. diff --git a/packages/sdui-parser/src/kanban-quick-add.ts b/packages/sdui-parser/src/kanban-quick-add.ts index 57e10ca01d..84cd79c23c 100644 --- a/packages/sdui-parser/src/kanban-quick-add.ts +++ b/packages/sdui-parser/src/kanban-quick-add.ts @@ -49,7 +49,7 @@ * * The ruling's word is "diagnosed", not "refused", and every diagnostic in this * family is a warning: `unknown-prop` (what this replaces, so nothing hardens), - * `inert-expression`, and `unconsumed-widget-option`, whose objectui#5709 + * `inert-expression`, and `unconsumed-widget-option`, whose 2026-08-23 * ruling states the constraint directly — "no gate weakening and no new red * gates were ruled". `validate.ts`'s `inert-expression` note records that * escalating an inert authored key to `error` is a SEPARATE question diff --git a/packages/sdui-parser/src/validate.ts b/packages/sdui-parser/src/validate.ts index 4498ba1fb8..519e8a9b40 100644 --- a/packages/sdui-parser/src/validate.ts +++ b/packages/sdui-parser/src/validate.ts @@ -47,7 +47,7 @@ export const CHILD_LIST_KEY = 'children'; * * ⛔ `isContainer` is NOT consulted and is NOT a fallback. It used to decide * this branch and it lied both ways: a hand-kept flag drifted from the code - * (objectui#3900 / #6740 / #6764 / #6779 found the same drift four times), + * (objectui#3900 / `7c9b044f4` / #6764 / #6779 found the same drift four times), * and after objectui#6771 converged a dozen registrations onto `children` * the flag put a FALSE `not-a-container` on the one key they read * (objectui#9910). The flag now means LAYOUT containment only — the @@ -183,7 +183,7 @@ export function validateTree(tree: SchemaElement | null, manifest: Manifest): Ma // an author to edit working source. What is left on this side of the // boundary is a genuine expression, so that is what the message names. // - // Warning, not error, per the objectui#5709 precedent for inert + // Warning, not error, per the `8d58f46b4` precedent for inert // authored keys. ⛔ Escalation to error is objectui#6614 Q2 and is // deliberately NOT part of this change: it belongs at the SAVE GATE, // once the framework wires the registry manifest into @@ -228,7 +228,7 @@ export function validateTree(tree: SchemaElement | null, manifest: Manifest): Ma // Dashboard widgets: an `options` key riding the spec's `.passthrough()` // that no renderer consumes is legal, silent and inert — warn, naming - // the consumed set (objectui#5709 ruling; census + scope in + // the consumed set (the 2026-08-23 ruling; census + scope in // `./dashboard-widget-options.ts`). Like `not-a-container`, this runs // only for a component the manifest knows: an unresolved tag already // drew `unknown-component`, and deep diagnostics on it would be noise. diff --git a/packages/types/src/__tests__/chart-data-model-7113.test.ts b/packages/types/src/__tests__/chart-data-model-7113.test.ts index 638f429b06..5bfeea4910 100644 --- a/packages/types/src/__tests__/chart-data-model-7113.test.ts +++ b/packages/types/src/__tests__/chart-data-model-7113.test.ts @@ -251,7 +251,7 @@ describe('objectui#6939 `chart` — the mirror accepts both binding dialects', ( it('CONTROL — the `series[].data` tombstone still refuses, with its migration note', () => { const r = ChartDataSeriesSchema.safeParse({ name: 'r', data: [1, 2, 3] }); expect(r.success).toBe(false); - if (!r.success) expect(r.error.issues[0]?.message).toMatch(/RETIRED \(objectui#6896\)/); + if (!r.success) expect(r.error.issues[0]?.message).toMatch(/RETIRED \(ADR-0049\)/); }); }); diff --git a/packages/types/src/__tests__/chart-inline-data-retired.test.ts b/packages/types/src/__tests__/chart-inline-data-retired.test.ts index 6910000965..a8c983f8f1 100644 --- a/packages/types/src/__tests__/chart-inline-data-retired.test.ts +++ b/packages/types/src/__tests__/chart-inline-data-retired.test.ts @@ -133,7 +133,7 @@ describe('objectui#6896 — the mirror REFUSES `data`, and the refusal carries i // The message is the migration note, not zod's generic string. expect(issue!.message).not.toContain('Invalid input: expected never, received '); - expect(issue!.message).toContain('RETIRED (objectui#6896)'); + expect(issue!.message).toContain('RETIRED (ADR-0049)'); expect(issue!.message).toContain('`xAxisKey`'); // ONE string, BOTH channels — the invariant `retirementTombstone()` exists @@ -152,7 +152,7 @@ describe('objectui#6896 — the mirror REFUSES `data`, and the refusal carries i if (!result.success) { const issue = result.error.issues.find((i) => i.path.join('.') === 'series.0.data'); expect(issue, 'no issue addressed to `series.0.data`').toBeDefined(); - expect(issue!.message).toContain('RETIRED (objectui#6896)'); + expect(issue!.message).toContain('RETIRED (ADR-0049)'); } }); }); @@ -164,7 +164,7 @@ describe('objectui#6896 — the retirement is ANNOUNCED', () => { expect(shapeOf(ChartDataSeriesSchema)).toHaveProperty('data'); const text = describeOf(ChartDataSeriesSchema, 'data'); expect(text).toBeDefined(); - expect(text).toContain('RETIRED (objectui#6896)'); + expect(text).toContain('RETIRED (ADR-0049)'); // The announcement names a REMEDY, not just a removal. This is the half a // silent deletion cannot carry at all. expect(text).toContain('chart-level `data`'); diff --git a/packages/types/src/__tests__/chart-series-keys-7546.test.ts b/packages/types/src/__tests__/chart-series-keys-7546.test.ts index 88036b9a83..7fe6aa0343 100644 --- a/packages/types/src/__tests__/chart-series-keys-7546.test.ts +++ b/packages/types/src/__tests__/chart-series-keys-7546.test.ts @@ -245,7 +245,7 @@ describe('objectui#7546 — what did NOT change', () => { it('the `data` tombstone (objectui#6896) still refuses with its remedy', () => { const r = ChartDataSeriesSchema.safeParse({ name: 'r', data: [1, 2, 3] }); expect(r.success).toBe(false); - if (!r.success) expect(r.error.issues[0]?.message).toMatch(/RETIRED \(objectui#6896\)/); + if (!r.success) expect(r.error.issues[0]?.message).toMatch(/RETIRED \(ADR-0049\)/); }); it('a series binding to neither `name` nor `dataKey` is still refused at `name` (objectui#6939)', () => { diff --git a/packages/types/src/__tests__/dashboard-config.test.ts b/packages/types/src/__tests__/dashboard-config.test.ts index 06fb07b74a..55dbfd53f0 100644 --- a/packages/types/src/__tests__/dashboard-config.test.ts +++ b/packages/types/src/__tests__/dashboard-config.test.ts @@ -223,7 +223,7 @@ describe('DashboardConfig Zod Validation', () => { // `error` would refuse with zod's generic "expected never, received // object", which names the key only via the path and tells the author // nothing about what to do. The tombstone carries a real message. - expect(issue!.message).toMatch(/RETIRED \(objectui#5852\)/); + expect(issue!.message).toMatch(/^RETIRED \(ADR-0049\) — /); expect(issue!.message).toMatch(/delete the key/); }); diff --git a/packages/types/src/__tests__/text-value-retired-6951.test.ts b/packages/types/src/__tests__/text-value-retired-6951.test.ts index dd84745911..a372bc2656 100644 --- a/packages/types/src/__tests__/text-value-retired-6951.test.ts +++ b/packages/types/src/__tests__/text-value-retired-6951.test.ts @@ -58,7 +58,7 @@ const ROOT = resolve(__dirname, '../../../..'); * on: the retired key, and the spelling to write instead. */ const GUIDANCE = - 'RETIRED (objectui#6951) — `value` is no longer part of TextSchema; write `content`. It was a second ' + 'RETIRED (ADR-0049) — `value` is no longer part of TextSchema; write `content`. It was a second ' + 'spelling of the one content slot, read only as the fallback limb of `schema.content || schema.value`, ' + 'and was retired under ADR-0049 enforce-or-remove with no deprecation window (maintainer ruling A1, ' + '2026-09-04). The renderer reads `content` alone now, so an authored `value` would render nothing. ' @@ -144,7 +144,7 @@ describe('TextSchema.value is RETIRED — the Zod half of the tombstone (objectu Object.keys(TextSchema.shape), 'value left the mirror — under .passthrough() the retired key becomes a silent blank', ).toContain('value'); - expect(describeOf(TextSchema, 'value')).toContain('RETIRED (objectui#6951)'); + expect(describeOf(TextSchema, 'value')).toContain('RETIRED (ADR-0049)'); }); }); diff --git a/packages/types/src/__tests__/tree-view-data-retired-6951.test.ts b/packages/types/src/__tests__/tree-view-data-retired-6951.test.ts index 692af86963..749eacee16 100644 --- a/packages/types/src/__tests__/tree-view-data-retired-6951.test.ts +++ b/packages/types/src/__tests__/tree-view-data-retired-6951.test.ts @@ -68,7 +68,7 @@ const ROOT = resolve(__dirname, '../../../..'); * on: the retired key, and the two spellings that still work. */ const GUIDANCE = - 'RETIRED (objectui#6951) — `data` is no longer part of TreeViewSchema; write `nodes` (or bind the tree with ' + 'RETIRED (ADR-0049) — `data` is no longer part of TreeViewSchema; write `nodes` (or bind the tree with ' + '`bind`). It was the second spelling of the one inline-nodes slot, read only as the last limb of ' + '`boundData || schema.nodes || schema.data || []`, and was retired under ADR-0049 enforce-or-remove with no ' + 'deprecation window (maintainer ruling B1, 2026-09-04). The renderer reads `bind` then `nodes` now, so an ' @@ -163,7 +163,7 @@ describe('TreeViewSchema.data is RETIRED — the Zod half of the tombstone (obje Object.keys(TreeViewSchema.shape), 'data left the mirror — an authored array now rides BaseSchema.data unvalidated', ).toContain('data'); - expect(describeOf(TreeViewSchema, 'data')).toContain('RETIRED (objectui#6951)'); + expect(describeOf(TreeViewSchema, 'data')).toContain('RETIRED (ADR-0049)'); }); }); diff --git a/packages/types/src/data-display.ts b/packages/types/src/data-display.ts index 9b20c93e11..58b3f146a2 100644 --- a/packages/types/src/data-display.ts +++ b/packages/types/src/data-display.ts @@ -1777,7 +1777,7 @@ export interface TreeNode { export interface TreeViewSchema extends BaseSchema { type: 'tree-view'; /** - * RETIRED (objectui#6951, ADR-0049 enforce-or-remove) — the second spelling + * RETIRED (`16a725f96`, ADR-0049 enforce-or-remove) — the second spelling * of the tree's one inline-nodes slot, read only as the LAST limb of * `boundData || schema.nodes || schema.data || []`. Maintainer ruling B1 * (2026-09-04): retire `data`; `nodes` is the only inline spelling; `nodes` @@ -1804,12 +1804,12 @@ export interface TreeViewSchema extends BaseSchema { * READ SITE: `renderers/data-display/tree-view.tsx:105`, the second limb of * `boundData || schema.nodes || []` — a `bind`-resolved value wins, and * {@link BaseSchema.bind} stays the first-read source, which is why this - * member is optional and no "at least one of" rule exists (objectui#6951 B1). + * member is optional and no "at least one of" rule exists (ruling B1, `16a725f96`). * * Declared by objectui#6150, which deliberately stopped at the declaration: * `{ type: 'tree-view', nodes }` only became a LEGAL document at * `777e5c6f4` (PR #7533), the accept-set change that relaxed the then - * required `data`; objectui#6951 retired that `data` spelling outright (the + * required `data`; `16a725f96` retired that `data` spelling outright (the * tombstone above). The registration's own `inputs` and `defaultProps` * spell it `nodes`, and the four catalog entries ARE those `defaultProps`. */ @@ -1968,7 +1968,7 @@ export type ChartType = SpecChartType; * and the category axis comes from `xAxisKey` / `xAxis`. That is the model * `normalizeChartSchema` in `@object-ui/plugin-charts` implements, and the only * one it has ever implemented. This header described an inline `data` array - * indexed by the chart's `categories` until objectui#6896 measured that no such + * indexed by the chart's `categories` until `b0d308da9` measured that no such * reader exists; `data` is now a retirement tombstone — see the member below. * * Renamed off `ChartSeries` (objectstack#4115): `@objectstack/spec/ui` owns that @@ -1999,7 +1999,7 @@ export interface ChartDataSeries { */ dataKey?: string; /** - * RETIRED (objectui#6896, ADR-0049 enforce-or-remove) — the inline-data model + * RETIRED (`b0d308da9`, ADR-0049 enforce-or-remove) — the inline-data model * this key belonged to was never implemented. `normalizeChartSchema`'s * `normalizeSeries` reads `dataKey`/`name`, `label`, `chartType`/`type`, * `variant`, `opacity`, `dashArray`, `stack`, `yAxis` and `color`; `data` is @@ -2198,7 +2198,7 @@ export interface ChartSchema extends BaseSchema { * category axis, and when `series` IS present they are ignored outright. * * The category axis comes from `xAxisKey` / `xAxis`. This docblock read - * "X-axis labels/categories" until objectui#6896 measured the read that has + * "X-axis labels/categories" until `b0d308da9` measured the read that has * always been there (maintainer ruling 2026-08-31 — prose follows machine). */ categories?: string[]; @@ -2216,7 +2216,7 @@ export interface ChartSchema extends BaseSchema { * `ChartRenderer.tsx:164` and were read back as columns at * `AdvancedChartImpl.tsx:2229` while surviving here only on `BaseSchema`'s * index signature. The `ChartDataSeries.data` tombstone above has been - * pointing authors at this key since objectui#6896. + * pointing authors at this key since `b0d308da9`. */ data?: Array>; /** diff --git a/packages/types/src/designer.ts b/packages/types/src/designer.ts index 3c890e3a7c..d9a968d276 100644 --- a/packages/types/src/designer.ts +++ b/packages/types/src/designer.ts @@ -637,7 +637,7 @@ export interface DashboardConfig { // -- Accessibility --------------------------------------------------------- // - // `aria?: { label?, description? }` was DECLARED here until objectui#5852. + // `aria?: { label?, description? }` was DECLARED here until `e7957ab87`. // It was never a contract: the spellings (`label`/`description`) match // neither `@objectstack/spec`'s `AriaProps` (`ariaLabel` / `ariaDescribedBy` // / `role`) nor anything a renderer maps, so no read point could have diff --git a/packages/types/src/layout.ts b/packages/types/src/layout.ts index 9e0276e109..a1f0114fb6 100644 --- a/packages/types/src/layout.ts +++ b/packages/types/src/layout.ts @@ -138,13 +138,13 @@ export interface TextSchema extends BaseSchema { * `[key: string]: any` (objectui#5155) and no shipped type mentioned it — * the docs page was the only record of a capability that works. #6150 * declared it next to a `value` fallback spelling and recorded that choosing - * between the two was an ADR-0049 question it did not decide; objectui#6951 - * (maintainer ruling A1, 2026-09-04) decided it: `content` is the one + * between the two was an ADR-0049 question it did not decide; maintainer + * ruling A1 (2026-09-04, `5ad86ddee`) decided it: `content` is the one * spelling, and {@link TextSchema.value} is the tombstone below. */ content?: string; /** - * RETIRED (objectui#6951 / objectui#7016, ADR-0049 enforce-or-remove) — the + * RETIRED (`5ad86ddee` / objectui#7016, ADR-0049 enforce-or-remove) — the * second spelling of the one content slot, read only as the fallback limb of * `schema.content || schema.value`. Maintainer ruling A1 (2026-09-04): retire * `value`, keep `content`, immediately and with no deprecation window diff --git a/packages/types/src/objectql.ts b/packages/types/src/objectql.ts index 6daad064e5..91bf0760f7 100644 --- a/packages/types/src/objectql.ts +++ b/packages/types/src/objectql.ts @@ -456,7 +456,7 @@ export interface BulkActionParam { * author especially) trusts the type absolutely (objectui#3309). * * Structurally identical to `@object-ui/core`'s `ActionParamOption` - * (objectui#3559), deliberately restated inline rather than imported: this + * (`fbc23e094`), deliberately restated inline rather than imported: this * package is the protocol layer and takes no workspace dependency. * * Naming the two keys this layer itself uses and passing the rest through is diff --git a/packages/types/src/zod/complex.zod.ts b/packages/types/src/zod/complex.zod.ts index d4ad4ab667..7a648f54c0 100644 --- a/packages/types/src/zod/complex.zod.ts +++ b/packages/types/src/zod/complex.zod.ts @@ -1421,7 +1421,7 @@ export const DashboardWidgetConfigSchema = z.object({ * * Validates the unified dashboard configuration used by create/edit workflows. * - * The `aria` member is an ADR-0049 retirement tombstone (objectui#5852), + * The `aria` member is an ADR-0049 retirement tombstone (`e7957ab87`), * following this package's convention (`data-display.zod.ts` * `StaticTableColumnSchema`, the set `crud.zod.ts` `confirm` established): * `z.never().optional()` REFUSES an authored value at parse time with the key @@ -1461,7 +1461,7 @@ export const DashboardConfigSchema = z.object({ icon: z.string().optional(), variant: z.string().optional(), })).optional().describe('Header action buttons'), - aria: z.never({ error: 'RETIRED (objectui#5852) — `aria` is no longer part of DashboardConfig; delete the key. The `{ label, description }` spellings matched no renderer vocabulary and nothing ever read them.' }).optional().describe('RETIRED (objectui#5852) — the `{ label, description }` spellings matched no renderer vocabulary and no read point ever consumed them; delete the key. For real ARIA use the spec vocabulary (`ariaLabel` / `ariaDescribedBy` / `role`) on a surface that reads it.'), + aria: z.never({ error: 'RETIRED (ADR-0049) — `aria` is no longer part of DashboardConfig; delete the key. The `{ label, description }` spellings matched no renderer vocabulary and nothing ever read them.' }).optional().describe('RETIRED (ADR-0049) — the `{ label, description }` spellings matched no renderer vocabulary and no read point ever consumed them; delete the key. For real ARIA use the spec vocabulary (`ariaLabel` / `ariaDescribedBy` / `role`) on a surface that reads it.'), }); /** diff --git a/packages/types/src/zod/data-display.zod.ts b/packages/types/src/zod/data-display.zod.ts index 638c54348e..517a43c838 100644 --- a/packages/types/src/zod/data-display.zod.ts +++ b/packages/types/src/zod/data-display.zod.ts @@ -554,7 +554,7 @@ export const TreeNodeSchema: z.ZodType = z.lazy(() => */ export const TreeViewSchema = BaseSchema.extend({ type: z.literal('tree-view'), - // ADR-0049 RETIREMENT TOMBSTONE (objectui#6951, maintainer ruling B1 of + // ADR-0049 RETIREMENT TOMBSTONE (`16a725f96`, maintainer ruling B1 of // 2026-09-04). `data` was the second spelling of the one inline-nodes slot, // read only as the last limb of `boundData || schema.nodes || schema.data || []`; // the renderer now reads `bind` then `nodes`. A plain deletion here would NOT @@ -565,14 +565,14 @@ export const TreeViewSchema = BaseSchema.extend({ // `./tombstone.zod.ts`; the base-vs-extended contrast is pinned in // `../__tests__/tree-view-data-retired-6951.test.ts`. data: retirementTombstone( - 'RETIRED (objectui#6951) — `data` is no longer part of TreeViewSchema; write `nodes` (or bind the tree with ' + 'RETIRED (ADR-0049) — `data` is no longer part of TreeViewSchema; write `nodes` (or bind the tree with ' + '`bind`). It was the second spelling of the one inline-nodes slot, read only as the last limb of ' + '`boundData || schema.nodes || schema.data || []`, and was retired under ADR-0049 enforce-or-remove with no ' + 'deprecation window (maintainer ruling B1, 2026-09-04). The renderer reads `bind` then `nodes` now, so an ' + 'authored `data` would render an empty tree. Rename the key; the array is unchanged.', ), nodes: z.array(TreeNodeSchema).optional() - .describe('Inline tree nodes — the one inline spelling, read as the second limb of `boundData || schema.nodes || []` (a `bind`-resolved value wins, so this stays optional and no presence rule exists — objectui#6951 B1). Declared by objectui#6150; a `nodes`-only document became LEGAL; the `data` fallback spelling was retired by objectui#6951 (the registration\'s own `inputs` and `defaultProps` spell it `nodes`, and the four catalog entries ARE those `defaultProps`)'), + .describe('Inline tree nodes — the one inline spelling, read as the second limb of `boundData || schema.nodes || []` (a `bind`-resolved value wins, so this stays optional and no presence rule exists). Declared by objectui#6150; a `nodes`-only document became LEGAL; the `data` fallback spelling was retired (the registration\'s own `inputs` and `defaultProps` spell it `nodes`, and the four catalog entries ARE those `defaultProps`)'), title: z.string().optional() .describe('Heading above the tree — renders only when set (objectui#6150)'), defaultExpandedIds: z.array(z.string()).optional().describe('Default expanded node IDs'), @@ -652,7 +652,7 @@ export const ChartTypeSchema = stripImportedDefaults(SpecChartTypeSchema); * consumer importing `ChartSeriesSchema` from `@object-ui/types` could not tell * which contract they had. * - * ⚠️ Since objectui#6896 this twin carries no inline numbers either: `data` is a + * ⚠️ Since `b0d308da9` this twin carries no inline numbers either: `data` is a * retirement tombstone. The distinction the rename drew is now one of ROLE, not * of payload — this is the STATIC SDUI node's series, the spec's is the * dataset-bound one, and neither carries values. @@ -672,13 +672,13 @@ export const ChartDataSeriesSchema = z.object({ dataKey: z.string().optional().describe( 'Column this series plots within each chart-level `data` row — the internal spelling of `name`, and the one the renderer takes when both are written', ), - // ADR-0049 RETIREMENT TOMBSTONE (objectui#6896). Deleting the member was the + // ADR-0049 RETIREMENT TOMBSTONE (`b0d308da9`). Deleting the member was the // option NOT taken: `ChartDataSeriesSchema` is a non-strict `z.object`, which // STRIPS an undeclared key in silence — the same silent no-op the retirement // exists to end. Kept declared and unwritable, so an authored value is a // NAMED refusal carrying its own remedy. data: retirementTombstone( - 'RETIRED (objectui#6896) — `ChartDataSeries.data` was never read: ' + 'RETIRED (ADR-0049) — `ChartDataSeries.data` was never read: ' + '`normalizeChartSchema` takes rows from the chart node\'s chart-level `data` and picks a ' + 'column with the series\' `name`/`dataKey`, so an authored array was dropped in silence. ' + 'Delete the key; put the rows on the chart-level `data` and the category axis on `xAxisKey`.', @@ -936,7 +936,7 @@ export const ChartSchema = BaseSchema.extend({ title: z.string().optional().describe('Chart title'), description: z.string().optional().describe('Chart description'), // NOT axis labels — `normalizeChartSchema` reads `categories` as an - // ALTERNATIVE SERIES LIST, used only when `series` is absent (objectui#6896). + // ALTERNATIVE SERIES LIST, used only when `series` is absent (`b0d308da9`). categories: z .array(z.string()) .optional() diff --git a/packages/types/src/zod/layout.zod.ts b/packages/types/src/zod/layout.zod.ts index b23db79a32..5c97a9877d 100644 --- a/packages/types/src/zod/layout.zod.ts +++ b/packages/types/src/zod/layout.zod.ts @@ -110,15 +110,15 @@ export const TextSpanSchema = BaseSchema.extend({ export const TextSchema = BaseSchema.extend({ type: z.literal('text'), content: z.string().optional() - .describe('Text content — the one content spelling `text` reads (declared by objectui#6150; its `value` fallback spelling was retired by objectui#6951)'), - // ADR-0049 RETIREMENT TOMBSTONE (objectui#6951 / objectui#7016, maintainer + .describe('Text content — the one content spelling `text` reads (declared by objectui#6150; its `value` fallback spelling was retired)'), + // ADR-0049 RETIREMENT TOMBSTONE (`5ad86ddee` / objectui#7016, maintainer // ruling A1 of 2026-09-04). `value` was the second spelling of the one // content slot; the renderer now reads `content` alone, so a plain deletion // here would let an authored `value` ride `BaseSchema.passthrough()` into a // silent blank. The tombstone refuses it BY NAME instead — one string, both // channels (parse-time message and `.describe()`), see `./tombstone.zod.ts`. value: retirementTombstone( - 'RETIRED (objectui#6951) — `value` is no longer part of TextSchema; write `content`. It was a second ' + 'RETIRED (ADR-0049) — `value` is no longer part of TextSchema; write `content`. It was a second ' + 'spelling of the one content slot, read only as the fallback limb of `schema.content || schema.value`, ' + 'and was retired under ADR-0049 enforce-or-remove with no deprecation window (maintainer ruling A1, ' + '2026-09-04). The renderer reads `content` alone now, so an authored `value` would render nothing. ' diff --git a/packages/types/src/zod/objectql.zod.ts b/packages/types/src/zod/objectql.zod.ts index 5cf08feec7..e7829e0318 100644 --- a/packages/types/src/zod/objectql.zod.ts +++ b/packages/types/src/zod/objectql.zod.ts @@ -92,7 +92,7 @@ import { stripImportedDefaults } from './imported-defaults.js'; * 17.0.0-rc.5 (objectstack#5832) to stop it colliding with the 7-value * `HttpMethod` in the published JSON Schema. The runtime domain is unchanged, * so this repo keeps exporting it under the `HttpMethodSchema` name — following - * the rename WITHOUT changing cross-package semantics (objectui#3499). + * the rename WITHOUT changing cross-package semantics (`48132f7e6`). */ export const HttpMethodSchema = stripImportedDefaults(SpecHttpMethodSubsetSchema); diff --git a/packages/types/src/zod/tombstone.zod.ts b/packages/types/src/zod/tombstone.zod.ts index 7cc8bdcba2..2187b5538f 100644 --- a/packages/types/src/zod/tombstone.zod.ts +++ b/packages/types/src/zod/tombstone.zod.ts @@ -33,7 +33,7 @@ import { z } from 'zod'; * names WHICH key is wrong (via the issue path) but says nothing about why * it was retired or what to write instead — so half of the loud refusal's * payload was being dropped (objectui#6105). `DashboardConfigSchema.aria` - * (`complex.zod.ts`, objectui#5852) landed the spelling by hand first; + * (`complex.zod.ts`, `e7957ab87`) landed the spelling by hand first; * this is that spelling as one shared mechanism. * * ONE argument feeding TWO channels is the point: the message an author reads