Closer/Future.md

12 KiB
Raw Blame History

Future — ideas & improvements backlog

Non-blocking ideas: things that work today but could be better, plus feature ideas. Actual bugs (broken/incorrect behavior) live in ClaudeReport.md, not here.

UI

(No open UI defects. The P0 onboarding/auth crash filed here 2026-06-28 was fixed + verified live and moved to ClaudeReport.md as O-ONBOARD-001 — root cause was painterResource on the <bitmap> ic_launcher_foreground (not the background, as originally guessed); fixed both OnboardingScreen.CtaSlide + AuthVisuals.AuthLogoMark to use the raster closer_launcher_foreground. The "Add to Bucket List mixed dark/light" item is also fully resolved — dialog tokens R16, add-FAB Color(0xFFB98AF4)primary R18.)

QA

Improvement & feature ideas surfaced while QA-testing as a consumer (each works today — none are defects).

  • Tier 3: Compose screenshot diff for visual regression. The static scanner in scripts/theme-scan.sh catches ~80% of light/dark theme mismatches, but it cannot detect compositional failures: a theme-token color used on the wrong surface, a gradient with hardcoded light stops, or subtle contrast collapse. Implement a screenshot pipeline with Roborazzi / Shot / papAROS that renders every AppRoute in both light and dark, pixel-diffs them, and fails on unexpected white backgrounds or invisible text. When done, run it in CI against every UI PR.

  • 🟡 STARTED (R20) — Instrumented / on-device test coverage (was 0 androidTest). First cut shipped: app/src/androidTest/.../ui/FirstRunRenderSmokeTest.kt — an on-device Compose render smoke of the first-run screens (CtaSlide + AuthLogoMark, light + dark), the exact painterResource logo sites that crashed every fresh install in O-ONBOARD-001. It's the net for the "composes fine, crashes on first paint" class the JVM unit tests + static scanners structurally can't catch. Proven (R20): passes green on-device, and FAILS with the original IllegalArgumentException: Only VectorDrawables… when the bug is reintroduced. Infra added: testInstrumentationRunner

    • ui-test-junit4 (build.gradle.kts); also un-blocked the androidTest source set (the stale CanonicalVectorCaptureInstrumentTest couldn't compile against private deriveKey → made it @VisibleForTesting internal). Run: ./gradlew :app:connectedDebugAndroidTest. Still to grow: it's Hilt-/Firebase-free leaf-composable rendering only — extend toward a fuller sign-in → pair → answer daily Q → open a game → send a message flow (needs a Hilt test runner + fakes), and wire connectedDebugAndroidTest into the per-round gate / CI alongside qa/entrypoint_smoke.sh. Prompted by: the QA-plan render-coverage gap (O-ONBOARD-001 escaped because nothing rendered a composable).
  • DONE — Consistent brand glyphs across game cards + waiting surfaces. G-set + G2 (17 glyphs) in res/drawable-nodpi/glyph_*.xml; 13 wired + verified live: every Play-hub card (This or That, How Well, Desire Sync, Connection Challenges, Memory Lane, Date Match, Plan Date, Question Packs, Bucket List, Past Games — Spin the Wheel keeps its full illustration), WaitingForPartner per-game glyph, and Settings (Subscription/Security/Privacy/ Delete). 4 unused have no clean slot (notif uses ic_notification_closer; Today uses hero art; quiet-hours uses its illustration; no export-data row exists). Full map in ClaudeBrandingReview.md. (This-or-That backdrop redesign is Codex C-DARK-UI-001.)

  • Minor proactive-notification gaps (low priority). No push when a partner joins your active game (partner_joined_game)BUILT (2026-06-28, pending deploy): the non-starter opening an active session writes joinedByUsers (rule-gated), onGameSessionUpdate notifies the starter " joined your game" with the joiner's avatar (one-time joinNotifiedAt); foreground shows the standardized in-app banner. Still open: no push when a partner ends/abandons a game (game_ended/game_abandoned) — the other partner sees it in-session / on WaitingForPartner, so nothing's broken, just less proactive. Prompted by: Pass E (R8) inventory.

  • Clarify Connection Challenges day-progress when partners are out of step. If one partner catches up a missed day ("Pick it back up") while the other doesn't, the two devices show different "Day N of 7" (seen R10: QA Day 4 vs Sam Day 3) even though the 🔥 streak stays in sync on both. Not broken (plausibly individual-pace-through-the-series by design), but two people in the same shared challenge seeing different day numbers is confusing — consider a shared "you're on Day N together" framing or a clearer caught-up/ahead indicator. Prompted by: Pass B (R10) Connection Challenges playthrough.

Security hardening (defense-in-depth — not vulnerabilities; rules already hold)

Canonical security doc: SECURITY.md (2026-06-29) — full threat model, what's protected vs. exposed (metadata), known caveats, and the prioritized hardening roadmap. The P0 there (enforce App Check on the backend, independent audit, release hardening), P1 (encrypt profile metadata, opt-in telemetry, recovery-phrase UX, biometric re-lock), and P2 (cert pinning, multi-device keys, data export, key rotation) are the authoritative list; the two items below are the older notes that fed into it.

  • Enforce App Check on Firestore (currently OFF). Round 7 raw-API test: an authenticated request with no App Check token (raw Firestore REST) returned 200 for a member — so rules are the sole gate. Rules correctly deny non-members/cross-couple (all 403), so this is not a live hole, but enabling App Check enforcement on Firestore would block non-app clients entirely (defense-in-depth). Prompted by: R7 D3 raw-API angle.
  • DONE (R21) — Biometric app-lock now re-arms on background/timeout (was: only cold-start/process-death). MainActivity observes the lifecycle: while the lock is on and the session is unlocked, it records when the app is backgrounded and re-locks if it returns after >60s away (BIOMETRIC_RELOCK_GRACE_MS) — so a picked-up, already-open phone re-prompts, not only on Activity recreation. The grace window avoids re-locking on quick task-switches (the biometric prompt, photo picker, share sheet). Code-complete + compiles; live re-lock not yet driven — emulators have no enrolled biometric/PIN, so verify on a physical device. (SECURITY.md rec #7.)

Artwork to generate (ChatGPT prompts, house-style-matched) lives in ClaudeBrandingReview.md, not here.

Roadmap — features & strategy (consolidated from the old FUTURE.md, 2026-06-28)

Unbuilt games (Play Hub is live; these remain):

  • Would You Rather / Truth or Dare — tiered sweet→spicy, consent-gated; reuses the deck + match engine. Strong premium "spicy" tier lever.
  • Daily Sync / Rose-Bud-Thorn — one-tap emotional check-in, see partner's; small/new, free retention driver.

"2026, not 2019" differentiators (strategic):

  • AI-personalized prompts — server-side (latest Claude) generate/weight prompts from the couple's history/season/unexplored topics; add a generatePrompts callable (Cloud Functions already in place). Biggest modern lever; pairs with content-metadata routing below.
  • Async + real-time hybrid — partner-presence ("they're here now") for live co-play, everything still async-friendly (long-distance).
  • Multi-modal answers — voice/photo answers (esp. Memory Lane + daily check-ins).
  • Home/lock-screen widgets / live updates — glanceable today's-prompt + partner status (Glance/Wear surface).
  • Gentle gamification — forgiving "gentle streaks" (grace days) + shared wins, not loss-aversion/guilt.
  • Consent-first spicy content — Intimacy/Dare tiers opt-in, double-confirmed, reveal-only-on-overlap.

Cross-platform: Android-first is fine for MVP; iOS is the strategic gap (couples split devices). Decision + plan live in ClaudeiOSPlan.md — don't start before release/trust polish.

Product polish (consolidated from the old FUTURE.md)

  • Skeleton/loading states over bare spinners (P8). LoadingState exists but many screens still use a bare CircularProgressIndicator. Add skeletons for question lists, game histories, home modules, paywall offerings, sync/reveal waits. Acceptance: no primary route shows an isolated spinner on an otherwise blank screen.
  • Paywall / store value framing (P12). Paywall has benefits/restore/legal/RevenueCat; needs stronger value framing, real offering/trial clarity, screenshots/previews, and test coverage before release. (Overlaps Pass K/O.)
  • Content metadata & personalization (P13). The bank is clean; the next leap is routing, not more questions — tag mood/depth/relationship-stage/conflict-safe/intimacy-level/time-needed and extend the selection APIs so prompts adapt to skipped topics, relationship length, and recent answers.

Release / pre-ship (consolidated + re-verified 2026-06-28)

  • Real release config before any store submission. Confirmed still open: app/build.gradle.kts versionCode = 1 / versionName = "0.1.0" and core/navigation/ExternalLinks.kt legal URLs are placeholder TODOs (https://closer.app/privacy|terms|subscription-terms). Already done: a release-blocking Gradle check now fails the build if RC_API_KEY is unset/placeholder (build.gradle.kts:106110), so the old "add a gradle guard" sub-item is closed. Remaining: set real version, real legal/support URLs, real RC key + verify offerings/purchase/restore on internal testing. (Tracked by Pass O release-readiness.)

Help & support surface (consolidated — old "Notes to Consider")

A future Help/Support screen could include: contact support · report a bug · send feedback · FAQ · subscription/billing help · pairing help · recovery-phrase/account help · app version + build number · optional "copy diagnostics" button.