Skip to content

Commit b220e09

Browse files
docs(qa): lift action-location-matrix's no-surface knownGap now that the showcase hosts record_header / record_more / record_related (#22040)
Fixes #22039 Clause-②: no The showcase change carded as #22030 landed as PR #22036 (`60ccda5a24`). It hosts `record_header`, `record_more` and `record_related` for `showcase_task` on stock showcase pages. This PR lifts the row-7 fixture knownGap on `records-forms.action-location-matrix` that parked those three locations, and A3's url / api dispatch legs, on that card. It is a checklist-only diff: one item in `docs/qa/platform-checklist/areas/records-forms.json`, no other item, no code. ## What changed (item `records-forms.action-location-matrix`, revision 8 to 9) | Key | Before | After | |---|---|---| | `revision` | 8 | 9 | | `fixtures.knownGaps[1]` | "the showcase hosts NO surface for three of the six locations on showcase_task …"; score them blocked(fixture); park on #22030 | Opens with a closed marker citing #22030 / PR #22036 / `60ccda5a24` and this card, then says where each location now lives on a stock boot (below) | | `steps[1]` | surfaces listed as "a not-done task's detail title bar / its ⋯ menu / a related-list section", plus "A location with no hosting surface at this fixture (record_header / record_more / record_related) is recorded blocked(fixture)" | Names each host: the Task Detail title bar, that title bar's ⋯ menu, and the rows of the Tasks related list on Project Detail's Related tab, "not the Tasks tab's line-items grid". The blocked(fixture) sentence is gone | | `acceptance[0].clause` | "… a parent record page that renders the synthesized Tasks related list …" | "… renders the Tasks related list …" (one word dropped) | | `acceptance[0].verify` | "At this fixture record_header, record_more and record_related are not hosted: record those three blocked(fixture), never as missing placements" | "The stock fixture hosts all six (fixtures.knownGaps names the page and tab …): an expected action absent from its host is a missing placement, never blocked(fixture)" | | `acceptance[2].clause` | "The url (open_docs) and api (recalc_selection) legs live on record_more and share its fixture gap: record them blocked(fixture) with it, never as dispatch failures" | "The url (open_docs) and api (recalc_selection) legs live on record_more, under the ⋯ overflow of the Task Detail title bar" | | `history` | 8 entries | plus one: revision 9, 2026-10-06, ref `#22039`, citing #22030 / PR #22036 | `fixtures.knownGaps[0]` (the objectui-pinned automation) is byte-identical. No other key and no other item changed. A structural diff of all 43 items against `60ccda5a24` shows exactly one changed item. ### The rewritten knownGap: where each location lives - **`record_header` / `record_more`: Task Detail** (`showcase_task_detail`, the record page the console opens for any task). Its first node is a `page:header`. The header renders the action ids it lists, each placed by its own `locations`, and the host's Edit / Share / Delete come after them. - Inline on a desktop viewport: `showcase_mark_done` (script, shown only while the task is not done), `showcase_log_time` (form) and `showcase_archive_task` (script, disabled until done). - Under the ⋯ overflow: `showcase_open_docs` (url), `showcase_recalc_estimate` (api) and `showcase_recalc_selection` (api). - The default inline budget is 3 (1 on mobile), and a `record_header` action past it folds into ⋯. Read from the `page:header` renderer at the objectui pin `a58626c88dc8`. The knownGap names this so that a runner on a narrow viewport does not score a folded action as an extra `record_more` placement. - **`record_related`: Project Detail** (`showcase_project_detail`), on the **Related tab** (`?tab=related`). The tab holds the Tasks related list, a `record:related_list` for `showcase_task` through its `project` FK. As PR #22036 noted, this is an authored node, not the synthesizer's strip. The page's `tabs` override still replaces that strip, and the tab puts the list back with no `actions` key, so its rows carry `showcase_log_time` beside the task's `list_item` actions. The Tasks tab next to it is the `record:line_items` grid, which hosts no `record_related` action. - A missing action on any of these hosts is now a missing placement, not blocked(fixture). The knownGap says the hosts were read from objectui source and served metadata, not from a browser render, because PR #22036 left the browser render NOT MEASURED. The first run against these hosts will be their first browser evidence. ### Scope reading, declared The dispatch scopes edits to `fixtures.requires`, `steps` and acceptance `verify` lines that still send the runner to a surface that does not host the leg. Two of the lines above are acceptance `clause` texts, not `verify` lines. Revision 7 added the gap's blocked(fixture) instructions in five places: knownGaps[1], step 2, clause 1, clause 1's verify, and clause 3. The item diff between `ff29410ed2` and `18c7dfd2e6` shows them. Clause 3's last sentence parks the url / api legs by itself, so leaving it would keep A3 parked after the lift. Clause 1's "synthesized" sends a runner to look for a strip that the page's `tabs` override removes. The edit to each clause is the minimum that undoes revision 7's gap text. Nothing else in either clause changed. `fixtures.requires` is unchanged: it describes the fleet and does not point the runner at any surface. ## Verification (head `d99f1f57ee`, after the final commit) - **Derived gates:** `node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack` on the actual diff derived 13 commands. The list is the same at both commits. Each was run with its exit code recorded before any pipe, and all 13 exited 0. `--ran`: "13 derived famil(ies) accounted for — 13 run, 0 NOT-MEASURED (a DERIVED zero — all 13 recorded an exit code and none of them is 3)". - `check:platform-checklist`: "OK — 15 areas, 276 items (272 active, 2 planned) …". - `check:doc-authoring`, `check:cross-package-test-inputs` and `check:nul-bytes` are green. - On the first commit, `check:doc-formula-expressions` answered PREREQUISITE NOT MET (exit 3: `@objectstack/formula` and `@objectstack/lint` were unbuilt). Both were then built under `os-verify-lock.sh` (VERDICT command-exit 0), and the gate ran green at both commits. - **The two checklist-reading package tests** run on the final head. These are the only tests declared as reading these files: `scripts/cross-package-test-inputs.mjs` names `docs/qa/platform-checklist/areas/*.json` for plugin-auth and `docs/**` for rest, and nothing else. - `pnpm --filter @objectstack/plugin-auth exec vitest run --maxWorkers=2 src/checklist-refusal-envelope-consistency.test.ts`: exit 0, 1 file / 5 tests passed. - `pnpm --filter @objectstack/rest exec vitest run --maxWorkers=2 src/meta-state-route-doc-spelling.test.ts`: exit 0, 1 file / 8 tests passed. - **Lint:** `eslint --no-inline-config --format json` on the changed file returns 1 file and 0 errors. The one message is "File ignored because no matching configuration was supplied". No block in `eslint.config.mjs` covers `.json` under `docs/`, so this diff cannot move any lint verdict. The full `pnpm lint` run is CI's. - **Changeset:** 69 published workspace manifests. None has a `files[]` entry naming `docs/qa` or the checklist (0 hits). Positive control: all 69 name `dist` (69 hits). The path is outside every package directory, so this diff publishes nothing. Hence `skip-changeset`. - **Typecheck / package tests:** no package source changed, so neither is owed locally. CI's Test Core reruns plugin-auth and rest because their declared inputs moved. ## Acceptance notes - **The empty-locations probe cannot discriminate on two authored-list surfaces.** The Task Detail `page:header` renders only the ids it lists (objectui `containers.tsx`, `resolvedHeaderActions`). The `record:quick_actions` bar is also an explicit `actionNames` list. So the step-7 probe action, and `showcase_new_task`, are absent from the record header, the ⋯ overflow and the quick-actions bar because those lists leave them out. That absence is decided before any `locations` predicate runs. The probe's verdict therefore rests on the list toolbar, the row menu and the related-list rows. The quick-actions half predates this card. The header half is new, because before PR #22036 the header did not exist. Not filed: this is an item-design observation, not a runtime defect, a contract violation or an authoring trap. Carrier: none. - `fixtures.requires[0]` and clause 4 spell mark_done's predicate as `'!record.done'`. The fixture's actual predicate is `has(record.done) && record.done != true`. `requires[0]` also leaves out `showcase_recalc_estimate` and `showcase_archive_task`, which the header now carries. Neither points the runner at a wrong surface, so both are outside this card's edit rule and are left as they are. Carrier: none. - NOT MEASURED: the browser render of the new hosts, as in PR #22036. No console bundle is built in this checkout. The knownGap says so. ## Labels `skip-changeset`: checklist-only diff, measured above. --- _Generated by [Claude Code](https://claude.ai/code/session_01VF48aw8RPG6wzDnMgp6rtw)_ --------- Co-authored-by: Claude <noreply@anthropic.com>
1 parent 0af4f66 commit b220e09

