diff --git a/docs/qa/platform-checklist/areas/records-forms.json b/docs/qa/platform-checklist/areas/records-forms.json index 2bb76959d0..227ff0069b 100644 --- a/docs/qa/platform-checklist/areas/records-forms.json +++ b/docs/qa/platform-checklist/areas/records-forms.json @@ -8,7 +8,7 @@ "title": "Create → read → update → delete a record through the console UI", "since": "v15", "status": "active", - "revision": 5, + "revision": 6, "priority": "P0", "surface": "browser", "personas": [ @@ -20,7 +20,7 @@ "showcase_account — writable standard object (sharingModel public_read_write), required name + status, format validations tax_id_format / billing_email_format (examples/app-showcase/src/data/objects/account.object.ts)" ], "knownGaps": [ - "Clause 7 (clone is RLS-gated) cannot be scored on showcase_account, the object every other clause here drives: it is public_read_write, so there is no persona for whom a source row is invisible. It needs showcase_invoice plus a contributor-bound member — the recipe qa-contributor-bound-member in areas/search.json. ⚠️ The recipe mechanism is AREA-SCOPED (provisioning.use must name a key in this area's own fixtures block, README.md; unresolved by the validator either way, deferred at #7716 / tracked #7720), so this item cross-references the recipe by name rather than opting in. Replay it from there; do not fork a second copy into this area." + "Clause 7 (clone is RLS-gated) cannot be scored on showcase_account, the object every other clause here drives: it is public_read_write, so there is no persona for whom a source row is invisible. It needs showcase_invoice plus a contributor-bound member — the recipe qa-contributor-bound-member in areas/search.json. ⚠️ The recipe mechanism is AREA-SCOPED (provisioning.use must name a key in this area's own fixtures block, README.md) and the validator now ENFORCES that scoping (#10593): a same-area `use` RESOLVES, and a `use` naming another area's recipe key FAILS check:platform-checklist as a dangling pointer, naming the item and the key that resolved to nothing. ⛔ So this reference cannot be spelled as `use` today — no cross-area spelling exists that the tooling accepts, and giving that pointer one is the open half of #10593 — and this item cross-references the recipe by name rather than opting in. Replay it from there; do not fork a second copy into this area." ] }, "steps": [ @@ -129,6 +129,12 @@ "date": "2026-08-21", "change": "named the object and persona clause 7 actually needs, and separated its refusal from the one next to it. The clause asks for a clone of a row the caller cannot SEE to be refused 404 RECORD_NOT_FOUND, but every other clause in this item drives showcase_account, which is public_read_write — no persona can fail to read a row there, so the clause was unscoreable on its own item's object. The 17.1.0 sweep hit this directly: cloning showcase_account as a seeded demo persona produced 403 PERMISSION_DENIED (a missing CREATE grant), a different gate that a status-only reading would have scored as the RLS refusal. Clause 7 now names showcase_invoice + INV-1003 + a contributor-bound member (recipe qa-contributor-bound-member, areas/search.json), requires the code and not just the status, requires the invisibility premise to be read first, and states the 404-vs-403 discriminator. A knownGap records the cross-area recipe reference and why `use` is not available here (#10236 B1)", "ref": "#10236" + }, + { + "revision": 6, + "date": "2026-08-21", + "change": "corrected a knownGap that had gone from stale FACT to stale PERMISSION. Clause 7's cross-area note said `provisioning.use` was 'unresolved by the validator either way' — true when written (deferred at #7716 / tracked #7720), false since the area-scoped resolve landed at #10593: a same-area `use` now resolves and a cross-area one FAILS check:platform-checklist, naming the item. The prose therefore invited exactly the edit the gate rejects. The note now states what is enforced today; the cross-area SPELLING is still undecided (the open half of #10593) and is deliberately NOT predicted here, so this correction cannot itself become the next stale permission. Item substance, steps, personas, fixtures and all acceptance clauses are unchanged — no run verdict is invalidated by this revision", + "ref": "#10809" } ] }, diff --git a/docs/qa/platform-checklist/areas/search.json b/docs/qa/platform-checklist/areas/search.json index fbd4fd2a7f..ef7f011ae8 100644 --- a/docs/qa/platform-checklist/areas/search.json +++ b/docs/qa/platform-checklist/areas/search.json @@ -49,7 +49,7 @@ ], "teardown": "delete the sys_user_position row and the invoice created in step 5, or simply discard the isolated file DB — the cheaper path an isolated boot makes free. The signed-up principal is not otherwise cleaned up; use a unique per-run email so a leftover account never collides.", "knownGaps": [ - "⚠️ The recipe mechanism is AREA-SCOPED: `provisioning.use` must name a key in the item's OWN area fixtures block (README.md), and the validator does not resolve it either way (deferred at #7716, tracked #7720). records-forms.crud-roundtrip clause 7 needs this same persona and lives in another area file, so it cross-references this recipe by name in its knownGaps instead of `use`-ing it. Replay it from here; do not fork a second copy.", + "⚠️ The recipe mechanism is AREA-SCOPED: `provisioning.use` must name a key in the item's OWN area fixtures block (README.md), and the validator now RESOLVES it (#10593): a same-area `use` resolves, and one naming another area's recipe key FAILS check:platform-checklist as a dangling pointer, naming the item and the key that resolved to nothing. records-forms.crud-roundtrip clause 7 needs this same persona and lives in another area file, so ⛔ it CANNOT `use` this recipe — no cross-area spelling exists that the tooling accepts today, and giving that pointer one is the open half of #10593 — and it cross-references this recipe by name in its knownGaps instead. Replay it from here; do not fork a second copy.", "The persona is a subset reader of showcase_invoice ONLY. showcase_account is public_read_write and showcase_contributor grants plain allowRead on it with no RLS, so a contributor still reads every account row — an item needing an invisible SOURCE row must drive showcase_invoice, not showcase_account.", "showcase_private_note is an EMPTY table for everyone and showcase_account reads identically (15 rows) for admin, Mei and Ada (#10236) — neither is usable as a both-sides RLS control. Recorded so the next runner does not reach for them." ] @@ -208,7 +208,7 @@ "title": "Search honors RLS both ways: a restricted member gets no hits — and no total leakage — from rows they cannot see; the entitled persona finds the same rows", "since": "v15", "status": "active", - "revision": 4, + "revision": 5, "priority": "P1", "surface": "api", "personas": ["seeded admin (sees all invoices)", "signed-up member bound to the contributor position via the qa-contributor-bound-member recipe (invoice_own_rows RLS: owner == current_user.email) — ⛔ NOT one of the seeded demo personas: Mei holds no position (PERMISSION_DENIED, object gate) and Ada holds auditor with viewAllRecords (all 12). See the recipe."], @@ -280,6 +280,12 @@ "date": "2026-08-21", "change": "promoted the contributor-bound-member provisioning from prose on this item to the replayable area recipe qa-contributor-bound-member, and named the two personas that do NOT satisfy it. The item was recorded blocked(fixture) by the 17.1.0 sweep, which reached for the seeded demo personas: Mei holds no position so showcase_invoice answers PERMISSION_DENIED at the OBJECT gate (no rows at all), and Ada holds auditor whose set carries viewAllRecords so she sees all 12 — neither is the strict subset every clause here rests on. Nothing was actually missing from the fixtures: #7629 drove this item 4/4 PASS on a fresh sign-up bound to `contributor`, whose invoice_own_rows RLS narrows selects to owner == current_user.email. The recipe now carries that sequence with a premise guard that distinguishes all three outcomes (403 = binding did not take, 12 rows = a VAMA set, 0 of 12 = correct), so the mis-provisioning is caught before any verdict rests on it (#10236 B1)", "ref": "#10236" + }, + { + "revision": 5, + "date": "2026-08-21", + "change": "pins the knownGaps correction made on the area recipe this item `use`s. qa-contributor-bound-member's first knownGap claimed the validator 'does not resolve it either way', which the area-scoped resolve at #10593 made false — a same-area `use` resolves, a cross-area one fails. Area-level recipes carry no `revision`/`history` of their own (the lifecycle check in scripts/check-platform-checklist.mjs is item-scoped, and none of the four recipes in this checklist has either field), so the revision of the item that `use`s the recipe is the ONLY pin a run record can hold that text against — which is why this item is bumped although none of its own fields changed. Steps, clauses, personas, fixtures and provisioning are all unchanged and no run verdict is invalidated", + "ref": "#10809" } ] },