Skip to content

Commit 275748e

Browse files
committed
docs(qa): invert the action-location-matrix empty-locations probe to the post-objectui#3142 contract (#7323)
`records-forms.action-location-matrix` asserted that an action with no `locations` renders at EVERY location. objectui#3142 collapsed four disagreeing renderers onto one membership predicate (`actionRendersAt`), so such an action now renders at NONE — the probe graded correct behavior as a FAIL, and contradicted the same item's own `negative` list, which already encoded the post-#3142 contract. The probe is inverted, not deleted — both halves stay observable end-to-end: - no `locations` key -> renders nowhere (the inert shape `packages/lint`'s `action-no-placement` rule warns about, and this repo's codification of the same contract); - `locations: []` -> renders nowhere too, deliberately: the headless declaration, read off the fixture fleet's `showcase_new_task`, which revision 3 (#6888) made headless. Also re-anchors the `recalc_selection` note — it names `record_more` because placement is an explicit declaration, not to opt out of an everywhere-default — rewords the objectui `source` line to name the predicate rather than the old rule, adds `packages/lint/src/validate-action-locations.ts` as a source, drops the "did not inherit via the empty-locations rule" clause from `negative`, and bumps the item revision 3 -> 4 with a history entry. Docs/QA-only: no product code, no changeset. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AccJhQLicuvwvYDUtzaG4d
1 parent 1788e19 commit 275748e

1 file changed

Lines changed: 17 additions & 10 deletions

File tree

