R3 runner, area 2 of 4. Part of the #9296 wave. No clause failed. Eight items were not reached and are recorded not-run rather than inferred.
⚠️ Title deviates from the wave's (FULL area) convention on purpose — 4 of 14 items consulted.
Environment fingerprint
Identical to #9330 (same tree, same boots): framework e4e5c6e3c608b1b807c83a0d5b734f213eb1a1dd · .objectui-sha665661ab093263f39f2e660a295ea615dbcee35a · console dist stamp equals pin (check:console-sha ✓) · port 3304 · file:/tmp/qa-r3b/identity-auth-pwreset.db (rm -f before boot) · --seed-admin (admin@objectos.ai) · 2026-08-17. Driving used http://localhost:<port> — better-auth rejects 127.0.0.1 with 403 INVALID_ORIGIN.
Spec provenance: as in #9330, the checklist came from PR #9309 head fbd1c049, not merged main — #9309 is open and explicitly held pending the maintainer. Validator (pinned): 190 items (190 active); 30 kinds mapped, 0 waived. Selector area:identity-auth → 12 runnable + 2 hidden-blocked = 14.
Automated pins (RUNNER rule 6)
pnpm exec vitest run over the area's three declared automated.ref files — 10/10 passed, 0 failed.
Per-clause verdicts
identity-auth.auth-method-matrix — rev 2, P1, mixed → partial
| clause group | verdict | oracle evidence (text) |
|---|
| OIDC authorization-code leg | pass (pin) | "authorize: skip_consent client gets an immediate code redirect"; "token exchange succeeds and persists the access-token row (the 1.7-drift 500)"; "userinfo answers with the signed-in subject" |
| remaining method cells (10 acceptance clauses total) | not-run | the pin covers the OIDC leg only; the rest of the method matrix was not driven |
identity-auth.invitation-scope-gates — rev 3, P1, mixed → partial
| clause | verdict | oracle evidence (text) |
|---|
| delegated_admin may invite | pass (pin) | "a delegated_admin CAN issue an invitation — the gate finally has a caller" |
delegate escalating to admin refused, no row left behind | pass (pin) | "the same delegate issuing admin is REFUSED, with no invitation row left behind" — persistence of the denial, not just the status |
| org owner may provision a delegated_admin | pass (pin) | "an org owner CAN invite someone AS a delegated_admin — the provisioning flow" |
| plain member cannot invite at all | pass (pin) | "a plain member still cannot invite at all — the ROLE is what opened the endpoint" — the unentitled side |
| remaining clauses (7 acceptance / 3 negative) | not-run | console-side and scope-boundary cells not driven |
Both sides of this gate are pinned, which is the substance of the item: entitled caller succeeds, unentitled caller refused, escalation refused with no residue.
identity-auth.admin-lifecycle-operations — rev 3, P1, mixed → partial
| clause | verdict | oracle evidence (text) |
|---|
POST /admin/create-user audited | pass (pin) | "plugin-audit's hook fires for the better-auth write, alongside the explicit row" |
POST /admin/set-user-password audited | pass (pin) | "sys_account is in SKIP_OBJECTS, so the explicit row is the ONLY trail" |
POST /admin/import-users audited | pass (pin) | "the run-level row complements the per-row rows the hook writes" |
| remaining clauses (10 acceptance / 4 negative) | not-run | lifecycle operations beyond the audit trail not driven |
identity-auth.self-service-password-reset — rev 1, P1, api → partial
Driven live on a dedicated boot with EMAIL_TRANSPORT_PROVIDERS=log.
| clause | verdict | oracle evidence (text) |
|---|
| A0 request produces a real reset artifact | blocked(fixture) | POST /auth/request-password-reset → 200 {"status":true,"message":"If this email exists in our system, check your email for the reset link"} — the non-leaking response is correct, but no reset link/token appeared in the transport output, so the artifact could not be captured. See the ruling-out below. |
| A1 token completes reset + rotates credential | blocked(fixture) | depends on A0's token |
| A2 consumed token cannot be reused | blocked(fixture) | depends on A0's token |
| A3 expired/tampered token refused loudly, credential unchanged | pass | garbage token → 400 INVALID_TOKEN; the old password still signs in afterwards, so nothing changed silently (N3 satisfied) |
| A4 no account-existence leak | pass | known-email and unknown-email requests are byte-identical in both status and body (200, same message) — computed as an equality check, not eyeballed (N2 satisfied) |
Why A0 is blocked(fixture), not a fail — ruled out before recording, per RUNNER rule 2:
EmailServicePluginis in the booted plugin list, so a service exists.auth-manager.ts:1187 throws "no email service is configured for this deployment" when one is absent — that error is not in the log, so the send path did not take the misconfiguration branch.- The only better-auth warning logged was
Reset Password: User not found, which corresponds to the unknown-email probe, not the known one. - The item's own
knownGaps name exactly this outcome: "if the deployment sends via a real provider with no capture hook, the token-capture step is blocked(fixture); the request/refusal clauses that don't need the token still run." That is precisely what happened.
Corroboration of the item's documented divergence: step s0 warns that the spec's AuthEndpointPaths says /forget-password while the live route is /request-password-reset. Confirmed — the live route answered 200. The item's instruction to trust the live server is correct and the divergence still stands at this sha.
Blocked (2, from the ledger)
identity-auth.oauth-app-consent-loop (P2) and identity-auth.linked-accounts-social (P2) carry blocked: fixture and are hidden by the resolver by design. Recorded, not run.
Not-run (8)
No oracle consulted, not inferred: sso-enforced-first-paint (P2, browser) · phone-signin-surfaces (P2, browser) · session-list-revoke (P1) · api-key-ui-lifecycle (P1) · self-service-profile-password (P1) · org-membership-team-management (P1) · teams-bu-membership (P2) · identity-import-wizard (P2).
Coverage honesty
4 of 14 items consulted; no clause failed; 4 partial, 2 blocked, 8 not-run. Every verdict above rests on server truth (test or api oracles) — no screenshot or DOM oracle was used in this area, and no clause was ticked from a sibling item's evidence.
On the standing wrong-persona risk: the invitation pin drives all four persona positions (delegate-allowed, delegate-escalating, owner-provisioning, plain-member-refused), so that item's gate is proven from both sides. The unreached items are the ones where a second real login would matter most; note for #9308 that POST /auth/sign-up/email does yield real loginable personas, which is how the access-security area (#9330) drove its gates both ways without a seeded fixture.
Links: #9296 (wave) · #9330 (area 1) · #9309 (spec provenance) · #9308 (fixture card).
R3 runner, area 2 of 4. Part of the #9296 wave. No clause failed. Eight items were not reached and are recorded
not-runrather than inferred.(FULL area)convention on purpose — 4 of 14 items consulted.Environment fingerprint
Identical to #9330 (same tree, same boots): framework
e4e5c6e3c608b1b807c83a0d5b734f213eb1a1dd·.objectui-sha665661ab093263f39f2e660a295ea615dbcee35a· console dist stamp equals pin (check:console-sha✓) · port 3304 ·file:/tmp/qa-r3b/identity-auth-pwreset.db(rm -fbefore boot) ·--seed-admin(admin@objectos.ai) · 2026-08-17. Driving usedhttp://localhost:<port>— better-auth rejects127.0.0.1with403 INVALID_ORIGIN.Spec provenance: as in #9330, the checklist came from PR #9309 head
fbd1c049, not mergedmain— #9309 is open and explicitly held pending the maintainer. Validator (pinned):190 items (190 active); 30 kinds mapped, 0 waived. Selectorarea:identity-auth→ 12 runnable + 2 hidden-blocked = 14.Automated pins (RUNNER rule 6)
pnpm exec vitest runover the area's three declaredautomated.reffiles — 10/10 passed, 0 failed.Per-clause verdicts
identity-auth.auth-method-matrix— rev 2, P1, mixed → partialidentity-auth.invitation-scope-gates— rev 3, P1, mixed → partialadminrefused, no row left behindadminis REFUSED, with no invitation row left behind" — persistence of the denial, not just the statusBoth sides of this gate are pinned, which is the substance of the item: entitled caller succeeds, unentitled caller refused, escalation refused with no residue.
identity-auth.admin-lifecycle-operations— rev 3, P1, mixed → partialPOST /admin/create-userauditedPOST /admin/set-user-passwordauditedPOST /admin/import-usersauditedidentity-auth.self-service-password-reset— rev 1, P1, api → partialDriven live on a dedicated boot with
EMAIL_TRANSPORT_PROVIDERS=log.POST /auth/request-password-reset→200 {"status":true,"message":"If this email exists in our system, check your email for the reset link"}— the non-leaking response is correct, but no reset link/token appeared in the transport output, so the artifact could not be captured. See the ruling-out below.INVALID_TOKEN; the old password still signs in afterwards, so nothing changed silently (N3 satisfied)200, same message) — computed as an equality check, not eyeballed (N2 satisfied)Why A0 is
blocked(fixture), not afail— ruled out before recording, per RUNNER rule 2:EmailServicePluginis in the booted plugin list, so a service exists.auth-manager.ts:1187throws "no email service is configured for this deployment" when one is absent — that error is not in the log, so the send path did not take the misconfiguration branch.Reset Password: User not found, which corresponds to the unknown-email probe, not the known one.knownGapsname exactly this outcome: "if the deployment sends via a real provider with no capture hook, the token-capture step isblocked(fixture); the request/refusal clauses that don't need the token still run." That is precisely what happened.Corroboration of the item's documented divergence: step s0 warns that the spec's
AuthEndpointPathssays/forget-passwordwhile the live route is/request-password-reset. Confirmed — the live route answered200. The item's instruction to trust the live server is correct and the divergence still stands at this sha.Blocked (2, from the ledger)
identity-auth.oauth-app-consent-loop(P2) andidentity-auth.linked-accounts-social(P2) carryblocked: fixtureand are hidden by the resolver by design. Recorded, not run.Not-run (8)
No oracle consulted, not inferred:
sso-enforced-first-paint(P2, browser) ·phone-signin-surfaces(P2, browser) ·session-list-revoke(P1) ·api-key-ui-lifecycle(P1) ·self-service-profile-password(P1) ·org-membership-team-management(P1) ·teams-bu-membership(P2) ·identity-import-wizard(P2).Coverage honesty
4 of 14 items consulted; no clause failed; 4 partial, 2 blocked, 8 not-run. Every verdict above rests on server truth (
testorapioracles) — no screenshot or DOM oracle was used in this area, and no clause was ticked from a sibling item's evidence.On the standing
wrong-personarisk: the invitation pin drives all four persona positions (delegate-allowed, delegate-escalating, owner-provisioning, plain-member-refused), so that item's gate is proven from both sides. The unreached items are the ones where a second real login would matter most; note for #9308 thatPOST /auth/sign-up/emaildoes yield real loginable personas, which is how the access-security area (#9330) drove its gates both ways without a seeded fixture.Links: #9296 (wave) · #9330 (area 1) · #9309 (spec provenance) · #9308 (fixture card).