diff --git a/docs/qa/platform-checklist/areas/records-forms.json b/docs/qa/platform-checklist/areas/records-forms.json index 0412d6fb5bf..549b4fc25f0 100644 --- a/docs/qa/platform-checklist/areas/records-forms.json +++ b/docs/qa/platform-checklist/areas/records-forms.json @@ -930,7 +930,7 @@ "title": "Grid-level conditional rules: row-scoped requiredWhen and parent-scoped readonlyWhen in the inline line-item grid", "since": "v16", "status": "active", - "revision": 6, + "revision": 7, "priority": "P1", "surface": "browser", "personas": [ @@ -997,7 +997,7 @@ ], "automated": { "kind": "e2e", - "ref": "objectui: e2e/live/grid-conditional-rules.spec.ts, e2e/live/grid-parent-rules.spec.ts, e2e/live/grid-file-upload.spec.ts", + "ref": "objectui: e2e/live/grid-conditional-rules.spec.ts (acceptance[0]'s inline-flag half ONLY — on the New Invoice dialog's first line, Description carries no required flag at Qty 2, is flagged at Qty 100 and clears once filled; the spec adds no second row and never saves, so neither the unflagged sibling row nor the blocked save is pinned), e2e/live/grid-parent-rules.spec.ts, e2e/live/grid-file-upload.spec.ts (stale at the pin, see automated.stale). No pin covers acceptance[1] or acceptance[4]", "stale": { "since": "2026-10-19", "observedIn": "#24598", @@ -1049,6 +1049,12 @@ "date": "2026-10-20", "change": "automated.stale added — §2 theme \"objectui live e2e is not green at its own pin\" of wave anchor #24579 (18.0 sweep). Tier 1 run #24598 at the sweep's console pin 4016370af3c9: grid-file-upload.spec.ts failed as a stale spec (a strict-mode locator collision; cause from QA run #24572, #24616 drove the item by hand); grid-conditional-rules.spec.ts and grid-parent-rules.spec.ts passed and stay cited. Re-read at the shipped pin 12dc7b47c340: the spec and the colliding description are unchanged. No clause changed", "ref": "#24697" + }, + { + "revision": 7, + "date": "2026-10-20", + "change": "automated.ref narrowed per clause — §2 theme \"pins that cover no full clause\" of wave anchor #24579 (18.0 sweep), one of the leftovers round 6 (#24697) named. Tier 1 run #24598 at the sweep's console pin 4016370af3c9: grid-conditional-rules.spec.ts passed, but it flags the Description cell on one row and never saves, so #24598 scored acceptance[0] not-run (round 1's QA run #24572 had scored it pass on that spec). The ref now says the spec claims acceptance[0]'s inline-flag half only, and that no pin covers acceptance[1] or [4]; QA run #24616 drove acceptance[1], [3] and [4] by hand. The spec is byte-identical at the shipped pin 12dc7b47c340. grid-parent-rules.spec.ts and grid-file-upload.spec.ts stay cited as they were, and the automated.stale record (grid-file-upload.spec.ts) is unchanged. No clause changed", + "ref": "#24723" } ] }, @@ -1175,7 +1181,7 @@ "title": "Master + line items save as one atomic batch, with server-side roll-up", "since": "v16", "status": "active", - "revision": 4, + "revision": 5, "priority": "P1", "surface": "browser", "personas": [ @@ -1216,7 +1222,7 @@ { "clause": "invoice.total is a SERVER-side roll-up: computed on the atomic create, recomputed when a line is added and again when it is deleted", "oracle": "api", - "verify": "total == sum(line.amount) after each mutation (pinned by objectui e2e/live/summary-rollup.spec.ts: computed on atomic create; recomputes on child add/delete)", + "verify": "total == sum(line.amount) after each mutation. No pin covers this clause: objectui e2e/live/summary-rollup.spec.ts, cited here until revision 5, asserts a server roll-up on another carrier (showcase_project's SUM / COUNT over showcase_task, written through a direct /api/v1/batch), never invoice.total", "evidence": "the three total reads" }, { @@ -1248,7 +1254,7 @@ ], "automated": { "kind": "e2e", - "ref": "objectui: e2e/live/master-detail.spec.ts, e2e/live/summary-rollup.spec.ts, e2e/live/form-view-subforms.spec.ts", + "ref": "objectui: e2e/live/master-detail.spec.ts, e2e/live/form-view-subforms.spec.ts. Dropped at revision 5: e2e/live/summary-rollup.spec.ts, which rolls showcase_task's estimate_hours up into showcase_project (total_estimate as a SUM, task_count as a COUNT) through a direct POST /api/v1/batch, reading both back after that create and again after a child delete. It never opens the invoice form and never reads invoice.total, the roll-up acceptance[2] scores, so it asserts no clause of this item (Tier 1 run #24598 scored acceptance[2] not-run on it for that carrier mismatch)", "stale": { "since": "2026-10-19", "observedIn": "#24598", @@ -1288,6 +1294,12 @@ "date": "2026-10-20", "change": "automated.stale added — §2 theme \"objectui live e2e is not green at its own pin\" of wave anchor #24579 (18.0 sweep). Tier 1 run #24598 at the sweep's console pin 4016370af3c9: form-view-subforms.spec.ts failed as a stale spec (a strict-mode locator collision; cause from QA run #24572, #24616 drove the item by hand); master-detail.spec.ts and summary-rollup.spec.ts passed and stay cited. Re-read at the shipped pin 12dc7b47c340: the spec and the colliding description are unchanged. No clause changed", "ref": "#24697" + }, + { + "revision": 5, + "date": "2026-10-20", + "change": "automated.ref and acceptance[2].verify corrected — §2 theme \"pins that cover no full clause\" of wave anchor #24579 (18.0 sweep), one of the leftovers round 6 (#24697) named. Tier 1 run #24598 at the sweep's console pin 4016370af3c9: summary-rollup.spec.ts passed 2/2, but it rolls showcase_task up into showcase_project through a direct batch and never reads invoice.total, so #24598 scored acceptance[2] not-run on it (round 1's QA run #24572 had scored acceptance[2] pass on it). It asserts no clause of this item, so it is dropped from the ref and named there, and acceptance[2].verify no longer says it pins the clause. The spec is byte-identical at the shipped pin 12dc7b47c340. QA run #24616 drove the invoice.total roll-up by hand. master-detail.spec.ts and form-view-subforms.spec.ts stay cited, and the automated.stale record (form-view-subforms.spec.ts) is unchanged. No clause text changed", + "ref": "#24723" } ] }, diff --git a/docs/qa/platform-checklist/areas/studio-authoring.json b/docs/qa/platform-checklist/areas/studio-authoring.json index c9e9588bf45..28ff00d21eb 100644 --- a/docs/qa/platform-checklist/areas/studio-authoring.json +++ b/docs/qa/platform-checklist/areas/studio-authoring.json @@ -377,7 +377,7 @@ "title": "Metadata draft→publish lifecycle: drafts staged not served, publish flips visibility atomically, conflicts and invalid drafts refused, and the history/audit/diff/rollback forensics tell the truth", "since": "v16", "status": "active", - "revision": 7, + "revision": 8, "priority": "P1", "surface": "mixed", "personas": ["admin (authors drafts)", "end user (must not see drafts)"], @@ -386,6 +386,9 @@ "requires": [ "scratch metadata names only (e.g. qa_lifecycle_probe) via the draft door PUT /api/v1/meta//?mode=draft — no shipped showcase file is touched", "a writable package with two stageable drafts for the package-wide publish-drafts door" + ], + "knownGaps": [ + "NO PIN COVERS A FULL CLAUSE — `automated` was dropped at revision 8, so this P1 item is hand-driven (Tier 2). packages/qa/dogfood/test/dashboard-designer-roundtrip.dogfood.test.ts, the pin it cited, saves a layout-less dashboard as a draft (PUT ?mode=draft answers 200), publishes it (200) and reads it back as { type, name, item } with its three widgets. That is acceptance[1]'s post-publish half and nothing more: it asserts no state:'draft' receipt and makes no pre-publish read (acceptance[0], and acceptance[1]'s never-served half), and it probes none of acceptance[2]–[11]: no second draft, stale If-Match, publish-drafts batch, invalid draft, Studio chrome, history, diff, rollback, audit or X-Actor. So it scores no clause (Tier 1 run #24598: every clause not-run). Re-add `automated` only with a pin that asserts a full clause." ] }, "steps": [ @@ -486,7 +489,6 @@ "OPEN LEDGER QUESTION, not a verdict (run #7695 → #7753 item 2): publish-drafts' namespace-gate abort answers HTTP 200 with data.success:false rather than a 4xx. The envelope-level success flag may well be the intended contract for this door, and the atomicity behind it is correct (the abort leaves both names 404) — but an HTTP-status-only client reads an aborted publish as a successful one, which is why it is worth ONE deliberate ruling. Recorded here so the observation is not re-derived every run; a runner does not adjudicate it and does not score it as a FAIL" ], "traps": ["hydration-race", "dispatcher-vs-hono-route"], - "automated": { "kind": "e2e", "ref": "packages/qa/dogfood/test/dashboard-designer-roundtrip.dogfood.test.ts" }, "source": [ "packages/spec/src/api/protocol.zod.ts#SaveMetaItemResponse (SaveMetaItemResponse: state draft|active, version as If-Match/409 OCC token, 'staged only — not served until published')", "packages/runtime/src/domains/packages.ts#packages (POST /packages/:id/publish-drafts, ADR-0033/ADR-0045 visibility flip + its failure warning)", @@ -503,7 +505,8 @@ { "revision": 4, "date": "2026-08-17", "change": "re-spell after [#7941]: the rollback step and the audit clause named X-Actor as an alternate actor source alongside the session identity; #7941 removed the header limb from resolveMetaWriteActor entirely (landed as commit 4dc8a618e, PR #9119) so it is now the SOLE source and X-Actor is ignored outright, not consulted even as a fallback. Re-spelled the rollback step, the audit acceptance clause, and the rest-server.ts source pointer to name the single source; added a new step + acceptance clause pairing the inverted check the finding asked for — send X-Actor and confirm it does NOT change the recorded actor — since that is now a meaningful QA-layer assertion nothing else covers (the unit pins live in packages/rest/src/meta-write-actor-identity.test.ts, added as a source pointer). The capability itself (audit rows name the acting user, never anonymous) is unchanged and was never wrong.", "ref": "#9118" }, { "revision": 5, "date": "2026-10-13", "change": "steps[9] and acceptance[8] (clause and verify) diff the two publish versions read off /history, and steps[8] and acceptance[7].verify say how history counts (assertion defect, #23166 A8; parked on #23121, carried by #23169). sys_metadata_history records draft saves and publishes alike, so ?from=1&to=2 compared the first draft save with its own publish (changed []); on QA run #23166's clean two-round run the published revisions were v2 and v4, and their diff named the edited widget key. The rollback steps are unchanged", "ref": "#23169" }, { "revision": 6, "date": "2026-10-16", "change": "steps[2] and acceptance[6] (clause, verify) re-pointed (checklist-accuracy finding 4 of QA run #23942, wave #23878). The Studio counter is no longer 'Changes · n' text but a numbered pill on the Changes button (objectui#12459), and the pill counts the drafts of the package in scope — an env-wide (package-less) dashboard draft is counted in none, so #23942 staged the browser leg's draft in a writable package. The step and clause name the pill and the writable-package staging, and the step says how to reach the draft in Studio — through an app of that package whose navigation names the dashboard, since a package with no app offers no dashboard to select (the re-run on #24036 found no chip until it staged one). Not loosened: a chip or pill that survives the publish, or is missing while the draft is pending, still FAILS", "ref": "#24036" }, - { "revision": 7, "date": "2026-10-19", "change": "steps[2], acceptance[6].clause and acceptance[6].verify corrected from QA run #24604 (18.0 sweep round 2, ba4afcc2), re-read at the console pin 4016370af3c9: the Studio item header reads 'Draft · N unpublished' (engine.studio.itemDraftPending, objectui#12725) — 'Unpublished draft' is the chip of other surfaces (ObjectListViewInspector, the OWD overview), not this item header — and a REST publish shows in Studio only after a reload. The round's other draft notes are not taken: no step of this item discards a draft (so the ?state=draft discard spelling has no clause to correct), and the NS_ prefix a scratch dashboard was given is not required (the namespace-prefix rule judges objects only — packages/spec/src/kernel/namespace-prefix.ts). Wave anchor #24579 round 2 §3 (6272314386)", "ref": "#24671" } + { "revision": 7, "date": "2026-10-19", "change": "steps[2], acceptance[6].clause and acceptance[6].verify corrected from QA run #24604 (18.0 sweep round 2, ba4afcc2), re-read at the console pin 4016370af3c9: the Studio item header reads 'Draft · N unpublished' (engine.studio.itemDraftPending, objectui#12725) — 'Unpublished draft' is the chip of other surfaces (ObjectListViewInspector, the OWD overview), not this item header — and a REST publish shows in Studio only after a reload. The round's other draft notes are not taken: no step of this item discards a draft (so the ?state=draft discard spelling has no clause to correct), and the NS_ prefix a scratch dashboard was given is not required (the namespace-prefix rule judges objects only — packages/spec/src/kernel/namespace-prefix.ts). Wave anchor #24579 round 2 §3 (6272314386)", "ref": "#24671" }, + { "revision": 8, "date": "2026-10-20", "change": "automated dropped and fixtures.knownGaps[0] added — §2 theme \"pins that cover no full clause\" of wave anchor #24579 (18.0 sweep), one of the leftovers round 6 (#24697) named. Tier 1 run #24598 scored every clause not-run on dashboard-designer-roundtrip.dogfood.test.ts, green 3/3 at ba4afcc2: it saves, publishes and reads back a layout-less dashboard, which is acceptance[1]'s post-publish half and no full clause. Round 1's QA run #24571 had scored acceptance[0]–[5] and [7]–[11] pass on that pin alone; QA run #24604 drove acceptance[6] and negative[0]–[4] by hand. The item had no knownGaps, so the line is new: it says what the pin asserts and when `automated` may return. The item is now Tier 2 (P1, no pin). No clause changed", "ref": "#24723" } ] }, {