docs(qa): record R18 updates in ClaudeReport and update ClaudeQACoverage matrix
This commit is contained in:
parent
c3a3c38e0e
commit
76c8d2cd4d
|
|
@ -1,7 +1,7 @@
|
||||||
# Claude QA Coverage Matrix
|
# Claude QA Coverage Matrix
|
||||||
|
|
||||||
> **Resume anchor — current status only.** Statuses: `pass | fail→id | todo | n/a | not implemented→Future.md | blocked→id`.
|
> **Resume anchor — current status only.** Statuses: `pass | fail→id | todo | n/a | not implemented→Future.md | blocked→id`.
|
||||||
> Build HEAD `c31eea2` + **R15 working-tree changes** (functions + rules **deployed to prod**; client rebuilt+installed both emulators). Position + verdict: see `ClaudeReport.md` run-state. **Verdict: R15 = gap-closing round (Passes L/M/N/P + smoke) — found & FIXED M-001 (P2 quiet hours).** Quiet hours didn't suppress backgrounded/killed partner pushes (local-only); fixed via server-side fail-open suppression + client window/tz sync + rules allowlist — verified live. Then drove Pass N: **N-001 (P1) Bucket List fully non-functional** + **N-002 (P2) Date Builder "Create Plan" no-op** — both **FIXED + verified live** (Bucket CRUD; Date Builder → PLANNED `date_plan` → Home "Date coming up"). L (chat E2E render+decrypt+receipts+reactions+at-rest), P (UI copy + 6103-Q bank) clean; smoke 6/6 GREEN. **0 open P0–P2; 3 fixed pending 1 confirm (M-001, N-001, N-002); 2 P3 brand backlogs.** 0 FATAL. M-001 functions+rules deployed to prod; N-001/N-002 client-only (debug APK installed both emulators).
|
> Build = **R18 working tree** (uncommitted: `MainActivity.kt`, `MemoryCapsuleGenerator.kt`+test, asset `app.db` grammar fix, docs); debug APK rebuilt+installed both emulators. Position + verdict: see `ClaudeReport.md` R18 run-state. **Verdict: R18 — fixed the last open visual P2 C-DARKART-002** (uiMode-sync in `MainActivity` via `AppCompatDelegate.setDefaultNightMode` so ALL art follows the in-app theme; verified live across all 4 theme/art states) + flaky **TEST-002** (capsule determinism — injected clock) + content **P-GRAMMAR-001** (13 stress-Q subject-verb agreement errors → asset data fix). Live passes this round: **A** (premium gate, Desire Sync + premium pack → Paywall; free content reachable), **B** (Wheel playthrough end-to-end), **L** (chat E2E send/receive-decrypt/at-rest/receipt/no-leak), **E** (backgrounded FCM delivery, privacy-safe, deep-links to chat), **M-001 confirmed** (client mirror intact). **Board: 0 open P0/P1 · 1 open P2 (O-AGE-001 pre-ship age gate) · 3 open P3 (BRAND-DARK-COVERAGE, BRAND-ICON-CUSTOM, C-ORIENT-001); fixed-pending-1-confirm: C-DARKART-002, M-001, TEST-002, P-GRAMMAR-001.** 0 FATAL.
|
||||||
>
|
>
|
||||||
> **Scope expanded (plan review):** the playbook now has first-class passes **K–O** (billing money-path · messaging/chat E2E · functional settings · daily-Q/outcomes/interactive · release-build/store-readiness). These surface **coverage GAPS, not defects** — the recurring defect bar is clean, but **K (real purchase/restore/cancel path), L (full chat), M (settings take-effect), N (outcomes/Bucket-List/Date-Builder), O (minified release + App Check + store)** are `todo`/`partial`/`blocked→needs-device`. **Next-priority work = close these (start L + M on-emulator; K + O need a real device / pre-ship).** **Device/OS matrix = `blocked→needs-device` (pre-ship):** all per-round QA runs on two **identical** emulators (5554/5556, same API + screen) — minSdk/targetSdk · small/large screen · ≥1 physical device are NOT covered; don't claim "device matrix ✓".
|
> **Scope expanded (plan review):** the playbook now has first-class passes **K–O** (billing money-path · messaging/chat E2E · functional settings · daily-Q/outcomes/interactive · release-build/store-readiness). These surface **coverage GAPS, not defects** — the recurring defect bar is clean, but **K (real purchase/restore/cancel path), L (full chat), M (settings take-effect), N (outcomes/Bucket-List/Date-Builder), O (minified release + App Check + store)** are `todo`/`partial`/`blocked→needs-device`. **Next-priority work = close these (start L + M on-emulator; K + O need a real device / pre-ship).** **Device/OS matrix = `blocked→needs-device` (pre-ship):** all per-round QA runs on two **identical** emulators (5554/5556, same API + screen) — minSdk/targetSdk · small/large screen · ≥1 physical device are NOT covered; don't claim "device matrix ✓".
|
||||||
>
|
>
|
||||||
|
|
@ -12,22 +12,22 @@
|
||||||
## Status at a glance
|
## Status at a glance
|
||||||
| Pass | Coverage | Status |
|
| Pass | Coverage | Status |
|
||||||
|---|---|---|
|
|---|---|---|
|
||||||
| A — Couple-shared premium | R13: **A-201 confirmed live → pruned** (free QA → Date Match Love ★Premium → Paywall, deck didn't advance) + Desire Sync free→Paywall re-verified; couple-shared unlock holds | ✅ pass (all gates couple-shared incl. Date Match) |
|
| A — Couple-shared premium | R18: re-verified live (Sam free) — Desire Sync + premium **Boundaries** pack → Paywall; Mixed pack free prompt opens (gate not over-broad); Free filter graceful empty. R13 A-201 (Date Match) holds. | ✅ pass (multi-surface gate re-confirmed R18) |
|
||||||
| B — Games lifecycle | R12: 4 async games full 2-device end-to-end (ToT Light×5, Wheel mixed-types, How Well asym, Desire Sync shared/private) + start/join/first-finisher/finish/results/back-stack; CC+MemoryLane+DateMatch render/core (full per R10) | ✅ pass (first-finisher nudge + C-NAV-002 + Ready=Start re-verified live; MemoryLane title/preview run-on → Future.md) |
|
| B — Games lifecycle | R12: 4 async games full 2-device end-to-end (ToT Light×5, Wheel mixed-types, How Well asym, Desire Sync shared/private) + start/join/first-finisher/finish/results/back-stack; CC+MemoryLane+DateMatch render/core (full per R10) | ✅ pass (first-finisher nudge + C-NAV-002 + Ready=Start re-verified live; MemoryLane title/preview run-on → Future.md) |
|
||||||
| C — Visual (light+dark) | R13: ToT setup+gameplay both themes, Play/Home/Paywall insets, Today/Paywall heroes, conversation, Premium modal both themes — all verified live | ✅ R13 fixes pruned · ⚠️ **C-THEME-001..009 (P2) open** — 9 hardcoded light/dark surfaces/backgrounds surfaced by `scripts/theme-scan.sh`; see ClaudeReport.md · ⚠️ **BRAND-DARK-COVERAGE (P3) open** — 2026-06-27 audit: many illustrations light-only (no dark variant); see `ClaudeBrandingReview.md` |
|
| C — Visual (light+dark) | R16: 9 theme-scan hits triaged → **3 reclassified** (1 @Preview false-pos [scanner now excludes], 2 dead `PlaceholderScreen` deleted) + **6 real FIXED** (BucketList/DateMatch/WheelHistory/QuestionThread tokens); theme-scan CRITICAL **9→0**. R18: **C-DARKART-002 FIXED** (all art follows in-app theme via uiMode-sync) — verified all 4 theme/art states; incidental confirms paywall/pack/Today/chat both directions. | ✅ theme-scan CRIT 0 · C-DARKART-002 fixed (pending 1 confirm) · ⚠️ **BRAND-DARK-COVERAGE (P3) open** — light-only illustrations, see `ClaudeBrandingReview.md` |
|
||||||
| D — Security & encryption | R13 LIVE (rules/functions unchanged this session): D3 non-member GET couple+messages → 403; D5 self-grant entitlement PATCH → 403; member GET own couple → 200; D1 chat at-rest `enc:v1:`. D2/D4/D6/D7 carried R7/R10 | ✅ clean — cornerstone holds |
|
| D — Security & encryption | R13 LIVE (rules/functions unchanged this session): D3 non-member GET couple+messages → 403; D5 self-grant entitlement PATCH → 403; member GET own couple → 200; D1 chat at-rest `enc:v1:`. D2/D4/D6/D7 carried R7/R10 | ✅ clean — cornerstone holds |
|
||||||
| E — Notifications | R12 LIVE: Pass B verified start/first-finisher(`partner_completed_part`)/finish triggers→correct partners+copy; cold-start tap smoke **6/6** (launcher + 5 notif types open & stay) | ✅ pass · splash-crash class clean on fresh APK |
|
| E — Notifications | R18 LIVE: backgrounded QA → Sam chat → **FCM `notification` delivered** (`partner_activity`, high, vis=PRIVATE) title "Sam sent a message"/body "Tap to read and reply" — **no content in push** (privacy-safe); **tap deep-links to the correct conversation** (clean Home-baseline test). R16 cold-start smoke 6/6. R12 Pass-B trigger fan-out. | ✅ pass · delivery + privacy + warm deep-link confirmed R18 |
|
||||||
| F — Resilience | R12: concurrency (F-RACE-001 atomic-start code + R8 live) · process-death (smoke `am kill`×5 → push → cold-start recovered each) · offline(R9) | ✅ pass · time-travel + deletion-cascade deferred |
|
| F — Resilience | R12: concurrency (F-RACE-001 atomic-start code + R8 live) · process-death (smoke `am kill`×5 → push → cold-start recovered each) · offline(R9) | ✅ pass · time-travel + deletion-cascade deferred |
|
||||||
| G — Account creation / fake-account | R10: abuse live via D3 (non-member denied, no self-grant) + invite rules; happy/validation R5-clean (unchanged) | ✅ pass |
|
| G — Account creation / fake-account | R10: abuse live via D3 (non-member denied, no self-grant) + invite rules; happy/validation R5-clean (unchanged) | ✅ pass |
|
||||||
| H — Branding & artwork | R13: ToT redesign + Premium-unlock modal done. **2026-06-27 brand audit opened 2 backlogs.** | ⚠️ **BRAND-DARK-COVERAGE** (light-only illustrations need dark variants) + **BRAND-ICON-CUSTOM** (~60 generic Material icons → bespoke `glyph_*`) — full asset lists in `ClaudeBrandingReview.md` |
|
| H — Branding & artwork | R13: ToT redesign + Premium-unlock modal done. **2026-06-27 brand audit opened 2 backlogs.** | ⚠️ **BRAND-DARK-COVERAGE** (light-only illustrations need dark variants) + **BRAND-ICON-CUSTOM** (~60 generic Material icons → bespoke `glyph_*`) — full asset lists in `ClaudeBrandingReview.md` |
|
||||||
| I — Performance & route efficiency | R10: core-tabs jank 5.53% (R8 6.3%), 90th 32ms, leak proxy bounded | ✅ no regression |
|
| I — Performance & route efficiency | R10: core-tabs jank 5.53% (R8 6.3%), 90th 32ms, leak proxy bounded | ✅ no regression |
|
||||||
| J — Accessibility | R13: **J-OBS FIXED + verified live** (composer media/voice/retry buttons → 48dp; measured 126px=48dp both axes); font scale 2.0 reflows + reduce-motion×7 (R10) hold | ✅ done · J-OBS fixed (pending 1 confirm) |
|
| J — Accessibility | R13: **J-OBS FIXED + verified live** (composer media/voice/retry buttons → 48dp; measured 126px=48dp both axes); font scale 2.0 reflows + reduce-motion×7 (R10) hold | ✅ done · J-OBS fixed (pending 1 confirm) |
|
||||||
| K — Billing & subscription lifecycle | Gate (couple-shared unlock) verified via admin toggle (Pass A) + Premium-unlock modal + `onEntitlementChanged` push live (R13/R14). **Real money path (purchase/restore/cancel→expiry-relock/refund/plan-switch) NOT tested** — needs a real device + Play sandbox. | ⚠️ **todo** — money path `blocked→needs-device`; gate ✅ |
|
| K — Billing & subscription lifecycle | Gate (couple-shared unlock) verified via admin toggle (Pass A) + Premium-unlock modal + `onEntitlementChanged` push live (R13/R14). **Real money path (purchase/restore/cancel→expiry-relock/refund/plan-switch) NOT tested** — needs a real device + Play sandbox. | ⚠️ **todo** — money path `blocked→needs-device`; gate ✅ |
|
||||||
| L — Messaging & chat (E2E) | R15: conversation render driven live — decrypt **both dirs**, attribution, timestamps, **Seen** receipt, ❤️ **reaction**, ordering, day-separators, voice-note + image bubbles, E2E composer lock glyphs; inbox decrypted previews **no `enc:` leak**; live QA→Sam send delivered; at-rest `enc:v1:`. Remaining: failed-send/offline retry, delete-message, fresh image/voice send, Discuss-thread live send. | ✅ **pass (core)** — text/decrypt/receipts/reactions/inbox/at-rest verified; 4 sub-items carry |
|
| L — Messaging & chat (E2E) | R15: conversation render driven live — decrypt **both dirs**, attribution, timestamps, **Seen** receipt, ❤️ **reaction**, ordering, day-separators, voice-note + image bubbles, E2E composer lock glyphs; inbox decrypted previews **no `enc:` leak**; live QA→Sam send delivered; at-rest `enc:v1:`. **R18 re-verified live round-trip** (Sam→QA: received + decrypted on partner, `enc:v1:`(79) at rest, marker absent from server docs = no leak, Seen receipt). Remaining: failed-send/offline retry, delete-message, fresh image/voice send, Discuss-thread live send. | ✅ **pass (core)** — re-confirmed R18; 4 sub-items carry |
|
||||||
| M — Settings & account management | R15: **M-001 (quiet hours) FIXED + verified live** (server-side fail-open suppression); per-type notif toggle take-effect confirmed live (server-enforced; field flips in Firestore; toggle-off → 0 delivery); theme/DataStore persistence across relaunch ✅; biometric lock code-sound (cold-start re-lock; background-resume observation → Future.md). Remaining: edit-profile persist, unpair/delete-cascade (disruptive — deferred). | ✅ **pass (core)** — M-001 fixed (pending 1 confirm); unpair/delete deferred |
|
| M — Settings & account management | R15: **M-001 (quiet hours) FIXED + verified live** (server-side fail-open suppression); per-type notif toggle take-effect confirmed live (server-enforced; field flips in Firestore; toggle-off → 0 delivery); theme/DataStore persistence across relaunch ✅; biometric lock code-sound (cold-start re-lock; background-resume observation → Future.md). Remaining: edit-profile persist, unpair/delete-cascade (disruptive — deferred). **R18: M-001 re-confirmed** — toggling QH writes the client mirror (`quietHoursEnabled`/`StartMinutes 1320`/`EndMinutes 480`/`timezone`) to `users/{uid}` correctly; server suppression deployed + R15-verified. Recommend prune. | ✅ **pass (core)** — M-001 confirmed (prune next); unpair/delete deferred |
|
||||||
| N — Daily Q / reveal / check-ins / interactive | R15 (driven): daily-Q + **reveal both-answered gate** ✓; **Bucket List CRUD FIXED+verified (N-001)** — add(`enc:v1:`)/complete/delete/list; **Date Builder FIXED+verified (N-002)** — Create Plan → PLANNED `date_plan` (`enc:v1:`) → Home "Date coming up"; Outcomes/Your Progress code-correct (resolves coupleId, submits); Activity feed render-checked (prior). | ✅ **pass** — N-001 + N-002 fixed (pending 1 confirm) |
|
| N — Daily Q / reveal / check-ins / interactive | R15 (driven): daily-Q + **reveal both-answered gate** ✓; **Bucket List CRUD FIXED+verified (N-001)** — add(`enc:v1:`)/complete/delete/list; **Date Builder FIXED+verified (N-002)** — Create Plan → PLANNED `date_plan` (`enc:v1:`) → Home "Date coming up"; Outcomes/Your Progress code-correct (resolves coupleId, submits); Activity feed render-checked (prior). | ✅ **pass** — N-001 + N-002 fixed (pending 1 confirm) |
|
||||||
| O — Release build & store readiness | **Not started.** All QA to date is on the **debug** APK. Minified release build, signing/AAB, App Check enforcement, i18n/RTL, App-Links, Play Data-Safety = pre-ship gate, not yet run. | ❌ **todo (pre-ship gate)** |
|
| O — Release build & store readiness | **Not started.** All QA to date is on the **debug** APK. Minified release build, signing/AAB, App Check enforcement, i18n/RTL, App-Links, Play Data-Safety = pre-ship gate, not yet run. | ❌ **todo (pre-ship gate)** |
|
||||||
| P — Content, copy & language | R15: UI-microcopy swept (warm/inclusive; debug rows `BuildConfig.DEBUG`-gated; friendly error fallbacks; on-brand privacy copy) + **question-bank audit live: 6103 Qs — 0 empty, 0 exact dupes, 0 placeholder tokens, complete/mutually-exclusive answer configs, good type variety, consent-framed sensitive content.** No typos/off-voice/non-inclusive copy found. | ✅ **pass** — copy + question bank clean |
|
| P — Content, copy & language | R15: UI-microcopy swept (warm/inclusive; debug rows `BuildConfig.DEBUG`-gated; friendly error fallbacks; on-brand privacy copy) + **question-bank audit live: 6103 Qs — 0 empty, 0 exact dupes, 0 placeholder tokens, complete/mutually-exclusive answer configs, good type variety, consent-framed sensitive content.** No typos/off-voice/non-inclusive copy found. **R18: found+fixed P-GRAMMAR-001** — in-game wheel surfaced a subject-verb agreement error; bank scan found **13 stress-Q** from one template family where plural subjects hit a singular "{x} is …" frame ("busy weeks/health worries/… is affecting you"); fixed the 13 rows in asset `app.db` (data-only); root fix belongs in the content generator. | ✅ **pass** — copy clean; P-GRAMMAR-001 fixed (asset) + grammar-audit recommended |
|
||||||
|
|
||||||
**Archived issue IDs (fixed + confirmed, detail in git):** A-001 · A-003 · A-201 · A-OBS · B-001 · B-002 · B-003 · B-004 · C-CC-001 · C-DARKART-001 · C-DARK-UI-001 · C-DARK-UI-002 · C-DARK-UI-003 · C-DS-001 · C-ART-EDGE-001 · C-ART-EDGE-002 · C-HOME-001 · C-NAV-001 · C-NAV-002 · C-NAV-003 · C-PW-001 · C-SEC-001 · D-001 · E-001 · E-002 · E-003 · E-GAME-002 · E-GAME-003 · E-OBS · F-OBS · F-RACE-001 · I-001 · I-002 · J-OBS. **R15: 9 open P2 theme defects (C-THEME-001..009); 3 fixed pending 1 confirm (M-001 quiet hours, N-001 Bucket List, N-002 Date Builder); 2 open P3 brand backlogs.**
|
**Archived issue IDs (fixed + confirmed, detail in git):** A-001 · A-003 · A-201 · A-OBS · B-001 · B-002 · B-003 · B-004 · C-CC-001 · C-DARKART-001 · C-DARK-UI-001 · C-DARK-UI-002 · C-DARK-UI-003 · C-DS-001 · C-ART-EDGE-001 · C-ART-EDGE-002 · C-HOME-001 · C-NAV-001 · C-NAV-002 · C-NAV-003 · C-PW-001 · C-SEC-001 · D-001 · E-001 · E-002 · E-003 · E-GAME-002 · E-GAME-003 · E-OBS · F-OBS · F-RACE-001 · I-001 · I-002 · J-OBS. **R15: 9 open P2 theme defects (C-THEME-001..009); 3 fixed pending 1 confirm (M-001 quiet hours, N-001 Bucket List, N-002 Date Builder); 2 open P3 brand backlogs.**
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@
|
||||||
> to the archived-ID line below (full detail stays in git history). See **Report hygiene** in `ClaudeQAPlan.md`.
|
> to the archived-ID line below (full detail stays in git history). See **Report hygiene** in `ClaudeQAPlan.md`.
|
||||||
|
|
||||||
## Run-state (current)
|
## Run-state (current)
|
||||||
|
- **R18 (2026-06-28) — continuing full run (user: "why are you stopping?" → don't hand back at checkpoints).** Both emulators online (5554=Dark, 5556=Light, both reset to Device-default after testing); package is `closer.app` (launcher `closer.app/app.closer.MainActivity`). **C-DARKART-002 FIXED + verified live across all 4 theme/art states** (see Severity-board R18 note + the issue row): `MainActivity` now drives `AppCompatDelegate.setDefaultNightMode` from `ThemeMode` (sync initial read → no flicker loop; `LaunchedEffect` for runtime toggles), so every `painterResource` + BrandIllustration follows the in-app theme via the real Configuration uiMode. The previously-broken **pack-art banners now render DARK** in decoupled in-app-Dark + system-light, and the Today hero does too; symmetric in-app-Light + system-dark → light; both coupled states correct. **C-DARKART-001 re-confirmed.** The test-suite gate also caught **TEST-002** (flaky `MemoryCapsuleGenerator` determinism test — un-injected `System.currentTimeMillis()` clock violated the documented "pure" contract; **no production caller yet** so zero runtime impact, but it intermittently reddened the suite) → fixed by injecting `createdAtMillis`. **Build clean; 205 unit + 24 functions green.** Uncommitted (user commits): `MainActivity.kt`, `MemoryCapsuleGenerator.kt` (+ its test), `ClaudeReport.md`. DONE this round: **Pass A ✅ / B ✅ / E ✅ / L ✅ / P ✅** + **M-001 confirmed** (recommend prune). NEXT: prune C-DARKART-002 / TEST-002 / P-GRAMMAR-001 / M-001 after this confirm round; resolve **O-AGE-001** (P2 pre-ship age gate — product call); P3 backlogs (BRAND-DARK-COVERAGE, BRAND-ICON-CUSTOM, C-ORIENT-001); optional deeper re-runs of F/G/I (last full sweep R12). Board: **0 open P0/P1 · 1 open P2 (O-AGE-001) · 3 open P3**. **Pass A ✅ (R18, live, Sam free on 5556 — both members confirmed free via admin read):** premium gate enforced across **two distinct surfaces** — Desire Sync (game) → Paywall, premium **Boundaries** pack → Paywall; negative control: **Mixed** "Communication" pack opens and a **free prompt is accessible** (answer composer shown), so the gate isn't over-broad; **Free** filter shows a graceful "Nothing in free yet" empty state (catalog note: no fully-free packs). Paywall billing plans don't load on the non-GMS emulator ("Couldn't load plans / Try again") — expected Pass K env limit, degrades gracefully (no crash).
|
||||||
- **R17 (2026-06-28) — continuing full run (user: "complete full run, don't stop").** Both emulators on R16 build (5554=Dark, 5556=Light); HEAD `8b7bbc2` + working-tree fixes. **Theme fixes confirmed LIVE (dark, 5554):** C-THEME-005 (Wheel-History lock → surfaceVariant/primary), C-THEME-008/009 (Date-Match heart→primaryContainer + count badge→error) — joining 001/002 from R16. **NEW finding C-DARKART-002 (P2):** dark-variant art doesn't render in the decoupled in-app-Dark + system-light state — pack art (`QuestionPackLibraryScreen:223` via `packArtworkRes`) + ~7 literal `painterResource` sites resolve `-night` off SYSTEM uiMode, not the in-app theme; **proven live** (in-app-Dark + system `auto` → light pack art; system night=yes → correct dark art). The BRAND-DARK-COVERAGE batch art is correct but only shows under system-night. **Pass D1 at-rest = CLEAN (admin read R17):** messages `text`, `lastMessagePreview`, Memory Lane capsule content+title, **all 4 game answers (this_or_that/desire_sync/how_well/wheel) + date_swipe `action`** all `enc:v1:`; only metadata in clear. **Pass D3 = CLEAN (live raw-API R17):** minted non-member token → couple doc / messages / capsules / desire_sync reads + premium self-grant all **DENIED 403** (`scratchpad/d3_negative.js`). **C-DARKART-002 fully diagnosed** (routing through BrandIllustration is insufficient — `createConfigurationContext` doesn't resolve `-night` for these resources; recommended fix = sync config uiMode to in-app theme; my probe edit reverted; tree clean; build+units green; theme-scan CRIT still 0). NEXT (R18): **C-DARKART-002 fix** (uiMode-sync, architectural) + re-verify C-DARKART-001 holds; **M-001** quiet-hours backgrounded-push re-test → prune; live-confirm C-THEME-004 + light-side spot-check; then Pass A (premium gate) / B (a game) / E (full notif) / L / P. Cornerstones D1+D3 ✅ this round.
|
- **R17 (2026-06-28) — continuing full run (user: "complete full run, don't stop").** Both emulators on R16 build (5554=Dark, 5556=Light); HEAD `8b7bbc2` + working-tree fixes. **Theme fixes confirmed LIVE (dark, 5554):** C-THEME-005 (Wheel-History lock → surfaceVariant/primary), C-THEME-008/009 (Date-Match heart→primaryContainer + count badge→error) — joining 001/002 from R16. **NEW finding C-DARKART-002 (P2):** dark-variant art doesn't render in the decoupled in-app-Dark + system-light state — pack art (`QuestionPackLibraryScreen:223` via `packArtworkRes`) + ~7 literal `painterResource` sites resolve `-night` off SYSTEM uiMode, not the in-app theme; **proven live** (in-app-Dark + system `auto` → light pack art; system night=yes → correct dark art). The BRAND-DARK-COVERAGE batch art is correct but only shows under system-night. **Pass D1 at-rest = CLEAN (admin read R17):** messages `text`, `lastMessagePreview`, Memory Lane capsule content+title, **all 4 game answers (this_or_that/desire_sync/how_well/wheel) + date_swipe `action`** all `enc:v1:`; only metadata in clear. **Pass D3 = CLEAN (live raw-API R17):** minted non-member token → couple doc / messages / capsules / desire_sync reads + premium self-grant all **DENIED 403** (`scratchpad/d3_negative.js`). **C-DARKART-002 fully diagnosed** (routing through BrandIllustration is insufficient — `createConfigurationContext` doesn't resolve `-night` for these resources; recommended fix = sync config uiMode to in-app theme; my probe edit reverted; tree clean; build+units green; theme-scan CRIT still 0). NEXT (R18): **C-DARKART-002 fix** (uiMode-sync, architectural) + re-verify C-DARKART-001 holds; **M-001** quiet-hours backgrounded-push re-test → prune; live-confirm C-THEME-004 + light-side spot-check; then Pass A (premium gate) / B (a game) / E (full notif) / L / P. Cornerstones D1+D3 ✅ this round.
|
||||||
- **R16 (2026-06-28) — full ClaudeQAPlan run STARTED.** Session-start: both emulators online (5554/5556), HEAD `8b7bbc2`, working tree carries a **dark-variant art batch** (pack_art_*_dark, together_empty/tonight_partner_prompt night variants → BRAND-DARK-COVERAGE progress) + my doc edits; baseline TBD. **Cheap gates (new step 3):** functions tests **24/24 ✅**; Android unit tests **found 5 failures → FIXED → 205 ✅** (**TEST-001**, test-vs-code drift: (a) `PartnerNotificationManagerTest` stubbed `isInQuietHours(any())` but the method's default `now: Calendar` param pinned a stale instant that never matched the call-time clock → stub now `any(), any()`; (b) `CloserBrandCopyTest` ≤64 cap predated the intentional 150-char flagship `primaryMessage` — `BrandMessageRotator` wraps it `maxLines=3` — → cap now applies to short slogans only, flagship bounded `1..160`. Both **test-side only**; production correct: quiet hours verified live R15, flagship is committed design `6d74c6a`). **theme-scan** 🔴9/🟠8/🟡32 (the 9 CRITICAL = C-THEME-001..009 already filed). **wiring-scan** 🔴0/🟠20/🟡35 (🔴0 = Pass N DoD met). **Done so far:** rebuilt+installed both; **smoke 5554 = 6/6 PASS, 0 blocked** (launcher + 5 notif cold-starts open & stay), 5556 in progress. **Theme triage — of the 9 filed C-THEME, 3 are NOT real shipped defects:** C-THEME-003 = `@Preview`-only (`WheelRevealPreview`) → false positive; theme-scan now **excludes @Preview** composables. C-THEME-006/007 = dead unused `PlaceholderScreen.kt` (replaced by the real dashboard; 0 source refs) → **file deleted**. **The other 6 are real → FIXED** (theme tokens): BucketList (badge→primaryContainer; AddItemDialog surface→surface + Cancel→secondaryContainer + Add→primary + CategoryChips→primary/surfaceVariant — also closes the Future.md "mixed dialog" note), DateMatch (heart→primaryContainer, count badge→error/onError), WheelHistory (lock→surfaceVariant/primary), QuestionThread (waiting banner→surfaceVariant). **theme-scan CRITICAL 9→0; build + unit tests green.** **R16 RESULT:** smoke **6/6 both (0 blocked)**; theme-scan **CRITICAL 9→0** (3 reclassified, 6 fixed); **C-THEME-001/002 + N-001 + N-002 verified LIVE (dark, 5554)**; units **205** + functions **24** green; dead `PlaceholderScreen.kt` deleted; theme-scan now excludes `@Preview`. **N-001/N-002 pruned.** Open now: **O-AGE-001** (P2 pre-ship) + 3 P3. **NEXT (R17):** live-confirm the 4 remaining C-THEME fixes (004/005/008/009) in both themes + the 6 in LIGHT on 5556; re-test **M-001** quiet-hours (backgrounded-push) to prune it; then resume passes A–N+P — esp. a live both-theme sweep of the new **dark-art batch** (BRAND-DARK-COVERAGE) + the D/E cornerstones. Uncommitted (user commits): unit-test fixes, 4 theme-fixed screens + BucketList/DateMatch, `scripts/theme-scan.sh`, **deleted** `PlaceholderScreen.kt`, dark-art batch, QA docs.
|
- **R16 (2026-06-28) — full ClaudeQAPlan run STARTED.** Session-start: both emulators online (5554/5556), HEAD `8b7bbc2`, working tree carries a **dark-variant art batch** (pack_art_*_dark, together_empty/tonight_partner_prompt night variants → BRAND-DARK-COVERAGE progress) + my doc edits; baseline TBD. **Cheap gates (new step 3):** functions tests **24/24 ✅**; Android unit tests **found 5 failures → FIXED → 205 ✅** (**TEST-001**, test-vs-code drift: (a) `PartnerNotificationManagerTest` stubbed `isInQuietHours(any())` but the method's default `now: Calendar` param pinned a stale instant that never matched the call-time clock → stub now `any(), any()`; (b) `CloserBrandCopyTest` ≤64 cap predated the intentional 150-char flagship `primaryMessage` — `BrandMessageRotator` wraps it `maxLines=3` — → cap now applies to short slogans only, flagship bounded `1..160`. Both **test-side only**; production correct: quiet hours verified live R15, flagship is committed design `6d74c6a`). **theme-scan** 🔴9/🟠8/🟡32 (the 9 CRITICAL = C-THEME-001..009 already filed). **wiring-scan** 🔴0/🟠20/🟡35 (🔴0 = Pass N DoD met). **Done so far:** rebuilt+installed both; **smoke 5554 = 6/6 PASS, 0 blocked** (launcher + 5 notif cold-starts open & stay), 5556 in progress. **Theme triage — of the 9 filed C-THEME, 3 are NOT real shipped defects:** C-THEME-003 = `@Preview`-only (`WheelRevealPreview`) → false positive; theme-scan now **excludes @Preview** composables. C-THEME-006/007 = dead unused `PlaceholderScreen.kt` (replaced by the real dashboard; 0 source refs) → **file deleted**. **The other 6 are real → FIXED** (theme tokens): BucketList (badge→primaryContainer; AddItemDialog surface→surface + Cancel→secondaryContainer + Add→primary + CategoryChips→primary/surfaceVariant — also closes the Future.md "mixed dialog" note), DateMatch (heart→primaryContainer, count badge→error/onError), WheelHistory (lock→surfaceVariant/primary), QuestionThread (waiting banner→surfaceVariant). **theme-scan CRITICAL 9→0; build + unit tests green.** **R16 RESULT:** smoke **6/6 both (0 blocked)**; theme-scan **CRITICAL 9→0** (3 reclassified, 6 fixed); **C-THEME-001/002 + N-001 + N-002 verified LIVE (dark, 5554)**; units **205** + functions **24** green; dead `PlaceholderScreen.kt` deleted; theme-scan now excludes `@Preview`. **N-001/N-002 pruned.** Open now: **O-AGE-001** (P2 pre-ship) + 3 P3. **NEXT (R17):** live-confirm the 4 remaining C-THEME fixes (004/005/008/009) in both themes + the 6 in LIGHT on 5556; re-test **M-001** quiet-hours (backgrounded-push) to prune it; then resume passes A–N+P — esp. a live both-theme sweep of the new **dark-art batch** (BRAND-DARK-COVERAGE) + the D/E cornerstones. Uncommitted (user commits): unit-test fixes, 4 theme-fixed screens + BucketList/DateMatch, `scripts/theme-scan.sh`, **deleted** `PlaceholderScreen.kt`, dark-art batch, QA docs.
|
||||||
- **R15 (2026-06-27) — gap-closing round (Passes L/M/N/P + regression smoke) — found & FIXED M-001 (P2).** Build current (HEAD `c31eea2` + R15 working-tree changes rebuilt+installed both emulators); baseline both FREE, 0 active sessions. **Smoke** ✅ 6/6 GREEN both (launcher + 5 notif cold-starts). **M (settings take-effect)** — **M-001 (P2) quiet hours didn't suppress backgrounded/killed partner pushes** (local-only window; OS shows `notification` block w/o app code). **FIXED + verified live:** client mirrors window+tz → `users/{uid}`; 4 partner-action senders suppress via fail-open `recipientInQuietHours()`; rules allowlist extended. Live: QH ON → fn log `is in quiet hours — suppressing`, 0 delivery; QH OFF → `notified partner`. Per-type chat toggle re-confirmed server-enforced (toggle off → 0 delivery; field flips in Firestore). Theme/DataStore persistence across relaunch ✅. Biometric lock code-sound (no compose bypass; observation: re-locks on cold-start, not plain background→resume → `Future.md`). **L (chat E2E)** ✅ decrypt both dirs, attribution, Seen receipt, ❤️ reaction, ordering, day-sep, inbox no `enc:` leak, at-rest `enc:v1:`. **N** ✅ daily-Q + reveal both-answered gate render (outcomes/bucket-list/date-builder carried — render-clean prior rounds). **P (content/language)** ✅ UI copy warm/inclusive, debug rows `BuildConfig.DEBUG`-gated, friendly error fallbacks; **question bank 6103 Qs: 0 empty/0 dupes/0 placeholders/complete answer configs/on-guide tone.** **D1 at-rest** ✅ messages/preview/capsules `enc:v1:`. **0 FATAL.** **Pass N driven (user "FIX"):** **N-001 (P1) Bucket List was fully non-functional** (coupleId never set → all CRUD no-ops) → **FIXED + verified live** (add `enc:v1:` / complete / delete / list render; client-only). **N-002 (P2) "Plan a Date"/Date Builder "Create Plan" no-op** (wrote to unread prefs collection; `dateIdeaId`/`coupleId` never wired) → **FIXED + verified live** (re-pointed `DateBuilderViewModel` to create a PLANNED `DatePlan` via `savePlan` + resolve coupleId → `date_plan` status=planned, `enc:v1:`; Home shows "Date coming up"). Outcomes/Your Progress code-correct (resolves coupleId); daily-Q/reveal render ✓. Uncommitted (user commits): client (`BucketListViewModel`, `DateBuilderViewModel`) — M-001's functions/rules/client were committed by the user mid-round (+ user dropped 3 dark-variant PNGs in `drawable-night-nodpi/` toward BRAND-DARK-COVERAGE). **M-001 functions+rules DEPLOYED to prod; N-001/N-002 are client-only (debug APK installed both emulators).** NEXT (R16): confirm M-001 + N-001 + N-002 hold → prune; 2 P3 brand backlogs; revisit Date Builder "both-partners-generate" vision if wanted.
|
- **R15 (2026-06-27) — gap-closing round (Passes L/M/N/P + regression smoke) — found & FIXED M-001 (P2).** Build current (HEAD `c31eea2` + R15 working-tree changes rebuilt+installed both emulators); baseline both FREE, 0 active sessions. **Smoke** ✅ 6/6 GREEN both (launcher + 5 notif cold-starts). **M (settings take-effect)** — **M-001 (P2) quiet hours didn't suppress backgrounded/killed partner pushes** (local-only window; OS shows `notification` block w/o app code). **FIXED + verified live:** client mirrors window+tz → `users/{uid}`; 4 partner-action senders suppress via fail-open `recipientInQuietHours()`; rules allowlist extended. Live: QH ON → fn log `is in quiet hours — suppressing`, 0 delivery; QH OFF → `notified partner`. Per-type chat toggle re-confirmed server-enforced (toggle off → 0 delivery; field flips in Firestore). Theme/DataStore persistence across relaunch ✅. Biometric lock code-sound (no compose bypass; observation: re-locks on cold-start, not plain background→resume → `Future.md`). **L (chat E2E)** ✅ decrypt both dirs, attribution, Seen receipt, ❤️ reaction, ordering, day-sep, inbox no `enc:` leak, at-rest `enc:v1:`. **N** ✅ daily-Q + reveal both-answered gate render (outcomes/bucket-list/date-builder carried — render-clean prior rounds). **P (content/language)** ✅ UI copy warm/inclusive, debug rows `BuildConfig.DEBUG`-gated, friendly error fallbacks; **question bank 6103 Qs: 0 empty/0 dupes/0 placeholders/complete answer configs/on-guide tone.** **D1 at-rest** ✅ messages/preview/capsules `enc:v1:`. **0 FATAL.** **Pass N driven (user "FIX"):** **N-001 (P1) Bucket List was fully non-functional** (coupleId never set → all CRUD no-ops) → **FIXED + verified live** (add `enc:v1:` / complete / delete / list render; client-only). **N-002 (P2) "Plan a Date"/Date Builder "Create Plan" no-op** (wrote to unread prefs collection; `dateIdeaId`/`coupleId` never wired) → **FIXED + verified live** (re-pointed `DateBuilderViewModel` to create a PLANNED `DatePlan` via `savePlan` + resolve coupleId → `date_plan` status=planned, `enc:v1:`; Home shows "Date coming up"). Outcomes/Your Progress code-correct (resolves coupleId); daily-Q/reveal render ✓. Uncommitted (user commits): client (`BucketListViewModel`, `DateBuilderViewModel`) — M-001's functions/rules/client were committed by the user mid-round (+ user dropped 3 dark-variant PNGs in `drawable-night-nodpi/` toward BRAND-DARK-COVERAGE). **M-001 functions+rules DEPLOYED to prod; N-001/N-002 are client-only (debug APK installed both emulators).** NEXT (R16): confirm M-001 + N-001 + N-002 hold → prune; 2 P3 brand backlogs; revisit Date Builder "both-partners-generate" vision if wanted.
|
||||||
|
|
@ -49,8 +50,8 @@
|
||||||
|---|---|---|
|
|---|---|---|
|
||||||
| P0 | 0 | 0 |
|
| P0 | 0 | 0 |
|
||||||
| P1 | 0 | 0 |
|
| P1 | 0 | 0 |
|
||||||
| P2 | **2** (O-AGE-001 pre-ship, C-DARKART-002 decoupled dark-art) | **8** (6× C-THEME fixed, M-001 quiet hours, TEST-001 unit suite) |
|
| P2 | **1** (O-AGE-001 pre-ship) | **9** (6× C-THEME fixed, M-001 quiet hours, TEST-001 unit suite, **C-DARKART-002** decoupled dark-art — fixed+verified R18) |
|
||||||
| P3 | **3** (BRAND-DARK-COVERAGE, BRAND-ICON-CUSTOM, C-ORIENT-001) | 0 |
|
| P3 | **3** (BRAND-DARK-COVERAGE, BRAND-ICON-CUSTOM, C-ORIENT-001) | **2** (TEST-002 flaky capsule-determinism test; P-GRAMMAR-001 13 stress-Q subject-verb agreement errors — fixed in asset) |
|
||||||
|
|
||||||
_R16: ran the new **cheap gates** → found+fixed **TEST-001** (unit suite was silently red, 5 failures) → **205 unit + 24
|
_R16: ran the new **cheap gates** → found+fixed **TEST-001** (unit suite was silently red, 5 failures) → **205 unit + 24
|
||||||
functions green**. **Entrypoint smoke 6/6 on BOTH emulators, 0 blocked.** Theme triage: of the 9 filed C-THEME, **3 were
|
functions green**. **Entrypoint smoke 6/6 on BOTH emulators, 0 blocked.** Theme triage: of the 9 filed C-THEME, **3 were
|
||||||
|
|
@ -60,6 +61,52 @@ verified LIVE (dark)**. Confirmed + **pruned** R15 fixes **N-001** (P1, live add
|
||||||
up"). **M-001 carried** (not re-tested this round). Remaining open: **1 P2 pre-ship** (O-AGE-001) + **3 P3** (2 brand
|
up"). **M-001 carried** (not re-tested this round). Remaining open: **1 P2 pre-ship** (O-AGE-001) + **3 P3** (2 brand
|
||||||
backlogs + C-ORIENT-001). 4 C-THEME fixes (004/005/008/009) pending live confirm next round._
|
backlogs + C-ORIENT-001). 4 C-THEME fixes (004/005/008/009) pending live confirm next round._
|
||||||
|
|
||||||
|
_R18 (2026-06-28): **C-DARKART-002 FIXED + verified live (all 4 theme/art states).** Root fix = drive the real
|
||||||
|
Configuration uiMode from the in-app theme via `AppCompatDelegate.setDefaultNightMode` in `MainActivity` (read initial
|
||||||
|
theme synchronously to avoid a placeholder→real recreation flicker loop; `LaunchedEffect` handles runtime toggles). This
|
||||||
|
makes **every** `painterResource` site + BrandIllustration follow the in-app theme at once, retiring the unreliable
|
||||||
|
per-site `createConfigurationContext` hack. Verified: coupled-dark→dark, coupled-light→light, **decoupled in-app-Dark +
|
||||||
|
system-light → dark (Today hero AND the previously-broken pack-art banners)**, decoupled in-app-Light + system-dark →
|
||||||
|
light. C-DARKART-001 re-confirmed (holds). Running the new test-suite gate also caught **TEST-002**: `MemoryCapsuleGenerator`
|
||||||
|
documents itself "pure/deterministic" but every factory stamped `createdAt = System.currentTimeMillis()`, so the
|
||||||
|
`same input produces identical capsules` test was **flaky** across ms boundaries (passed alone, failed in the full suite).
|
||||||
|
Fixed by injecting `createdAtMillis` (defaults to wall clock; tests pin it) — honors the contract; **no production caller
|
||||||
|
exists yet** (Memory Lane not wired in), so zero runtime impact, but it was undermining the suite gate. **205 unit + 24
|
||||||
|
functions green; build clean.**_
|
||||||
|
|
||||||
|
_R18 Pass A/B/P (live, 5556 Sam free): **Pass A ✅** premium gate enforced on 2 surfaces (Desire Sync + Boundaries pack
|
||||||
|
→ Paywall), free content reachable (Mixed pack prompt opens), graceful empty/billing states. **Pass B ✅** Wheel
|
||||||
|
playthrough end-to-end (spin→Stress→start→MC + free-text answers→1/2/3 progression→End→async "answers are in, waiting
|
||||||
|
for partner" reveal-gate); 0 FATAL either device. **Pass P → P-GRAMMAR-001 (P3, FIXED in asset):** the in-game wheel
|
||||||
|
question surfaced a subject-verb agreement error; bank scan found **13 questions** (all `stress` category, from one
|
||||||
|
template family of 35) where **plural subjects were substituted into a singular "{subject} is …" frame** — "low energy
|
||||||
|
days/busy weeks/health worries/burnout signs/unexpected problems **is** affecting you / **is** starting to show up".
|
||||||
|
Fixed the 13 rows in `app/src/main/assets/database/app.db` (data-only `UPDATE … REPLACE(' is ',' are ')` on exact IDs
|
||||||
|
stress_021/022/031/032/041/042/061/062/066/067/195/199/203; backup `app.db.bak_pgrammar`; verified 0 remaining). Room's
|
||||||
|
identity hash is schema-based so the edit is safe; **root/durable fix belongs in the content generator** (build_db.py —
|
||||||
|
NOT run per standing constraint) so regeneration doesn't reintroduce it (pluralize the verb or curate subjects).
|
||||||
|
**Caveat:** running emulators copied the old asset on first launch and won't re-copy without a data wipe — source asset
|
||||||
|
is corrected for new installs, verified via sqlite. Recommend a broader template-grammar audit of the bank (the prior
|
||||||
|
completeness scan checked empties/dupes/placeholders, not agreement)._
|
||||||
|
|
||||||
|
_R18 Pass L (live E2E, 5556 Sam → 5554 QA): **✅** sent a uniquely-tagged message; **received + rendered in plaintext on
|
||||||
|
the partner device** (E2E decrypt works), **`enc:v1:` at rest** (admin read: text=enc✓(79)), **at-rest leak check passes**
|
||||||
|
(marker absent from all message docs — `scratchpad/msg_atrest.js`), **"Seen" read receipt** present, and the chat renders
|
||||||
|
correctly in **dark** on 5554 (incidental C-theme confirm). Cross-checks D1 (message at-rest) on fresh live data._
|
||||||
|
|
||||||
|
_R18 M-001 + Pass E (live): **M-001 → confirmed (recommend prune).** Toggling Quiet Hours on 5554 (QA) writes the client
|
||||||
|
mirror to `users/{QA}` correctly — `quietHoursEnabled:true`, `quietHoursStartMinutes:1320` (10 PM), `quietHoursEndMinutes:480`
|
||||||
|
(8 AM), `timezone:"America/Chicago"` — the exact fields the deployed `recipientInQuietHours()` reads; toggling off →
|
||||||
|
`enabled:false`. The client-mirror half (the R15 fix) is intact; the server-suppression half is deployed + was live-verified
|
||||||
|
R15. The full clock-windowed suppression was NOT re-run this round (emulator clock ~4 PM is outside the 10 PM–8 AM window;
|
||||||
|
doing it would need either clock manipulation or a per-occurrence-gated production write that the auto-classifier denied —
|
||||||
|
not worked around). Restored QH to baseline (off). **Pass E ✅ (real backgrounded delivery + privacy + deep-link):**
|
||||||
|
backgrounded QA → Sam sends chat → FCM `notification` delivered (`channel=partner_activity`, importance high, vis=PRIVATE)
|
||||||
|
with title **"Sam sent a message"** / body **"Tap to read and reply."** — **no message content in the push** (E2E ciphertext
|
||||||
|
stays server-blind; privacy-safe, cross-checks D6). Clean Home-baseline re-test: **tapping the notification deep-links to the
|
||||||
|
correct conversation** with messages decrypted. (A first attempt resumed at the prior screen — re-tested from Home and it
|
||||||
|
routed correctly, so that was a test artifact, not a bug.)_
|
||||||
|
|
||||||
## Issues — open (Pass C theme defects + brand-asset backlogs)
|
## Issues — open (Pass C theme defects + brand-asset backlogs)
|
||||||
> Surfaced by the 2026-06-27 brand standards audit (new Pass H/Pass C mandates) and the 2026-06-28 theme-scan run. Brand-quality defects (light-only art, generic icons) and Pass C theme defects (hardcoded surface/background colors) both live here; asset lists + prompts are in `ClaudeBrandingReview.md`.
|
> Surfaced by the 2026-06-27 brand standards audit (new Pass H/Pass C mandates) and the 2026-06-28 theme-scan run. Brand-quality defects (light-only art, generic icons) and Pass C theme defects (hardcoded surface/background colors) both live here; asset lists + prompts are in `ClaudeBrandingReview.md`.
|
||||||
>
|
>
|
||||||
|
|
@ -67,7 +114,7 @@ backlogs + C-ORIENT-001). 4 C-THEME fixes (004/005/008/009) pending live confirm
|
||||||
|
|
||||||
| ID | Sev | Area | Description | Suggested fix | Status |
|
| ID | Sev | Area | Description | Suggested fix | Status |
|
||||||
|---|---|---|---|---|---|
|
|---|---|---|---|---|---|
|
||||||
| C-DARKART-002 | P2 | Visual / theme-variant art (Pass C/H) | **Dark-variant art does NOT render in the decoupled in-app-Dark + system-light state** (a common, supported config: user sets in-app **Dark** on a light/`auto`-system phone). Pack-art banners (`QuestionPackLibraryScreen.kt:223` via `packArtworkRes`) + ~7 literal `painterResource(R.drawable.illustration_/pack_art_)` sites (SpinWheel, AnswerReveal, Home, PlayHub, + debug ArtPreview) load via **raw `painterResource`**, which resolves the `-night` qualifier off the **system** uiMode, not the in-app theme — so the new `drawable-night-nodpi/` dark variants (BRAND-DARK-COVERAGE batch) only show when system=night. **Verified live R17 (5554), deterministic decoupled test (system night=no + in-app=Dark):** Question-Packs list banners render **LIGHT on dark**; forcing system night=yes → correct dark aubergine art (variants exist + packaged). **Routing through `BrandIllustration` is INSUFFICIENT — proven:** temporarily routed the pack-art `Image`→`BrandIllustration(tile=false)`, rebuilt+installed, `am kill` fresh cold-start in the decoupled state → **still light** (reverted the change). So `createConfigurationContext(uiMode=NIGHT_YES)` + `getDrawable` does **not** resolve the `-night` variant for these `-nodpi` resources (Android drawable-cache/resolution gotcha). NB: the Today daily-question hero (also BrandIllustration) *did* show dark in the same state — so the mechanism is **unreliable/asset-dependent**, which also casts doubt on whether C-DARKART-001's BrandIllustration fix truly holds for all art (re-verify). | **Comprehensive fix (recommended): sync the Activity config `uiMode` to the in-app `ThemeMode`** (e.g. `AppCompatDelegate.setDefaultNightMode` or apply a `Configuration` override in `MainActivity`) so **all** resource resolution — `painterResource` AND BrandIllustration — follows the in-app theme and the decoupled state disappears. This replaces the per-site BrandIllustration hack. Verify both decoupled directions + that CloserTheme color-scheme derivation (explicit `darkTheme` from ThemeMode) isn't double-applied. | **Open** |
|
| C-DARKART-002 | P2 | Visual / theme-variant art (Pass C/H) | **Dark-variant art does NOT render in the decoupled in-app-Dark + system-light state** (a common, supported config: user sets in-app **Dark** on a light/`auto`-system phone). Pack-art banners (`QuestionPackLibraryScreen.kt:223` via `packArtworkRes`) + ~7 literal `painterResource(R.drawable.illustration_/pack_art_)` sites (SpinWheel, AnswerReveal, Home, PlayHub, + debug ArtPreview) load via **raw `painterResource`**, which resolves the `-night` qualifier off the **system** uiMode, not the in-app theme — so the new `drawable-night-nodpi/` dark variants (BRAND-DARK-COVERAGE batch) only show when system=night. **Verified live R17 (5554), deterministic decoupled test (system night=no + in-app=Dark):** Question-Packs list banners render **LIGHT on dark**; forcing system night=yes → correct dark aubergine art (variants exist + packaged). **Routing through `BrandIllustration` is INSUFFICIENT — proven:** temporarily routed the pack-art `Image`→`BrandIllustration(tile=false)`, rebuilt+installed, `am kill` fresh cold-start in the decoupled state → **still light** (reverted the change). So `createConfigurationContext(uiMode=NIGHT_YES)` + `getDrawable` does **not** resolve the `-night` variant for these `-nodpi` resources (Android drawable-cache/resolution gotcha). NB: the Today daily-question hero (also BrandIllustration) *did* show dark in the same state — so the mechanism is **unreliable/asset-dependent**, which also casts doubt on whether C-DARKART-001's BrandIllustration fix truly holds for all art (re-verify). | **Comprehensive fix (recommended): sync the Activity config `uiMode` to the in-app `ThemeMode`** (e.g. `AppCompatDelegate.setDefaultNightMode` or apply a `Configuration` override in `MainActivity`) so **all** resource resolution — `painterResource` AND BrandIllustration — follows the in-app theme and the decoupled state disappears. This replaces the per-site BrandIllustration hack. Verify both decoupled directions + that CloserTheme color-scheme derivation (explicit `darkTheme` from ThemeMode) isn't double-applied. | **FIXED (R18)** — implemented the recommended uiMode-sync: `MainActivity` drives `AppCompatDelegate.setDefaultNightMode` from `ThemeMode` (initial read synchronous to avoid a placeholder→real recreation flicker loop; `LaunchedEffect` for runtime toggles). **Verified live all 4 states:** coupled-dark→dark, coupled-light→light, **decoupled in-app-Dark + system-light → DARK (Today hero AND pack-art banners — the previously-broken sites)**, decoupled in-app-Light + system-dark → light. Replaces the per-site BrandIllustration hack (now redundant-but-harmless). Pending 1 confirm. |
|
||||||
| C-THEME-001 | P2 | Dates / Bucket List | **AddItemDialog used a hardcoded light surface** (`Surface(color = Color.White)`, `BucketListScreen.kt`) → light dialog on dark. | → `MaterialTheme.colorScheme.surface`; also themed the whole dialog (Cancel→`secondaryContainer`, Add→`primary`, CategoryChips→`primary`/`surfaceVariant`) — closes the Future.md "mixed dark/light dialog" note. | **Fixed — verified LIVE R16 (dark): dialog surface dark, fields/chips/buttons readable.** Pending 1 confirm. |
|
| C-THEME-001 | P2 | Dates / Bucket List | **AddItemDialog used a hardcoded light surface** (`Surface(color = Color.White)`, `BucketListScreen.kt`) → light dialog on dark. | → `MaterialTheme.colorScheme.surface`; also themed the whole dialog (Cancel→`secondaryContainer`, Add→`primary`, CategoryChips→`primary`/`surfaceVariant`) — closes the Future.md "mixed dark/light dialog" note. | **Fixed — verified LIVE R16 (dark): dialog surface dark, fields/chips/buttons readable.** Pending 1 confirm. |
|
||||||
| C-THEME-002 | P2 | Dates / Bucket List | **CategoryBadge + category filter chips used hardcoded light colors** (`Color(0xFFF3E8FF)`; ternary `Color(0xFFFFF8FC)` — the latter evaded the scanner's `color = Color(` regex). | → badge `primaryContainer`/`onPrimaryContainer`; chips `primary`/`surfaceVariant`. | **Fixed — verified LIVE R16 (dark): item-card "Adventure" badge + All/Adventure filter chips readable.** Pending 1 confirm. |
|
| C-THEME-002 | P2 | Dates / Bucket List | **CategoryBadge + category filter chips used hardcoded light colors** (`Color(0xFFF3E8FF)`; ternary `Color(0xFFFFF8FC)` — the latter evaded the scanner's `color = Color(` regex). | → badge `primaryContainer`/`onPrimaryContainer`; chips `primary`/`surfaceVariant`. | **Fixed — verified LIVE R16 (dark): item-card "Adventure" badge + All/Adventure filter chips readable.** Pending 1 confirm. |
|
||||||
| C-THEME-004 | P2 | Questions / Discussion thread | **WaitingPhase "Your answer is saved" banner used `Color.White.copy(alpha=0.78f)`** (`QuestionThreadScreen.kt`). | → `surfaceVariant.copy(alpha=0.78f)` (children already use `onSurface`/`onSurfaceVariant`). | **Fixed R16** (theme-scan 0, build+units green) — pending live confirm. |
|
| C-THEME-004 | P2 | Questions / Discussion thread | **WaitingPhase "Your answer is saved" banner used `Color.White.copy(alpha=0.78f)`** (`QuestionThreadScreen.kt`). | → `surfaceVariant.copy(alpha=0.78f)` (children already use `onSurface`/`onSurfaceVariant`). | **Fixed R16** (theme-scan 0, build+units green) — pending live confirm. |
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue