Skip to content

Commit feba1a9

Browse files
committed
chore(spec): regenerate the migration registry with the two inline grid column D3 entries
Written after merging a main that carries both in-flight registry changes. Claude-Session: https://claude.ai/code/session_01Sfe5YjBLwB9J3y8fvm2xq1 Co-authored-by: Claude <noreply@anthropic.com>
1 parent 72860fc commit feba1a9

1 file changed

Lines changed: 77 additions & 0 deletions

File tree

‎packages/spec/src/migrations/registry.ts‎

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11867,6 +11867,44 @@ const step18: MigrationStep = {
1186711867
+ 'the field left empty is stored with that value — or the author has decided the form needs '
1186811868
+ 'no pre-selection and the object field is unchanged.',
1186911869
},
11870+
// #20901 — the form-view carrier of the inline grid column. `subforms[].columns`
11871+
// was `z.array(z.any())` while the other carrier, a relationship field's
11872+
// `inlineColumns`, has been the strict `InlineGridColumnSchema` since #9227; the
11873+
// carrier now REFERENCES that schema, so both carriers are judged by one
11874+
// contract. D3 only, deliberately: the one mechanical respelling the family
11875+
// had (`field` → `name`, conversion `field-column-lists-canonicalized`) is
11876+
// already retired from the load path, and every other refused shape is a
11877+
// judgment only the author can make. A stored view whose column fails is
11878+
// refused with the column schema's own prescription, never stripped.
11879+
{
11880+
id: 'form-view-subform-columns-closed',
11881+
surface: 'view.form.subforms[].columns[] and view.formViews.<key>.subforms[].columns[] — the '
11882+
+ 'form view\'s inline grid columns, which used to accept any value',
11883+
replacement: 'each entry is the strict, name-keyed inline grid column a relationship field\'s '
11884+
+ '`inlineColumns` takes — `{ name, label?, type?, … }`, where `{ name }` alone hydrates the rest '
11885+
+ 'from the child object\'s field. Write `name` where a column said `field` (or `fieldName`, '
11886+
+ '`key`); delete `scale` from a column declaring `type: \'currency\'`; delete any key the '
11887+
+ 'column schema does not declare.',
11888+
reason: 'Both carriers feed the one console grid, which reads only the keys the column schema '
11889+
+ 'declares and keys a column by `name` alone. On the form view the columns were never judged, '
11890+
+ 'so a mis-keyed column published clean and drew a blank grid column, and a key the other '
11891+
+ 'carrier refuses — `scale` on a currency column, under the maintainer\'s ruling of 2026-09-23 '
11892+
+ '(option B, `scale` retired from the currency type) and the remedy ruled on 2026-09-24 '
11893+
+ '(option 乙 — a currency\'s ISO 4217 minor unit decides its display) — published green here. '
11894+
+ 'The carrier now references the column schema, so every rule it holds applies here too, with '
11895+
+ 'its own prescription. NOT mechanically converted: the `field` → `name` respelling this family '
11896+
+ 'had is already retired from the load path, and which column an unknown key or a mixed '
11897+
+ '`field`/`name` entry meant is the author\'s call — a conversion that dropped the key would '
11898+
+ 'accept on every load what the parse now refuses. Population measured at the change, on '
11899+
+ 'origin/main cb4c31dd52: zero authored `subforms` in the repository (the showcase derives its '
11900+
+ 'master-detail grids from the data model instead), against one authored `inlineColumns` block '
11901+
+ 'as the control. Deployed metadata NOT MEASURED.',
11902+
acceptanceCriteria: 'Every view in the stack parses: `objectstack validate` and a view parse report '
11903+
+ 'no issue on a `subforms[].columns[]` path. Every column entry is an object carrying `name`, '
11904+
+ 'no entry carries `field`, `fieldName` or `key`, and no column declaring `type: \'currency\'` '
11905+
+ 'carries `scale`. Each column `name` names a field of the subform\'s `childObject`, and the '
11906+
+ 'master-detail grid renders a value — not a blank cell — in each column for a row that has one.',
11907+
},
1187011908
{
1187111909
id: 'hook-register-undispatched-lifecycle-event-refused',
1187211910
surface:
@@ -12303,6 +12341,45 @@ const step18: MigrationStep = {
1230312341
+ 'that one line deleted and no key added. `number` columns, and columns declaring no `type`, '
1230412342
+ 'keep their `scale`; a column\'s `prefix` is still accepted on a currency column.',
1230512343
},
12344+
// #20901 — the reach of `inline-grid-column-currency-scale-refused`, extended to
12345+
// the column that declares no `type`. The column schema judges only a DECLARED
12346+
// type; an identity-only column takes its type from the child field when the
12347+
// console hydrates it, and the child field is a fact the stack holds. So
12348+
// `defineStack`'s cross-reference check re-parses such a column as the type it
12349+
// renders as and reports the column schema's own refusal — no second scale
12350+
// rule. D3 only, for the reason the declared-type entry gives: a conversion
12351+
// that dropped the key would accept it on every load, the grace window the
12352+
// ruling refused.
12353+
{
12354+
id: 'inline-grid-column-identity-only-currency-scale-refused',
12355+
surface: 'object.fields.<name>.inlineColumns[].scale and view.form.subforms[].columns[].scale '
12356+
+ '(and each formViews entry) on a column that declares NO `type` and whose `name` is a '
12357+
+ '`currency` field of the child object — any value, `scale: 0` included. A column declaring '
12358+
+ '`type: \'number\'`, and a column over a field of any other type, keep `scale`',
12359+
replacement: 'no `scale` on the column. DELETE the key — that is the whole migration: the column '
12360+
+ 'renders as a currency column, and a currency amount\'s decimal places are its currency\'s. '
12361+
+ 'The currency\'s ISO 4217 minor unit decides how the cell displays the amount and the width a '
12362+
+ 'computed amount is rounded to. ⛔ Nothing replaces the key: do not re-declare its value under '
12363+
+ 'any other key, and do not add `type: \'number\'` to keep it on a currency amount.',
12364+
reason: 'The refusal of `scale` on a currency inline grid column (entry '
12365+
+ '`inline-grid-column-currency-scale-refused`, under the maintainer\'s rulings of 2026-09-23, '
12366+
+ 'option B, and 2026-09-24, option 乙) reached only a column that DECLARES `type: \'currency\'`, '
12367+
+ 'because the column schema cannot see the child field. An identity-only column — the '
12368+
+ 'recommended form — over a currency field renders as a currency column all the same, so it '
12369+
+ 'published green carrying the refused key, and the console ignored it. `defineStack`\'s '
12370+
+ 'cross-reference check, which holds the child object\'s fields, now judges such a column as the '
12371+
+ 'type it renders as and refuses it with the column schema\'s own message. Reach: the child '
12372+
+ 'object must be declared in the same stack; a column naming no field of it, or a subform whose '
12373+
+ 'child object comes from another package, is not judged there. Population measured at the '
12374+
+ 'change, on origin/main cb4c31dd52: one authored `inlineColumns` block (the showcase invoice, '
12375+
+ 'seven identity-only columns, none carrying `scale`) and zero authored `subforms`. Deployed '
12376+
+ 'metadata NOT MEASURED.',
12377+
acceptanceCriteria: '`objectstack validate` and `defineStack` report no cross-reference finding on '
12378+
+ 'an `inlineColumns[].scale` or `subforms[].columns[].scale` path. A column that carried `scale` '
12379+
+ 'over a currency child field no longer declares it, and a diff of the column shows that one line '
12380+
+ 'deleted and no key added. Columns over `number` fields, and columns declaring `type: '
12381+
+ '\'number\'`, keep their `scale`.',
12382+
},
1230612383
// #14478 (maintainer ruling B: a duration key carries its unit in its NAME) —
1230712384
// the D3 entry of the `job-timeout-to-timeout-ms` family (ruling B on #17152:
1230812385
// one D3 entry per retirement family, even when D2 is lossless). The job half

0 commit comments

Comments
 (0)