Files
Ferrous-Solitaire/SESSION_HANDOFF.md
T
funman300 41a009a693 docs: cut v0.20.0 — Terminal design system + Android persistence
Promotes the [Unreleased] section to [0.20.0] dated 2026-05-07
and opens a fresh empty [Unreleased]. The cycle's two through-
lines:

- **Terminal visual-identity port.** ui_theme token system
  (0d477ac) is load-bearing; downstream chrome migrations cover
  the modal scaffold, gameplay-feedback layer (ceec4fc), toasts
  with a new ToastVariant enum (a137607), table chrome (651f406),
  card chrome (d752870), splash cursor (cdcadda), and final
  hint-source / dest pairing (9891ae4). Card-face / suit / card-
  back palette intentionally NOT migrated — those track PNG
  artwork that hasn't been regenerated yet. The 24 Stitch-rendered
  mockups and design-system.md spec landed in fa7f98a.
- **Android persistence shim.** solitaire_data::data_dir
  routes through a per-platform shim (4b51e50) closing the
  CLAUDE.md §10 dirs::data_dir() = None pitfall on Android.
  Settings, stats, achievements, replays, game-state, time-attack
  sessions, and user themes now persist on a real APK.

Also closes three v0.19.0 punch-list candidates that landed
earlier in the cycle (pull_failure flake at 67c150b, smart-window-
size opt-out at e1b8766, Shareable badge at 9b065e5).

Tests: 1176 passing / 0 failing (six new this cycle: ui_theme
invariant guards, toast-variant-border-mapping, palette-tracking
guards on MARKER_VALID / HINT_PILE_HIGHLIGHT_COLOUR /
RIGHT_CLICK_HIGHLIGHT_COLOUR / toast-border distinctness).

SESSION_HANDOFF.md refreshed: HEAD pointer, test count, the
v0.20.0 changelog summary, the open punch list (Phase Android
runtime gaps, visual-identity follow-ups including the artwork
regeneration item), the updated design-direction box (was
Midnight Purple + Balatro yellow; now base16-eighties Terminal),
and a refreshed Resume Prompt offering A–F next-step options.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-07 18:58:51 -07:00

13 KiB
Raw Permalink Blame History

Solitaire Quest — Session Handoff

Last updated: 2026-05-07 — v0.20.0 cut. Two through-lines closed in this cycle: a full Terminal visual-identity port (token system in ui_theme plus downstream chrome migrations across modal scaffold, gameplay-feedback, toasts, and the table / card / splash surfaces) and the Android persistence shim that closes the dirs::data_dir() = None pitfall flagged in CLAUDE.md §10. The Android build target landed earlier in the cycle (fb8b2ac); this session paid down the persistence half so a real APK can survive a cold start. The 24 Stitch-rendered mockups are now in-tree under docs/ui-mockups/; future plugin work diffs against the matching mockup before touching pixels.

Status at pause

  • HEAD on origin: the v0.20.0 docs commit (the one that lands this file + CHANGELOG cut). Tag not yet pushed; cut whenever feels right.
  • Working tree: clean apart from the still-untracked artwork/ directory (intentional — the card PNGs there are mid-flight for the Terminal aesthetic and committing now would freeze a transitional state).
  • Build: cargo clippy --workspace --all-targets -- -D warnings clean.
  • Tests: 1176 passing / 0 failing across the workspace. Six new tests this cycle: four ui_theme invariant guards (type / spacing / z-index scales + scaled_duration), one toast-variant-border-mapping pair, and four palette-tracking guards on MARKER_VALID / HINT_PILE_HIGHLIGHT_COLOUR / RIGHT_CLICK_HIGHLIGHT_COLOUR / toast-border distinctness. No known flakes.
  • Tags on origin: v0.9.0 through v0.19.0. v0.20.0 not yet tagged.

What shipped in v0.20.0

Terminal visual-identity port

