ledger
1 file changed,
+4
−0
.superpowers/sdd/2026-08-23-idear/progress.md+4 −0
diff --git a/.superpowers/sdd/2026-08-23-idear/progress.md b/.superpowers/sdd/2026-08-23-idear/progress.md| index 2b5a324..955bf71 100644 |
| --- a/.superpowers/sdd/2026-08-23-idear/progress.md |
| +++ b/.superpowers/sdd/2026-08-23-idear/progress.md |
| @@ -84,3 +84,7 @@ Task 4: review — spec ❌, quality Needs work: 1 CRITICAL, 2 Important, 5 Mino |
| Task 4: Ruling (CRITICAL): canonicalise the Subject on BOTH sides, not one. Authorize normalises the address before writing Subject; rastrillo/auth mints the session as id.Address, and keymaildev/signin@v0.1.1 deliberately lowercases only the DOMAIN, preserving local-part case ("some ordinary mail systems are case-sensitive there"). So a visitor typing Alice@Corp.Test — which iOS does by default without autocapitalize="none" — gets a successful claim writing Subject "alice@corp.test", then a session with Subject "Alice@Corp.Test" that 404s on every guarded route forever, /members included. The instance is then permanently unusable and needs DB surgery. Fix: one normalizeSubject used at every Subject WRITE and in BySubject. It is a no-op on password's decimal ids and it makes the unique index on Subject actually mean one row per person. Writing the raw address (the literal spec text) is less catastrophic but still lets one human hold two rows. Cost if wrong: two case-variant addresses are treated as one member, which for a roster is the desired reading anyway. |
| Task 4: Ruling (spec clarification, done by me): the spec claimed the reconciliation route "resolves the Claim-race loser". Too terse rather than false — the loser holds no token, so the route cannot help until someone invites them; then they sign in (their app user row exists) and redeem there rather than through sign-up, which would fail on the duplicate email. Spec corrected so Task 5 does not implement a promise it cannot keep. |
| Task 4: fix round 1 dispatched (resume original implementer, opus), FIX_BASE 7fc0ee0 |
| +Task 4: fix round 1/5 (CRITICAL + 2 Important + 4 Minor all addressed; commits 7fc0ee0..ff6fafa). Re-reviewer independently reverted BySubject alone and reproduced the brick, confirming the round-trip tests genuinely pin it. Both contested claims verified: the DROP TABLE fault really is structurally insufficient (BySubject returns first), and Count(&n) is the ONLY *int64-destination query in the package so breakCounting cannot collide. |
| +Task 4: minor (deferred): internal/ideartest MemberAs seeds a raw Subject, bypassing normalizeSubject — deliberate, documented, test-only. Worth a cross-reference if a future test relies on seeded-vs-written Subject equality. Final review to triage. |
| +Task 4: complete (commits 5707e39..ff6fafa, review clean) |
| +Task 5: dispatched (opus), BASE ff6fafa — HTTP handlers + the reconciliation route |