| Prior finding | Disposition | Rev-4 assessment |
|---|---|---|
| R1-1: Login CSRF | fixed | §5.1 requires a confirmation nonce and origin checks; §11 retires legacy confirmation. |
| R1-2: Unlimited guessing budgets | fixed | §5 bounds guesses across challenges and creates no redeemable challenge for refused requests. |
| R1-3: Pending-action hash mismatch | fixed | §6 specifies redemption by hash with session binding, expiry and single-use checks. |
| R1-4: SMTP fallback to Keymail | fixed | §§4 and 11 specify discovery and the settled B4 fallback policy for invites and notices. |
| R1-5: First CLI step-up email suppressed | fixed | Email sign-in records fresh authentication; step-up has separate send limits. |
| R1-6: Challenge outlives pending action | fixed | §6 aligns step-up challenges with the pending action’s ten-minute lifetime. |
| R1-7: Recipient validation | fixed | §11 requires a normalized, strictly parsed bare address throughout. |
| R1-8: `next` bypasses onboarding | fixed | §8 requires account selection or creation before following `next`. |
| R1-9: Existing SES identity ownership | fixed | §9 requires the adoption check and ownership TXT record. |
| R2-1: Offline code recovery | fixed | §5 authenticates code digests with a key held outside the database. |
| R2-2: Cross-browser link invalidation | fixed | §5 preserves other challenges’ links when the shared guessing limit is exhausted. |

Reviewed spec rev 4 at `0c1a28ba`. These dispositions concern the design, not completed implementation. **No new P1 findings; two new P2 findings.**

1. **P2 — The unavailable-mailer response exposes rate limiting.**

   **Spec:** [§4.2](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/email-signin/docs/superpowers/specs/2026-10-21-console-email-signin-design.md:128), §7 and §3’s anti-oracle requirement.

   **Evidence:** A disabled mailer is an ordinary supported state: [cmd/console/main.go:1024](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/email-signin/cmd/console/main.go:1024) returns `nil` under claim mode; missing mail configuration also returns `nil`.

   **Failure:** §4.2 explicitly gives an email-bound request an unavailable-mailer response, but gives a rate-limited request the normal “check your email” page. With mail disabled, submitting the same address before and after the 30-submissions IP cap produces distinguishable responses. This reveals throttling, contrary to §3, and tells the throttled person to expect mail from a console that cannot send it.

   **Fix:** Make the unavailable-mailer response independent of throttling. Enforce request limits internally while rendering the same unavailable response for both cases.

2. **P2 — The unverified-mailer refusal lacks a readiness mechanism.**

   **Spec:** §4.2 requires an immediate refusal when the sending identity is unverified, while moving delivery into a background goroutine.

   **Evidence:** [consolemail.go:33](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/email-signin/internal/console/consolemail.go:33) exposes only `Send`. The constructor returns a non-nil mailer before verification; its startup `Ensure` provisions the identity but does not establish readiness. Verification occurs inside private `ready`, called by [Send at consolemail.go:166](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/email-signin/internal/console/consolemail.go:166).

   **Failure:** With configuration present but DKIM verification pending, a nil check passes. Following the specified background-send sequence renders “check your email” before `Send` returns `ErrConsoleMailNotReady`. The required refusal cannot be implemented through the existing interface, and the spec supplies no replacement readiness mechanism.

   **Fix:** Specify a readiness API or maintained readiness state, including refresh while verification is pending. Check it before creating the challenge and choosing the response; keep delivery asynchronous.

No files were edited. No test suites were run.