From 7fa0175c545596b092d0cb54fbb51efb28d2b1e2 Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 29 Sep 2026 03:12:13 +0000 Subject: [PATCH 1/3] docs(spec): re-anchor the dead tracker citations in ui/ and two freed sites to the commits that decided them (stage 5) Comment and docblock lines only. Each line that cited a tracker number answering 404 now cites the commit on main that decided what the line describes, or ADR-0087's own amendment where the line quotes it. Two sibling pairs are respelled so each number carries its own qualifier (objectui#6110 + objectui#6111, objectui#8221's PR objectui#8758). No code token moves; every file keeps its line count. Claude-Session: https://claude.ai/code/session_014EJ1ED8X4MMrT18BhVx4tx Co-authored-by: Claude --- .../src/data/filter-subtree-provenance.ts | 6 +-- .../manifest-collection-spelling.ts | 4 +- .../src/ui/action-param-carryover.test.ts | 6 +-- packages/spec/src/ui/action.test.ts | 6 +-- packages/spec/src/ui/action.zod.ts | 16 ++++---- packages/spec/src/ui/bulk-action.test.ts | 4 +- packages/spec/src/ui/bulk-action.zod.ts | 6 +-- ...component-element-navigation-17987.test.ts | 2 +- .../src/ui/component-type-vocabulary.test.ts | 4 +- .../spec/src/ui/component-type-vocabulary.ts | 2 +- packages/spec/src/ui/component.test.ts | 22 +++++----- packages/spec/src/ui/component.zod.ts | 40 +++++++++---------- packages/spec/src/ui/dashboard.zod.ts | 2 +- .../ui/expression-bindable-text-keys.test.ts | 6 +-- .../ui/expression-bindable-text-keys.zod.ts | 4 +- .../spec/src/ui/form-select-option.test.ts | 2 +- packages/spec/src/ui/index.ts | 4 +- .../ui/interaction-config-retirement.test.ts | 2 +- packages/spec/src/ui/react-blocks.test.ts | 2 +- packages/spec/src/ui/react-blocks.ts | 8 ++-- .../src/ui/view-form-features-root.test.ts | 2 +- .../spec/src/ui/view-metadata-schema.test.ts | 4 +- .../src/ui/view-submit-redirect-url.test.ts | 2 +- packages/spec/src/ui/view.zod.ts | 22 +++++----- .../src/ui/widget-i18n-retirement.test.ts | 2 +- 25 files changed, 90 insertions(+), 90 deletions(-) diff --git a/packages/spec/src/data/filter-subtree-provenance.ts b/packages/spec/src/data/filter-subtree-provenance.ts index 03b3e1092cc..26ceabafb09 100644 --- a/packages/spec/src/data/filter-subtree-provenance.ts +++ b/packages/spec/src/data/filter-subtree-provenance.ts @@ -127,8 +127,8 @@ export const FILTER_SUBTREE_PROVENANCE: symbol = Symbol.for( * This paragraph used to end by calling the mark *"safe on filter objects that * are reused across requests (view metadata, cached scopes): the * classification of one subtree does not change between requests"*. The - * #8794 survey measured that claim and it is true in ONE direction only; the - * correction is pinned by `filter-subtree-provenance.test.ts` (#8836). The + * survey commit 1850ebbb0 records measured that claim and it is true in ONE direction only; the + * correction is pinned by `filter-subtree-provenance.test.ts` (same commit). The * claim holds where provenance is **intrinsic** to the subtree, and a caller's * `where` is the half where it is not: * @@ -153,7 +153,7 @@ export const FILTER_SUBTREE_PROVENANCE: symbol = Symbol.for( * > that vouched it. * * It holds across every in-repo caller today — enumerated with controls in - * #8794 — and it holds *incidentally*: every caller in a markable position + * the survey commit 1850ebbb0 records — and it holds *incidentally*: every caller in a markable position * (`options.where` itself, or an arm of a pure `$and` root) happens to build * its filter fresh per request. This module does not and cannot enforce it, * because "the request" is not a concept it can see. What is enforced is that diff --git a/packages/spec/src/meta-spelling/manifest-collection-spelling.ts b/packages/spec/src/meta-spelling/manifest-collection-spelling.ts index c5bf5ecb7b8..1deaf26a62a 100644 --- a/packages/spec/src/meta-spelling/manifest-collection-spelling.ts +++ b/packages/spec/src/meta-spelling/manifest-collection-spelling.ts @@ -64,11 +64,11 @@ export const PLURAL_TO_SINGULAR: Record = { reports: 'report', datasets: 'dataset', actions: 'action', - // `themes: 'theme'` was removed at #10485 (ADR-0049; the carrier key is + // `themes: 'theme'` was removed by commit 35ad101bc (ADR-0049; the carrier key is // retired). Its absence here is load-bearing twice over: the generated // `META_URL_TO_SINGULAR` (gen:meta-url-spelling) loses the fold, so // `/meta/theme` gets `unrecognisedMetaTypeRefusal`'s loud verdict instead of - // the pre-#10194 store-anything branch; and `applyConversionsToStoredItem` + // the store-anything branch from before commit 2306a765c; and `applyConversionsToStoredItem` // passes legacy `theme` rows through untouched rather than manufacturing a // collection for them. flows: 'flow', diff --git a/packages/spec/src/ui/action-param-carryover.test.ts b/packages/spec/src/ui/action-param-carryover.test.ts index fd69409acad..daabdfab62f 100644 --- a/packages/spec/src/ui/action-param-carryover.test.ts +++ b/packages/spec/src/ui/action-param-carryover.test.ts @@ -1,4 +1,4 @@ -// #11992 — `ActionParamSchema.carryOver`, the #11753 ruling's spec half +// #11992 — `ActionParamSchema.carryOver` (commit 0e4e51b0a), the carry-over ruling's spec half // (maintainer 2026-08-25, recommendation A): a declared carry-over param is // seeded from the row, rendered as a NON-EDITABLE summary, and submitted // VERBATIM. These pins hold the ruled shape: the accept set (key + parsed @@ -9,8 +9,8 @@ // // Measured constraint restated from the parent card, because it is the reason // the key exists at all: `visible: false` is NOT this contract — it omits the -// param from the dialog AND from the submission, which is the #11703 -// silent-drop shape. `carryOver` must keep the param in the submission. +// param from the dialog AND from the submission, which is the silent-drop +// shape commit 5cb62d88b fixed. `carryOver` must keep the param in the submission. import { describe, it, expect } from 'vitest'; import { ActionParamSchema } from './action.zod'; diff --git a/packages/spec/src/ui/action.test.ts b/packages/spec/src/ui/action.test.ts index 093db2029e9..76a6eeb9adc 100644 --- a/packages/spec/src/ui/action.test.ts +++ b/packages/spec/src/ui/action.test.ts @@ -265,7 +265,7 @@ describe('requiresFeature lowering', () => { expect(bare).not.toHaveProperty('requiresFeature'); }); - // #5970 gave `visible` a boolean arm, so the lowering now meets two literals + // Commit 97e7e3caa gave `visible` a boolean arm, so the lowering now meets two literals // it never could before. Boolean algebra decides both, in opposite directions. it('treats `visible: true` as the explicit default — lowers to the gate alone', () => { const result = ActionSchema.parse({ @@ -301,7 +301,7 @@ describe('requiresFeature lowering', () => { }); }); -// ── #5970 — `visible` / `disabled` speak ONE shape ──────────────────────────── +// ── commit 97e7e3caa — `visible` / `disabled` speak ONE shape ───────────────── // Ruled 2026-08-06: both keys are `boolean | string(CEL) | {dialect, source}`. // Before this, `visible` had no boolean arm while `disabled` did, so the very // common `visible: true` was a spec-side parse error that objectui's `ActionDef` @@ -351,7 +351,7 @@ describe('ActionSchema — visible/disabled unified condition shape', () => { }); // The widening must not shrink the rejection surface by one shape. Each - // of these was rejected before #5970 and is asserted to still be. + // of these was rejected before commit 97e7e3caa and is asserted to still be. it.each([ ['an empty CEL string', ''], ['a number', 1], diff --git a/packages/spec/src/ui/action.zod.ts b/packages/spec/src/ui/action.zod.ts index 2e0a17b14b0..a73dc5a13c3 100644 --- a/packages/spec/src/ui/action.zod.ts +++ b/packages/spec/src/ui/action.zod.ts @@ -63,7 +63,7 @@ const ACTION_PARAM_KEY_ALIASES: Readonly> = { default: 'defaultValue', // The words an author borrows from `FieldSchema` (`readonly`) or widget // vocabulary (`disabled`) for "the user must not edit this". On a param the - // declared contract is `carryOver` (#11753): non-editable AND still + // declared contract is `carryOver` (commit 0e4e51b0a): non-editable AND still // submitted verbatim — which is the half `readonly`'s field semantics // (write-path strip) would get exactly wrong here. readonly: 'carryOver', @@ -387,7 +387,7 @@ export const ActionParamSchema = lazySchema(() => strictObject( */ defaultFromRow: z.boolean().optional().meta({ title: 'Default From Row' }), /** - * Carry-over declaration (#11753 ruling, 2026-08-25): the param's value is + * Carry-over declaration (maintainer ruling 2026-08-25, commit 0e4e51b0a): the param's value is * carried through the dialog rather than collected from the user — seeded * from the current row (`defaultFromRow` is required alongside), rendered as * a NON-EDITABLE summary, and submitted VERBATIM in the request body. @@ -395,9 +395,9 @@ export const ActionParamSchema = lazySchema(() => strictObject( * The knob exists because neither neighbour expresses this contract: * * - `visible: false` omits the param from the dialog AND from the submission - * — measured on #11753; a clone action that hid its facet params this way - * would silently stop copying them, which is exactly the #11703 defect - * shape. + * — the measurement commit 0e4e51b0a records; a clone action that hid its facet params this way + * would silently stop copying them, which is exactly the defect shape + * commit 5cb62d88b fixed in `clone_permission_set`. * - Leaving the param editable invites the failure the ruling names: the * clone dialog offered `member_default`'s `row_level_security` — a JSON * array of 17+ policy objects — as a prefilled textarea on the platform's @@ -406,7 +406,7 @@ export const ActionParamSchema = lazySchema(() => strictObject( * (`PermissionSetSchema` validates shape, not intent). * * "Not editable" is expressed by contract and enforced by the renderer - * (maintainer ruling on #11753, recommendation A): objectui's + * (maintainer ruling 2026-08-25, recommendation A, commit 0e4e51b0a): objectui's * `ActionParamDialog` renders a declared carry-over as a read-only summary * while keeping the seeded value in its submit state, so what is declared is * what is sent. Requiring `defaultFromRow: true` is the declared = enforced @@ -457,7 +457,7 @@ export const ActionParamSchema = lazySchema(() => strictObject( // A carry-over param must have its row seed declared. The pair is checked at // parse time because the failure it prevents is silent at runtime: a // `carryOver: true` param with no `defaultFromRow` would render an empty - // read-only control and submit `undefined` — the #11703 silent-drop shape, + // read-only control and submit `undefined` — the silent-drop shape commit 5cb62d88b fixed, // reintroduced through the very key added to close it. (p) => !p.carryOver || p.defaultFromRow === true, { @@ -816,7 +816,7 @@ export type ActionAiParsed = z.infer; * | `string` | `disabled: "record.status == 'closed'"` | CEL shorthand, normalized to the envelope at parse time | * | `{ dialect, source }` | `{ dialect: 'cel', source: '…', meta: { rationale } }` | the full envelope, for authorship metadata or a non-default dialect | * - * The two keys were asymmetric until #5970 — `visible` had no `boolean` arm, so + * The two keys were asymmetric until commit 97e7e3caa — `visible` had no `boolean` arm, so * the very common `visible: true` was a parse error on the spec side while * objectui's `ActionDef` accepted it and stored metadata was already written * that way. An asymmetry between two keys that mean the same *kind* of thing is diff --git a/packages/spec/src/ui/bulk-action.test.ts b/packages/spec/src/ui/bulk-action.test.ts index 2b75694fab8..f086c88399a 100644 --- a/packages/spec/src/ui/bulk-action.test.ts +++ b/packages/spec/src/ui/bulk-action.test.ts @@ -58,7 +58,7 @@ describe('BulkActionDefSchema (#4457)', () => { expect(def.params?.[0]).toMatchObject({ object: 'sys_user', labelField: 'name' }); }); - // ── RE-JUDGED, NOT RE-SPELLED (#18177) ───────────────────────────────── + // ── RE-JUDGED, NOT RE-SPELLED (commit adabccf5f) ─────────────────────── // This case used to be `forwards unknown WIDGET config on a param — the // renderer declares a catch-all`, and it asserted that `min`/`max`/`step` // rode through. That is the exact behaviour letter A removed, so the @@ -304,7 +304,7 @@ describe('BulkActionDefSchema (#4457)', () => { }); // ───────────────────────────────────────────────────────────────────────── - // #18177 — maintainer ruling batch #146 item 4, letter A. + // Commit adabccf5f — maintainer ruling batch #146 item 4, letter A. // // The card that produced this ruling turned on ONE measurement: the open // shape accepted `zzz_nonsense_key_that_no_producer_emits_8755` in the same diff --git a/packages/spec/src/ui/bulk-action.zod.ts b/packages/spec/src/ui/bulk-action.zod.ts index 0bea10dc557..281e495c700 100644 --- a/packages/spec/src/ui/bulk-action.zod.ts +++ b/packages/spec/src/ui/bulk-action.zod.ts @@ -48,7 +48,7 @@ import { FieldType } from '../data/field.zod'; // error for a blank screen. Localizing means declaring a real action and // naming it in `bulkActions`: THAT path runs through the i18n resolver // (`toBulkActionDef`'s `localize`). -// - `params[]` is STRICT (#18177, maintainer ruling batch #146 item 4, +// - `params[]` is STRICT (commit adabccf5f, maintainer ruling batch #146 item 4, // letter A). It used to be `.passthrough()`, mirroring the // `[key: string]: unknown` catch-all on objectui's `BulkActionParam` — and // that made its accept a NULL READING: measured against installed spec @@ -166,7 +166,7 @@ const BULK_PARAM_WIDGET_CONFIG_KEYS = [ * (merged over the def's static `patch`); for an aggregate `custom` def they * ride along as the action's params. * - * STRICT since #18177 — see the module header. An unknown key is refused by + * STRICT since commit adabccf5f — see the module header. An unknown key is refused by * name, carrying either the rename or the prescription that fixes it, exactly * as on `ActionParamSchema`. The sentence this replaced said strictness "would * lie" at this level; the measurement said the opposite — the OPEN shape was @@ -259,7 +259,7 @@ export const BulkActionParamSchema = lazySchema(() => strictObject( /** * Cascade binding — the ONE key this close DECLARES rather than refuses - * (#18177, ruling batch #146 item 4 letter A). + * (commit adabccf5f, ruling batch #146 item 4 letter A). * * Shape and description mirror the single-record twin. ⚠️ That twin is * `FieldSchema.dependsOn` (`data/field.zod.ts`), NOT `ActionParamSchema`, diff --git a/packages/spec/src/ui/component-element-navigation-17987.test.ts b/packages/spec/src/ui/component-element-navigation-17987.test.ts index a8e57436dcf..f63f6b9c5ec 100644 --- a/packages/spec/src/ui/component-element-navigation-17987.test.ts +++ b/packages/spec/src/ui/component-element-navigation-17987.test.ts @@ -1,7 +1,7 @@ // Copyright (c) 2026 ObjectStack. Licensed under the Apache-2.0 license. /** - * [#17987] Record-click navigation on the STANDALONE element faces — the spec + * [commit e233db9db] Record-click navigation on the STANDALONE element faces — the spec * half of the objectui#8652 maintainer ruling (four options were put; the reply * was verbatim `B`: declare `navigation` on the platform element schemas). * diff --git a/packages/spec/src/ui/component-type-vocabulary.test.ts b/packages/spec/src/ui/component-type-vocabulary.test.ts index bf0956c8f9d..336a23a38c4 100644 --- a/packages/spec/src/ui/component-type-vocabulary.test.ts +++ b/packages/spec/src/ui/component-type-vocabulary.test.ts @@ -1,7 +1,7 @@ // Copyright (c) 2026 ObjectStack. Licensed under the Apache-2.0 license. /** - * Pins for the page-component type vocabulary claim (#12950) — the + * Pins for the page-component type vocabulary claim (commit 225e7690f) — the * `vocabulary-derivation.test.ts` discipline applied to the namespace claim: * every set here is DERIVED in the source module, so these tests assert the * derivation still holds and the ledger still earns its rows. The failure mode @@ -98,7 +98,7 @@ describe('KNOWN_COMPONENT_TYPES covers every declared face', () => { }); /** - * #12950's own readiness verdict, pinned: `global:search` and + * Commit 225e7690f's own readiness verdict, pinned: `global:search` and * `global:notifications` STAY declared — the 2026-08-26 ruling retires a * member only when no data source covers the horizon, and both are backed by * shipped platform data sources (the cross-object search protocol behind diff --git a/packages/spec/src/ui/component-type-vocabulary.ts b/packages/spec/src/ui/component-type-vocabulary.ts index 1c1a40be3d4..99b9820d073 100644 --- a/packages/spec/src/ui/component-type-vocabulary.ts +++ b/packages/spec/src/ui/component-type-vocabulary.ts @@ -1,7 +1,7 @@ // Copyright (c) 2026 ObjectStack. Licensed under the Apache-2.0 license. /** - * The page-component TYPE vocabulary claim (#12950, riding the #12183 ruling of + * The page-component TYPE vocabulary claim (commit 225e7690f, riding the #12183 ruling of * 2026-08-26) — which `PageComponentSchema.type` strings the spec answers for, * and which half of the string space stays open. * diff --git a/packages/spec/src/ui/component.test.ts b/packages/spec/src/ui/component.test.ts index 91bf6a0c082..8706a4388c4 100644 --- a/packages/spec/src/ui/component.test.ts +++ b/packages/spec/src/ui/component.test.ts @@ -305,7 +305,7 @@ describe('PageAccordionProps variant (#6776)', () => { // declares `of: 'object'`, carries a longer description and no `label` — // while the member list this pin cites stayed unchanged.) Identity preserves a // wrong anchor as faithfully as a right one, which is why neither was carried -// (#10274). +// (commit d1ba685ec). // // #9397 spent a full dispatch cycle re-deriving that read point from scratch // after the sweep proposed retiring the key. This block plus the `.describe()` @@ -379,7 +379,7 @@ describe('PageTabsProps items[].value / items[].count (#5775)', () => { }); }); -// #9972 — the accept-pin for `page:tabs` items[].icon, the exact sibling of the +// Commit 60e0f900a — the accept-pin for `page:tabs` items[].icon, the exact sibling of the // #9881 accordion key: same file, same renderer, same `LazyIcon` slot, and the // same bare declaration a liveness sweep reads as declared-but-unenforced. // objectui's `PageTabsRenderer` renders `{item.icon && { // the same. (The hop before, off `53ded82bf`, moved them from // `730-736` and `789` and rewrote the input LINE — `of: 'object'`, a longer // description, no `label` — while the member list this pin cites stayed -// unchanged.) Never inferred (#10274). +// unchanged.) Never inferred (commit d1ba685ec). // // #9397 spent a full dispatch cycle re-deriving the accordion's read point // after the sweep proposed retiring it. This block plus the `.describe()` it @@ -2123,7 +2123,7 @@ describe('Interactive Elements — element:record_picker', () => { .toThrow(/`targetVariable`.*removed.*Delete the key/s); }); - // ── #6276 — the flat `sort` / `limit` shorthands ───────────────────────── + // ── commit 78f0be872 — the flat `sort` / `limit` shorthands ────────────── // The renderer resolves four keys through one pattern // (`ds. ?? props.`); after #5775 two of the four flat spellings were // declared and two were not. These pin the other two, in BOTH halves of what @@ -2333,7 +2333,7 @@ describe('the seven `object-*` `filter` doors — one filter orthography platfor // hand it verbatim to `$filter`, where `convertQueryParams` lowers it; the // metric's aggregate path lowers it through `translateFilterArray` and // `parseFilterAST` before `POST /analytics/query` (objectui#7754 — the - // door the family was sequenced behind, #15828 / #16626). Re-measured at + // door the family was sequenced behind, #15828 / the pin bump commit 30b099078). Re-measured at // the same pin for the three #18305 doors: `ObjectMap.tsx:742`, // `ObjectGantt.tsx:738` and `ObjectTree.tsx:474` each hand `schema.filter` // verbatim to `$filter`, the kanban/calendar shape. @@ -2722,8 +2722,8 @@ describe('RecordActivityProps (enhanced)', () => { }); // ------------------------------------------------------------------------- - // `types` is an OPEN vocabulary (#11658, executing the 2026-08-24 maintainer - // ruling on #11507: `sys_activity.type` is author-extensible, and "every + // `types` is an OPEN vocabulary (commit 1a6a19c31, executing the 2026-08-24 maintainer + // ruling commit 88b9d749a declared: `sys_activity.type` is author-extensible, and "every // closed map over this vocabulary is now the bug"). The closed-enum pin that // used to live here ("should reject invalid feed item type", // `types: ['invalid_type']` throwing) pinned exactly the branch the ruling @@ -3562,7 +3562,7 @@ describe('ObjectKanbanPropsSchema quickAdd is retired (#17260)', () => { // the `page:header` `icon` retired in #6946 *because nothing reads it*, so the // prose could not separate a live key from a refused one — the same absence // that sent #9397 on a full dispatch cycle re-deriving the accordion read point. -// #9881 and #9972 recorded the accordion and tab items; these two close the set. +// #9881 and commit 60e0f900a recorded the accordion and tab items; these two close the set. // // The button record re-measured at the pin this repo builds against — // `.objectui-sha` = `dd3f7e1be`, re-derived there 2026-09-28: `button.tsx` and @@ -3588,7 +3588,7 @@ describe('ObjectKanbanPropsSchema quickAdd is retired (#17260)', () => { // the hop onto `62597c588`. The hop before that, // onto `87af769e9` (re-derived 2026-09-20), moved both files in this chain — // `resolve-icon.ts` +203/-7 and `button.tsx` +6/-11 against `53ded82bf` — so -// no anchor below was carried there and every one was re-READ (#10274). ⚠️ `resolveIcon` itself was rewritten: its tail no +// no anchor below was carried there and every one was re-READ (commit d1ba685ec). ⚠️ `resolveIcon` itself was rewritten: its tail no // longer indexes `lucide-react`'s `icons` record, it asks `recordIconName` // for the kebab-case name and hands the pair to `lazyIconComponent`, so the // glyph arrives lazily. What an author may write did not change with it. The @@ -3600,7 +3600,7 @@ describe('ObjectKanbanPropsSchema quickAdd is retired (#17260)', () => { // splits on hyphen, underscore AND whitespace (`/[-_\s]+/`), where this record // used to say "splits on `-` only". That sentence was true when written and // was false by then, which is exactly why a citation refresh re-READS instead -// of moving numbers (#10274). +// of moving numbers (commit d1ba685ec). // The one move that changed the button READ POINT and not merely its line // numbers was the one onto `9602dc820`: objectui#5993 deleted `button.tsx`'s // file-local `toPascalCase` + `iconNameMap` + `icons` index and routed the @@ -3609,7 +3609,7 @@ describe('ObjectKanbanPropsSchema quickAdd is retired (#17260)', () => { // What an author sees did not move with it: an unknown name still resolves to // `null` and draws nothing, which is still the `LazyIcon` contrast the third // test below pins. The moves before that were line-number drift only — #10137 -// moved the pin while #9881/#9972 still cited `82a94170c`, #10274 re-measured +// moved the pin while the #9881 / commit 60e0f900a records still cited `82a94170c`, commit d1ba685ec re-measured // those four onto `9a3daf8d3`, and `button.tsx` was byte-identical at // `9a3daf8d3` and `190fbd01d`. describe('ElementButtonPropsSchema icon liveness (#10053)', () => { diff --git a/packages/spec/src/ui/component.zod.ts b/packages/spec/src/ui/component.zod.ts index 1fb93dca91b..cdfd2845ea5 100644 --- a/packages/spec/src/ui/component.zod.ts +++ b/packages/spec/src/ui/component.zod.ts @@ -7,7 +7,7 @@ import { GanttConfigSchema, TreeConfigSchema, ListMapConfigSchema, - // [#17987] The element-level record-click carrier and the timeline config + // [commit e233db9db] The element-level record-click carrier and the timeline config // block are taken BY REFERENCE from the view face — one def each, so the // standalone element cannot fork the vocabulary a view already declares. NavigationConfigSchema, @@ -31,7 +31,7 @@ import { retiredKey } from '../shared/retired-key'; import { RETIRED_PAGE_COMPONENT_TYPES } from './page.zod'; // `element:record_picker`'s flat `sort` shorthand is the SAME contract as // `ElementDataSourceSchema.sort` (page.zod.ts) — one shape, imported from the -// shared source rather than re-spelled here (#6276). +// shared source rather than re-spelled here (commit 78f0be872). import { SortItemSchema } from '../shared/enums.zod'; import { strictObject } from '../shared/strict-object'; import { ruleArrayFilterError } from './filter-rule-array'; @@ -162,7 +162,7 @@ import { SectionGroupKeySchema, sectionGroupReferenceRefinement } from '../share // happened is the reusable part: #5775's ruling named its keys individually, so // the two `element:record_picker` shorthands the renderer reads through the // SAME `ds.x ?? props.x` line as the keys that were named — `sort` and `limit` -// — fell outside it and stayed undeclared. #6276 declared them on the same +// — fell outside it and stayed undeclared. Commit 78f0be872 declared them on the same // #5611 rule (maintainer ruling 2026-08-08, direction A). The lesson for the // next divergence sweep: enumerate by the RENDERER'S read pattern, not by the // key list a previous ruling happened to quote. Retiring the flat family @@ -565,7 +565,7 @@ export const PageHeaderProps = strictObject({ * twin), the `?? 3` / `?? 1` are its own fallbacks, and its comment says out * loud that both are "overridable on the page:header". Closing this shape * without declaring them would turn an invited affordance into a hard - * rejection — the #6276 lesson, which is to enumerate by the RENDERER'S read + * rejection — the lesson of commit 78f0be872, which is to enumerate by the RENDERER'S read * pattern rather than by the key list a previous ruling happened to quote. * * Optional with NO schema default, deliberately: 3 and 1 are the renderer's @@ -1461,8 +1461,8 @@ export const RecordActivityProps = strictObject({ guidanceSets: COMPONENT_LEVEL_GUIDANCE, }, { /** - * Feed/activity kinds to show — an OPEN vocabulary (#11658, executing the - * 2026-08-24 maintainer ruling on #11507: `sys_activity.type` is + * Feed/activity kinds to show — an OPEN vocabulary (commit 1a6a19c31, executing the + * 2026-08-24 maintainer ruling commit 88b9d749a declared: `sys_activity.type` is * author-extensible and "every closed map over this vocabulary is now the * bug"). The `FeedItemType` union branch is guidance only — it keeps the * built-in kinds visible in editor autocomplete and as an `anyOf` member of @@ -2210,7 +2210,7 @@ export const ElementButtonPropsSchema = lazySchema(() => strictObject({ * precisely because no render path reads it. Vocabulary does not separate * the two verdicts; a read point does. That missing separation has already * cost a full dispatch cycle re-deriving a cross-repo read point from - * scratch (#9397, closed premise-overtaken), which is why #9881 and #9972 + * scratch (#9397, closed premise-overtaken), which is why #9881 and commit 60e0f900a * recorded it for the accordion and tab items. This is the same record for * the button. * @@ -2301,7 +2301,7 @@ export const ElementButtonPropsSchema = lazySchema(() => strictObject({ * They read `70-87` / `88-92` until the * `a472b0716` re-measure: wrong since written rather than shifted — * `button.tsx` was byte-identical at `00d3f09c5` and `a472b0716`, so only a - * re-READ could find them and a line-number refresh never would (#10274). Unpublished is not unread — the header `icon` + * re-READ could find them and a line-number refresh never would (commit d1ba685ec). Unpublished is not unread — the header `icon` * above is refused for the second, not the first, and this docblock exists * to hold them apart. */ @@ -2452,7 +2452,7 @@ export const ElementFormPropsSchema = lazySchema(() => strictObject({ * box, so both were capability claims nothing kept (#5021 / #4988 precedent). * Either may return the day it is implemented; a declaration is not a roadmap. * - * ⚠️ #6276 finished the same inventory one key-pair later, and the finding is + * ⚠️ Commit 78f0be872 finished the same inventory one key-pair later, and the finding is * worth stating as a rule rather than as two more keys. The renderer resolves * its query from FOUR keys through one identical pattern — `dataSource` first, * the flat `properties` shorthand second: @@ -2543,7 +2543,7 @@ export const ElementRecordPickerPropsSchema = lazySchema(() => strictObject({ }).optional() .describe('Filter rules narrowing which records the picker offers — the ViewFilterRule array form `[{ field, operator, value }, ...]`, the one filter orthography the array-declared `filter` doors of this map share. The MongoDB-style record form is refused — see migration `element-record-picker-filter-rule-array`. The binding-level `dataSource.filter` wins outright when both are set'), /** - * Row order (#6276). The flat shorthand for `dataSource.sort`, and the same + * Row order (commit 78f0be872). The flat shorthand for `dataSource.sort`, and the same * shape — `SortItemSchema[]`, the pairs the renderer forwards to the query as * `$orderby`. `dataSource.sort` wins when both are written * (`ds.sort ?? props.sort`). @@ -2551,7 +2551,7 @@ export const ElementRecordPickerPropsSchema = lazySchema(() => strictObject({ sort: z.array(SortItemSchema).optional() .describe('Row order — synonym of the component-level `dataSource.sort`, which takes precedence when both are set'), /** - * Row cap (#6276). The flat shorthand for `dataSource.limit`, same shape. + * Row cap (commit 78f0be872). The flat shorthand for `dataSource.limit`, same shape. * `dataSource.limit` wins when both are written, and with neither the * renderer queries `$top: 50` (`ds.limit ?? props.limit ?? 50`) — that 50 is * the renderer's fallback, not a schema default, so it is documented here @@ -3476,7 +3476,7 @@ export const ObjectGridPropsSchema = lazySchema(() => strictObject({ * `[{ field, order }]` onto the same parameter. ⚠️ At THIS pin the string is * therefore still lowered, and this door refuses a spelling the pinned * renderer honours — the ruled sequence, not an oversight: objectui#8221's - * PR #8758 (merged 2026-09-09, after this pin) drops the string arm from + * PR objectui#8758 (merged 2026-09-09, after this pin) drops the string arm from * `convertSortToQueryParams`, and the next pin bump carries it in. The array * is the spelling both ends already agree on today; the header-arrow read at * `:3998` hands `schemaSort` to `parseSchemaSort` as `TableSortItem[]`, the @@ -4011,7 +4011,7 @@ export const ObjectKanbanPropsSchema = lazySchema(() => strictObject({ coverImageField: z.string().optional().describe('Image field rendered as the card cover'), conditionalFormatting: z.unknown().optional().describe('Card conditional formatting rules'), /** - * Card-click navigation (#17987 — the spec half of the objectui#8652 + * Card-click navigation (commit e233db9db — the spec half of the objectui#8652 * maintainer ruling, verbatim `B`: declare `navigation` on the platform * element schemas). * @@ -4059,7 +4059,7 @@ export type ObjectKanbanProps = z.input; * ADR-0122: the parsed state differs from the authored state on TWO keys. * `filter` carries `z.array(ViewFilterRuleSchema)` (the ui#6206-B family * convergence, #15449), whose own input ≠ infer (`operator` is normalized on - * parse); `navigation` carries {@link NavigationConfigSchema} (#17987), whose + * parse); `navigation` carries {@link NavigationConfigSchema} (commit e233db9db), whose * four defaulted members (`mode`, `preventNavigation`, `openNewTab`, `size`) * materialize on parse — but only on a document that AUTHORED the key, since * the door itself is `.optional()` with no default of its own. So @@ -4137,7 +4137,7 @@ export const ObjectCalendarPropsSchema = lazySchema(() => strictObject({ * (`core/src/utils/sort-query.ts`) as the fetch's `$orderby`. ⚠️ That sink * still honours the legacy string clause at this pin — `sort-query.ts:66-70` * — so, exactly as on `object-grid`, this declaration lands ahead of the - * consumer-side retirement (objectui#8221's PR #8758, merged 2026-09-09) and + * consumer-side retirement (objectui#8221's PR objectui#8758, merged 2026-09-09) and * refuses a spelling the pinned helper still lowers. The array arm is * unaffected: the sink folds `[{ field, order }]` into the field-direction * map either way. Unlike the grid, `plugin-calendar/src/index.tsx` declares @@ -4150,7 +4150,7 @@ export const ObjectCalendarPropsSchema = lazySchema(() => strictObject({ locale: z.string().optional().describe('Locale override for the calendar chrome'), loading: z.boolean().optional().describe('External loading state (honoured only alongside `data`)'), /** - * Event-click navigation (#17987 — the spec half of the objectui#8652 + * Event-click navigation (commit e233db9db — the spec half of the objectui#8652 * maintainer ruling, verbatim `B`), the same carrier and the same def as * `object-kanban`'s above. * @@ -4190,7 +4190,7 @@ export type ObjectCalendarProps = z.input; * ADR-0122: the parsed state differs from the authored state on TWO keys. * `filter` carries `z.array(ViewFilterRuleSchema)` (the ui#6206-B family * convergence, #15449), whose own input ≠ infer (`operator` is normalized on - * parse); `navigation` carries {@link NavigationConfigSchema} (#17987), whose + * parse); `navigation` carries {@link NavigationConfigSchema} (commit e233db9db), whose * four defaulted members (`mode`, `preventNavigation`, `openNewTab`, `size`) * materialize on parse — but only on a document that AUTHORED the key, since * the door itself is `.optional()` with no default of its own. So @@ -5065,7 +5065,7 @@ const OBJECT_TIMELINE_FLAT_CONFIG_GUIDANCE: readonly KeySetGuidance[] = [ * other anchor beside it was still a `53ded82bf` reading, in the same file, * with nothing to tell the two apart. Every anchor below is now at this pin.) * - * #17987 executes the objectui#8652 maintainer ruling (verbatim `B`). The + * Commit e233db9db executes the objectui#8652 maintainer ruling (verbatim `B`). The * ruling's carrier is `navigation`, declared below beside its `object-kanban` * and `object-calendar` twins; the ROW is the other half of the same card. * `object-timeline` is a registered renderer reachable only through the type @@ -5223,7 +5223,7 @@ export const ObjectTimelinePropsSchema = lazySchema(() => strictObject({ mapping: z.unknown().optional() .describe("Record-to-entry field mapping ({ title, date, description, variant }) — the objectui-side binding record read BETWEEN the `timeline` block and the flat fallbacks. Its `variant` member (the field whose value picks each marker colour, renderer default `variant`) is the only spelling that binding has"), /** - * Entry-click navigation (#17987 — the spec half of the objectui#8652 + * Entry-click navigation (commit e233db9db — the spec half of the objectui#8652 * maintainer ruling, verbatim `B`), the same carrier and the same def as * `object-kanban`'s and `object-calendar`'s above. Measured at the pin: * `ObjectTimeline.tsx:462-466` hands `(schema as any).navigation` to @@ -5454,7 +5454,7 @@ export const ComponentPropsMap = { 'object-map': ObjectMapPropsSchema, 'object-gantt': ObjectGanttPropsSchema, 'object-tree': ObjectTreePropsSchema, - // #17987, the row half of the objectui#8652 ruling (verbatim `B`). Same + // Commit e233db9db, the row half of the objectui#8652 ruling (verbatim `B`). Same // mechanism as the three rows above, on the LAST object-bound block that had // none: registered in objectui (`plugin-timeline`), reachable through the // type union's open string arm, and with no row here the #5068 gate skipped diff --git a/packages/spec/src/ui/dashboard.zod.ts b/packages/spec/src/ui/dashboard.zod.ts index 6dffeea2a7c..fe3b5b89c10 100644 --- a/packages/spec/src/ui/dashboard.zod.ts +++ b/packages/spec/src/ui/dashboard.zod.ts @@ -683,7 +683,7 @@ export function checkDashboardWidgetMetricMeasureArity( * class-wide, so one spelling is one thing to keep right. * * ⚠️ The version sentence names the **npm release** this ships in, never the - * protocol major (ADR-0087, 「Amended 2026-09-13 (#18003) — the level half」): + * protocol major (ADR-0087, its 2026-09-13 amendment, 「the level half」): * the migration entries below are numbered at protocol 18 while * `@objectstack/spec` is on the 17.x line, and the two differ by construction * while the launch window holds. diff --git a/packages/spec/src/ui/expression-bindable-text-keys.test.ts b/packages/spec/src/ui/expression-bindable-text-keys.test.ts index 1cfbfd21759..a9438307925 100644 --- a/packages/spec/src/ui/expression-bindable-text-keys.test.ts +++ b/packages/spec/src/ui/expression-bindable-text-keys.test.ts @@ -62,7 +62,7 @@ describe('EXPRESSION_BINDABLE_TEXT_KEYS_BY_COMPONENT — measured carriage', () // form/button.tsx reads schema.label — and the row covers that BARE // `button` spelling alone: action/action-button.tsx registers as // `action:button`, a different key this map deliberately does not - // carry (objectstack#13672; see the module docblock). + // carry (commit e854a531a; see the module docblock). expect(EXPRESSION_BINDABLE_TEXT_KEYS_BY_COMPONENT).toEqual({ statistic: ['label', 'value', 'description'], card: ['title', 'description'], @@ -115,8 +115,8 @@ describe('expressionBindableTextKeysFor — the mechanical per-type answer', () // `text` binds through its own `content` leg; `element:*` / `page:*` // config rides the evaluated `properties` bag; and a namespace-prefixed // spelling is a DIFFERENT key from the bare name, so `action:button` and - // `ui:button` answer empty by construction — the pair the objectstack#13672 - // ruling recorded as deliberately out, pinned here so a later prefix- + // `ui:button` answer empty by construction — the pair commit e854a531a + // recorded as deliberately out, pinned here so a later prefix- // stripping "fix" cannot move the machine face in silence. None of them get // rows inferred from what their renderers happen to read. for (const type of [ diff --git a/packages/spec/src/ui/expression-bindable-text-keys.zod.ts b/packages/spec/src/ui/expression-bindable-text-keys.zod.ts index 88ece8d6b7f..f66ade845fa 100644 --- a/packages/spec/src/ui/expression-bindable-text-keys.zod.ts +++ b/packages/spec/src/ui/expression-bindable-text-keys.zod.ts @@ -69,7 +69,7 @@ * spelling for the same slot `content` already evaluates (see `content` NOT a * member, above), not a second read point, so a `text: ['value']` row would * legitimize the fallback spelling and give one slot two declared evaluation - * paths. The objectstack#13670 ruling settled `text`'s intended evaluation + * paths. The ruling that commit 8c6a7fc0b records settled `text`'s intended evaluation * channel as `content` alone and declared `text.value` OUT on those grounds — * this omission is deliberate, not pending measurement. Adding a row is * additive and spec-first; do it here, never as a renderer-side inference. @@ -86,7 +86,7 @@ * `properties` bag and never read these keys at the node's top level. * * `action:button` is therefore deliberately OUT, and `ui:button` with it - * (objectstack#13672); the `button` row above covers the bare `button` + * (commit e854a531a); the `button` row above covers the bare `button` * spelling alone, which is why its citation names `form/button.tsx` only. Two * measured grounds, the same two kinds every other row runs on — zero pull * (the objectui corpus census of 736 JSON documents / 2747 typed nodes finds 5 diff --git a/packages/spec/src/ui/form-select-option.test.ts b/packages/spec/src/ui/form-select-option.test.ts index 9785e3656c6..932e0ff7ea7 100644 --- a/packages/spec/src/ui/form-select-option.test.ts +++ b/packages/spec/src/ui/form-select-option.test.ts @@ -1,7 +1,7 @@ // Copyright (c) 2026 ObjectStack. Licensed under the Apache-2.0 license. /** - * [#12868] The per-option `default` key is narrowed OUT of the form-view + * [commit c459da6bc] The per-option `default` key is narrowed OUT of the form-view * options vocabulary — and ONLY there (maintainer-ruled disposition 甲, * 2026-08-28, on the objectui#6263 analysis). * diff --git a/packages/spec/src/ui/index.ts b/packages/spec/src/ui/index.ts index affc3886843..ab66dc592c1 100644 --- a/packages/spec/src/ui/index.ts +++ b/packages/spec/src/ui/index.ts @@ -48,7 +48,7 @@ export * from './widget.zod'; export * from './component.zod'; export * from './component-type-vocabulary'; export * from './react-blocks'; -// `theme.zod.ts` was RETIRED WHOLE at #10485 (ADR-0049 enforce-or-remove; +// `theme.zod.ts` was RETIRED WHOLE by commit 35ad101bc (ADR-0049 enforce-or-remove; // maintainer ruling 2026-08-21: 退役授权面 — `app.branding` is the one colour // surface; objectui's ThemeEngine/ThemeContext and their unit tests are // retained). `ThemeSchema`, its sub-blocks (`ColorPaletteSchema`, @@ -102,7 +102,7 @@ export * from './expression-bindable-text-keys.zod'; // [#12414] entry-nameability: factory return types expand to mention // `/data`'s `FilterCondition`, which `/ui` does not re-export. Same invariant -// (maintainer ruling recorded on #11350), same repair: re-export from the +// (maintainer ruling 2026-08-23, recorded in commit ece4dad31), same repair: re-export from the // declaring module. export type { FilterCondition } from '../data/filter.zod'; // [#14556] entry-nameability, the same shape one module over: the compiled diff --git a/packages/spec/src/ui/interaction-config-retirement.test.ts b/packages/spec/src/ui/interaction-config-retirement.test.ts index e68cce7792d..977dc72021f 100644 --- a/packages/spec/src/ui/interaction-config-retirement.test.ts +++ b/packages/spec/src/ui/interaction-config-retirement.test.ts @@ -113,7 +113,7 @@ describe('[#4988] ui/ interaction config family retirement', () => { * - `NotificationTypeSchema` — `ui/notification.zod.ts` kept its presentation * enums when PR #5300 retired `NotificationActionSchema` out of it. * - `SharingConfigSchema` — `ui/sharing.zod.ts`'s live door. - * - (`ThemeSchema` stood here until #10485 retired the theme surface whole, + * - (`ThemeSchema` stood here until commit 35ad101bc retired the theme surface whole, * ADR-0049 — a survivor list entry follows its subject out.) * - `PageSchema` / `PageComponentSchema` — the authoring roots the five * vocabularies would have hung off had they ever had a carrier. diff --git a/packages/spec/src/ui/react-blocks.test.ts b/packages/spec/src/ui/react-blocks.test.ts index 22ed942e481..db7ede8aab3 100644 --- a/packages/spec/src/ui/react-blocks.test.ts +++ b/packages/spec/src/ui/react-blocks.test.ts @@ -136,7 +136,7 @@ describe('REACT_BLOCKS — the record:* family is out (#4413)', () => { }); /** - * #11284 — the react tier converges on the metadata-tier vocabulary, + * Commit 5383fa670 — the react tier converges on the metadata-tier vocabulary, * deprecate-first (maintainer ruling 2026-08-23, recorded on-card): the * canonical spellings were declared and the old ones kept as deprecated * aliases. #14791 (maintainer ruling 2026-09-07) is the removal card: the diff --git a/packages/spec/src/ui/react-blocks.ts b/packages/spec/src/ui/react-blocks.ts index b8883033de7..3db542897a4 100644 --- a/packages/spec/src/ui/react-blocks.ts +++ b/packages/spec/src/ui/react-blocks.ts @@ -36,7 +36,7 @@ export interface ReactInteractionProp { required?: boolean; description: string; /** - * Deprecate-first retirement of a react-tier spelling (#11284, maintainer + * Deprecate-first retirement of a react-tier spelling (commit 5383fa670, maintainer * ruling 2026-08-23): the react tier converges on the metadata-tier * vocabulary. A deprecated prop stays published and accepted for the whole * deprecation window — removal is a later card, never a side effect here, and @@ -91,7 +91,7 @@ export const REACT_OVERLAY_SHADOWS: Readonly> /** * Overlay props RETIRED from a block, per tag — the react-tier twin of * `retiredKey()` on a metadata schema (#14791, maintainer ruling 2026-09-07: - * the #11284 aliases go with no deprecation window). The spelling is gone + * the aliases commit 5383fa670 deprecated go with no deprecation window). The spelling is gone * from {@link REACT_BLOCKS}, so the generated contract no longer publishes it; * this ledger is what lets `validate-react-page-props` refuse it BY NAME, with * the prescription, instead of passing it as an unknown prop the renderer may @@ -106,7 +106,7 @@ export const REACT_RETIRED_OVERLAY_PROPS: Readonly< Record>> > = { ListView: { - // #11284 published these as deprecated aliases of ListViewSchema's own + // Commit 5383fa670 published these as deprecated aliases of ListViewSchema's own // `data` / `type`; #14791 retires them outright, the consumer fold having // landed (objectui `normalizeListViewSchema`, console pin a472b071). objectName: { @@ -292,7 +292,7 @@ export const REACT_BLOCKS: ReactBlockDef[] = [ schemaType: 'list-view', summary: "Server-connected object table with toolbar and switchable visualizations (grid/kanban/calendar/gantt/…). Config props come from the spec ListView schema. Bind the object with the metadata-tier data source — data={{ provider: 'object', object: '…' }} — and pick the visualization with `type`: the same two keys a metadata list view authors, and the only spellings (the `objectName` / `viewType` aliases are retired).", schema: ListViewSchema, - // #11284 (maintainer ruling 2026-08-23): the react tier converges on the + // Commit 5383fa670 (maintainer ruling 2026-08-23): the react tier converges on the // metadata-tier vocabulary — `type` and `data` are ListViewSchema's own // props (objectui#2890 A6). #14791 (maintainer ruling 2026-09-07) retired // the overlay aliases `objectName` / `viewType` with no window once the diff --git a/packages/spec/src/ui/view-form-features-root.test.ts b/packages/spec/src/ui/view-form-features-root.test.ts index c83d0752eea..e59de96b9e7 100644 --- a/packages/spec/src/ui/view-form-features-root.test.ts +++ b/packages/spec/src/ui/view-form-features-root.test.ts @@ -67,7 +67,7 @@ function expectFeaturesRefusal( expect(issue!.message).toContain('Form-view predicates may not name the `features.*` scope root'); expect(issue!.message).toContain('ruled 2026-08-27'); // The negative twin of the citation pin: the ruling is cited by DATE, never - // by a tracker id a refused author cannot resolve (#13156's strip). + // by a tracker id a refused author cannot resolve (commit fd289be45's strip). expect(issue!.message).not.toMatch(/(? { diff --git a/packages/spec/src/ui/view-submit-redirect-url.test.ts b/packages/spec/src/ui/view-submit-redirect-url.test.ts index db4f871de9c..f856aa7a307 100644 --- a/packages/spec/src/ui/view-submit-redirect-url.test.ts +++ b/packages/spec/src/ui/view-submit-redirect-url.test.ts @@ -107,7 +107,7 @@ describe('#7496 bullet 1 — relative paths only', () => { expect(msg, 'names the reason the rule exists').toContain('open'); expect(msg, 'cites the ruling so the refusal is traceable').toContain('ruled 2026-08-11'); // The negative twin: traceable by DATE, never by a tracker id a refused - // author cannot resolve (#13156's strip). + // author cannot resolve (commit fd289be45's strip). expect(msg).not.toMatch(/(? strictObject({ surface: 'this list view', history: VIEW_HISTORY, guidance: { - // [#9933] Runtime-only overlay key, deliberately NOT declared here: this + // [commit d5552ca13] Runtime-only overlay key, deliberately NOT declared here: this // is the AUTHORING shape, and column order/widths are per-user state the // console grid writes through the `view` metadata API (objectui's // `gridNonAuthorKeys` disposition). The overlay-validation face declares @@ -2935,7 +2935,7 @@ export const ListViewSchema = lazySchema(() => .superRefine(checkListViewCalendarVisualization)); /** - * [#12868] Form-view select option — {@link SelectOptionSchema} minus the + * [commit c459da6bc] Form-view select option — {@link SelectOptionSchema} minus the * per-option `default` key (maintainer-ruled narrowing, 2026-08-28, on the * objectui#6263 analysis; disposition 甲). * @@ -2963,7 +2963,7 @@ export const ListViewSchema = lazySchema(() => * alias row must name a key the shape accepts (`alias-integrity.test.ts`) and * suggesting a key the schema refuses is the `triggerPhrases` failure shape * `shared/strict-object.ts` documents. The census that gates this narrowing - * (issue #12868, part of the ruling) measured ZERO occurrences of + * (recorded in commit c459da6bc, part of the ruling) measured ZERO occurrences of * `default`/`isDefault`/`selected` inside form-view options across this tree, * the example apps and the published `*.form.ts` corpus, with the instrument's * positive control hitting the 40+ enforced object-field usages. @@ -3176,7 +3176,7 @@ const FormFieldBaseSchema = lazySchema(() => { /** * Select/multiselect options — only needed when type=select/multiselect/radio/checkboxes. * - * [#12868] `FormSelectOptionSchema`, not `SelectOptionSchema`: the form-view + * [commit c459da6bc] `FormSelectOptionSchema`, not `SelectOptionSchema`: the form-view * face refuses the per-option `default` key the object-field face enforces — * see the narrowed schema's docblock for the ruling and the census. * @@ -3631,7 +3631,7 @@ export const FormSectionSchema = lazySchema(() => strictObject({ * runtime forms, `data` in metadata-editing forms. * * ## `current_user` DOES bind here — client-side, and only under a host that - * publishes a scope (objectui#6110 + #6111) + * publishes a scope (objectui#6110 + objectui#6111) * * This block said "no `current_user` at section level" (#6146) for as long as * that held, and it held for TWO reasons, both since discharged. The console @@ -4835,7 +4835,7 @@ export function defineView(config: z.input): ViewParsed { * recovered from the prefix, so the registry key never collides across objects. * * The dot-REQUIRED arity of the platform's one item-name grammar - * (`QUALIFIED_ITEM_NAME_PATTERN`, `shared/identifiers.zod.ts` — #12194): same + * (`QUALIFIED_ITEM_NAME_PATTERN`, `shared/identifiers.zod.ts` — commit 311433f6b): same * segment source as `MetadataItemNameSchema`, which the metadata publish door * enforces with the qualifier optional. Grammar changes belong there, not here. */ @@ -5057,7 +5057,7 @@ type ViewItemWireArmShape = { }; /** - * [#9933] The per-user column layout the console's grid persists through the + * [commit d5552ca13] The per-user column layout the console's grid persists through the * `view` metadata door — an **explicitly runtime-only overlay key**, admitted * where overlays are validated and deliberately NOT authorable. * @@ -5083,7 +5083,7 @@ type ViewItemWireArmShape = { * protocol def / authorable-surface entries, and declaring it on the * authoring shape would bless hand-authoring a payload the product writes * on the user's behalf. Author-writability is a DIFFERENT spec change, - * explicitly out of #9933's scope; the authoring doors keep rejecting the + * explicitly out of commit d5552ca13's scope; the authoring doors keep rejecting the * key by name (see `VIEW_ITEM_SURFACE.guidance` and `ListViewSchema`'s * `guidance`). * @@ -5115,7 +5115,7 @@ const VIEW_ITEM_SURFACE = { // instead of leaving them to guess. isPinned: 'Pinning is per-user Studio state, not authored metadata — the console writes it through the `view` metadata API. Remove it from authored metadata.', sortOrder: 'Switcher position is per-user Studio state, not authored metadata — use `order` for the authored default. Remove it from authored metadata.', - // [#9933] Runtime-only overlay key — same disposition as the two above. + // [commit d5552ca13] Runtime-only overlay key — same disposition as the two above. columnState: 'Column order/widths are per-user runtime personalization the console grid writes through the `view` metadata API — not authored metadata. Remove it from authored metadata.', // [#20456] Declared on the wire members with the switcher's other row // state; named here so an author who reaches for it as access control is @@ -5510,7 +5510,7 @@ function flattenedViewOverlayFields(kind: K) { + 'personalization PUTs.', ), label: I18nLabelSchema.optional().describe('Display label (inherited from the shadowed entry —).'), - // [#9933] Runtime-only overlay key — declared HERE (the overlay-validation + // [commit d5552ca13] Runtime-only overlay key — declared HERE (the overlay-validation // face) and on `viewItemWireFields()`, never on an authoring shape. This is // what lets a `columnState`-only personalization patch through the // identity precondition (the vocabulary is derived from the members' keys) @@ -7084,7 +7084,7 @@ export type FormViewParsed = z.infer; export type FormSection = z.input; /** Post-parse shape of {@link FormSection} — defaults applied, transforms run (ADR-0122). */ export type FormSectionParsed = z.infer; -/** Authoring shape of {@link FormSelectOptionSchema} — the object-field option minus `default` (#12868). */ +/** Authoring shape of {@link FormSelectOptionSchema} — the object-field option minus `default` (commit c459da6bc). */ export type FormSelectOption = z.input; /** Post-parse shape of {@link FormSelectOption} — defaults applied, transforms run (ADR-0122). */ export type FormSelectOptionParsed = z.infer; diff --git a/packages/spec/src/ui/widget-i18n-retirement.test.ts b/packages/spec/src/ui/widget-i18n-retirement.test.ts index 3f17653d6f7..10aa834ab38 100644 --- a/packages/spec/src/ui/widget-i18n-retirement.test.ts +++ b/packages/spec/src/ui/widget-i18n-retirement.test.ts @@ -109,7 +109,7 @@ describe('[#5055] ui/ widget + i18n family retirement', () => { // layout surface whole — a survivor list entry follows its subject out.) 'NotificationTypeSchema', 'SharingConfigSchema', - // (`ThemeSchema` stood here until #10485 retired the theme surface whole.) + // (`ThemeSchema` stood here until commit 35ad101bc retired the theme surface whole.) 'PageSchema', 'PageComponentSchema', ] as const; From 83e39641d07b01898700187ef7f6ab0dada61365 Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 29 Sep 2026 03:14:38 +0000 Subject: [PATCH 2/3] chore(changeset): patch for the re-anchored ui/ provenance comments Claude-Session: https://claude.ai/code/session_014EJ1ED8X4MMrT18BhVx4tx Co-authored-by: Claude --- .changeset/spec-ui-provenance-anchors.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 .changeset/spec-ui-provenance-anchors.md diff --git a/.changeset/spec-ui-provenance-anchors.md b/.changeset/spec-ui-provenance-anchors.md new file mode 100644 index 00000000000..481d7837223 --- /dev/null +++ b/.changeset/spec-ui-provenance-anchors.md @@ -0,0 +1,14 @@ +--- +'@objectstack/spec': patch +--- + +Provenance comments in `ui/` were re-anchored + +Comment and docblock lines under `src/ui/`, and in +`src/data/filter-subtree-provenance.ts` and +`src/meta-spelling/manifest-collection-spelling.ts`, that cited tracker numbers +which no longer resolve on GitHub now cite the commit in this repository's +history that decided the matter, or the ADR amendment they quote, and say in +their own words what was decided. Two references to objectui numbers now name +objectui on each number. Comments only: no type, schema, export or runtime +behaviour changes. From a78f7f596335b77111b7c70c8f9cb1d5472c8aea Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 29 Sep 2026 03:42:27 +0000 Subject: [PATCH 3/3] docs(references): regenerate expression-bindable-text-keys from the re-anchored docblock Generated by `pnpm --filter @objectstack/spec check:generated --fix`, which proved only this page stale; never hand-edited. Claude-Session: https://claude.ai/code/session_014EJ1ED8X4MMrT18BhVx4tx Co-authored-by: Claude --- content/docs/references/ui/expression-bindable-text-keys.mdx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/content/docs/references/ui/expression-bindable-text-keys.mdx b/content/docs/references/ui/expression-bindable-text-keys.mdx index 03d8c447a36..1cc31b33366 100644 --- a/content/docs/references/ui/expression-bindable-text-keys.mdx +++ b/content/docs/references/ui/expression-bindable-text-keys.mdx @@ -74,7 +74,7 @@ above, its omission is not merely unmeasured: `value` there is a fallback spelling for the same slot `content` already evaluates (see `content` NOT a member, above), not a second read point, so a `text: ['value']` row would legitimize the fallback spelling and give one slot two declared evaluation -paths. The objectstack#13670 ruling settled `text`'s intended evaluation +paths. The ruling that commit 8c6a7fc0b records settled `text`'s intended evaluation channel as `content` alone and declared `text.value` OUT on those grounds — this omission is deliberate, not pending measurement. Adding a row is additive and spec-first; do it here, never as a renderer-side inference. @@ -91,7 +91,7 @@ rule would in the same motion grant rows to `element:button` and `properties` bag and never read these keys at the node's top level. `action:button` is therefore deliberately OUT, and `ui:button` with it -(objectstack#13672); the `button` row above covers the bare `button` +(commit e854a531a); the `button` row above covers the bare `button` spelling alone, which is why its citation names `form/button.tsx` only. Two measured grounds, the same two kinds every other row runs on — zero pull (the objectui corpus census of 736 JSON documents / 2747 typed nodes finds 5