docs(qa): update report with couple-key encryption, onAnswerRevealed, both-answered unlock
This commit is contained in:
parent
b9b15604ef
commit
e6a8deef67
117
ClaudeQAPlan.md
117
ClaudeQAPlan.md
|
|
@ -97,6 +97,30 @@ confirms + enumerates this; the fix phase applies couple-shared everywhere.
|
|||
re-checks it cheaply instead of by hand.
|
||||
- **Test-data hygiene:** keep known test accounts; clean up artifacts (stray messages/reactions/sessions) between
|
||||
rounds so they don't masquerade as bugs.
|
||||
- **Evidence standard:** every filed bug must be reproducible from text alone: build/commit, device, account, theme,
|
||||
app/process state, screen/route, exact tap/input sequence, expected result, actual result, and whether logcat showed
|
||||
a crash/ANR/permission denial. Screenshots/videos are helpful but never the only evidence because session artifacts
|
||||
may not survive compaction.
|
||||
- **Flake policy:** if something fails once and then passes, do not dismiss it. Repeat from a clean state, vary timing
|
||||
(rapid tap / slow network / background-resume), inspect logs, and file it as intermittent if it cannot be made fully
|
||||
deterministic. Intermittent routing, notification, encryption, duplicate-write, or crash behavior is still a bug.
|
||||
|
||||
## Living discovery ritual (before each round, and whenever reality disagrees with the docs)
|
||||
The app is allowed to grow; the QA plan must keep up. Before a pass or chunk, quickly inventory the current code/app
|
||||
surface and reconcile it with `ClaudeQACoverage.md`:
|
||||
- **Routes/screens:** inspect `core/navigation/AppRoute.kt`, navigation graph call sites, Settings sub-pages, dialogs,
|
||||
bottom tabs, deep links, and any new composables reachable by buttons/cards.
|
||||
- **Notifications:** inspect notification type enums/classes, Cloud Function triggers, Android intent/deep-link handling,
|
||||
notification channels/actions, FCM token registration, and Android runtime notification permission paths.
|
||||
- **Features/gates:** grep for premium checks, permission requests, media pickers, billing/paywall entry points,
|
||||
destructive actions, account/couple lifecycle actions, and admin/server-only writes.
|
||||
- **Assets/content:** inventory new drawables, `drawable-night*` variants, pack art, empty states, strings, feature flags,
|
||||
remote config, and any debug-only screens that should not ship.
|
||||
- **Backend/rules:** inspect Firestore rules, indexes/queries, Functions triggers/callables, Storage paths, scheduled
|
||||
jobs, and migrations for new data shapes or access paths.
|
||||
- **Docs update rule:** if the inventory finds a page, feature, notification, asset, state, backend path, or edge case
|
||||
missing from the playbook/coverage, update `ClaudeQAPlan.md` and `ClaudeQACoverage.md` before marking the chunk done.
|
||||
If it is product polish, also add it to `Future.md`; if it needs new artwork, add it to `ClaudeBrandingReview.md`.
|
||||
|
||||
## Multi-angle attack mandate (go DEEPER than "does the happy path work")
|
||||
A capability can pass via the UI yet fail when hit directly. Probe each meaningful capability (read/write a private
|
||||
|
|
@ -139,6 +163,13 @@ State lives in **files**, not memory:
|
|||
every `fail`. Never renumber or reuse.
|
||||
- **Source of truth**: the two MD files are authoritative; the TodoWrite list is scratch for the current chunk only.
|
||||
Update the MD files + run-state header *before* ending a session.
|
||||
- **Living playbook rule:** when QA discovers any new app surface or recurring lesson — a new page/route, feature,
|
||||
setting, game state, notification type/action/channel, entry point, background/killed-state behavior, asset/art
|
||||
placement, repeatable bug class, missed edge case, fragile route, confusing state, image/layout failure mode,
|
||||
security angle, or anything else that should be checked every future round — update **this `ClaudeQAPlan.md`** in the
|
||||
relevant pass before ending the chunk. Also add the matching row/cell to `ClaudeQACoverage.md` if it needs recurring
|
||||
verification. Do this even after the immediate bug is filed/fixed so the lesson or newly discovered surface is not
|
||||
lost to memory or git history.
|
||||
- **Commit cadence**: commit `ClaudeReport.md` + `ClaudeQACoverage.md` after each pass and each chunk.
|
||||
- **Chunking**: run small chunks (Pass C one screen-group; Pass A one feature), checkpoint after each.
|
||||
- **Session-start ritual**: (1) read run-state header + both MD files; (2) `adb devices` shows **both** emulators
|
||||
|
|
@ -153,16 +184,22 @@ with a commit + run-state update. If a chunk starts overflowing, split it; if ch
|
|||
**Why:** in Round 1, A & D fit as single batches, but B/C/E were too large → got cut off → deferred. Sub-batching
|
||||
prevents half-done/lost work and gives cleaner per-chunk verification + revertable commits.
|
||||
|
||||
Default small: if a chunk requires two-device live driving, screenshots/montage review, logcat checks, or admin/API
|
||||
verification, keep it to **one small route family, one game phase, or one notification type**. A chunk is too large if
|
||||
it cannot produce a precise coverage update, issue log, and commit before context gets tight. Split before starting
|
||||
rather than leaving a half-tested matrix behind. **Prefer Claude-friendly micro-batches**: smaller chunks let the agent
|
||||
fully inspect screenshots, tap every CTA, vary app states, update files accurately, and avoid shallow "covered" rows.
|
||||
|
||||
| Pass | Chunk granularity | ~chunks |
|
||||
|---|---|---|
|
||||
| A Premium | free-state gating sweep; then couple-shared verify (mostly code + a few live taps) | 1–2 |
|
||||
| B Games | **one game per chunk** — full two-device playthrough + edges + commit | 7 |
|
||||
| C Visual | **one screen-group per chunk** (both themes, ~6–10 screens, montage-reviewed + nav/back for that group) — never "all screens" at once (heaviest, image-bound) | 6–8 |
|
||||
| D Security | D1 at-rest · D2 rules + D3 negative · D4 keys/recovery · D5–D7 appcheck/secrets/leaks/migration | ~4 |
|
||||
| E Notifications | **3–5 types per chunk** × {foreground/background/killed} + tap-to-open; **game/join-game notification chunks** included; both clients (QA→Sam, Sam→QA) | ~5–6 |
|
||||
| A Premium | one gated-feature family per chunk if live toggles are needed; otherwise free-state sweep → couple-shared verify | 2–4 |
|
||||
| B Games | **one game per chunk max**; split complex games into lifecycle/playthrough chunk + join/resume/results/notification-entry chunk | 7–14 |
|
||||
| C Visual | **one small route family per chunk** (both themes, ~2–3 screens/states, screenshots reviewed + nav/back + image-fit + all CTAs for that family) — never "all screens" or a broad tab at once | 16–25 |
|
||||
| D Security | one security assertion group per chunk: D1 at-rest · D2 rules static · D3 live negative raw API · D4 keys/recovery · D5/D6 leaks · D7 migration | ~6 |
|
||||
| E Notifications | **one notification type per chunk** with the full contract below; split a type into direction/state subchunks if needed, but do not mark the type pass until both clients + source screens + fg/bg/killed + stale/malformed + payload/back-stack are covered | 16–30 |
|
||||
| F Resilience | **one dimension per chunk** (concurrency · lifecycle/process-death · network · time · account-lifecycle) | ~5 |
|
||||
| G Account creation | **one creation/abuse dimension per chunk** (happy/validation · duplicate/conflict · fake-account abuse · lifecycle) | ~4 |
|
||||
| H Branding | **one screen-group per chunk** (consumer brand walk → ready-to-paste art prompts) | ~4 |
|
||||
| H Branding | **one small route family per chunk** (~2–3 screens/states) consumer brand walk + ready-to-paste art prompts + existing-image integration verdict | 8–14 |
|
||||
| I Performance | **one route-group per chunk** — gfxinfo/jank + read-count instrumentation (build the route smoke checklist) | ~3 |
|
||||
| J Accessibility | **one a11y setting per chunk** (font scale · TalkBack · contrast · targets · keyboard · reduce-motion) | ~5 |
|
||||
|
||||
|
|
@ -253,11 +290,21 @@ auth/onboarding/pairing (fresh acct); Home (solo + paired); Play + every game; T
|
|||
(inbox + conversation); Packs; Dates (Match/Builder/Matches/Bucket List); Wheel (picker/session/complete/history);
|
||||
Settings + all sub-pages (Account, Notifications, Appearance, Privacy, Subscription, Relationship, Security, Delete
|
||||
Account); Paywall; Your Progress/Activity; Recovery.
|
||||
- **Images must belong to the screen:** during the UI sweep, visually inspect every illustration, glyph, banner,
|
||||
empty-state image, pack art, celebration asset, and dark/light variant in context. It should feel intentionally
|
||||
integrated with the page hierarchy, copy, spacing, and action area — not like a forgotten placeholder dropped into
|
||||
an empty slot. Check crop, scale, padding, alignment, corner radius, background/tile treatment, theme variant,
|
||||
loading/fallback state, and whether the image competes with or clarifies the primary task. If it is broken,
|
||||
clipped, low-contrast, off-brand, stale, or placeholder-looking, file a bug in `ClaudeReport.md`; if the screen
|
||||
works but would benefit from new/better art, log the prompt need in `ClaudeBrandingReview.md`.
|
||||
- **Probe:** `ui/theme/Theme.kt` hardcoded brand colors + chat's custom `closerBackgroundBrush` — verify dark mode
|
||||
truly adapts; grep screens for hardcoded `Color(0x...)`.
|
||||
- **States, not just happy path:** empty / loading / error / not-paired / locked-premium / signed-out /
|
||||
stale-or-deleted-target / populated-with-many where they exist; many need data setup (seeding is user-gated) — note
|
||||
unreachable states in coverage rather than skipping silently.
|
||||
- **Text/data stress:** test long names, long relationship labels, long question/answer text, emoji, multiline content,
|
||||
empty optional fields, many list items, and both partners having similar names. Verify no clipping, overlap,
|
||||
confusing attribution, broken sorting, or hidden actions.
|
||||
- **Readability at scale:** default font size + spot-check largest system font scale on text-heavy screens. (The full
|
||||
accessibility sweep — large-font on every primary flow, TalkBack labels, touch targets, keyboard, reduce-motion — is
|
||||
**Pass J**; per-route performance/jank is **Pass I**.)
|
||||
|
|
@ -265,6 +312,11 @@ Account); Paywall; Your Progress/Activity; Recovery.
|
|||
opens correctly each time — e.g. a conversation from the inbox AND from "Discuss" AND from a notification; a game
|
||||
from the Play hub AND from a notification; Paywall from each gated feature; Settings sub-pages; reveal from Today
|
||||
AND from history AND from `partner_answered`. A screen that works from one entry but breaks/duplicates from another = bug.
|
||||
- **Every link, CTA, and mission must prove its destination:** actively hunt for dead buttons, wrong targets, generic
|
||||
Home fallbacks, no-op taps, stale routes, and confusing affordances. Example class: a Reveal card saying
|
||||
**"Tiny Mission: Send one flirty text"** must open the relevant Messages/conversation flow, not do nothing. For every
|
||||
button/card/chip/row, record the expected destination before tapping, then verify the actual destination, state,
|
||||
payload, and back stack. Broken/no-op/wrong-destination CTA = bug (usually P2; P1 if it blocks a core flow).
|
||||
- **All routes into a game / join-game state (verify each opens the correct game + session + partner-state + mode +
|
||||
premium/couple-entitlement + back stack):** Play-hub cards (incl. premium-gated), active-session banners, Home/Today
|
||||
game prompts, game history, replay/results, waiting screens, notification-opened screens, in-app banners,
|
||||
|
|
@ -291,6 +343,11 @@ Account); Paywall; Your Progress/Activity; Recovery.
|
|||
back twice** (duplicate/stacked destinations on the back stack = bug). Bottom-tab reselection and deep-link/
|
||||
notification entries must land with a sane back stack (back → Home, not off the app or a blank screen). Wrong/
|
||||
double back or a dead-end = **P2** (P1 if it traps the user).
|
||||
- **UI consistency / polish defects:** compare each screen against sibling patterns in the same area and across the
|
||||
app. Headers, labels, status chips, partner names, connected-state copy, spacing, card treatments, and button
|
||||
hierarchy should feel intentional and consistent. Awkward or out-of-place UI such as a Settings relationship row
|
||||
where **"Connected with ..."** looks visually odd, cramped, misaligned, or unlike the rest of Settings is a finding:
|
||||
file as a bug if it looks broken/inconsistent; log to `Future.md` only if it is purely a product/content improvement.
|
||||
- **D1 At-rest coverage:** admin-read RAW docs/objects, assert ciphertext for every private type — chat text +
|
||||
`lastMessagePreview` (`enc:v1:`), chat media bytes (Tink `01 69 59 51 f0…`), answers (`sealed:v1:`/`enc:v1:`),
|
||||
date plans + `date_swipes`, Memory Lane capsules, Bucket List. Also: **wrappedCoupleKey** + recovery material never
|
||||
|
|
@ -348,10 +405,46 @@ Run the **complete** suite across **both clients** (QA→Sam AND Sam→QA). Each
|
|||
→ delivered to the right partner (never self/non-member/ex-partner) → correct channel + copy with no private content →
|
||||
tap opens exactly the right item (loaded, not generic Home/dead-end) → sane back stack → privacy/authz re-checked on
|
||||
open**. No duplicates; rate limiter (20/day, 100/week) doesn't drop legit ones.
|
||||
- **Notification chunk contract (small chunks, complete coverage):** each chunk owns **one notification type** (or one
|
||||
explicit subchunk of that type, e.g. `chat_message QA→Sam foreground/source-screen sweep`, then
|
||||
`chat_message Sam→QA background+killed+stale`). Before starting, write the chunk's matrix in `ClaudeQACoverage.md`;
|
||||
after finishing, mark each cell `pass | fail→id | blocked→id | not implemented→Future.md`. A notification type is
|
||||
not complete until all applicable cells below are covered:
|
||||
- **Directions:** QA→Sam and Sam→QA; sender must not receive their own push unless intentionally designed.
|
||||
- **Process states:** foreground, background/warm, killed/cold-start, force-stopped if deliverable, screen locked,
|
||||
and resumed after rotation/process recreation when relevant.
|
||||
- **Current screens:** Home, Play hub, active game/waiting/results, Today/reveal, Messages inbox, exact conversation,
|
||||
Settings/sub-settings, Paywall, unrelated deep screen, logged-out, unpaired, and stale prior-partner context.
|
||||
- **Entry surfaces:** foreground in-app banner/head, Android system tray tap, any push action button, crafted
|
||||
deep-link/intent matching the payload, repeated/double tap, and tap after the target has changed.
|
||||
- **Targets:** fresh target, already-open target, completed target, stale/expired/deleted target, unauthorized target,
|
||||
wrong couple/session/item ID, malformed/missing extras, and no-network-on-open.
|
||||
- **Assertions:** correct recipient, correct channel/priority/copy, no private payload/log content, exact destination,
|
||||
membership/auth/entitlement re-check, no duplicate route/session, sane back stack, logcat clean, and coverage/docs
|
||||
updated before the chunk ends.
|
||||
- **Notification tap crash triage (mandatory):** never conclude "the notification didn't open" from UI behavior alone.
|
||||
Before each notification/deep-link tap, clear or timestamp logcat; after the tap, inspect both devices for
|
||||
`FATAL EXCEPTION`, ANR, ActivityTaskManager errors, `RuntimeException`, navigation/deep-link exceptions,
|
||||
`PERMISSION_DENIED`, and swallowed repository/decryption errors. If the app returns Home, stays put, flashes,
|
||||
restarts, or silently fails, classify whether it was wrong routing, missing extras, stale data, permission denial, or
|
||||
a crash. Any notification tap that crashes (example class: tapping a game notification to open **Spin the Wheel**)
|
||||
is a filed bug with stack trace + exact payload/session/game type, not a vague "didn't open" note.
|
||||
- **Both-client × app-state matrix (per type):** QA→Sam and Sam→QA, each in **foreground / background / killed
|
||||
(cold-start)**, plus **already on the target screen**, **on a different screen**, **logged out**, **unpaired**, with
|
||||
a **stale/expired/completed/deleted target**, and **both users opening around the same time**. Not a `pass` unless it
|
||||
works from both clients in every state that applies.
|
||||
- **Current-screen/source-screen matrix (per type):** do not test notifications only from Home or only from a clean
|
||||
launch. For each notification type, vary where the receiving client is when the notification arrives/taps: **Home,
|
||||
Play hub, active game/waiting/results, Today/reveal, Messages inbox, exact conversation, Settings/sub-settings,
|
||||
Paywall, an unrelated deep screen, app backgrounded from each major tab, and app fully closed/killed**. Foreground
|
||||
banners, system-tray taps, warm-start `onNewIntent`, and cold-start launch must all route to the exact target. A tap
|
||||
that lands on generic Home, stays on the old screen, opens the wrong tab, loses extras, duplicates the destination,
|
||||
or needs a second tap is a bug.
|
||||
- **Permission/token health:** cover Android `POST_NOTIFICATIONS` granted, denied, "don't ask again"/system-disabled,
|
||||
and re-enabled states; Settings notification toggles; sign-out/sign-in token refresh; same account on two devices;
|
||||
partner/account switch; stale token cleanup; app reinstall/update; and notification channel migration. Denied/system
|
||||
disabled notifications should fail gracefully with in-app state still correct, never with lost data or broken routing
|
||||
after permission is restored.
|
||||
- **Six assertions per notification:** (1) trigger fires correctly — right event, not early, not twice, sender doesn't
|
||||
get their own (unless intended), retry/idempotency doesn't duplicate; (2) delivered to the right person — correct
|
||||
token, old tokens unused after sign-out/account-switch; (3) copy + channel correct — friendly, right channel/
|
||||
|
|
@ -383,7 +476,9 @@ open**. No duplicates; rate limiter (20/day, 100/week) doesn't drop legit ones.
|
|||
→ finish push opens the exact results/reveal → re-opening the push after completion opens replay/results (not a dead
|
||||
active session) → if A ends/quits, B is notified or shown a graceful ended state → a **stale** game push routes to
|
||||
results/history or a clear expired-session message → simultaneous start/join yields **one** session, neither stuck →
|
||||
premium gate holds (neither-premium push must NOT bypass paywall; either-premium unlocks for both).
|
||||
premium gate holds (neither-premium push must NOT bypass paywall; either-premium unlocks for both). For each game
|
||||
type, including **Spin the Wheel**, notification taps must be paired with logcat review so crashes are caught even if
|
||||
the visible symptom looks like a no-op or generic Home fallback.
|
||||
- **Join-game navigation suite:** every entry that leads to joining/resuming a game opens the correct game + session +
|
||||
partner-state + mode + entitlement + back stack — Play-hub card, active-game banner/card, Home active-game card,
|
||||
Today game prompt, notification tap, in-app foreground banner, game history/replay, partner waiting screen, results/
|
||||
|
|
@ -424,6 +519,10 @@ open**. No duplicates; rate limiter (20/day, 100/week) doesn't drop legit ones.
|
|||
- **Account/couple lifecycle:** brand-new (empty) account; unpaired state; pair → unpair → re-pair; partner leaves
|
||||
mid-session; account deletion cascade; same account on two devices; stale notifications after unpair/delete are
|
||||
graceful; invite accepted while already paired is rejected cleanly. No orphaned/broken state.
|
||||
- **Install/update/migration lifecycle:** fresh install, update over an existing signed-in install, app data retained,
|
||||
Room/DataStore/SharedPreferences migrations, notification channel migration, cached encryption/key material,
|
||||
pending deep links/notifications across update, and version-skew between partners if one device updates first. No
|
||||
sign-out loops, stale build routing, lost local state, broken permissions, or migration crashes.
|
||||
- **Crash reporting:** confirm crashes/ANRs are actually captured (Crashlytics) so field issues surface.
|
||||
|
||||
### Pass H — Branding & artwork (every screen: could it carry more of the brand? where would art help?)
|
||||
|
|
@ -431,6 +530,10 @@ A consumer-mindset pass focused on **brand presence and delight**, not defects.
|
|||
ask: *does this feel like Closer (private, warm, equal, intentional — a ritual for two)? Could brand color, the heart
|
||||
mark, a brand message, or an illustration make it warmer or clearer without clutter?* Output is **artwork descriptions
|
||||
written as ready-to-paste ChatGPT image-generation prompts** — the user generates the images; we only describe them.
|
||||
- **Existing art integration check:** judge the art as part of the whole page, not as a standalone asset. Confirm each
|
||||
image supports the screen's job, aligns with the surrounding typography/actions, has enough breathing room, and uses
|
||||
the right light/dark treatment. Art that looks generic, unfinished, randomly placed, or visually disconnected is a
|
||||
finding even if the bitmap itself is technically valid.
|
||||
- **First, lock the house style (do this once per round, refresh if the art evolved):** read `docs/brand/visual-identity.md`
|
||||
+ `docs/brand/asset-system.md` AND open 2–3 existing illustrations (`illustration_couple_onboarding`,
|
||||
`illustration_reveal_celebration`, `pack_art_*`) to capture the *actual* look. New screens/features since the last
|
||||
|
|
|
|||
|
|
@ -1,13 +1,13 @@
|
|||
# Claude QA Report — Full-App QA (living report)
|
||||
|
||||
> **Verdict (2026-06-26, R9): 0 open P0–P2 (1 P3 J-OBS, non-blocking). I-001/I-002 confirmed + pruned. Security cornerstone clean. At the flawless bar.**
|
||||
> **Verdict (2026-06-26): 0 open P0–P2 (1 P3 J-OBS). Fixed this session: E-GAME-001 (notifications now deep-link into the live game) + dark-theme illustrations wired. Nav/button/image QA sweep both themes = 0 FATAL. (Changes uncommitted — user commits.)**
|
||||
>
|
||||
> 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 P0–P2 (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.
|
||||
`Post-R9 session (2026-06-26) | 0 open P0–P2 (1 P3 J-OBS) | Fixed E-GAME-001 (notif→game) + wired dark-theme art + nav/button/image QA sweep (0 FATAL) | NEXT ACTION: user to commit working tree; optional P3 J-OBS + low-risk deferred later.`
|
||||
- **Build:** working tree ahead of HEAD `23dd6a7` — **uncommitted** (per user: I no longer commit). Pending: notification→game fix (AndroidManifest singleTop + QuestionSessionRepositoryImpl server-first read), `drawable-night-nodpi/` dark art (+ prior art-drop commits already in history).
|
||||
- **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`.
|
||||
|
||||
|
|
@ -34,6 +34,7 @@ A-001 · A-003 · A-OBS · B-001 · B-002 · B-003 · B-004 · C-CC-001 · C-DS-
|
|||
- **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)
|
||||
- **Notif→game fix + dark art + QA sweep (2026-06-26, uncommitted).** **E-GAME-001 (P1, FIXED+VERIFIED):** game notifications "led nowhere" — backgrounded/warm taps landed on Home (MainActivity was standard launch mode → `onNewIntent` never delivered the tap's extras → `pendingDeepLink` unset), and even when routed, the game screen showed *setup* instead of joining (one-shot `getActiveSessionForCouple` raced the post-push Firestore sync → returned stale-empty). Fixes: `AndroidManifest` `MainActivity launchMode=singleTop` + `QuestionSessionRepositoryImpl.getActiveSessionForCouple` now SERVER-first (cache fallback). **Verified live:** Sam backgrounded → taps partner_started_game → lands IN the active This-or-That (1/10), joined, no duplicate session; back-stack sane (game→back→Home→back→exit, C-NAV-001 holds). Generic across game types (shared routing + getActiveSession). **Dark-theme art:** 12 `_dark` variants → `drawable-night-nodpi/` (light names) so dark mode auto-swaps; verified live (Security shows the aubergine variant on dark; light unchanged). **QA sweep:** tabs both themes, deep-link back-stack, all 12 illustrations both themes — **0 FATAL**, baseline intact.
|
||||
- **Brand art drop (2026-06-26) — wired + QA-swept, 0 issues.** All 11 generated illustrations (A1–A12, source gitignored) wired into their screens via shared `EmptyState` + new `BrandIllustration` helper (commits `077a408`→`5868d06`). **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 P0–P2.
|
||||
- **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 P0–P2.
|
||||
|
|
|
|||
Loading…
Reference in New Issue