Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
ac41de6
docs(qa): re-point query-contract-matrix to the doors' post-schema-re…
claude Oct 1, 2026
809aa82
test(dogfood): pin the anonymous 401 on POST /batch and GET /security…
claude Oct 1, 2026
bcb97af
docs(qa): close the P0 run's access-security checklist-accuracy findings
claude Oct 1, 2026
b6b8d70
test(showcase): smoke reaches all 49 nav destinations and waits past …
claude Oct 1, 2026
89177bc
test(showcase): judge the two chart destinations among the 18 as charts
claude Oct 1, 2026
bec0fa0
docs(qa): nav-surfaces-render and RUNNER facts follow the re-measured…
claude Oct 1, 2026
4d3bd4b
docs(qa): boot-health, seed-integrity and packaged-action items read …
claude Oct 1, 2026
faf39ec
docs(qa): mcp-stdio-fail-closed names two personas, the real refusal …
claude Oct 1, 2026
108a2d3
docs(qa): dev-boot-contract prescribes an unshared app dir, names exi…
claude Oct 1, 2026
e28b931
docs(qa): datasource-credential-refusal-matrix matches the doors a st…
claude Oct 1, 2026
a9abef2
docs(qa): console-login and builtin-apps-nav-render match what a stoc…
claude Oct 1, 2026
bf76844
docs(qa): crud-roundtrip records its unobservable readonly half and t…
claude Oct 1, 2026
4f98e8f
docs(qa): approvals account-app-entry names the zh-CN option, both ta…
claude Oct 1, 2026
385f131
docs(qa): first-run-loop follows the Studio the pinned console ships
claude Oct 1, 2026
de73aa8
Merge origin/main into claude/issue-21060-p0-sweep-checklist
claude Oct 1, 2026
db092de
docs(qa): RUNNER states the stock invite_only posture and the two doo…
claude Oct 1, 2026
2868709
Merge origin/main into claude/issue-21060-p0-sweep-checklist
claude Oct 1, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions docs/qa/platform-checklist/FOLLOW-UPS.md
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,14 @@ declares exactly `.` and `./logger`. Do not re-derive the subpath.
| D14 | `MigrationRecoveryPlugin` is composed by NO boot path — `serve.ts` auto-registers `PlatformObjectsPlugin` but never the recovery plugin; standalone-stack, default-host, the showcase config, and the migrate CLI boot all omit it; only its unit test instantiates it. Interrupted-migration detection therefore never runs on any shipped boot, while `sys-migration-journal.object.ts` argues recovery must need "zero host wiring" | `packages/runtime/src/index.ts` (exported); `serve.ts` (what IS auto-registered) | platform-core.interrupted-migration-boot-report (fixtures an explicit registration; knownGap names the composition hole) | correctness/composition — safe to file |
| D15 | `extract-hook-body.ts`'s header promises "the build fails… no silent fallback" on a forbidden pattern, but the DEFAULT `os build` catches every extraction error and silently falls back to the.mjs bundle (`lower-callables.ts`), printing the warnings nowhere; only `--strict-body` (`compile.ts`) produces the worded refusals with exit 1. `hook-bodies.mdx` documents the warn-and-bundle default, so code comment and docs disagree with each other | `extract-hook-body.ts` vs `lower-callables.ts`, `compile.ts` | cli.hook-body-extraction-gates (default-path silent-fallback encoded as expected-fail contradiction clause) | correctness — safe to file |

