From e11ef3a7bd7bab512c3165348e9fdbf91af7d91b Mon Sep 17 00:00:00 2001 From: Claude Date: Sat, 10 Oct 2026 05:46:18 +0000 Subject: [PATCH 1/3] feat(spec): ListView.userActions.editInline defaults to true on the v18 line; editInline: false is the opt-out MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Maintainer ruling 2026-10-10, verbatim: 「乙 v18 把 spec 默认翻成 true,editInline: false 变成关法。」 A list view is editable in place by default under the permission gate that already exists. The declared default of UserActionsConfigSchema.editInline moves false -> true with the describe rewritten; the declared default change is ledgered at major 17 and the D3 semantic entry list-view-edit-inline-default-on is added at protocol 18. Pins: an absent key parses to true, an explicit false stays false, the view-level inlineEdit still parses as before. Claude-Session: https://claude.ai/code/session_01KNKBCRDJCu5tGy3TEbvtrF Co-authored-by: Claude --- packages/spec/scripts/lib/default-changes.ts | 24 ++++++++ .../18.list-view-edit-inline-default-on.ts | 52 +++++++++++++++++ packages/spec/src/ui/view.test.ts | 57 ++++++++++++++++++- packages/spec/src/ui/view.zod.ts | 11 +++- 4 files changed, 142 insertions(+), 2 deletions(-) create mode 100644 packages/spec/src/migrations/entries/semantic/18.list-view-edit-inline-default-on.ts diff --git a/packages/spec/scripts/lib/default-changes.ts b/packages/spec/scripts/lib/default-changes.ts index d5206e12ac3..5f1db428195 100644 --- a/packages/spec/scripts/lib/default-changes.ts +++ b/packages/spec/scripts/lib/default-changes.ts @@ -554,6 +554,30 @@ export const DEFAULT_CHANGES_BY_MAJOR: Readonly { expect(config.rowHeight).toBe(true); expect(config.group).toBe(true); expect(config.addRecordForm).toBe(false); - expect(config.editInline).toBe(false); + expect(config.editInline).toBe(true); expect(config.hideFields).toBe(false); expect(config.rowColor).toBe(false); expect(config.buttons).toBeUndefined(); }); + // Maintainer ruling 2026-10-10 (the v18 line): 「乙 v18 把 spec 默认翻成 true, + // editInline: false 变成关法。」 A list view is editable in place by default, + // under the permission gate that already exists; `editInline: false` is the + // opt-out. The rule of objectui#5144 (one vocabulary, the `inlineEdit` fold, + // declared = enforced) stands — only the default's value moves. + describe('editInline defaults ON (maintainer ruling, protocol 18)', () => { + it('an absent key parses to true', () => { + expect(UserActionsConfigSchema.parse({}).editInline).toBe(true); + const view = ListViewSchema.parse({ + name: 'audit_log', + label: 'Audit Log', + columns: [{ field: 'name' }], + userActions: {}, + }); + expect(view.userActions?.editInline).toBe(true); + }); + + it('an explicit false stays false — the opt-out the ruling names', () => { + expect(UserActionsConfigSchema.parse({ editInline: false }).editInline).toBe(false); + const view = ListViewSchema.parse({ + name: 'audit_log', + label: 'Audit Log', + columns: [{ field: 'name' }], + userActions: { editInline: false }, + }); + expect(view.userActions?.editInline).toBe(false); + }); + + it('an explicit true still parses to true', () => { + expect(UserActionsConfigSchema.parse({ editInline: true }).editInline).toBe(true); + }); + + // The fold (`inlineEdit` → `userActions.editInline`, an explicit `editInline` + // winning) lives in the renderer, not here: the spec keeps both spellings + // as declared, so this pins the inputs the fold reads are unchanged — the + // view-level `inlineEdit` is still optional with no default of its own, and + // it does not materialise a `userActions` block. + it('the view-level `inlineEdit: true` still parses as before, beside the new default', () => { + const view = ListViewSchema.parse({ + name: 'tasks', + label: 'Tasks', + columns: [{ field: 'name' }], + inlineEdit: true, + }); + expect(view.inlineEdit).toBe(true); + expect(view.userActions).toBeUndefined(); + const silent = ListViewSchema.parse({ + name: 'tasks', + label: 'Tasks', + columns: [{ field: 'name' }], + }); + expect(silent.inlineEdit).toBeUndefined(); + }); + }); + // The split is copied from the renderer's reads, not chosen by the spec // (ruled A on objectui#5435): ListView.tsx computes `showGroup` as // `ua?.group !== false` (absent ⇒ shown) but `showHideFields` / `showColor` diff --git a/packages/spec/src/ui/view.zod.ts b/packages/spec/src/ui/view.zod.ts index 3b9089e2b5f..6979ade6158 100644 --- a/packages/spec/src/ui/view.zod.ts +++ b/packages/spec/src/ui/view.zod.ts @@ -1512,6 +1512,15 @@ export const VisualizationTypeSchema = lazySchema(() => z.enum([ * other core toolbar controls, while `hideFields` / `rowColor` default OFF * (`=== true`) — column hiding and row colouring are opt-in affordances. * + * `editInline` defaults ON by maintainer ruling (2026-10-10, the v18 line: + * 「乙 v18 把 spec 默认翻成 true,editInline: false 变成关法。」): a list view + * is editable in place by default under the permission gate that already + * exists, and `editInline: false` is the opt-out. The renderer reads an absent + * key as this default; a boolean `inlineEdit` on the view folds into it, and + * an explicit `editInline` wins (objectui#5144's one-vocabulary rule, whose + * default value this flip changes and whose fold it leaves alone). D3 entry: + * `list-view-edit-inline-default-on` (protocol 18). + * * Name-collision note (same key NAME, different shape, on OTHER surfaces — * deliberate, each toggle is named after the config it gates): these three are * booleans HERE, while `rowColor` on the list view itself is a @@ -1532,7 +1541,7 @@ export const UserActionsConfigSchema = lazySchema(() => strictObject({ rowHeight: z.boolean().default(true).describe('Allow users to toggle row height/density'), group: z.boolean().default(true).describe('Allow users to change record grouping from the toolbar. Toggle only — the grouping itself is configured in the view-level `grouping` block.'), addRecordForm: z.boolean().default(false).describe('Add records through a form instead of inline'), - editInline: z.boolean().default(false).describe('Allow users to edit records inline — click a cell to edit it with the field\'s type-aware widget (the same control the form uses). Off by default: the list is read-only unless the author opts in.'), + editInline: z.boolean().default(true).describe('Allow users to edit records inline. On by default: a user who may update the object edits a cell in place with the field\'s type-aware widget (the same control the form uses), under the permission gate that already decides whether the object is editable at all. Declare `editInline: false` to make the list read-only in place.'), hideFields: z.boolean().default(false).describe('Allow users to hide/show fields from the toolbar (the affordance behind the view-level `hiddenFields` list). Boolean toggle — distinct from the record-details component\'s `hideFields`, which is an array of field names to omit. Off by default: column hiding is opt-in.'), rowColor: z.boolean().default(false).describe('Allow users to configure row colouring from the toolbar. Boolean toggle — the colour rules themselves live in the view-level `rowColor` block. Off by default: row colouring is opt-in.'), buttons: z.array(z.string()).optional().describe('Custom action button IDs to show in the toolbar'), From 4974a6ecc4cebda312890115e115fc035d2b6202 Mon Sep 17 00:00:00 2001 From: Claude Date: Sat, 10 Oct 2026 05:55:31 +0000 Subject: [PATCH 2/3] chore(spec): regenerate the registry, defaults ledger and reference pages for the editInline default; add the changeset gen:migration-registry concatenates the D3 entry into registry.ts; the spec build moved ui/UserActionsConfig:editInline to true in authorable-defaults/ui.json under the declared chain; gen:docs rewrote the four editInline rows in references/ui/view.mdx and page.mdx. spec-changes.json and docs/protocol-upgrade-guide.md are not regenerated here: the PR-stage check projects the registry in memory and compares no committed copy, and the committed copies on origin/main already carry sibling drift this diff does not own. Claude-Session: https://claude.ai/code/session_01KNKBCRDJCu5tGy3TEbvtrF Co-authored-by: Claude --- ...5-spec-list-view-edit-inline-default-on.md | 38 +++++++++++++++ content/docs/references/ui/page.mdx | 2 +- content/docs/references/ui/view.mdx | 6 +-- packages/spec/authorable-defaults/ui.json | 2 +- packages/spec/src/migrations/registry.ts | 48 +++++++++++++++++++ 5 files changed, 91 insertions(+), 5 deletions(-) create mode 100644 .changeset/22605-spec-list-view-edit-inline-default-on.md diff --git a/.changeset/22605-spec-list-view-edit-inline-default-on.md b/.changeset/22605-spec-list-view-edit-inline-default-on.md new file mode 100644 index 00000000000..6f628fece67 --- /dev/null +++ b/.changeset/22605-spec-list-view-edit-inline-default-on.md @@ -0,0 +1,38 @@ +--- +'@objectstack/spec': minor +--- + +`ListView.userActions.editInline` defaults to `true` on the v18 line: a list view is editable in place by default, under the permission gate that already exists, and `userActions: { editInline: false }` is the opt-out. + +Clause-②: yes (widening) + + + +**BREAKING** — a declared default moves, shipped as `minor` under the launch-window convention. The author who relied on the documented default (`false`, "the list is read-only unless the author opts in") for a list that is read-only by nature — a log, an audit trail, a history, a report roll-up — now gets an inline-edit toggle on it, for every user who may `update` the object. The remedy is one key on that view: `userActions: { editInline: false }`. + +**The ruling.** Maintainer, 2026-10-10, verbatim: 「乙 v18 把 spec 默认翻成 true,editInline: false 变成关法。」 The rule of objectui#5144 stands — one vocabulary (`editInline`), a boolean view-level `inlineEdit` folds into it, an explicit `editInline` wins, declared = enforced; only the default's value changes. Not taken: declaring `editInline: true` on every existing view, and an app-level default between the spec default and the view. + +**What moves.** `UserActionsConfigSchema.editInline` is `z.boolean().default(true)` where it was `.default(false)`, with the `describe` rewritten: on by default; a user who may update the object edits a cell in place with the field's type-aware widget; declare `editInline: false` to make the list read-only in place. A list view's `userActions` block, and a page's `interfaceConfig.userActions` block (the same schema), that omits `editInline` now parses to `true` where it parsed to `false`; the published JSON Schema and the reference pages (`content/docs/references/ui/view.mdx`, `page.mdx`) say so. A view with no `userActions` block at all parses with none on either side; the renderer reads an absent key as this default. The accept set is unchanged: `editInline` is still a boolean, and every authored value parses exactly as before. The permission gate is untouched: the renderer offers the toggle only where the object is editable in place and the current principal may `update` it. + +**The consumer half** is objectui's (objectstack-ai/objectui#12086): `ListView.tsx` and `InterfaceListPage.tsx` read an absent key as `editInline !== false`. Until that lands, the console at the pinned objectui still reads an absent key as off, so nothing regresses against today in the window. + +## FROM → TO + +| you wrote | what it means now | write instead, to keep the old behaviour | +|:--|:--|:--| +| nothing (no `editInline`) on a list view or a page list | editable in place by a user who may `update` the object | `userActions: { editInline: false }` | +| `editInline: false` | unchanged: read-only in place | nothing | +| `editInline: true` | unchanged: editable in place | nothing | +| a view-level `inlineEdit: true` | unchanged: folds to on and opens the grid in edit mode | nothing | + +**The one-line fix: on a list that must stay read-only in place, write `userActions: { editInline: false }`.** An `os compile` artifact that serialised an earlier parse carries a written `editInline: false` and stays read-only in place: recompile it, or delete the key. + +**Who is affected, measured** at `e11ef3a7bd`. No metadata in this repository declares `editInline` at all (0 `editInline: false`, 0 `editInline: true` across `examples/**` and `packages/**`, tests and changelogs excluded). Every list view that declares nothing gains the toggle: 38 list-kind views declared with an explicit `type` across 10 example `*.view.ts` files (entries with no `type` are grid by default and count the same way), 12 `interfaceConfig` page lists across 5 showcase page files (11 declare a `userActions` block, none naming `editInline`), and 105 list-kind views across 40 platform `*.object.ts` files in `packages/**`. One list view declares the view-level `inlineEdit: true` (the showcase `task` grid saved view) and keeps opening in edit mode. The card's readings outside this repository: cloud's `sys-package.page.ts` already declares `editInline: false` explicitly; HotCRM's 41 undeclared views regain cell editing after both packages upgrade, with no metadata change there. + +### The kit + +- **The default and its describe.** `packages/spec/src/ui/view.zod.ts`, `UserActionsConfigSchema.editInline`; the schema docblock records the ruling beside the group/hideFields/rowColor asymmetry it already explains. +- **The declared default change.** `DEFAULT_CHANGES_BY_MAJOR[17]` (`packages/spec/scripts/lib/default-changes.ts`) carries `ui/UserActionsConfig:editInline` `false` → `true`, which is what lets `check:authorable-surface` authorise the moved fingerprint in `authorable-defaults/ui.json`; `CURRENT_MAJOR` is the package major (17) until the version pass takes the group to 18. +- **The ledger.** The D3 semantic entry `list-view-edit-inline-default-on` (protocol 18), one file under `src/migrations/entries/semantic/`, concatenated into `registry.ts` by `gen:migration-registry`, projected into `spec-changes.json` and `docs/protocol-upgrade-guide.md`. No key is removed, so there is no tombstone and no `RETIRED_KEYS_BY_MAJOR` row; no D2 conversion exists, because a mechanical pass writing `editInline: false` into every silent view would preserve the old posture and defeat the ruling, and one writing `true` would add nothing the default does not already do. The same class as `view-pagination-page-size-default-50` and protocol 12's `rest-requireauth-default-flip`. +- **The pins.** `packages/spec/src/ui/view.test.ts`: an absent key parses to `true` (on `UserActionsConfigSchema` and through `ListViewSchema`), an explicit `false` stays `false`, an explicit `true` stays `true`, and the view-level `inlineEdit: true` still parses as before with no `userActions` block materialised. +- **The skill.** `skills/objectstack-ui/rules/list-views.md` gains its paragraph in a separate pull request, because `skills/**` is Tier H. diff --git a/content/docs/references/ui/page.mdx b/content/docs/references/ui/page.mdx index c88eda893c9..74e9453e0f8 100644 --- a/content/docs/references/ui/page.mdx +++ b/content/docs/references/ui/page.mdx @@ -145,7 +145,7 @@ View filter rule | **rowHeight** | `boolean` | optional (default: `true`) | Allow users to toggle row height/density | | **group** | `boolean` | optional (default: `true`) | Allow users to change record grouping from the toolbar. Toggle only — the grouping itself is configured in the view-level `grouping` block. | | **addRecordForm** | `boolean` | optional (default: `false`) | Add records through a form instead of inline | -| **editInline** | `boolean` | optional (default: `false`) | Allow users to edit records inline — click a cell to edit it with the field's type-aware widget (the same control the form uses). Off by default: the list is read-only unless the author opts in. | +| **editInline** | `boolean` | optional (default: `true`) | Allow users to edit records inline. On by default: a user who may update the object edits a cell in place with the field's type-aware widget (the same control the form uses), under the permission gate that already decides whether the object is editable at all. Declare `editInline: false` to make the list read-only in place. | | **hideFields** | `boolean` | optional (default: `false`) | Allow users to hide/show fields from the toolbar (the affordance behind the view-level `hiddenFields` list). Boolean toggle — distinct from the record-details component's `hideFields`, which is an array of field names to omit. Off by default: column hiding is opt-in. | | **rowColor** | `boolean` | optional (default: `false`) | Allow users to configure row colouring from the toolbar. Boolean toggle — the colour rules themselves live in the view-level `rowColor` block. Off by default: row colouring is opt-in. | | **buttons** | `string[]` | optional | Custom action button IDs to show in the toolbar | diff --git a/content/docs/references/ui/view.mdx b/content/docs/references/ui/view.mdx index 76fc5efec84..982391d7691 100644 --- a/content/docs/references/ui/view.mdx +++ b/content/docs/references/ui/view.mdx @@ -1081,7 +1081,7 @@ View filter rule | **rowHeight** | `boolean` | optional (default: `true`) | Allow users to toggle row height/density | | **group** | `boolean` | optional (default: `true`) | Allow users to change record grouping from the toolbar. Toggle only — the grouping itself is configured in the view-level `grouping` block. | | **addRecordForm** | `boolean` | optional (default: `false`) | Add records through a form instead of inline | -| **editInline** | `boolean` | optional (default: `false`) | Allow users to edit records inline — click a cell to edit it with the field's type-aware widget (the same control the form uses). Off by default: the list is read-only unless the author opts in. | +| **editInline** | `boolean` | optional (default: `true`) | Allow users to edit records inline. On by default: a user who may update the object edits a cell in place with the field's type-aware widget (the same control the form uses), under the permission gate that already decides whether the object is editable at all. Declare `editInline: false` to make the list read-only in place. | | **hideFields** | `boolean` | optional (default: `false`) | Allow users to hide/show fields from the toolbar (the affordance behind the view-level `hiddenFields` list). Boolean toggle — distinct from the record-details component's `hideFields`, which is an array of field names to omit. Off by default: column hiding is opt-in. | | **rowColor** | `boolean` | optional (default: `false`) | Allow users to configure row colouring from the toolbar. Boolean toggle — the colour rules themselves live in the view-level `rowColor` block. Off by default: row colouring is opt-in. | | **buttons** | `string[]` | optional | Custom action button IDs to show in the toolbar | @@ -1464,7 +1464,7 @@ View filter rule | **rowHeight** | `boolean` | optional (default: `true`) | Allow users to toggle row height/density | | **group** | `boolean` | optional (default: `true`) | Allow users to change record grouping from the toolbar. Toggle only — the grouping itself is configured in the view-level `grouping` block. | | **addRecordForm** | `boolean` | optional (default: `false`) | Add records through a form instead of inline | -| **editInline** | `boolean` | optional (default: `false`) | Allow users to edit records inline — click a cell to edit it with the field's type-aware widget (the same control the form uses). Off by default: the list is read-only unless the author opts in. | +| **editInline** | `boolean` | optional (default: `true`) | Allow users to edit records inline. On by default: a user who may update the object edits a cell in place with the field's type-aware widget (the same control the form uses), under the permission gate that already decides whether the object is editable at all. Declare `editInline: false` to make the list read-only in place. | | **hideFields** | `boolean` | optional (default: `false`) | Allow users to hide/show fields from the toolbar (the affordance behind the view-level `hiddenFields` list). Boolean toggle — distinct from the record-details component's `hideFields`, which is an array of field names to omit. Off by default: column hiding is opt-in. | | **rowColor** | `boolean` | optional (default: `false`) | Allow users to configure row colouring from the toolbar. Boolean toggle — the colour rules themselves live in the view-level `rowColor` block. Off by default: row colouring is opt-in. | | **buttons** | `string[]` | optional | Custom action button IDs to show in the toolbar | @@ -1635,7 +1635,7 @@ User action toggles for the view toolbar | **rowHeight** | `boolean` | optional (default: `true`) | Allow users to toggle row height/density | | **group** | `boolean` | optional (default: `true`) | Allow users to change record grouping from the toolbar. Toggle only — the grouping itself is configured in the view-level `grouping` block. | | **addRecordForm** | `boolean` | optional (default: `false`) | Add records through a form instead of inline | -| **editInline** | `boolean` | optional (default: `false`) | Allow users to edit records inline — click a cell to edit it with the field's type-aware widget (the same control the form uses). Off by default: the list is read-only unless the author opts in. | +| **editInline** | `boolean` | optional (default: `true`) | Allow users to edit records inline. On by default: a user who may update the object edits a cell in place with the field's type-aware widget (the same control the form uses), under the permission gate that already decides whether the object is editable at all. Declare `editInline: false` to make the list read-only in place. | | **hideFields** | `boolean` | optional (default: `false`) | Allow users to hide/show fields from the toolbar (the affordance behind the view-level `hiddenFields` list). Boolean toggle — distinct from the record-details component's `hideFields`, which is an array of field names to omit. Off by default: column hiding is opt-in. | | **rowColor** | `boolean` | optional (default: `false`) | Allow users to configure row colouring from the toolbar. Boolean toggle — the colour rules themselves live in the view-level `rowColor` block. Off by default: row colouring is opt-in. | | **buttons** | `string[]` | optional | Custom action button IDs to show in the toolbar | diff --git a/packages/spec/authorable-defaults/ui.json b/packages/spec/authorable-defaults/ui.json index 9cd6a41865a..6c631261088 100644 --- a/packages/spec/authorable-defaults/ui.json +++ b/packages/spec/authorable-defaults/ui.json @@ -107,7 +107,7 @@ "ui/TimelineConfig:scale = \"week\"", "ui/UrlNavItem:target = \"_self\"", "ui/UserActionsConfig:addRecordForm = false", - "ui/UserActionsConfig:editInline = false", + "ui/UserActionsConfig:editInline = true", "ui/UserActionsConfig:filter = true", "ui/UserActionsConfig:group = true", "ui/UserActionsConfig:hideFields = false", diff --git a/packages/spec/src/migrations/registry.ts b/packages/spec/src/migrations/registry.ts index 63d0b662bcf..de098800eeb 100644 --- a/packages/spec/src/migrations/registry.ts +++ b/packages/spec/src/migrations/registry.ts @@ -15614,6 +15614,54 @@ const step18: MigrationStep = { + 'PluginStartupResult interface — a different type, carrying startTime rather than any ' + 'duration key — which is not a reader of this schema and is unchanged.', }, + // The declared default of `ListView.userActions.editInline` moved from `false` + // to `true` (maintainer ruling 2026-10-10, the v18 line, verbatim: + // 「乙 v18 把 spec 默认翻成 true,editInline: false 变成关法。」). A default move + // reaches every silent document with no parse error and nothing in the + // author's diff, so the upgrade path carries it as a TODO: only the deployment + // can say which list that never declared the key was relying on read-only + // cells. The same class as `view-pagination-page-size-default-50` and + // protocol 12's `rest-requireauth-default-flip`: no key is removed, so there + // is no tombstone and no RETIRED_KEYS_BY_MAJOR row, and no D2 conversion + // exists — a mechanical pass writing `editInline: false` into every silent + // view would preserve the old posture and defeat the ruling, and one writing + // `true` would add nothing the default does not already do. + { + id: 'list-view-edit-inline-default-on', + // No backticks in `surface` — build-upgrade-guide.ts renders it inside a code + // span AND a table cell. + surface: 'ui.UserActionsConfig.editInline — an OMITTED editInline inside a list view\'s ' + + 'userActions block, or a page interfaceConfig.userActions block', + replacement: 'nothing, to take the platform default: the list is editable in place by a user who ' + + 'may update the object, under the permission gate that already exists. To keep a list ' + + 'read-only in place — a log, an audit trail, a history, a report roll-up — write it: ' + + '`userActions: { editInline: false }`', + reason: + 'A RULED behaviour change on a default, so there is nothing to rewrite and nothing to ' + + 'refuse: the maintainer\'s ruling of 2026-10-10 made a list view editable in place by ' + + 'default on the v18 line, and the declared default of `UserActionsConfigSchema.editInline` ' + + 'moved from `false` to `true`. A `userActions` block that omits `editInline` now parses to ' + + '`true` — the renderer offers the inline-edit toggle, and a user who may `update` the object ' + + 'edits a cell in place with the field\'s type-aware widget; a user without `update` sees no ' + + 'toggle, because the permission gate is untouched. A view with no `userActions` block at all ' + + 'parses with none on either side; the renderer reads an absent key as the spec default. The ' + + 'one-vocabulary rule of objectui#5144 stands: a boolean view-level `inlineEdit` folds into ' + + '`editInline` (`true` reads on and opens the grid in edit mode), and an explicit `editInline` ' + + 'wins. Not losslessly convertible because the question is intent, not text: only the ' + + 'deployment knows which silent lists were relying on read-only cells. The accept set is ' + + 'unchanged — a boolean — and every authored `editInline` parses exactly as before. A ' + + 'document that serialised an earlier parse (an `os compile` artifact) carries a written ' + + '`false` and stays read-only in place; recompile it, or delete the key.', + acceptanceCriteria: + 'An empty `userActions` block parses to `editInline: true`, and a list view carrying ' + + '`userActions: {}` parses to `userActions.editInline` true; an authored ' + + '`userActions: { editInline: false }` still parses to `false`; a view-level `inlineEdit: true` ' + + 'still parses as before, with no `userActions` block materialised. In the console, a grid view ' + + 'that declares neither key offers the inline-edit toggle to a user with `update` on the object ' + + 'and not to a user without it; `userActions: { editInline: false }` removes it; ' + + '`inlineEdit: true` still opens the grid in edit mode. Every list that must stay read-only in ' + + 'place declares `userActions: { editInline: false }` and shows no toggle.', + }, { id: 'list-view-navigation-view-retired', surface: 'view.list.navigation.view', From fc3733b9714493610f60cc80e7849f36471a6548 Mon Sep 17 00:00:00 2001 From: Claude Date: Sat, 10 Oct 2026 07:29:39 +0000 Subject: [PATCH 3/3] =?UTF-8?q?fix(spec):=20the=20editInline=20D3=20guidan?= =?UTF-8?q?ce=20names=20no=20tracker=20id;=20the=20changeset=20declares=20?= =?UTF-8?q?Clause-=E2=91=A1:=20no?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Patch round on the contract review (a moved default neither widens nor narrows the accept set; the banner and the ADR-0087 marker carry the breaking signal) and the Test Core red it found: packages/cli/test/migrate-meta-engine-guidance.test.ts refuses a tracker id in printed guidance. The entry's reason now says "the one-vocabulary rule objectui ruled for the fold"; the citation moves to the file's leading comment, as the other entries do; the DEFAULT_CHANGES_BY_MAJOR[17] reason is rewritten the same way; registry.ts regenerated. Claude-Session: https://claude.ai/code/session_01KNKBCRDJCu5tGy3TEbvtrF Co-authored-by: Claude --- .changeset/22605-spec-list-view-edit-inline-default-on.md | 2 +- packages/spec/scripts/lib/default-changes.ts | 4 ++-- .../semantic/18.list-view-edit-inline-default-on.ts | 8 ++++++-- packages/spec/src/migrations/registry.ts | 8 ++++++-- 4 files changed, 15 insertions(+), 7 deletions(-) diff --git a/.changeset/22605-spec-list-view-edit-inline-default-on.md b/.changeset/22605-spec-list-view-edit-inline-default-on.md index 6f628fece67..ca9a8e7a6cc 100644 --- a/.changeset/22605-spec-list-view-edit-inline-default-on.md +++ b/.changeset/22605-spec-list-view-edit-inline-default-on.md @@ -4,7 +4,7 @@ `ListView.userActions.editInline` defaults to `true` on the v18 line: a list view is editable in place by default, under the permission gate that already exists, and `userActions: { editInline: false }` is the opt-out. -Clause-②: yes (widening) +Clause-②: no diff --git a/packages/spec/scripts/lib/default-changes.ts b/packages/spec/scripts/lib/default-changes.ts index 5f1db428195..991abd11a7a 100644 --- a/packages/spec/scripts/lib/default-changes.ts +++ b/packages/spec/scripts/lib/default-changes.ts @@ -562,8 +562,8 @@ export const DEFAULT_CHANGES_BY_MAJOR: Readonly