Skip to content

Commit 30e0411

Browse files
committed
fix(spec): the bulk-param migration entry names the promoted field-backed route
The major-18 semantic entry ui-bulk-action-param-unknown-keys-refused said the bulk surface has no field-backed param route. Since objectui 29b99490 (carried by the console pin) a promoted bulk action resolves its field-backed params through the single-record dialog's resolver, and accept / maxSize arrive from the field. The replacement and reason clauses now say the AUTHORED bulkActionDefs[].params surface has no such route and name the promoted one, in the wording BulkActionParamSchema's rejection text uses. Claude-Session: https://claude.ai/code/session_01KNKBCRDJCu5tGy3TEbvtrF Co-authored-by: Claude <noreply@anthropic.com>
1 parent 75b6d6a commit 30e0411

2 files changed

Lines changed: 40 additions & 11 deletions

File tree

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
---
2+
'@objectstack/spec': patch
3+
---
4+
5+
fix(spec): the `ui-bulk-action-param-unknown-keys-refused` upgrade guidance names the promoted field-backed bulk route instead of saying the bulk surface has none (#22858)
6+
7+
Clause-②: no
8+
9+
The major-18 semantic entry `ui-bulk-action-param-unknown-keys-refused`, which `objectstack migrate meta` prints, said two things that stopped being true once the console resolved a promoted bulk action's params through the single-record dialog's resolver. It called `field` / `objectOverride` contracts "the bulk surface does not implement", and it told the reader that declaring a widget-config key on the object's field cannot help because "the bulk surface has no field-backed param route". The entry now uses the wording the `BulkActionParamSchema` rejection messages already use.
10+
11+
- **`replacement`.** An authored `bulkActionDefs[].params` entry has no field-backed route: it reaches the dialog as written. The `field` rejection offers two fixes: declare the param inline, or declare the action on the object with the field-backed param and name it in the view's `bulkActions`. That second form is the promoted route, whose params are resolved when the bulk dialog opens. Of the widget-config keys, only `accept` / `maxSize` declared on the field reach the dialog, through a promoted action. `carryOver` / `defaultFromRow` / `requiresFeature` are still ACTION-param contracts the bulk surface does not implement.
12+
- **`reason`.** Declaring the key on the field and keeping the authored def still does not reach the dialog. A promoted action is the one route that consults the field. Of the refused keys, only `accept` / `maxSize` arrive that way. `lookupFilters` / `lookupColumns` / `lookupPageSize` / `descriptionField` are resolved and then dropped on the bulk path, and the rest are never read off the field.
13+
14+
Nothing to migrate: the accepted and refused keys are unchanged. Only the guidance text of one migration entry moved.

‎packages/spec/src/migrations/entries/semantic/18.ui-bulk-action-param-unknown-keys-refused.ts‎

Lines changed: 26 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -22,14 +22,22 @@ export const entry: SemanticMigration = {
2222
+ '`help`, `defaultValue` → `default`, `reference` → `object`, `displayField` → '
2323
+ '`labelField`); the keys that belong one layer out are pointed there (`visible` and a '
2424
+ 'capability gate belong on the DEF, `visibleWhen` belongs on an `options[]` entry, '
25-
+ '`field` / `objectOverride` / `carryOver` / `defaultFromRow` / `requiresFeature` are '
26-
+ 'field-backed ACTION-param contracts the bulk surface does not implement); and the '
27-
+ 'widget-config family (`min`, `max`, `step`, `precision`, `scale`, `rows`, `accept`, '
28-
+ '`maxSize`, and the picker knobs `lookupFilters` / `lookupColumns` / `lookupPageSize` / '
25+
+ '`carryOver` / `defaultFromRow` / `requiresFeature` are ACTION-param contracts the bulk '
26+
+ 'surface does not implement); `field` / `objectOverride` declare a FIELD-BACKED param, '
27+
+ 'and an authored `bulkActionDefs[].params` entry has no such route — it reaches the '
28+
+ 'dialog as written, and nothing on that path resolves it against the object\'s field '
29+
+ 'definitions — so the `field` rejection offers two fixes: declare the param inline, or '
30+
+ 'declare the action on the object with that field-backed param and name it in the '
31+
+ 'view\'s `bulkActions`, the PROMOTED route, whose params are resolved through the '
32+
+ 'single-record dialog\'s resolver when the bulk dialog opens; and the widget-config '
33+
+ 'family (`min`, `max`, `step`, `precision`, `scale`, `rows`, `accept`, `maxSize`, and '
34+
+ 'the picker knobs `lookupFilters` / `lookupColumns` / `lookupPageSize` / '
2935
+ '`descriptionField` / `picker` / `subtitle` / `avatarField` / `idField` / `allowCreate`) '
3036
+ 'is answered with one prescription naming `FieldSchema` as the shape those keys are real '
31-
+ 'on. `dependsOn` needs NO edit — it is declared, in the same shape the field-level key '
32-
+ 'takes (`[\'parent\']`, or `[{ field, param }]` when the remote filter key differs).',
37+
+ 'on, and saying that of them only `accept` / `maxSize` declared there reach this dialog, '
38+
+ 'through a promoted action. `dependsOn` needs NO edit — it is declared, in the same '
39+
+ 'shape the field-level key takes (`[\'parent\']`, or `[{ field, param }]` when the remote '
40+
+ 'filter key differs).',
3341
reason:
3442
'The accept was a NULL READING, and that is what makes this a contract fix rather than a '
3543
+ 'preference. Measured against installed spec 17.4.0, three parses per schema in one '
@@ -51,11 +59,18 @@ export const entry: SemanticMigration = {
5159
+ 'accepted cost of closing the shape (maintainer ruling, letter '
5260
+ 'A, 2026-09-17: 「Breaking for authored metadata」, one-shot, no grace window and no dual '
5361
+ 'spelling). ⛔ Do not read their rejection as "the renderer ignores them", and ⛔ do not '
54-
+ 'answer it by declaring the key on the object\'s FIELD: the bulk surface has no '
55-
+ 'field-backed param route, so that value does not reach this dialog either. A census of '
56-
+ 'authored bulk params taken at registration time over the two repositories reachable from '
57-
+ 'that session found ZERO carrying an undeclared key (objectstack@176b03582e: 7 param '
58-
+ 'literals; objectui@3e4f6324f7: 3), so no in-corpus configuration is known to break. '
62+
+ 'answer it by declaring the key on the object\'s FIELD and keeping the authored def: an '
63+
+ 'authored `bulkActionDefs[].params` entry has no field-backed param route, so that value '
64+
+ 'does not reach this dialog either. The one route that consults the field is a PROMOTED '
65+
+ 'action — an action the object declares, named in the view\'s `bulkActions`, whose '
66+
+ 'field-backed params (`{ field }`) are resolved through the single-record dialog\'s '
67+
+ 'resolver when the bulk dialog opens — and of these keys only `accept` / `maxSize` arrive '
68+
+ 'that way: `lookupFilters` / `lookupColumns` / `lookupPageSize` / `descriptionField` are '
69+
+ 'resolved and then dropped on the bulk path, and the rest are never read off the field. '
70+
+ 'A census of authored bulk params taken at registration time over the two repositories '
71+
+ 'reachable from that session found ZERO carrying an undeclared key '
72+
+ '(objectstack@176b03582e: 7 param literals; objectui@3e4f6324f7: 3), so no in-corpus '
73+
+ 'configuration is known to break. '
5974
+ '⚠️ That census did NOT cover hotcrm, which was unreachable from the session that took it '
6075
+ '— that leg is UNMEASURED, not clean, and an upgrader with their own metadata corpus '
6176
+ 'should run the check below rather than inherit this result.',

0 commit comments

Comments
 (0)