docs/qa/platform-checklist/areas/records-forms.json

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1362,7 +1362,7 @@
13621362
"title": "Action buttons surface at exactly their declared locations — list toolbar, list row, record header/more/related/section — and each dispatches for real",
13631363
"since": "v15",
13641364
"status": "active",
1365-
"revision": 3,
1365+
"revision": 4,
13661366
"priority": "P1",
13671367
"surface": "browser",
13681368
"personas": [
@@ -1371,7 +1371,7 @@
13711371
"fixtures": {
13721372
"app": "showcase",
13731373
"requires": [
1374-
"the per-location action fleet on showcase_task (examples/app-showcase/src/ui/actions/index.ts): showcase_bulk_reassign (list_item+list_toolbar, flow), showcase_quick_view (list_item, modal), showcase_mark_done (list_item+record_header+record_section, script, visible '!record.done'), showcase_log_time (record_header+record_related+record_section, form), showcase_open_docs (record_more, url), showcase_recalc_selection (record_more, api — deliberately kept OFF the toolbar, objectui#3142)",
1374+
"the per-location action fleet on showcase_task (examples/app-showcase/src/ui/actions/index.ts): showcase_bulk_reassign (list_item+list_toolbar, flow), showcase_quick_view (list_item, modal), showcase_mark_done (list_item+record_header+record_section, script, visible '!record.done'), showcase_log_time (record_header+record_related+record_section, form), showcase_open_docs (record_more, url), showcase_recalc_selection (record_more, api — declares record_more ONLY, which is what keeps it off the toolbar; objectui#3142), showcase_new_task (locations: [] — the fleet's headless specimen, read by the empty-locations probe)",
13751375
"seeded tasks in both done and not-done states for the CEL visibility both-sides check"
13761376
]
13771377
},
@@ -1382,7 +1382,7 @@
13821382
"record_more — showcase_open_docs / showcase_recalc_selection under the ⋯ overflow",
13831383
"record_related — showcase_log_time on the related-list section",
13841384
"record_section — showcase_mark_done / showcase_log_time in the Task Detail quick-actions bar (record:quick_actions resolves through the location filter)",
1385-
"empty-locations semantics probe — a locations-less action lands on EVERY location including the toolbar (objectui action-bar.tsx documented behavior; the reason recalc_selection must declare record_more)"
1385+
"empty-locations semantics probe — an action with NO locations key renders on NO surface, and `locations: []` likewise (objectui#3142 collapsed the renderers onto one membership predicate, `actionRendersAt`; placement is a declaration, which is why recalc_selection has to name record_more)"
13861386
],
13871387
"steps": [
13881388
"boot the showcase isolated; sign in as admin; open the showcase_task list view",
@@ -1391,7 +1391,7 @@
13911391
"dispatch one action per location with a ref-targeted click: bulk_reassign (screen-flow wizard opens), quick_view (modal opens), mark_done (script executes), log_time (form dialog opens on showcase_task.edit), open_docs (url navigation), recalc_selection from the ⋯ menu (api POST); capture each network trace",
13921392
"verify the state-changing dispatches server-side: mark_done flips the task's done flag (API re-read), recalc_selection's per-record branch recomputes the estimate",
13931393
"CEL visibility both sides: locate a done task and a not-done task; read the row menu and record header of each for showcase_mark_done",
1394-
"empty-locations probe: in a scratch/writable package author a copy of an api action with NO locations key; reload and record every surface it appears on (including the toolbar), then delete the probe"
1394+
"empty-locations probe, both halves: (a) in a scratch/writable package author a copy of an api action with NO locations key; reload and sweep all six surfaces (list toolbar, row menu, record header, ⋯ overflow, related-list section, quick-actions bar) recording every surface it appears on the expected list is EMPTY — then delete the probe; (b) sweep the same six surfaces for showcase_new_task, the fixture fleet's headless `locations: []` declaration, and record that its list is empty too"
13951395
],
13961396
"acceptance": [
13971397
{
@@ -1419,14 +1419,14 @@
14191419
"evidence": "the four reads + screenshots"
14201420
},
14211421
{
1422-
"clause": "empty/missing locations means EVERY location — the probe action appears on all surfaced slots including the list toolbar (the objectui#3142 semantics that forces recalc_selection to declare record_more, because a toolbar dispatch has no selection and the endpoint rejects it)",
1422+
"clause": "empty/missing locations means NO location — the probe action with no `locations` key renders on none of the six surfaces, and the headless `locations: []` declaration (showcase_new_task) renders on none either. Placement is a declaration, not a default: objectui#3142 collapsed four disagreeing renderers onto the single `actionRendersAt` predicate, a plain membership test, so an undeclared or empty list matches nothing. recalc_selection names record_more for that reason — an explicit single-record placement that also keeps it off the toolbar, where a dispatch would carry no selection and the endpoint would reject it — NOT to opt out of an everywhere-default",
14231423
"oracle": "dom",
1424-
"verify": "the locations-less probe's placement list covers all applicable surfaces; recalc_selection itself stays OFF the toolbar",
1425-
"evidence": "probe placement list + toolbar DOM read"
1424+
"verify": "both six-surface DOM sweeps (the locations-less probe, and showcase_new_task) come back with an empty placement list; recalc_selection is present under ⋯ and absent from the toolbar",
1425+
"evidence": "the two empty placement lists + the toolbar DOM read"
14261426
}
14271427
],
14281428
"negative": [
1429-
"any action rendering at a location it did not declare (and did not inherit via the empty-locations rule) is a FAIL — placement is a contract, not a hint",
1429+
"any action rendering at a location it did not declare is a FAIL — placement is a contract, not a hint, and since objectui#3142 there is no everywhere-default left to inherit",
14301430
"showcase_recalc_selection appearing on the list toolbar is the objectui#3142 regression shape — FAIL even though clicking it would merely error",
14311431
"a dispatch that opens the wrong target (e.g. log_time opening a list view instead of the showcase_task.edit form — the #2554 build-gate class) is a FAIL of the dispatch clause, not a cosmetic note"
14321432
],
@@ -1441,8 +1441,9 @@
14411441
},
14421442
"source": [
14431443
"packages/spec/src/ui/action.zod.ts:565 (ACTION_LOCATIONS — the canonical 6-value enum, single source of truth; `global_nav` was the 7th until #6888 retired it — no product surface rendered it)",
1444-
"examples/app-showcase/src/ui/actions/index.ts (per-location fixture fleet + the record:quick_actions filter note + the objectui#3142 empty-locations commentary)",
1445-
"objectui: packages/.../action-bar.tsx (missing/empty locations → every location)",
1444+
"examples/app-showcase/src/ui/actions/index.ts (per-location fixture fleet + the record:quick_actions filter note + the two headless `locations: []` declarations). NOTE: RecalcSelectionAction's TSDoc there still narrates the pre-objectui#3142 'missing/empty locations → every location' rule — stale prose, filed separately; the declaration it explains (record_more) is correct either way",
1445+
"packages/lint/src/validate-action-locations.ts (the `action-no-placement` rule — this repo's codification of the current contract: an action with no `locations` renders nowhere and is therefore inert, while `locations: []` is the deliberate headless declaration and is NOT flagged)",
1446+
"objectui: packages/types/src/ui-action.ts `actionRendersAt` (the single placement predicate — a membership test, so an undeclared or empty `locations` matches nothing) + packages/.../action-bar.tsx, its consumer since objectui#3142",
14461447
"cross-ref: bulk dispatch-count semantics live in records-forms.list-view-capabilities (bulk-actions variant); param dialogs in records-forms.action-param-widgets"
14471448
],
14481449
"history": [
@@ -1463,6 +1464,12 @@
14631464
"date": "2026-08-10",
14641465
"change": "dropped the global_nav variant — the vocabulary lost that member (#6888). The variant was UNRUNNABLE as written, not merely obsolete: its step 'new_task from the palette' could never pass, because the console ⌘K palette builds its groups from nav items, objects, dashboards, pages, reports, recent items and record search and reads no action metadata at all. The fixture fleet loses showcase_new_task with it (now headless, locations: []); the dispatch step drops from seven traces to six; enumSource.expect 7 → 6",
14651466
"ref": "claude/issue-6888-retire-global-nav"
1467+
},
1468+
{
1469+
"revision": 4,
1470+
"date": "2026-08-10",
1471+
"change": "inverted the empty-locations probe to the post-objectui#3142 contract (#7323). The variant, its step and its acceptance clause all asserted that a locations-less action lands on EVERY location; objectui#3142 collapsed four disagreeing renderers onto one membership predicate (actionRendersAt), so such an action now lands on NONE. The probe was therefore grading correct behavior as a FAIL, and contradicted this same item's negative list, which already encoded the post-#3142 contract. The probe is kept rather than deleted — both halves stay observable end-to-end: no `locations` key → nowhere (the inert shape packages/lint's action-no-placement warns about), and `locations: []` → nowhere deliberately (read off the fleet's showcase_new_task, which revision 3 made headless). Re-anchored the recalc_selection note — record_more is an explicit placement, not an opt-out of an everywhere-default — reworded the objectui source line to name the predicate, and added the in-repo codification as a source",
1472+
"ref": "claude/issue-7323-action-location-matrix-probe"
14661473
}
14671474
],
14681475
"enumSource": {

0 commit comments

Comments
 (0)