Top-down stack — every commit downstream of the token system reads from it, so swapping the palette is now a one-file edit:

  • ui_theme token system (0d477ac). base16-eighties palette, 5-rung type scale, 7-rung 4-multiple spacing scale, 3-step radius, 14-rung z-index hierarchy, full motion budget, 4 invariant-pinning unit tests. Card-shadow alphas pinned to 0 (Terminal achieves depth via 1px borders + tonal layering).
  • Modal scaffold already on tokensui_modal was ported in the same commit's wake; three stale "loud yellow" / "magenta secondary" doc comments fixed.
  • Gameplay feedback → semantic state tokens (ceec4fc). Selection / valid-drop tints route through ACCENT_PRIMARY / STATE_WARNING / STATE_SUCCESS.
  • Toasts (a137607). New ToastVariant enum (Info / Warning / Error / Celebration); opaque BG_ELEVATED
    • 1px accent border + bottom-anchor. All ten call sites pass their semantic variant.
  • table_plugin chrome (651f406). PILE_MARKER_DEFAULT_COLOUR promoted; cursor_plugin imports it, replacing a "kept in sync" doc comment with a compile- enforced invariant. HINT_PILE_HIGHLIGHT_COLOURSTATE_WARNING.
  • card_plugin chrome (d752870). Drag-elevation shadow routes through CARD_SHADOW_* tokens. RIGHT_CLICK_HIGHLIGHT_COLOURSTATE_SUCCESS. Stock recycle "↺" text → TEXT_PRIMARY @ 0.7α. Card-face / suit / card-back palette intentionally NOT migrated (artwork dependency — see open-list item below).
  • Splash cursor (cdcadda). The signature cyan glyph (96 px) added above the wordmark, matching the spec.
  • Hint-source / dest pairing (9891ae4). input_plugin's source-card tint now matches the destination pile's STATE_WARNING.
  • Design system + 24-mockup library (fa7f98a). docs/ui-mockups/design-system.md + 24 Stitch mockups (HTML + PNG) covering every screen plus 9 missing-plugin surfaces.
  • card_shadow_params test aligned (1d1543e). Drag-vs- idle shadow assertion loosened to >= to accept the Terminal "no shadow" intent without losing the regression-guard.

Android persistence

  • solitaire_data::data_dir shim (4b51e50). New solitaire_data::platform::data_dir() falls through to dirs::data_dir() on desktop and returns the per-app sandbox at /data/data/com.solitairequest.app/files on Android — no JNI needed (package id pinned in [package.metadata.android]). Six solitaire_data callsites + solitaire_engine/assets/user_dir.rs migrated. Settings, stats, achievements, replays, game-state, time-attack sessions, and user themes now persist on Android.

Inherited from earlier in the cycle (pre-session)

  • Android build target + APK (fb8b2ac), runbook (59424a3), F3 FPS overlay (690e1d2), Smart Window Size opt-out (e1b8766), Shareable badge (9b065e5), Help cheat-sheet M/P/Enter rows (35516d3), pull_failure_sets_error_status flake fix (67c150b).

Open punch list

Phase Android (build + persistence shipped; runtime gaps remain)

  • APK launch verification on AVD / device. adb install then adb logcat against the bevy_test AVD or an x86_64 device. The build works and persistence is wired, but no end-to-end device run has been logged. Shakes out runtime bugs the build + unit tests can't catch.
  • JNI ClipboardManager bridge. Replaces the Android stub for the Stats "Copy share link" toast. arboard doesn't ship an Android backend; small custom JNI call.
  • Android Keystore for credentials. keyring is target-gated to a stub returning KeychainUnavailable; replace with Android Keystore via JNI when sync auth ships on mobile.
  • Google Play Games (gpgs) integration. Listed as a Phase-Android target since Phase 1; now unblocked by the build target.
  • Cosmetic cargo apk build --lib workaround. Post-sign panic doesn't affect the APK on disk but produces noisy stderr. Either upstream a cargo-apk fix or document --lib as canonical in the runbook.