1 file changed

Lines changed: 12 additions & 6 deletions

File tree

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

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1547,7 +1547,7 @@
15471547
"title": "Action buttons surface at exactly their declared locations — list toolbar, list row, record header/more/related/section — and each dispatches for real",
15481548
"since": "v15",
15491549
"status": "active",
1550-
"revision": 8,
1550+
"revision": 9,
15511551
"priority": "P1",
15521552
"surface": "browser",
15531553
"personas": [
@@ -1561,7 +1561,7 @@
15611561
],
15621562
"knownGaps": [
15631563
"AUTOMATION IS PINNED IN THE objectui REPO, NOT HERE — `automated.ref` names objectui specs exclusively, so from this checkout the item is neither runnable nor pin-evidenced (no console bundle is built here and none of those specs exist here). Drive it by hand in the browser and score it as a manual run, OR run the pin in an objectui checkout and cite the output naming the revision (17.1.0 sweep subject: 9a3daf8d37ad). ⛔ Never score it as covered on the strength of the `automated` field alone — an unrun pin is a claim, not evidence. Full protocol: RUNNER.md, the objectui-pinned-automation standing fact.",
1564-
"the showcase hosts NO surface for three of the six locations on showcase_task (#21782 VF4; measured at objectui 2e818d0b51ec, re-read at 9dfaca6543). task-detail.page.ts is kind 'full' with no record:header node, and an authored page gets no injected header actions (objectui#7298 ruling), so record_header and record_more have no surface. project-detail.page.ts overrides the tabs slot with an inline record:line_items grid in place of the synthesized related strip, and project (a master-detail) is showcase_task's only parent relation, so record_related has no surface either. The console's renderer half is landed in the pin (objectui#11270, RelatedRecordActionsBridge). Hosting the three needs a showcase_task page that composes a record header and a parent record page that renders the synthesized Tasks related list, which is a showcase fixture change outside this checklist. Until it lands, score record_header / record_more / record_related blocked(fixture), never a missing placement. That showcase change is carded as #22030 (#21797's breach B-1, filed from #22017 row 7, QA run #21782's A3 url / api gap): record_header / record_more / record_related and A3's url / api legs park on #22030"
1564+
"[CLOSED by #22030 (PR #22036, 60ccda5a24), lifted by #22039 — the gap text is rewritten to say where each location now lives] a stock showcase boot hosts all six locations on showcase_task, including the three this gap used to block. record_header and record_more: Task Detail (showcase_task_detail, the record page the console opens for any task), whose first node is a page:header. That header renders the action ids it lists, each placed by its own locations, followed by the host's Edit / Share / Delete. Inline (record_header) on a desktop viewport, where the header's default inline budget is 3 (1 on mobile; a record_header action past the budget folds into ⋯): showcase_mark_done (script, shown only while the task is not done), showcase_log_time (form) and showcase_archive_task (script, disabled until the task is done). Under the ⋯ overflow (record_more without record_header): showcase_open_docs (url), showcase_recalc_estimate (api) and showcase_recalc_selection (api). record_related: Project Detail (showcase_project_detail, the record page for any project) → the Related tab (?tab=related), which holds the Tasks related list, a record:related_list for showcase_task through its project FK; open a project that has tasks. It is an authored node, not the synthesizer's strip: the page's tabs override still replaces that strip, and this tab puts the list back with no actions key, so its rows carry showcase_log_time beside the task's list_item actions. The Tasks tab beside it is the record:line_items grid, which hosts no record_related action. An expected action missing from one of these hosts is a missing placement, never blocked(fixture). The hosts were read from objectui source at pin a58626c88dc8 and from the served metadata, not from a browser render, so the first run against them is their first browser evidence"
15651565
]
15661566
},
15671567
"variants": [
@@ -1575,7 +1575,7 @@
15751575
],
15761576
"steps": [
15771577
"boot the showcase isolated; sign in as admin; open the showcase_task list view",
1578-
"for each location variant, navigate to its surface (list header / row menu / a not-done task's detail title bar / its ⋯ menu / a related-list section / the Task Detail quick-actions bar), screenshot AFTER render settles, then read the rendered action buttons from the DOM. A location with no hosting surface at this fixture (record_header / record_more / record_related — fixtures.knownGaps) is recorded blocked(fixture)",
1578+
"for each location variant, navigate to its surface (list header / row menu / a not-done task's Task Detail title bar / that title bar's ⋯ menu / the rows of the Tasks related list on a project's Project Detail Related tab, not the Tasks tab's line-items grid / the Task Detail quick-actions bar; fixtures.knownGaps names each record host), screenshot AFTER render settles, then read the rendered action buttons from the DOM",
15791579
"record for every fixture action WHERE it rendered — building the full placement matrix (rendered locations vs declared locations)",
15801580
"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.form), open_docs (url navigation), recalc_selection from the ⋯ menu (api POST); capture each network trace",
15811581
"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",
@@ -1584,9 +1584,9 @@
15841584
],
15851585
"acceptance": [
15861586
{
1587-
"clause": "Per variant, every location the fixture actually HOSTS renders ≥1 action declared for it; record_header/record_more require a showcase_task page that composes a record header and record_related a parent record page that renders the synthesized Tasks related list (fixture must provide both).",
1587+
"clause": "Per variant, every location the fixture actually HOSTS renders ≥1 action declared for it; record_header/record_more require a showcase_task page that composes a record header and record_related a parent record page that renders the Tasks related list (fixture must provide both).",
15881588
"oracle": "dom",
1589-
"verify": "after each hosted surface's screenshot confirms render, the DOM read lists the expected action names in that slot; matrix compiled per variant. At this fixture record_header, record_more and record_related are not hosted (fixtures.knownGaps): record those three blocked(fixture), never as missing placements",
1589+
"verify": "after each hosted surface's screenshot confirms render, the DOM read lists the expected action names in that slot; matrix compiled per variant. The stock fixture hosts all six (fixtures.knownGaps names the page and tab for record_header, record_more and record_related): an expected action absent from its host is a missing placement, never blocked(fixture)",
15901590
"evidence": "per-location screenshots + the placement matrix"
15911591
},
15921592
{
@@ -1596,7 +1596,7 @@
15961596
"evidence": "the same matrix, extra-placement columns"
15971597
},
15981598
{
1599-
"clause": "each HOSTED location's sampled action DISPATCHES for real — flow wizard opens and resumes, modal opens, script executes, form opens the declared edit form view, url navigates, api POSTs — and state-changing ones round-trip server-side (mark_done flips done; recalc updates the estimate). The url (open_docs) and api (recalc_selection) legs live on record_more and share its fixture gap: record them blocked(fixture) with it, never as dispatch failures",
1599+
"clause": "each HOSTED location's sampled action DISPATCHES for real — flow wizard opens and resumes, modal opens, script executes, form opens the declared edit form view, url navigates, api POSTs — and state-changing ones round-trip server-side (mark_done flips done; recalc updates the estimate). The url (open_docs) and api (recalc_selection) legs live on record_more, under the ⋯ overflow of the Task Detail title bar",
16001600
"oracle": "network",
16011601
"verify": "one captured dispatch per location + API re-reads for the two state changes",
16021602
"evidence": "the six traces + the two re-reads"
@@ -1683,6 +1683,12 @@
16831683
"date": "2026-10-06",
16841684
"change": "partial-coverage gap of QA run #21782 parked on #22017 (row 7). A3's url / api dispatch legs were blocked(fixture): the fixture hosts no ⋯ surface. Revision 7 (#21797) already scores them blocked(fixture) with record_more. Disposition: recorded knownGap. The leg needs an examples/app-showcase fixture change, carded as #22030, and the knownGap now parks the three record_* variants and A3's url / api legs on #22030. No clause changed",
16851685
"ref": "#22017"
1686+
},
1687+
{
1688+
"revision": 9,
1689+
"date": "2026-10-06",
1690+
"change": "lifted the row-7 fixture knownGap (#22039): #22030 (PR #22036, 60ccda5a24) hosts record_header, record_more and record_related for showcase_task on stock showcase pages. knownGaps[1] is rewritten from 'no surface' to where each location lives: Task Detail's page:header (record_header inline; record_more's url / api / api under the ⋯ overflow) and Project Detail's Related tab (the Tasks related list, an authored record:related_list rather than the synthesizer's strip). The lines revision 7 added for the gap are re-pointed. Step 2 names each host and drops its blocked(fixture) sentence. Clause 1 drops 'synthesized', and its verify scores an absent action as a missing placement. Clause 3 no longer parks the url / api legs. knownGaps[0] is unchanged",
1691+
"ref": "#22039"
16861692
}
16871693
],
16881694
"enumSource": {

0 commit comments

Comments
 (0)