Round R3 of the #9296 QA wave. One selector, one run, one issue. Sibling rounds: #9351 (records-forms), #9352 (approvals).
Environment fingerprint
| reading | value |
|---|
| framework sha | e4e5c6e3c608b1b807c83a0d5b734f213eb1a1dd (2026-08-17 11:29:50Z) |
.objectui-sha (pin) | 665661ab093263f39f2e660a295ea615dbcee35a |
| console dist stamp | 665661ab093263f39f2e660a295ea615dbcee35a — stamp == pin, pnpm check:console-sha exits 0 |
| app | showcase, --seed-admin (admin@objectos.ai / admin123) |
| port / db | 3203 · file:/tmp/qa-r3a/st.db (fresh, rm -f before boot) |
| runner | R3 runner session, 2026-08-17 |
Spec-forward step: as in #9351 — PR #9309 has not merged, and studio-authoring.json is not in its diff, so this area's spec is byte-identical either way. Nothing was committed.
Scope
node scripts/checklist-select.mjs area:studio-authoring --json → 12 runnable items, 0 blocked.
Result
0 PASS · 1 PARTIAL · 0 FAIL · 11 NOT-RUN.
This is the third area of a three-area assignment and got the remaining budget. Only org-override-registry-gate (the one api-surface item in the area) was driven. The other eleven are mixed — every one needs the browser — and are recorded not-run, not pass. The area needs a dedicated round.
Per-clause verdicts
studio-authoring.org-override-registry-gate rev 2 (P1, api) — partial (3 pass, 1 partial, 1 not-run)
Automated pin run first (RUNNER rule 6):
pnpm --filter @objectstack/objectql exec vitest run src/overlay-precedence.test.ts
→ Test Files 1 passed (1) · Tests 26 passed (26)
| # | oracle | verdict | evidence (one line) |
|---|
| 0 | api | pass | PUT /api/v1/meta/object/showcase_task replaying the object's own body with label changed → 403 NOT_OVERRIDABLE. The lock is server-side on an artifact-backed item of an allowOrgOverride=false kind |
| 1 | api | partial | the write half passes: PUT /api/v1/meta/view/qa_probe_view (an overlay-enabled kind) → 200. The "overlay takes precedence at read" half is not proven — the immediate GET /meta/view/qa_probe_view answered 404. That is almost certainly correct staging behaviour rather than a defect (a /meta write lands a draft, and studio-authoring.draft-publish-lifecycle c0 asserts drafts are staged and not served by the runtime read), but this round did not publish, so precedence-at-read is unverified. Deliberately not scored as a fail |
| 2 | api | pass | PUT /api/v1/meta/field/qa_probe_field → 403 NOT_CREATABLE, message: "Metadata type 'field' is code-only: the metadata-type registry declares allowRuntimeCreate=false" — declared-but-inert metadata refused at the door, not stored to never run |
| 3 | api | not-run | a brand-new object PUT (the "create open" half) returned 422 INVALID_METADATA against my minimal payload — the shape was incomplete, so the gate was never reached. Driver error, not a finding; the clause is unproven either way |
| 4 | api | pass | DELETE /api/v1/meta/view/qa_probe_view → 200 {"success":true,"reset":true,"seq":2,"message":"Deleted view 'qa_probe_view' — it no longer exists."}; the immediately repeated DELETE → 200 {"success":true,"reset":false,"message":"No view 'qa_probe_view' found — nothing to delete."}. reset:true when a row was removed, reset:false when none existed — exactly the clause |
Method note, since it changes how the next runner should probe this item: spec validation (422) runs before the registry gate, so a malformed payload masks the very refusal you are testing. My first pass sent thin bodies to six override-locked kinds and got 422 INVALID_METADATA from five of them — only field surfaced its real 403, because that gate fires earlier. To exercise clause 0 you must send a well-formed body; the reliable trick is to GET the artifact and PUT it back with one field changed, which is what produced the 403 above.
Not-run items (11)
first-run-loop (rev 1, P0) · object-designer-roundtrip (rev 1) · view-authoring-live (rev 1) · record-page-roundtrip (rev 2) · draft-publish-lifecycle (rev 4) · authoring-validation-not-persisted (rev 2) · expression-editors (rev 1) · permission-matrix-editor-ux (rev 1) · custom-page-render-and-blocks (rev 1) · page-variables-and-actions (rev 1) · custom-page-source-tiers (rev 1)
⚠️first-run-loop is a P0 and was not run. It should lead the next round.
draft-publish-lifecycle (rev 4) is the highest-value next target after it: 12 clauses, 11 of them api, so it is drivable without the browser — and this round's clause-1 observation above (a /meta PUT answering 200 while the runtime read 404s) is exactly its subject, already half-set-up.
Standing note carried forward, re-confirmed
RUNNER.md's environment fact — that view is in the overlay-allowed set and authoring one on stock read-only showcase is not blocked — held on this boot: the view PUT answered 200 with no OS_METADATA_WRITABLE and no ?package= trick, while object refused NOT_OVERRIDABLE and field refused NOT_CREATABLE. The fact needs no correction.
record-page-roundtrip rev 2 — stale-ref warning honoured, not re-derived
Its automated.ref carries an explicit stale marker (since: 2026-08-11, #7753 item 6) with a runnerRule: do not satisfy the item by citing those specs, and do not score their failure as a FAIL — drive the clauses by hand. Since the item was not driven this round, nothing was cited and nothing was scored from them. Flagging so the next round does not "discover" that red and misread it.
Browser prerequisite for the next round
Eleven of twelve items need the console. State verified this round: the console dist is built and stamped equal to the pin, /_console/ serves 200, and Chromium launches when given an explicit path (/opt/pw-browsers/chromium-1194/chrome-linux/chrome). What does not work is the repo's pinned @playwright/test@1.62.1, which resolves revision 1234 and fails instantly — full evidence in #9351. So this area is drivable; it just needs a driver that does not go through the repo's playwright config.
Links back to #9296.
Round R3 of the #9296 QA wave. One selector, one run, one issue. Sibling rounds: #9351 (records-forms), #9352 (approvals).
Environment fingerprint
e4e5c6e3c608b1b807c83a0d5b734f213eb1a1dd(2026-08-17 11:29:50Z).objectui-sha(pin)665661ab093263f39f2e660a295ea615dbcee35a665661ab093263f39f2e660a295ea615dbcee35a— stamp == pin,pnpm check:console-shaexits 0--seed-admin(admin@objectos.ai / admin123)file:/tmp/qa-r3a/st.db(fresh,rm -fbefore boot)Spec-forward step: as in #9351 — PR #9309 has not merged, and
studio-authoring.jsonis not in its diff, so this area's spec is byte-identical either way. Nothing was committed.Scope
node scripts/checklist-select.mjs area:studio-authoring --json→ 12 runnable items, 0 blocked.Result
0 PASS · 1 PARTIAL · 0 FAIL · 11 NOT-RUN.
This is the third area of a three-area assignment and got the remaining budget. Only
org-override-registry-gate(the oneapi-surface item in the area) was driven. The other eleven aremixed— every one needs the browser — and are recordednot-run, notpass. The area needs a dedicated round.Per-clause verdicts
studio-authoring.org-override-registry-gaterev 2 (P1, api) — partial (3 pass, 1 partial, 1 not-run)Automated pin run first (RUNNER rule 6):
PUT /api/v1/meta/object/showcase_taskreplaying the object's own body withlabelchanged → 403NOT_OVERRIDABLE. The lock is server-side on an artifact-backed item of anallowOrgOverride=falsekindPUT /api/v1/meta/view/qa_probe_view(an overlay-enabled kind) → 200. The "overlay takes precedence at read" half is not proven — the immediateGET /meta/view/qa_probe_viewanswered 404. That is almost certainly correct staging behaviour rather than a defect (a/metawrite lands a draft, andstudio-authoring.draft-publish-lifecyclec0 asserts drafts are staged and not served by the runtime read), but this round did not publish, so precedence-at-read is unverified. Deliberately not scored as afailPUT /api/v1/meta/field/qa_probe_field→ 403NOT_CREATABLE, message: "Metadata type 'field' is code-only: the metadata-type registry declaresallowRuntimeCreate=false" — declared-but-inert metadata refused at the door, not stored to never runobjectPUT (the "create open" half) returned 422INVALID_METADATAagainst my minimal payload — the shape was incomplete, so the gate was never reached. Driver error, not a finding; the clause is unproven either wayDELETE /api/v1/meta/view/qa_probe_view→ 200{"success":true,"reset":true,"seq":2,"message":"Deleted view 'qa_probe_view' — it no longer exists."}; the immediately repeated DELETE → 200{"success":true,"reset":false,"message":"No view 'qa_probe_view' found — nothing to delete."}.reset:truewhen a row was removed,reset:falsewhen none existed — exactly the clauseMethod note, since it changes how the next runner should probe this item: spec validation (422) runs before the registry gate, so a malformed payload masks the very refusal you are testing. My first pass sent thin bodies to six override-locked kinds and got
422 INVALID_METADATAfrom five of them — onlyfieldsurfaced its real403, because that gate fires earlier. To exercise clause 0 you must send a well-formed body; the reliable trick is toGETthe artifact andPUTit back with one field changed, which is what produced the 403 above.Not-run items (11)
first-run-loop(rev 1, P0) ·object-designer-roundtrip(rev 1) ·view-authoring-live(rev 1) ·record-page-roundtrip(rev 2) ·draft-publish-lifecycle(rev 4) ·authoring-validation-not-persisted(rev 2) ·expression-editors(rev 1) ·permission-matrix-editor-ux(rev 1) ·custom-page-render-and-blocks(rev 1) ·page-variables-and-actions(rev 1) ·custom-page-source-tiers(rev 1)first-run-loopis a P0 and was not run. It should lead the next round.draft-publish-lifecycle(rev 4) is the highest-value next target after it: 12 clauses, 11 of themapi, so it is drivable without the browser — and this round's clause-1 observation above (a/metaPUT answering 200 while the runtime read 404s) is exactly its subject, already half-set-up.Standing note carried forward, re-confirmed
RUNNER.md's environment fact — that
viewis in the overlay-allowed set and authoring one on stock read-only showcase is not blocked — held on this boot: the view PUT answered 200 with noOS_METADATA_WRITABLEand no?package=trick, whileobjectrefusedNOT_OVERRIDABLEandfieldrefusedNOT_CREATABLE. The fact needs no correction.record-page-roundtriprev 2 — stale-ref warning honoured, not re-derivedIts
automated.refcarries an explicitstalemarker (since: 2026-08-11,#7753 item 6) with arunnerRule: do not satisfy the item by citing those specs, and do not score their failure as a FAIL — drive the clauses by hand. Since the item was not driven this round, nothing was cited and nothing was scored from them. Flagging so the next round does not "discover" that red and misread it.Browser prerequisite for the next round
Eleven of twelve items need the console. State verified this round: the console dist is built and stamped equal to the pin,
/_console/serves 200, and Chromium launches when given an explicit path (/opt/pw-browsers/chromium-1194/chrome-linux/chrome). What does not work is the repo's pinned@playwright/test@1.62.1, which resolves revision 1234 and fails instantly — full evidence in #9351. So this area is drivable; it just needs a driver that does not go through the repo's playwright config.Links back to #9296.