From 51fcedaa0b2973e780dcd6cebcc65622f43356ab Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 1 Oct 2026 04:49:39 +0000 Subject: [PATCH] fix(spec): step 18's rationale gains the form-view-subform-columns-closed fragment One STEP18_RATIONALE fragment for the inline grid column family: the form view's subforms[].columns closure, its D2 conversion form-view-subform-columns-canonicalized, and the identity-only currency scale refusal. Inserted where its id sorts, order one above the highest (53 at the base). Plus a patch changeset for @objectstack/spec. Claude-Session: https://claude.ai/code/session_01Sfe5YjBLwB9J3y8fvm2xq1 Co-authored-by: Claude --- ...p18-rationale-form-view-subform-columns.md | 10 ++++++ packages/spec/src/migrations/registry.ts | 31 +++++++++++++++++++ 2 files changed, 41 insertions(+) create mode 100644 .changeset/20901-step18-rationale-form-view-subform-columns.md diff --git a/.changeset/20901-step18-rationale-form-view-subform-columns.md b/.changeset/20901-step18-rationale-form-view-subform-columns.md new file mode 100644 index 00000000000..fe1eeab3164 --- /dev/null +++ b/.changeset/20901-step18-rationale-form-view-subform-columns.md @@ -0,0 +1,10 @@ +--- +'@objectstack/spec': patch +--- + +fix(spec): protocol 18's migration rationale now covers the form view's inline grid columns and the identity-only currency `scale` refusal (#20901) + +**`@objectstack/spec`** + +- **`MIGRATIONS_BY_MAJOR[18].rationale` gains one fragment, `form-view-subform-columns-closed`.** It is the paragraph `os migrate meta --step` shows for the protocol 17 β†’ 18 hop. The new sentences say that a form view's `subforms[].columns` now takes the strict `InlineGridColumnSchema` a relationship field's `inlineColumns` takes, that the conversion `form-view-subform-columns-canonicalized` respells a `{ field }` column as `{ name }` in stored rows and assembled artifacts while an author writing `field` is refused, and that `defineStack` refuses `scale` on a column that declares no `type` when its `name` is a `currency` field of a child object declared in the same stack (`inline-grid-column-identity-only-currency-scale-refused`). +- Text only: no schema, conversion or migration entry changes, and `conversionIds` and `semantic` for step 18 are unchanged. diff --git a/packages/spec/src/migrations/registry.ts b/packages/spec/src/migrations/registry.ts index e186e8ef657..dda2626a17d 100644 --- a/packages/spec/src/migrations/registry.ts +++ b/packages/spec/src/migrations/registry.ts @@ -5504,6 +5504,37 @@ const STEP18_RATIONALE: readonly RationaleFragment[] = [ + 'the key with the prescription; the mechanical conversion strips it from stored ' + 'sources (pure lossless delete β€” it never had an effect on this surface to lose).', }, + { + id: 'form-view-subform-columns-closed', + order: 54, + text: + 'It also closes the form view\'s inline grid columns: `subforms[].columns`, on `view.form` ' + + 'and on `formViews` entries, was `z.array(z.any())` while a relationship field\'s ' + + '`inlineColumns` was already the strict `InlineGridColumnSchema`, so a mis-keyed column ' + + 'published clean and drew a blank grid column, and `scale` on a currency column, which the ' + + 'other carrier refuses under the maintainer\'s rulings of 2026-09-23 (option B) and ' + + '2026-09-24 (option δΉ™), published green. The carrier now references that schema, so both ' + + 'carriers are judged by it, with its own prescriptions. The D2 conversion ' + + '`form-view-subform-columns-canonicalized` respells a `{ field }` column as `{ name }`, the ' + + 'respelling `field-column-lists-canonicalized` makes on `inlineColumns`: it rewrites stored ' + + 'rows and assembled artifacts and lists the edit under `os migrate meta`, and it is retired ' + + 'from the load path, so an author writing `field` meets the refusal. A view saved with a ' + + 'failing column is refused with the column schema\'s prescription, and a stored row carrying ' + + 'one is diagnosed at rehydration; neither is stripped, because which column an unknown key ' + + 'or a mixed `field`/`name` entry meant is the author\'s call, and a conversion that dropped ' + + 'the key would accept at load what the parse now refuses. Its D3 record is the semantic ' + + 'entry `form-view-subform-columns-closed`. On both carriers, the reach of ' + + '`inline-grid-column-currency-scale-refused` extends to a column that declares no `type`: ' + + 'such a column takes its type from the child field, which the column schema cannot see, ' + + 'when the console hydrates it, so `defineStack`\'s cross-reference check re-parses a column ' + + 'whose `name` is a `currency` field of the child object as the type it renders as, and the ' + + 'refusal of its `scale` is the column schema\'s own. Reach: the child object must be ' + + 'declared in the same stack; a column naming no field of it, or a subform whose child ' + + 'object comes from another package, is not judged there. It has no D2 conversion, for the ' + + 'declared-type entry\'s reason: deleting the key is the migration, and a conversion that ' + + 'dropped it would accept it at load, the grace window ruling B refused. Its D3 record is ' + + 'the semantic entry `inline-grid-column-identity-only-currency-scale-refused`.', + }, { id: 'list-view-page-mount-retired', order: 27,