diff --git a/.changeset/10321-named-view-kanban-groupby-refused.md b/.changeset/10321-named-view-kanban-groupby-refused.md index 05e53f0c5c..a3912a9677 100644 --- a/.changeset/10321-named-view-kanban-groupby-refused.md +++ b/.changeset/10321-named-view-kanban-groupby-refused.md @@ -21,6 +21,18 @@ bag. The issue is `custom` at `listViews.KEY.kanban.groupBy` or `groupBy`. Did you mean `groupBy` → `groupByField`?", followed by the same explanation. Write `groupByField` (or the deprecated `groupField`). +⚠️ **Dated note, 2026-09-28 — `listViews` has since been mirrored, and the +`options.kanban` bag is refused whole — objectui#7928.** Later in this same release +`ObjectViewSchema.listViews` became the protocol's strict `ObjectListViewSchema` record, +by reference, so "`ObjectViewSchema.listViews` is unmirrored" above no longer holds. The +protocol now refuses `listViews.KEY.kanban.groupBy` itself (`unrecognized_keys` at +`listViews.KEY.kanban`), and this check still adds its `custom` issue at +`listViews.KEY.kanban.groupBy`, with the same message. It no longer judges the legacy +bag: the record refuses a named view's `options` whole (`unrecognized_keys` at +`listViews.KEY`, naming `options`), so nothing reports +`listViews.KEY.options.kanban.groupBy`. `.changeset/7928-listviews-by-reference-fold.md` +(PR objectui#10821) states what ships; the text above is kept as the reading of this change. + The protocol agrees on this route too. Measured on `@objectstack/spec` 17.4.0 when this change was made, `ViewSchema` refuses `listViews.KEY.kanban.groupBy` as an unrecognized key exactly as `ListViewSchema` refuses `kanban.groupBy`, @@ -43,3 +55,16 @@ an undeclared sibling in the kanban block nor the legacy `options` bag itself; the value type `listViews` should enforce is objectui#7928's. `groupBy` is not honoured as an alias (the ruling rules that out), and `groupBy` on the generated `object-kanban` node, the lane key `ObjectKanban` reads, is untouched. + +⚠️ **Dated note, 2026-09-28 — what a written key now reports, and what the record now +refuses — objectui#7928.** Later in this same release the named-view record became the +protocol's own, by reference. A `groupBy` in a named view's `kanban` block now reports +two issues, the protocol's `unrecognized_keys` and this entry's pointer; one in the +`options.kanban` bag reports only the refusal of `options`, which names neither `groupBy` +nor `groupByField`. So "one issue per written key, naming the key and the replacement" +no longer holds. `ObjectViewSchema` now declares the value type the paragraph above +defers to objectui#7928: `listViews` is in its shape, a named view needs `columns`, and +the record refuses an undeclared sibling in the kanban block and the `options` bag. This +entry's check now adds its message to a document the record already refuses. +`.changeset/7928-listviews-by-reference-fold.md` (PR objectui#10821) states what ships; +the text above is kept as the reading of this change. diff --git a/.changeset/10584-object-chart-series-describe.md b/.changeset/10584-object-chart-series-describe.md index b3c3e1e135..0558616f1b 100644 --- a/.changeset/10584-object-chart-series-describe.md +++ b/.changeset/10584-object-chart-series-describe.md @@ -15,5 +15,16 @@ The TypeScript docblock on the same member now says the omission is deliberate rather than a lag: taking `type` up would widen a published accept set, and that waits for a named producer that writes it on an `object-chart` node. +⚠️ **Dated note, 2026-09-28 — `series` has since become two arms — objectui#10770.** Later +in this same release each `ObjectChartSchema.series` entry became ONE of two arms, on +both faces: the spec's `ChartSeriesSchema` (`{ name }`, by reference, the AUTHOR arm) or +the internal `{ dataKey }` arm. The `.describe()` and the docblock now describe both. So +"the copy is that `{ dataKey }` arm minus its per-series `type`" holds for the internal +arm only, and `chartType` is the per-series family override on that arm only: on a +`{ name }` entry the override is the spec's `type`, which an `object-chart` node now +accepts. The deliberate omission of `type` stands on the `{ dataKey }` arm, where the +zod mirror still strips it. `.changeset/10770-object-chart-react-tier-node.md` (PR +objectui#10802) states what ships; the text above is kept as the reading of this change. + Wording only. The accepted shape does not move on either face: the element type, its members and the mirror's parse result are what they were. diff --git a/.changeset/7924-named-list-view-retire.md b/.changeset/7924-named-list-view-retire.md index 0de0b5ec35..0b01166bc4 100644 --- a/.changeset/7924-named-list-view-retire.md +++ b/.changeset/7924-named-list-view-retire.md @@ -7,6 +7,16 @@ sixteen members on its TypeScript authoring face (objectui#7924). Each is now a `?: never` tombstone: a TypeScript author who writes one gets a compile error at that key, and the member's docblock names the key to write instead. +⚠️ **Dated note, 2026-09-28 — `NamedListView` no longer types a named view — +objectui#7928.** Later in this same release `ObjectViewSchema.listViews` became the +protocol's own record by reference: on both faces its value is `@objectstack/spec`'s +strict `ObjectListViewSchema`, and a `NamedListView` is not assignable to it. So "one +entry of `ObjectViewSchema.listViews`" above no longer holds. `NamedListView` stays +exported with the tombstones this entry describes; a retired spelling written in a +named view is refused there by the protocol's record as an unrecognized key, not by a +tombstone here and its pointer. `.changeset/7928-listviews-by-reference-fold.md` (PR +objectui#10821) states what ships; the text above is kept as the reading of this change. + **The eight legacy `show*` spellings** (bucket ② of the director-seat ruling on objectui#7924, letter **A**). None is a protocol key on a view; the protocol's `userActions` and `appearance` blocks are the canonical home, and `NamedListView` @@ -43,6 +53,14 @@ row-colour configuration `rowColor: { field }`, and `addRecordViaForm` at the `densityMode` is folded onto `rowHeight` by `normalizeListViewSchema`. They stay declared as they were. +⚠️ **Dated note, 2026-09-28 — `densityMode` has since been retired too — objectui#7924.** +Later in this same release ruling A′ made `NamedListView.densityMode` a `?: never` +tombstone as well, its docblock pointing at top-level `rowHeight`. So "Two bucket-③ +members are NOT retired" and "They stay declared as they were" now hold for +`allowExport` only. `normalizeListViewSchema` still folds a stored `densityMode` onto +`rowHeight`. `.changeset/7924-density-mode-through-fold.md` (PR objectui#10793) states +what ships; the text above is kept as the reading of this change. + **Only the authoring face changes.** Stored view documents that still carry a legacy spelling keep loading: `normalizeListViewSchema` (`@object-ui/core`) still folds the eight `show*` flags onto `userActions` / `appearance` at runtime, and hosts that read a stored diff --git a/.changeset/8355-retire-calendar-date-aliases.md b/.changeset/8355-retire-calendar-date-aliases.md index 93c884bd83..3f665b7959 100644 --- a/.changeset/8355-retire-calendar-date-aliases.md +++ b/.changeset/8355-retire-calendar-date-aliases.md @@ -84,6 +84,20 @@ to `SchemaRenderer` never parses the mirror at all — `SchemaRenderer` runs the structural core validator, which is dev-only and names no key — so the compiler is that population's channel, not this one. +⚠️ **Dated note, 2026-09-28 — a named view's `options.calendar` nesting is no longer +judged inside — objectui#7928.** Later in this same release `ObjectViewSchema.listViews` +became the protocol's strict `ObjectListViewSchema` record, by reference, and that +record refuses a named view's `options` bag whole (`unrecognized_keys` at +`listViews.KEY`, naming `options`). So an alias written under +`listViews.KEY.options.calendar` no longer draws an issue naming the key or the remedy. +The named view's `calendar` block still does: the protocol refuses the alias there as an +unrecognized key, and this entry's check adds the pointer at the key beside it. A stored +body that `@object-ui/app-shell`'s `ViewPreview` relays has its `options.calendar` folded +onto the `calendar` block first (`foldStoredListOptions`). The list view's two nestings +and both `object-calendar` surfaces are unchanged; `calendar-date-alias-refusal-8355.test.ts` +in `@object-ui/types` re-derives each surface. `.changeset/7928-listviews-by-reference-fold.md` +(PR objectui#10821) states what ships; the text above is kept as the reading of this change. + ⚠️ **Why this is `minor` and not `major`.** This repository forbids `major` in a changeset: the fixed release group's major tracks `@objectstack`'s, so any `major` here would push all of it off that cadence @@ -136,6 +150,19 @@ undeclared key nor the legacy `options` bag. It judges exactly the two spellings this entry retires, at the two nestings the producer merges — with pins on each of those non-effects. +⚠️ **Dated note, 2026-09-28 — `listViews` has since been mirrored — objectui#7928.** Later +in this same release the maintainer's ruling A chose the value type this paragraph waits +on: `ObjectViewSchema.listViews` is now `@objectstack/spec`'s own +`ViewSchema.shape.listViews`, a record of the strict `ObjectListViewSchema`, by reference +on both faces. It is in the object's `shape`, a named view needs `columns`, and the +record refuses an undeclared key and the legacy `options` bag whole. The named-view check +described here and in the `@object-ui/types` bullet above now reads the protocol's own +refusal at `listViews.KEY.calendar` and adds the pointer at the key; it no longer walks +the `options.calendar` nesting, so "a named view's two nestings" and "at the two nestings +the producer merges" now hold for the `calendar` block only. +`.changeset/7928-listviews-by-reference-fold.md` (PR objectui#10821) states what ships; +the text above is kept as the reading of this change. + ⛔ **Not a producer-side fold.** Normalising `dateField` to `startDateField` in `ListView` (option A) was put to the director seat and refused as the end state: it keeps a second spelling alive at the producer, which is the lenient alias @@ -184,3 +211,12 @@ structural guard that `listViews` stays out of the object's `shape`), reading the node their producer really emits through a spy registration, which is the only census that can see a key arriving through a spread — and the inverted ledger rows in `calendarUnionReads-8651.test.tsx` (`@object-ui/plugin-calendar`). + +⚠️ **Dated note, 2026-09-28 — a named view now refuses `timeline.dateField`, and the +shape guard is inverted — objectui#7928.** Later in this same release the protocol's +strict named-view record refuses `timeline.dateField` on a named view as an unrecognized +key; the `list-view` route still accepts it, and that route is the one the timeline pin +reads. The structural guard in `calendar-date-alias-refusal-8355.test.ts` now asserts +the opposite of "`listViews` stays out of the object's shape": `listViews` is a member +of `ObjectViewSchema.shape`. `.changeset/7928-listviews-by-reference-fold.md` (PR +objectui#10821) states what ships; the text above is kept as the reading of this change. diff --git a/.changeset/8365-stray-kanban-groupby-refused.md b/.changeset/8365-stray-kanban-groupby-refused.md index df11629078..a179740e9b 100644 --- a/.changeset/8365-stray-kanban-groupby-refused.md +++ b/.changeset/8365-stray-kanban-groupby-refused.md @@ -40,6 +40,19 @@ fallback and was **not** taken): this arm; objectui#10321 gives that route its own door, which refuses the key in either nesting with the same message. +⚠️ **Dated note, 2026-09-28 — a named view's `options.kanban` bag is refused whole — +objectui#7928.** Later in this same release a named view became the protocol's strict +`ObjectListViewSchema` record, by reference, which refuses its `options` bag by name +(`unrecognized_keys` at `listViews.KEY`, naming `options`). So the objectui#10321 door no +longer refuses the key "in either nesting with the same message": it still adds that +message at `listViews.KEY.kanban.groupBy`, beside the protocol's own refusal of the key, +and nothing reports `listViews.KEY.options.kanban.groupBy`. A stored body that +`@object-ui/app-shell`'s `ViewPreview` relays has its `options.kanban` folded onto the +`kanban` block first (`foldStoredListOptions`). The `list-view` route described above is +unchanged, its `options.kanban` check included. +`.changeset/7928-listviews-by-reference-fold.md` (PR objectui#10821) states what ships; +the text above is kept as the reading of this change. + **Breaking, in the sense worth stating explicitly** (shipped `minor`: this repo never declares `major`, and `.changeset/config.json` puts every package in one `fixed` group, so levels cannot be split). Two behaviours change for **stored diff --git a/.changeset/9242-stray-kanban-groupby-lane-second-route.md b/.changeset/9242-stray-kanban-groupby-lane-second-route.md index c5f85d6d7f..5a4204519b 100644 --- a/.changeset/9242-stray-kanban-groupby-lane-second-route.md +++ b/.changeset/9242-stray-kanban-groupby-lane-second-route.md @@ -40,6 +40,18 @@ storage nor one that never passes through a validator, so what this change repairs is a pure **behaviour** gap, on any document that reaches this branch carrying the key. +⚠️ **Dated note, 2026-09-28 — the named-view route's two faces have since changed — +objectui#7928.** Later in this same release a named view became the protocol's strict +`ObjectListViewSchema` record, by reference, on both faces. On the zod face the +objectui#10321 door adds its message at `listViews.KEY.kanban.groupBy` only: the record +refuses the `options` bag whole (`options` by name), so "refuses the key in either +nesting with the same message" no longer holds. On the TypeScript face a named view's +`kanban` is typed as the protocol's kanban block, not the `list-view`'s: `tsc` still +refuses `kanban.groupBy` there, as an excess property on an object literal rather than a +`never` member, and it now refuses the `options` bag itself. The `list-view` route is +unchanged on both faces. `.changeset/7928-listviews-by-reference-fold.md` (PR +objectui#10821) states what ships; the text above is kept as the reading of this change. + Maintainer ruling of 2026-09-12 (decision batch #117 item 5, verbatim 「8365 同意」) — option B. Option A (strip the key and silently re-group) was not taken. This card applies that ruling to the second route; it re-opens nothing. diff --git a/.changeset/object-view-unmirrored-keys-7779.md b/.changeset/object-view-unmirrored-keys-7779.md index 44221551ed..2c4a8711a0 100644 --- a/.changeset/object-view-unmirrored-keys-7779.md +++ b/.changeset/object-view-unmirrored-keys-7779.md @@ -67,6 +67,24 @@ very thing ruling B refused for the six local keys. The key therefore stays in the parity ledger with that measurement, pinned, until the maintainer decides its value type. It is not papered over with `z.any()`. +⚠️ **Dated note, 2026-09-28 — the value type has since been decided, and `listViews` is +mirrored by reference — objectui#7928.** Later in this same release the maintainer's +ruling A made `ObjectViewSchema.listViews` the protocol's own named-view record, by +reference: on both faces its value is `@objectstack/spec`'s strict `ObjectListViewSchema`, +and a `NamedListView` is not assignable to it. The docs have taught that shape since +objectui#8255. So "`listViews` stays unmirrored", "The declaration's value is the local +`NamedListView`", the key "stays in the parity ledger … until the maintainer decides its +value type" and the table's "still unmirrored" above no longer hold: the +`ObjectViewSchema` entry has left `UnmirroredDeclared`. `NamedListView` stays exported +with its 64 declared members. The renderer reads some of them off a named view and +leaves the rest unread, and the split is no longer the 21 and 43 this entry counted: +objectui#7928 stopped reading the `options` bag, which the record refuses, and +objectui#10758 made the host delegation read a named view's remaining protocol members +off the named view. The census in `object-view-unmirrored-keys-7779.test.ts` pins the +current figures. +`.changeset/7928-listviews-by-reference-fold.md` (PR objectui#10821) states what ships; +the text above is kept as the reading of this change. + **Who is affected:** an author who wrote `viewTabBar` on an `object-view` node (remove it), or who wrote a wrong-typed value for one of the eight keys — e.g. `defaultViewType: 'tree'` (host-composition-only, objectui#5321), diff --git a/.changeset/objectchart-schema-anchor-7946.md b/.changeset/objectchart-schema-anchor-7946.md index 492f89f608..bf9800c5ab 100644 --- a/.changeset/objectchart-schema-anchor-7946.md +++ b/.changeset/objectchart-schema-anchor-7946.md @@ -37,6 +37,18 @@ internal spellings by name). The internal pair is declared anyway, because it wa already passing through unvalidated: declaring buys the value check without minting authorable vocabulary, and each description says which it is. +⚠️ **Dated note, 2026-09-28 — `series` has since gained an AUTHOR arm — objectui#10770.** +Later in this same release each `ObjectChartSchema.series` entry became ONE of two arms, +on both faces: the spec's `ChartSeriesSchema` (TS: `ChartSeries`), by reference, which is +AUTHORABLE (the react tier's `ObjectChart` block publishes it as its `series` prop, and the +react-page wrapper forwards the authored array onto the node), or the unchanged INTERNAL +`{ dataKey }` arm, still typed from `ChartRendererProps`. So "two are INTERNAL, +relay-composed (`xAxisKey`, `series` …)" now holds for `xAxisKey` and for the +`{ dataKey }` arm only, and "except where `@objectstack/spec` already owns the shape, +which is `aggregate`" now takes in the `{ name }` arm of `series` too. The `series` +description names both arms. `.changeset/10770-object-chart-react-tier-node.md` (PR +objectui#10802) states what ships; the text above is kept as the reading of this change. + `filter` keeps BOTH arms (a `FilterArray` or the ObjectQL `$filter` object), and narrowing to one is a decision LOCAL TO THIS NODE rather than a fleet-wide one: the six sibling `object-*` widgets that declare `filter` are already array-only, @@ -76,6 +88,19 @@ change had to absorb: `{ dataKey, … }`; the spec's author-facing `{ name, … }` arm is a different shape, translated by `normalizeChartSchema` one layer down. +⚠️ **Dated note, 2026-09-28 — a `{ name }`-shaped `series` entry is now accepted — +objectui#10770.** Later in this same release `ObjectChartSchema.series` took the spec's +`ChartSeriesSchema` (TS: `ChartSeries`), by reference, as a second arm beside the +`{ dataKey }` one, on both faces. So "`series` entries must be `dataKey`-shaped" no +longer holds, and that narrowing no longer bites: +`series: [{ name: 'total', label: 'Invoice value' }]` compiles and parses. An entry with +neither `name` nor `dataKey` is still refused, and `normalizeChartSchema` is still the one +translation between the arms. +What bites instead is reading: an element of `ObjectChartSchema['series']` is a union, so +a consumer narrows it (for example with `'dataKey' in entry`) before it reads `.dataKey`. +`.changeset/10770-object-chart-react-tier-node.md` (PR objectui#10802) states what ships; +the text above is kept as the reading of this change. + And, from the by-reference `aggregate`: - **`aggregate.function` and `aggregate.groupBy` are REQUIRED**, `aggregate.field` @@ -96,3 +121,13 @@ WRITE, not about what the renderer will tolerate. `BaseSchema` carries `[key: string]: any` (objectui#5155), the same ceiling objectui#6576 accepted. `aggregate` is the exception, and only because the spec's own object is strict. + +⚠️ **Dated note, 2026-09-28 — `aggregate` is no longer the only strict member — +objectui#10770.** Later in this same release a `series` entry on the `{ name }` arm became +the spec's closed `ChartSeriesSchema`, by reference, so on the zod face a misspelled key +in one is refused, while one in a `{ dataKey }` entry is still stripped. So "`aggregate` +is the exception" no longer holds alone. Other changes in this release did the same for +`drillDown` (objectui#8885) and for `xAxis` / `yAxis` (objectui#10518), each a strict spec +object by reference. A misspelled key on the node itself still passes, as above. +`.changeset/10770-object-chart-react-tier-node.md` (PR objectui#10802) states what ships; +the text above is kept as the reading of this change.