From 2821d5d0848df5df33bd848028d3ef2c10c78f22 Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 31 Aug 2026 03:02:50 +0000 Subject: [PATCH] docs(qa): retarget readonly-package-locks-studio writable contrast at duplicate route (#9788) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit access-security.readonly-package-locks-studio's writable-package contrast side (step 5, acceptance clause 3) left "a WRITABLE (draft/app-local) object" unqualified. The maintainer ruled NO on a stock writable showcase package (2026-08-19, "接受你的所有建议"; reaffirmed 2026-08-25, "其他接 受") and directed retargeting at the platform's own runtime path instead: the runner clones the showcase base into a writable target via POST /packages/:id/duplicate (ADR-0070 D4 "duplicate base"). Bumped revision to 3 with a history entry; added a fixtures.requires line naming the runtime route explicitly, since the item never had a fixtures block before. Oracle stays api on both sides of the gate. Mirrors the sibling half already landed for automation.rollup-summary-filter (PR #11913, bb62d4d08) — same retarget, same route. This half's item never carried a blocked.by:fixture entry or a fixtures.knownGaps line (unlike the automation item), so there is nothing of that shape to remove here. Claude-Session: https://claude.ai/code/session_01Pk26oZ12t5N1hwGW1m1MgC Co-authored-by: Claude --- .../areas/access-security.json | 24 +++++++++++++++---- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/docs/qa/platform-checklist/areas/access-security.json b/docs/qa/platform-checklist/areas/access-security.json index 4fde3b4606..2cae993a2d 100644 --- a/docs/qa/platform-checklist/areas/access-security.json +++ b/docs/qa/platform-checklist/areas/access-security.json @@ -314,18 +314,24 @@ "title": "A read-only package actually locks Studio editing surfaces", "since": "v16", "status": "active", - "revision": 2, + "revision": 3, "priority": "P2", "surface": "mixed", "personas": [ "admin" ], + "fixtures": { + "app": "showcase", + "requires": [ + "the writable-package contrast side (step 5, acceptance clause 3) needs a writable target package — obtained at runtime via POST /packages/:id/duplicate (ADR-0070 D4 'duplicate base'), not a stock fixture" + ] + }, "steps": [ "boot showcase with the console; open Studio → object designer and the permission matrix on an object belonging to a read-only (installed/locked) package", "screenshot the surface; then read the DOM state of the edit affordances (checkboxes, Save)", "attempt the edit through the UI anyway (click a checkbox / Save) and capture what the client does", "forge the write directly: PUT /api/v1/meta/object/ with a trivial field change, as the same admin session", - "repeat the same PUT against a WRITABLE (draft/app-local) object to prove the guard discriminates by package writability, not by blanket denial" + "POST /packages/com.example.showcase/duplicate {targetPackageId: } (ADR-0070 D4 'duplicate base' — the platform's supported writable-base route) to clone the showcase base into a writable target, then repeat the same PUT against an object in that writable package to prove the guard discriminates by package writability, not by blanket denial" ], "acceptance": [ { @@ -341,9 +347,9 @@ "evidence": "PUT trace" }, { - "clause": "the same PUT against a writable object SUCCEEDS for the same admin — the lock keys on package writability, not on the route (both sides of the gate)", + "clause": "the same PUT against a writable object — obtained through the platform's own duplicate-base route, not a stock fixture — SUCCEEDS for the same admin — the lock keys on package writability, not on the route (both sides of the gate)", "oracle": "api", - "verify": "writable-target PUT answers 2xx and a follow-up GET shows the change", + "verify": "POST /packages/com.example.showcase/duplicate (ADR-0070 D4) to clone the showcase base into a writable target package, then PUT on an object in that target answers 2xx and a follow-up GET shows the change", "evidence": "both traces" }, { @@ -363,7 +369,9 @@ "source": [ "#3358 §5", "packages/spec/src/api/error-code-ledger.zod.ts (@objectstack/metadata-protocol codes)", - "ADR-0010 §3.3 (_lock)" + "ADR-0010 §3.3 (_lock)", + "packages/runtime/src/domains/packages.ts (POST /packages/:id/duplicate — ADR-0070 D4 'duplicate base', the writable-target route)", + "docs/adr/0070-package-first-authoring.md §D4 ('clone a base into a new writable package')" ], "history": [ { @@ -377,6 +385,12 @@ "date": "2026-08-07", "change": "expanded to deep-test contract: concrete steps, multi-clause acceptance, negatives, variants", "ref": "claude/platform-test-checklist-ocwugl" + }, + { + "revision": 3, + "date": "2026-08-31", + "change": "retargeted the writable-package contrast side (step 5, acceptance clause 3) at the platform's supported runtime path per the maintainer ruling on #9788 (2026-08-19, 「接受你的所有建议」; reaffirmed 2026-08-25, 「其他接受」): the stock showcase does NOT boot with a writable package, so the runner instead clones the showcase base via POST /packages/:id/duplicate (ADR-0070 D4 'duplicate base') to get the writable contrast object. Added a fixtures.requires line naming the runtime route explicitly, since the item previously left the writable side as an unqualified 'a WRITABLE (draft/app-local) object'. Mirrors the sibling half landed for automation.rollup-summary-filter (PR #11913, bb62d4d08).", + "ref": "#9788" } ] },