Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions .changeset/20901-step18-rationale-form-view-subform-columns.md
Original file line number Diff line number Diff line change
@@ -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.
31 changes: 31 additions & 0 deletions packages/spec/src/migrations/registry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
Loading