Visual-identity follow-ups (opened by v0.20.0's port)

  • Card-face / suit / card-back artwork regeneration. The Terminal spec calls for dark #1a1a1a cards with light suit pips (pink for hearts/diamonds, foreground gray for spades/ clubs); the runtime path still renders the legacy white-card PNG artwork. The fallback constants in card_plugin (CARD_FACE_COLOUR, RED_SUIT_COLOUR, BLACK_SUIT_COLOUR, CARD_FACE_COLOUR_RED_CBM, card_back_colour palette) are intentionally unmigrated and should swap in lockstep with the artwork. Largest visible payoff remaining in the visual- identity arc.
  • Splash boot-loader richness. The mockup (docs/ui-mockups/splash-mobile.html) calls for a scanline overlay, ✓ lime check log lines, pulsing cursor, ROOT@SOLITAIRE prompt, and a loading bar — none of which v0.20.0's cursor-glyph-only port pulled in. Aesthetic feature, its own commit.
  • Replay-overlay redesign. The mockup (docs/ui-mockups/replay-overlay-mobile.html) envisions a much richer surface (terminal ▌replay.tsx header, move log scroll, MOVE 47/87 chip, WIN MOVE callout, status bar) versus the current top banner. Aesthetic feature.
  • Toast Warning / Error variants. The new ToastVariant enum has slots for Warning (gold) and Error (pink) but no in-engine event uses them yet (the four current toast events all map to Info or Celebration). Wire when a warning- or error-flavoured toast event materialises.

Carried forward from v0.19.0

  • App icon round. Window::icon not yet wired; no .icns / .ico / Linux hicolor PNG hierarchy. The 11-size icon export the v0.19 handoff referenced is not currently in artwork/ (current artwork/ holds the reverted Rusty Pixel card PNGs and is intentionally untracked); icon-export needs to be re-run before this item can be picked up. Half-day task once the PNGs are back in place. No cert dependency.

Other small candidates

  • Prev/Next selector chips spawn site. v0.19.0's 9b065e5 noted Prev/Next markers exist in stats_plugin but no spawn site renders them today — the Shareable badge therefore lands on the single-replay caption. If/when Prev/Next is plumbed, the badge will need to follow.
  • Toast queue / immediate unification. The two toast paths (spawn_queued_toast for InfoToastEvent queue; spawn_toast for fire-and-forget) now share visual treatment but remain separate functions because they serve different temporal needs (sequential vs. parallel). If overlap becomes a UX issue, merge into one queue with priority lanes.

Process notes

  • Token-port pattern. v0.20.0's chrome-migration commits set a reusable shape for "centralized design system applied across N plugins":
    1. Constants module (ui_theme.rs) is the source of truth.
    2. Const sites that can't call Alpha::with_alpha (not yet const on stable) use a literal RGB matching the token, with a unit test pinning the RGB to the token (e.g. MARKER_VALID, HINT_PILE_HIGHLIGHT_COLOUR, RIGHT_CLICK_HIGHLIGHT_COLOUR).
    3. Cross-plugin duplication (e.g. MARKER_DEFAULTPILE_MARKER_DEFAULT_COLOUR) collapses to a single promoted const re-exported from one plugin and imported by the other — replaces "kept in sync" doc comments with a compile-time invariant.
    4. Domain colours (suit pips, card faces, lerp helpers) stay as literals with a comment naming the rationale; only UI chrome routes through tokens.
  • Audit before migrating wide. Before touching any plugin, grep for the literal pattern (Color::srgb\(|Color::srgba\(| Color::WHITE|Color::BLACK) and classify each hit as domain vs. chrome. Most plugins after the modal scaffold port turned out to be 100 % token-correct already; the audit prevents wasted churn.

Canonical remote

github.com/funman300/Rusty_Solitaire is the canonical repo. Always push there.

Design direction (now Terminal — base16-eighties)

  • Tone: retro-terminal / synthwave — flat depth (no box-shadows), monospaced-forward typography (JetBrains Mono / FiraMono), tight 16 px edge margins, 8 px card radius.
  • Palette: near-black surface ramp (#151515 / #202020 / #2a2a2a / #353535), cyan primary CTA (#6fc2ef), lime success (#acc267), gold warning (#ddb26f), pink error / suit-red (#fb9fb1), lavender celebration (#e1a3ee), teal info (#12cfc0).
  • Two-color suits. Red = #fb9fb1, black = #d0d0d0. Outlined glyphs for diamonds & clubs are always on; the Settings "color-blind mode" toggle only swaps red → cyan.

(Was: Midnight Purple base + Balatro yellow primary + warm magenta. Replaced this cycle.)

Resume prompt

You are a senior Rust + Bevy developer working on Solitaire Quest.
Working directory: <Rusty_Solitaire clone path on this machine>.
Branch: master. v0.20.0 just cut on 2026-05-07; CHANGELOG's new
[Unreleased] section is empty pending the next cycle's threads.

State: HEAD on the v0.20.0 docs commit. Tag not pushed yet — last
pushed tag is v0.19.0. Working tree clean apart from the
intentionally-untracked `artwork/`.

READ FIRST (in order, before doing anything):
  1. SESSION_HANDOFF.md  — this file
  2. CHANGELOG.md        — [0.20.0] section is the most recent cut
  3. CLAUDE.md           — unified-3.0 rule set
  4. CLAUDE_SPEC.md      — formal architecture spec
  5. ARCHITECTURE.md     — crate responsibilities + data flow
  6. docs/ui-mockups/    — design system + 24-mockup library
                           (Terminal aesthetic — landed in fa7f98a)
  7. docs/android/*      — Android setup + build runbook
  8. ~/.claude/projects/<this-project>/memory/MEMORY.md
                         — saved feedback / project context
                           (machine-local; may be missing on a
                           fresh machine)

DECISION TO ASK THE PLAYER FIRST:
  A. Push v0.20.0 tag — `git tag v0.20.0 && git push --tags`. If
     the player wants the cut formalised before any new work.
  B. APK launch verification — `adb install` + `adb logcat` on
     bevy_test AVD or an x86_64 device. Now that persistence is
     wired (4b51e50), shake out remaining runtime bugs.
  C. Card-face artwork regeneration — generate Terminal-aesthetic
     card PNGs (dark face, light suit pips), then migrate
     CARD_FACE_COLOUR / RED_SUIT_COLOUR / BLACK_SUIT_COLOUR /
     CARD_FACE_COLOUR_RED_CBM in lockstep. Largest visible
     payoff remaining in the visual-identity arc.
  D. Splash boot-loader richness — port the scanline overlay,
     ✓ check log, pulsing cursor, ROOT@SOLITAIRE prompt, and
     loading bar from docs/ui-mockups/splash-mobile.html. Pure
     polish; no behavioural change.
  E. App icon round — re-run artwork/Icon Export.html (the
     export PNGs are not currently in `artwork/`), then wire
     Window::icon + generate .icns / .ico. Half-day task. No
     cert dependency.
  F. JNI ClipboardManager / Keystore bridge — replaces the
     Android stubs for Stats clipboard share + sync auth.

WORKFLOW NOTES:
  - Use the system git config (already correct).
  - When attributing playtester feedback in commits/docs, use
    "Quat" not "Rhys" (saved feedback memory).
  - Sub-agents stage + verify only; orchestrator commits.
  - Every commit must pass build / clippy / test before pushing.
  - Push to GitHub (origin) — gh auth setup-git wired on
    primary dev box; verify on laptop before first push.

OPEN AT THE START: ask which of AF. Don't pick unilaterally.