qa(R8): Pass I performance — route smoke checklist + I-001 (P1) outcomes read denied
Cold start 1253ms; core tabs 6.3% janky; conversation/Play-hub scroll ~36ms 90th; no window/Activity/listener leak (meminfo stable over open/close x6); lazy-load (17), Coil (11), Room caching all in place. Found I-001 (P1): FirestoreOutcomeDataSource .getOutcomes() does a bare collection list .get() that firestore.rules:658 denies (reads allowed only for dayKey in day_0/30/60/90) -> always PERMISSION_DENIED, swallowed to emptyList() -> "Your Progress" never shows recorded outcomes + re-prompts done days. Fix (fix phase): whereIn(documentId, [day_0..90]). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
11208c6fb5
commit
f740b1d9a1
|
|
@ -1,7 +1,7 @@
|
|||
# Claude QA Coverage Matrix
|
||||
|
||||
> **Resume anchor — current status only.** Statuses: `pass | fail→id | todo | n/a | not implemented→Future.md | blocked→id`.
|
||||
> Build `23dd6a7`. Position + verdict: see `ClaudeReport.md` run-state. **Verdict: 0 open issues (P0–P3); A–G covered, I/J pending.**
|
||||
> Build `23dd6a7`. Position + verdict: see `ClaudeReport.md` run-state. **Verdict: A–G + I covered (I-001 open P1 — outcomes read), J pending.**
|
||||
> Hygiene: this is a *current-status* matrix, not a per-round changelog — `fail→id` flips to `pass` once a fix is
|
||||
> confirmed (ID archived below); finished rounds collapse to the history line. (See Report hygiene in `ClaudeQAPlan.md`.)
|
||||
|
||||
|
|
@ -16,7 +16,7 @@
|
|||
| F — Resilience | concurrency · offline · lifecycle · process-death · time | ✅ pass |
|
||||
| G — Account creation / fake-account | sign-up · validation · duplicate · invite-abuse | ✅ pass |
|
||||
| H — Branding & artwork | consumer brand walk → prompts | see `ClaudeBrandingReview.md` |
|
||||
| I — Performance & route efficiency | — | **todo (Round 8)** |
|
||||
| I — Performance & route efficiency | cold-start, jank (core/conversation/hub), leak proxy, caching | ✅ done · **I-001 (P1)** outcomes read denied |
|
||||
| J — Accessibility | — | **todo (Round 8)** |
|
||||
|
||||
**Archived issue IDs (fixed + confirmed, detail in git):** 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. Pending one confirm: **F-RACE-001**.
|
||||
|
|
@ -80,9 +80,21 @@ Full live two-device run (games + messages):
|
|||
## Pass G — Account creation, validation & fake-account abuse
|
||||
Sign-up end-to-end (email/pw/confirm → 3-step profile → unpaired home) ✅; weak-password → friendly "at least 8 characters" ✅; fresh-account isolation (zero couple data) ✅; **duplicate-email → `auth/email-already-exists`** rejected ✅; invite single-use + 24h expiry, **bogus code → "Invite not found."** ✅; recovery phrase client-generated ✅; sign-out → onboarding → debug-token restore ✅. **No security findings.** (Non-member READ denial = live D3 above + app-level isolation.)
|
||||
|
||||
## Passes H / I / J
|
||||
## Pass I — Performance & route efficiency (R8, build `23dd6a7`, emulator-5554, debug build)
|
||||
Route smoke-test checklist (re-runnable: `dumpsys gfxinfo closer.app reset` → drive route → read `gfxinfo`):
|
||||
| Route / list | Jank / latency | Notes |
|
||||
|---|---|---|
|
||||
| Cold start → Home | 1253ms to first frame | acceptable (debug; release AOT-faster); no skipped frames, no ANR |
|
||||
| Core tabs (Home/Today/Play/Messages/Settings) | 6.3% janky frames | smooth; no Choreographer-skip spam |
|
||||
| Conversation (realtime listener) scroll | 90th 36ms / 95th 53ms | minor debug hitching; **no leak** |
|
||||
| Play hub scroll | 90th 36ms / 95th 38ms | smooth |
|
||||
- **Caching / lazy-load:** LazyColumn/Row/Grid in 17 files; Coil (AsyncImage) in 11; Room DAOs cache static question/category data locally — all in place, no load-all anti-patterns seen.
|
||||
- **Leak check:** conversation open/close ×6 → ViewRootImpl=1, Activities=1, Views +2, PSS bounded after trim → no window/Activity/listener leak.
|
||||
- **Redundant reads:** precise per-read counts need an instrumented/Perfetto build (Firestore success reads aren't in adb logcat); no failing-read spam **except I-001**; no leaked listeners.
|
||||
- **Finding: I-001 (P1)** — `getOutcomes()` bare-list query is rules-denied → "Your Progress"/outcomes silently broken (see ClaudeReport.md).
|
||||
|
||||
## Passes H / J
|
||||
- **H Branding** — deliverable in `ClaudeBrandingReview.md` (consumer brand walk → ready-to-paste art prompts).
|
||||
- **I Performance & route efficiency** — **todo (Round 8):** gfxinfo/jank, redundant-read counts, listener-leak check, route smoke checklist.
|
||||
- **J Accessibility** — **todo (Round 8):** font_scale 1.3/1.5/2.0, TalkBack semantics, WCAG-AA contrast, 48dp targets, keyboard, reduce-motion.
|
||||
|
||||
---
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
# Claude QA Report — Full-App QA (living report)
|
||||
|
||||
> **Verdict (2026-06-25): 0 open issues at every severity (P0–P3). Security cornerstone fully clean. App is at the "flawless" bar.**
|
||||
> **Verdict (2026-06-25, R8): 1 open P1 — I-001 ("Your Progress" outcomes read is rules-denied → feature silently broken). All else clean; security cornerstone clean.**
|
||||
>
|
||||
> 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 8 (re-QA + Passes I/J) — IN PROGRESS | 0 open P0–P3 | F-RACE-001 re-confirmed + pruned | NEXT ACTION: Pass I (performance), then Pass J (a11y).`
|
||||
`Round 8 (re-QA + Passes I/J) — IN PROGRESS | 1 open P1 (I-001) | F-RACE-001 re-confirmed + pruned; Pass I found I-001 | NEXT ACTION: finish Pass I, run Pass J, then fix phase (I-001).`
|
||||
- **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`.
|
||||
|
|
@ -15,12 +15,14 @@
|
|||
| Severity | Open | Fixed (pending 1 confirm) |
|
||||
|---|---|---|
|
||||
| P0 | 0 | 0 |
|
||||
| P1 | 0 | 0 |
|
||||
| P1 | **1** | 0 |
|
||||
| P2 | 0 | 0 |
|
||||
| P3 | 0 | 0 |
|
||||
|
||||
## Open issues
|
||||
**None.**
|
||||
| ID | Sev | Area | Description | Repro | Suggested fix | Status |
|
||||
|---|---|---|---|---|---|---|
|
||||
| I-001 | **P1** | Outcomes / "Your Progress" read | `FirestoreOutcomeDataSource.getOutcomes()` (line 45-53) issues a **bare collection list** `.get()` on `couples/{cid}/outcomes`, but the rule (firestore.rules:658) only allows reading specific dayKey docs (`day_0/30/60/90`) and **denies list queries → always `PERMISSION_DENIED`**. `OutcomeRepositoryImpl.getOutcomes` (26-29) swallows it (records non-fatal → returns `emptyList()`). Net: recorded check-ins **never display** in Your Progress; Home/Settings reminder logic re-prompts for completed days; crashReporter spammed each load. Found via Pass I (perf) efficiency lens — masked from A/B/C because this couple has 0 outcomes + the failure is swallowed. | Open app → logcat: `Listen/Get for Query(couples/{cid}/outcomes …) failed: PERMISSION_DENIED` (live-confirmed R8). | Constrain the query to satisfy the rule: `.whereIn(FieldPath.documentId(), listOf("day_0","day_30","day_60","day_90")).get()` (or 4 parallel `getOutcome` gets). No rules change needed. | **Open** |
|
||||
|
||||
## 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 — all fixed and re-verified (commits in history; **F-RACE-001** fixed `23dd6a7`, re-confirmed live R8: race → 1 session, loser joins same set). Pruned per the one-confirmation-round rule. (C-OBS / `outcomes` list / SubscriptionScreen per-user gate = investigated, **not bugs**.)
|
||||
|
|
|
|||
Loading…
Reference in New Issue