⚠️ **Handle collision on D11 (#21060).** The D11 row above is the two-factor `get-totp-uri`
re-reveal. It is **not** the private handle D11 that `access-security.rls-both-sides`
clause 5 and `access-security.owd-sharing-matrix` clause 4 cite. That handle names a
security-sensitive defect delivered to the maintainer privately (#7463), and it is
deliberately not reproduced in this file. The two numbers collided when this table continued
the D-series. Cite the item and its clause, never the bare handle, and never read one D11 as
the other.

Two design notes captured inside items rather than as defect rows: `sys_user.mfa_required_at`
is stamped lazily and never cleared anywhere in source, so post-disable re-gating branches on
a pre-existing stamp (identity-auth.two-factor-disable-lifecycle, design-note clause); and
Expand Down
48 changes: 40 additions & 8 deletions docs/qa/platform-checklist/RUNNER.md
Original file line number Diff line number Diff line change
Expand Up @@ -139,17 +139,19 @@ contradicts it, and correct it here when it does.
section at all.** `runRlsProofs` runs only behind the flag
(`packages/cli/src/commands/verify.ts`: `rls: Flags.boolean({ default: false })`, the
proofs sit inside `if (flags.rls)`, and the report prints `if (rls)`). **Check:** the
last block of a bare run is the CRUD summary — `── 16 verified, 0 gaps, 0 FAILED, 1
needs-fixture, 7 skipped` on stock showcase — with no `PROVEN`/`HOLES` line anywhere.
last block of a bare run is the CRUD summary — `── 15 verified, 0 gaps, 0 FAILED, 1
needs-fixture, 8 skipped` on stock showcase — with no `PROVEN`/`HOLES` line anywhere.
Adding `--rls` appends the RLS block. ⛔ Do not cite plain `verify` output as the
oracle for an RLS clause — that run never consulted one.

**The discriminator is the PRESENCE of a `PROVEN`/`HOLES` line, never its digits.**
The counts move with the seed set and are recorded here only as the shape to expect:
the CRUD tail read `15 verified` through 2026-08-18 and reads `16` on 17.1.0 because
the CRUD tail read `15 verified` through 2026-08-18 and `16` on 17.1.0 because
the showcase gained one object (`client-brief.object.ts`, added between the two sweep
subjects); a run whose digits differ has a different seed, not a regression. Re-derive
the number, do not file it.
subjects), and reads `15 verified … 1 needs-fixture, 8 skipped` again by 2026-10-01
(QA run #21056, re-measured for #21060): one object moved from verified to skipped,
the 24-object total unchanged. A run whose digits differ has a different seed, not a
regression. Re-derive the number, do not file it.

⚠️ **The `--rls` block prints TWO summary lines in DIFFERENT units — do not compare
them.** `formatRlsReport` (`packages/verify/src/rls.ts`) emits a per-persona
Expand All @@ -160,7 +162,9 @@ contradicts it, and correct it here when it does.
source stamps that unit into the line precisely so the two are not read as one number
moving. Measured on 17.1.0: the total line reads
`all personas: 38 PROVEN (38 consistent, 0 HOLES) · 226 NOT PROVEN`, alongside
`9 of 9 declared position(s) probed`. An older note here recorded
`9 of 9 declared position(s) probed`; re-measured 2026-10-01 (#21060), the total line is
unchanged and the positions read `10 of 10` — the showcase declares ten positions
now (digits only, as above). An older note here recorded
`20 PROVEN … over 23 objects` — that was the per-persona line, so it is **not
comparable** to the total rather than merely stale. Name which of the two lines you
are quoting whenever you cite either.
Expand All @@ -174,15 +178,16 @@ contradicts it, and correct it here when it does.
dies at browser launch — the error names the **headless-shell** variant it wanted
(`Executable doesn't exist at .../chromium_headless_shell-1234/...`), which is the
signature to recognise. Pass `launchOptions.executablePath=/opt/pw-browsers/chromium`
and the same specs pass (verified: Playwright launches through it, reporting Chromium
(for the smoke, `OS_TEST_CHROMIUM_EXECUTABLE_PATH=/opt/pw-browsers/chromium`, which the
config reads since #21060) and the same specs pass (verified: Playwright launches through it, reporting Chromium
141.0.7390.37, and drives a real page). ⚠️ Use that **alias**, not the versioned
`chromium-1194/chrome-linux/chrome` beneath it: `/opt/pw-browsers/chromium` is a
symlink maintained by the image build, so it still resolves after the image moves to
1234, while the versioned literal stops existing at exactly that moment — and a dead
path copied out of this section is the `absence-inference` trap one level up.
**The discriminator is uniformity:** a launch/environment failure
takes down the whole run at once (`showcase-smoke.spec.ts` generates one test per
`SURFACES` entry — 31 today, so "31 failed" means all of them), while a product defect
`SURFACES` entry — 49 today, so "49 failed" means all of them), while a product defect
fails selectively. ⛔ Do not file a whole-run red as a product defect before checking
the browser resolved.

Expand Down Expand Up @@ -263,6 +268,33 @@ contradicts it, and correct it here when it does.
upload is broken". ⛔ Do not drive any storage/upload surface from an injected
token: **sign in through the form** so both halves exist.

- **A stock showcase boot refuses self-registration — no item can mint a member by
"fresh sign-up".** The showcase declares no `auth.audience`, so its posture is the
`invite_only` default (`packages/plugins/plugin-auth/src/audience-posture.ts`:
`resolveAudience` — undeclared ⇒ `invite_only`; the migration entry
`audience-posture-default-invite-only` records the flip), and
`POST /api/v1/auth/sign-up/email` for an address holding no pending invitation answers
**`403 SELF_REGISTRATION_CLOSED`** (`decideAudienceAdmission` in the same file; the code
is in the ADR-0112 ledger, `error-code-ledger.zod.ts`). QA run #21056 met it on every
member persona it needed. Two doors mint one instead:
1. **Invite, then sign up.** As admin, `POST /api/v1/auth/organization/invite-member`
with `{"email": "EMAIL", "role": "member"}`; a pending, unexpired `sys_invitation`
row for that address is what admits the following `sign-up/email`
(`packages/plugins/plugin-auth/src/auth-manager.ts`, `hasPendingInvitationFor`).
2. **Admin create.** `POST /api/v1/auth/admin/create-user`, which answers
`mustChangePassword: true` by default
(`packages/plugins/plugin-auth/src/admin-user-endpoints.ts`, `runAdminCreateUser`);
have the persona `POST /api/v1/auth/change-password` before driving it.

The worked example is the shared recipe `search:qa-contributor-bound-member`
(`areas/search.json`), whose `requires` carries the invite ahead of its step-1 sign-up.
Wherever an item still says "fresh sign-up", read it as an identity minted one of these
two ways. ⛔ Do not record a member clause `blocked(fixture)` on the strength of the 403,
and do not file it: the refusal is the posture working. The seeded demo personas
(`examples/app-showcase/src/security/demo-personas.ts`, password `showcase123`) are
loginable already, but they hold fixed positions, so they fit only where an item names
them.

- **A cold tree cannot boot the app from the console-build recipe alone.**
`pnpm objectui:build` runs `scripts/build-console.sh`, which builds the **console**, not
the framework CLI. On a fresh tree `packages/cli` has no `dist`, and the bare binary
Expand Down
Loading
Loading