diff --git a/ClaudeQACoverage.md b/ClaudeQACoverage.md index da1fc1eb..ec644bee 100644 --- a/ClaudeQACoverage.md +++ b/ClaudeQACoverage.md @@ -63,15 +63,16 @@ Note: exit each game via "Back to Play" between games so the session closes (B-0 ## Pass C — Visual (light + dark), all ~50 routes ~14 screen-types swept Dark (5554) + several Light (5556): all render clean, readable, no FATAL, no dark-mode contrast issues; **0 `enc:v1:` leaked to conversation UI**. Covered: Home, Play hub, all 7 game screens (setup/play/reveal), Paywall, Settings (+Subscription +Appearance), Today/daily-question (+answer detail), Messages inbox, Conversation (image+voice+text+reaction). Back-stack clean (deep→hub→Home→launcher, no double-back). -- **Theme-scan execution tracking (MANDATORY):** every Pass C round must record: - | Round | Scanner run | CRITICAL | MAJOR | REVIEW | Findings filed to ClaudeReport.md | - |---|---|---|---|---|---| - | R15 | ✅ | 9 | 0 | 0 | ✅ | - | R16 | — | — | — | — | — | +- **Theme-scan execution tracking (MANDATORY):** every Pass C round must record the counts exactly as + `scripts/theme-scan.sh` reports them in its `## Summary` section, then file the appropriate items: + | Round | Scanner run | CRITICAL | MAJOR | REVIEW | CRITICAL filed to ClaudeReport.md | MAJOR filed (if any break themes) | + |---|---|---|---|---|---|---| + | R15 | ✅ | 9 | 8 | 32 | ✅ (C-THEME-001..009) | — | + | R16 | — | — | — | — | — | — | - R15 scanner findings: 9 CRITICAL hardcoded light/dark surface/background colors filed as C-THEME-001..009 - (BucketList ×2, WheelCompleteScreen, QuestionThreadScreen, WheelHistoryScreen, PlaceholderScreen ×2, - DateMatchScreen ×2). + R15 scanner: 9 CRITICAL hardcoded surface/background colors filed as C-THEME-001..009; 8 MAJOR (1 component + color override + 7 direct `painterResource` hits) and 31 REVIEW items deferred to the visual sweep. Update this + row if any MAJOR is promoted to a filed defect. - **R10 re-sweep (both themes where relevant):** Messages inbox ✅ (dark+light: conversations, avatars, unread dot, previews decrypted, no `enc:` leak), Conversation ✅ (image/voice/text/reaction/read-receipt/date-sep, E2E lock glyphs, correct attribution both dirs), per-question Discussion thread ✅, Today/daily-question ✅ (dark+light, paired-books art on-brand), Activity/Together ✅ (dark). **5 P2 found:** C-HOME-001 (Home shows top pending action twice — `primaryAction` hero + `buildPendingActions` row), C-NAV-002 (wheel results→BACK re-enters finished play screen, no popUpTo), C-NAV-003 (Wheel History/Past Games + PartnerHome double app-bar — route in `shellBackRoutes` while screen owns a TopAppBar; C-CC-001 class), C-PW-001 (dark paywall "What's included" pills light-on-light, `BenefitPill` onSurface text), C-SEC-001 (accepter recovery copy). Premium-locked Wheel History state renders. Date Builder · Question Packs(gated→paywall) · Answer Reveal sealed = token-consistent, R9-clean. - **R9 deferred sweep — 0 new issues:** Answer History, Together/Activity, Bucket List (empty state + FAB), Date Match deck, Date Matches all render cleanly in **dark** (good contrast, no clipping, no FATAL); Privacy & Terms + Home confirm **light** parity (shared Material3 tokens). Remaining standard list/detail (Wheel History · Date Builder · Past Games · Answer Reveal sealed · Question Packs[gated→paywall]) are token-consistent with the above; fresh-account auth/onboarding visual covered R3/R5. No C findings. diff --git a/ClaudeQAPlan.md b/ClaudeQAPlan.md index e1f064c7..47f92e8a 100644 --- a/ClaudeQAPlan.md +++ b/ClaudeQAPlan.md @@ -42,6 +42,7 @@ For each Pass below, before you start, read the relevant section of [`docs/Engin | **An idea / improvement** — works but could be better, confusing copy, missing affordance, rough-but-not-broken flow, "it'd be great if…", feature idea | **`Future.md`** `## QA` | Short title + what prompted it + suggested improvement | | **New artwork to create** — illustrations, glyphs, image-gen prompts | **`ClaudeBrandingReview.md`** | House-style prompt + placement | | **What got tested + its status** (pass / fail / todo / deferred) | **`ClaudeQACoverage.md`** | Coverage cell (the resume anchor) | +| **Automated scanner findings** | **`ClaudeReport.md`** (CRITICAL/MAJOR that break themes/functionality) **+** `ClaudeQACoverage.md` (execution counts + filing status) | ID + file:line + pattern + fix suggestion | | **Durable engineering knowledge** — a fixed bug's root cause + how it's easy to re-introduce, a new architecture fact / data path / wire-format contract / security invariant / gate pattern, or anything the manual is now stale/missing about | **[`docs/Engineering_Reference_Manual.md`](docs/Engineering_Reference_Manual.md)** (esp. [Known landmines and recent fixes](docs/Engineering_Reference_Manual.md#known-landmines-and-recent-fixes)) | New landmine entry (ID + cause + the guard) and/or an updated architecture/gate/flow section | - A branding **defect** (mis-colored, clipped, off-brand, low-contrast art) is a **bug → `ClaudeReport.md`**, not a brand @@ -171,6 +172,13 @@ confirms + enumerates this; the fix phase applies couple-shared everywhere. splash-crash class that `am start` can't. Run it **every round and after any commit touching MainActivity / splash / theme / manifest / nav / notifications**. `FAIL` = an app crash (real bug); `BLOCK` = push not delivered (flaky emulator FCM — rerun, not a bug). +- **Run associated automated scanners BEFORE the manual pass.** Every pass with a supporting script must start with it: + - **Pass C:** run `scripts/theme-scan.sh` and review `/tmp/claude-theme-scan-.md` before looking at any screen. + - If a scanner does not yet exist for a pass but the pass is highly automatable (e.g. touch-target sizing for Pass J, + `enc:v1:` leak grep for Pass L, redundant-read count for Pass I), consider building it and adding it here. + - Scanner findings narrow the manual sweep: every 🔴 CRITICAL must be verified in both themes; 🟠 MAJOR must be + reviewed for theme/art breakage; 🟡 REVIEW is checked during the visual sweep. + - If a manual finding is something the scanner should have caught, improve the scanner (see Living discovery ritual). - **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, @@ -209,6 +217,10 @@ surface and reconcile it with `ClaudeQACoverage.md`: 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. +- **Scanner update rule:** if a manual finding is a pattern an existing scanner *should* have caught (e.g. a hardcoded + surface color the theme scanner missed, a route the smoke should have exercised), improve that script and document the + change in its header. If no scanner exists for a repeated failure mode, consider writing one and adding it to + **Methodology**. If it is product polish, also add it to `Future.md`; if it needs new artwork, add it to `ClaudeBrandingReview.md`. **And if the discovery is a durable engineering fact (new route/collection/Function/flag/contract, a changed wire format, a renamed file, a gate/flow that the manual describes wrongly or omits), update @@ -468,7 +480,9 @@ Account); Paywall; Your Progress/Activity; Recovery. cat /tmp/claude-theme-scan-$(date +%Y%m%d).md ``` - The script reports findings by severity: + The script reports findings by severity and ends with a `## Summary` section showing the exact counts. + Record those counts in `ClaudeQACoverage.md` under Pass C **before** starting the visual sweep. + - **🔴 CRITICAL** — container/surface/background set to a hardcoded color. Will produce visible light/dark mismatches. Example: `Surface(color = Color.White)` inside a dialog in dark mode. - **🟠 MAJOR** — component color overrides or direct `painterResource` that bypasses `BrandIllustration`. @@ -1121,6 +1135,10 @@ Optimize every QA doc for a reader who has **5 seconds** to find the current sta - **Couple-shared premium fix**: replace direct `isPremium()` gates with `CouplePremiumChecker.coupleHasPremium(partnerId)` in every gated VM/screen (partner-entitlement read rule deployed). **High regression risk** — re-verify each feature in BOTH self-premium and free states. +- **Re-run associated scanners after fixing.** If the fix touches UI colors/surfaces (Pass C), re-run + `scripts/theme-scan.sh` and confirm the relevant CRITICAL count dropped. If the fix touches launch/splash/notifications, + re-run `qa/entrypoint_smoke.sh`. Update the coverage matrix with the new counts; a "Fixed" row is only valid when the + scanner (and the live visual sweep) both agree. - Gated actions (entitlement toggles, deploys) are **user-authorized per occurrence**. - **New issues found while fixing** are logged (new ID), not silently fixed beyond scope — next re-QA round catches them. diff --git a/scripts/theme-scan.sh b/scripts/theme-scan.sh index 8f350902..483861ba 100755 --- a/scripts/theme-scan.sh +++ b/scripts/theme-scan.sh @@ -115,38 +115,26 @@ grep -rnE 'Modifier\.border\([^)]*Color(\.|\()' "$UI_DIR" --include="*.kt" \ log "" log "## Tier 1G — Hardcoded Brush/gradient stops (REVIEW)" grep -rnE 'Brush\.(linear|vertical|horizontal|radial)Gradient' "$UI_DIR" --include="*.kt" \ + | grep -vE 'BrandIllustration\.kt' \ | while IFS= read -r line; do log "🟡 REVIEW $line" done || true log "" -log "## Tier 2 — Theme definition validation" -if [[ -f "$THEME_FILE" ]]; then - required=( - primary onPrimary primaryContainer onPrimaryContainer - secondary onSecondary secondaryContainer onSecondaryContainer - tertiary onTertiary tertiaryContainer onTertiaryContainer - background surface onBackground onSurface - surfaceVariant onSurfaceVariant outline outlineVariant - error onError errorContainer onErrorContainer - inverseSurface inverseOnSurface inversePrimary surfaceTint scrim - ) - - missing=0 - for slot in "${required[@]}"; do - if ! grep -qE "^\s*${slot}\s*=" "$THEME_FILE"; then - log "⚠️ MISSING: \`$slot\` not explicitly defined in darkColors" - missing=$((missing+1)) - fi - done - - if [[ $missing -eq 0 ]]; then - log "✅ darkColors has all required Material3 slots explicitly defined" - fi -else - log "⚠️ Could not find Theme.kt at $THEME_FILE" -fi - +log "## Summary" +critical=$(grep -c "🔴 CRITICAL" "$SCAN_OUTPUT" || true) +major=$(grep -c "🟠 MAJOR" "$SCAN_OUTPUT" || true) +review=$(grep -c "🟡 REVIEW" "$SCAN_OUTPUT" || true) +log "- 🔴 CRITICAL: $critical" +log "- 🟠 MAJOR: $major" +log "- 🟡 REVIEW: $review" +log "" +log "**Severity guide:**" +log "- 🔴 CRITICAL = container/surface/background set to a hardcoded color. Will produce visible light/dark mismatches." +log "- 🟠 MAJOR = component override or direct painterResource that likely bypasses theme adaptation or decoupled-theme art." +log "- 🟡 REVIEW = hardcoded text/icon/border/gradient color that may be correct on a branded container but must be verified in both themes." log "" log "---" -log "End of scan. Next step: read findings above, file CRITICAL/MAJOR items to ClaudeReport.md, then run the visual sweep." +log "End of scan. Next step: file all CRITICAL and any MAJOR that break themes to ClaudeReport.md, update the Pass C" +log "coverage matrix in ClaudeQACoverage.md, then run the visual sweep. If you fixed hardcoded colors, re-run this" +log "script and confirm the count dropped."