Closer/ClaudeReport.md

6.0 KiB
Raw Blame History

Claude QA Report — Full-App QA (living report)

Verdict (2026-06-26, R9): 0 open P0P2 (1 P3 J-OBS, non-blocking). I-001/I-002 confirmed + pruned. Security cornerstone clean. At the flawless bar.

This report shows current state only. Fixed issues live here for one confirmation round, then they're pruned to the archived-ID line below (full detail stays in git history). See Report hygiene in ClaudeQAPlan.md.

Run-state (current)

Round 9 — COMPLETE (clean confirmation round, 0 new findings) | 0 open P0P2 (1 P3 J-OBS) | I-001/I-002 pruned; deferred Pass C + Pass F network swept | NEXT ACTION: FLAWLESS — optional P3 J-OBS fix + low-risk deferred (time-gated content, deletion-cascade) in a future round.

  • Build: client HEAD 23dd6a7, Cloud Functions deployed.
  • Devices / accounts: emulator-5554 = QA (Y05AKO2IlTPMa0JQW1BiNIM0uzK2) · emulator-5556 = Sam (imDjjO…) · paired, coupleId Xal3Kw3gjSdn0niERYKJ, both free (baseline restored).
  • Docs: Playbook ClaudeQAPlan.md · Coverage ClaudeQACoverage.md · Ideas Future.md ## QA · Branding ClaudeBrandingReview.md.

Severity board

Severity Open Fixed (pending 1 confirm)
P0 0 0
P1 0 0
P2 0 0
P3 1 0

Open issues

ID Sev Area Description Repro Suggested fix Status
J-OBS P3 A11y / touch targets A few conversation icon-buttons measure ~4245dp wide (48dp tall) — single-axis marginal miss of the 48dp target; fully operable. Most controls are 48dp. Pass J: uiautomator bounds on conversation → 23 clickables <126px wide. Bump those icon-buttons to 48dp min (e.g. Modifier.minimumInteractiveComponentSize() / size(48.dp)). Open (P3, non-blocking)

Resolved & confirmed (archived — full detail in git history)

A-001 · A-003 · A-OBS · B-001 · B-002 · B-003 · B-004 · C-CC-001 · C-DS-001 · C-NAV-001 · D-001 · E-001 · E-002 · E-003 · E-OBS · F-OBS · F-RACE-001 · I-001 · I-002 — all fixed and re-verified (commits in history; F-RACE-001 re-confirmed R8; I-001 query→whereIn(dayKeys) + I-002 Long-score→Number.toInt(), fixed ab29f6b, re-confirmed live R9: 0 outcomes denials/CCE). Pruned per the one-confirmation-round rule. (C-OBS / outcomes list / SubscriptionScreen per-user gate = investigated, not bugs.)

Security cornerstone — clean (Pass D, deep dive, Round 7)

  • D1 at-rest: chat text + lastMessagePreview + all 4 game-answer collections (ToT / How Well / Desire Sync / Wheel, both users) + Memory Lane capsules + date-swipe actions = enc:v1:. No plaintext content; only metadata in clear.
  • D2/D3 access: non-member denied all reads/writes (raw Firestore REST → 403); real premium write users/{uid}/entitlements/premium denied (server-only → no self-grant); cross-couple denied.
  • D4 keys: couple key phrase-wrapped (argon2id); recovery phrase server-blind; encryptedRecoveryPhrase wiped on acceptance; plaintext inviteCode not exploitable (invite readable only by inviter; no code-encrypted secret persisted).
  • Robustness: malformed/abusive deep-link intents (unknown type, missing extras, injection/path-traversal) → 0 crash; killed-state cold-start chat deep-link → conversation loads.

Round history (one line each)

  • Brand art drop (2026-06-26) — wired + QA-swept, 0 issues. All 11 generated illustrations (A1A12, source gitignored) wired into their screens via shared EmptyState + new BrandIllustration helper (commits 077a4085868d06). Complete both-theme sweep: in-context dark and light verified for Bucket List (A6), Quiet hours (A9), Security (A11), Delete account (A12) — all render as crisp rounded tiles, on-brand, no clipping/contrast issue; A1 (transparent), A3 (banner) + the empty-only states (A2/A4/A5/A8/A10, unreachable on the baseline couple) verified via the debug Art-preview gallery on both themes + the proven shared tile. 0 FATAL/ANR both devices; baseline intact (0 sessions/outcomes). Process catch: 5556 was on a stale build mid-sweep → reinstalled current, both now on 768f511. Details in ClaudeBrandingReview.md.
  • R9 — clean confirmation round (0 new findings): confirmed + pruned I-001/I-002 (0 outcomes denials/CCE on the fixed build); swept deferred Pass C deep/list screens (Answer History, Activity, Bucket List, Date Match/Matches — both themes) + Pass F network (offline cache render + clean reconnect). 0 open P0P2.
  • R8 — F-RACE-001 re-confirmed + pruned; Passes I (perf) + J (a11y) run; found+fixed+verified I-001 & I-002 (outcomes read: query rules-denied + Long/Int parse CCE → "Your Progress" was silently dead). 0 open P0P2.
  • R7 — multi-angle security/concurrency deep dive → cornerstone fully clean; F-RACE-001 found + fixed + verified. 0 new open.
  • R6 — branding drop + Future.md backlog regression (white-keyhole icons/loader/splash, inclusive gender, copy, rate-limit split, results-push suppression, paywall retry/offline) → 0 new open.
  • R5 — Cloud Functions deployed (E-OBS channel fix, E-003 results routing) + new Pass G (account creation / fake-account abuse) clean → 0 open.
  • R1R4 — baseline Passes AF report-only; every P0P2 found was fixed + verified (see archived IDs).

Operational constants

  • Execution mode: autonomous run-to-completion — don't stop; fix blockers inline; cycle fix→re-QA until flawless. Don't hand back when context fills — re-read this run-state + coverage after any compaction. Commit before interruptible work; recover stuck sessions via the session-start ritual.
  • Standing authorization (user, 2026-06-24): may firebase deploy --only firestore:rules + has admin access (Firestore reads/writes/seeds + entitlement toggles) — run without pausing. Only the macOS requirement for iOS (Parts 2/3) is a hard stop.
  • Hardening backlog → Future.md: App Check not enforced on Firestore; users/{uid} update rule allows arbitrary non-hasPremium fields (tighten to a field allowlist).