Files
Ferrous-Solitaire/SESSION_HANDOFF.md
T
funman300 31139ae455 docs(handoff): record Options A + F closures, refresh Resume prompt menu
Two post-v0.21.0 options closed today; "Since the v0.21.0 cut"
section now narrates both:

- A — App icon (`3eb3a26` + `716a025`). Runtime Window::icon
  wired via WinitWindows on desktop, 9-size PNG hierarchy at
  assets/icon/. The follow-up `716a025` wraps NonSend in
  Option<...> to satisfy Bevy 0.18's stricter system-param
  validation.
- F — Accessibility modes (`c5787c6` + `07e0357`). High-
  contrast and reduce-motion settings flags + Settings UI
  toggles + engine wiring. CBM and HC compose; reduce-motion
  forces card slide_secs to 0.

Open punch list refreshed:

- Visual-identity follow-ups: HC and reduce-motion entries
  marked closed with future-scope notes (HC chrome borders,
  reduce-motion splash gating).
- Carried forward from v0.19.0: App icon entry marked closed
  with future-scope note for .ico/.icns bundle formats (need
  new deps + matter only at packaging time).

Resume prompt menu trimmed: A and F decision options now
marked closed inline (preserved for audit-trail readability).
B, C, D, E remain live.

No runtime / test changes — pure docs hygiene to keep the
handoff orientation accurate as work flows.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-08 11:28:27 -07:00

15 KiB
Raw Blame History

Solitaire Quest — Session Handoff

Last updated: 2026-05-08 — v0.21.0 cut and tagged at 04f9bf9, working tree clean, all post-tag work pushed to origin.

v0.21.0 closes the visual-identity arc opened in v0.20.0. Three through-lines landed in this cycle: the card-face / suit / card-back artwork migration that v0.20.0 deliberately deferred (both rendering paths in lockstep — assets/cards/*.png fallback plus the bundled-default theme SVGs at solitaire_engine/assets/themes/default/*.svg that include_bytes!()-embed into the binary), the splash boot- screen + replay-overlay polish that closed Resume-prompt Options B and C, and a late-cycle ACCENT_PRIMARY palette swap from cyan #6fc2ef to brick red #a54242 after a quick stakeholder review of the shipped art.

Full v0.21.0 detail lives in CHANGELOG.md § [0.21.0]. This file from here on focuses on what's open post-cut and how to resume.

Status at pause

  • HEAD locally: see git rev-parse HEAD. The cut commit is 04f9bf9; any post-cut docs edits ride on top of that.
  • HEAD on origin: matches local. v0.21.0 is fully on origin.
  • Working tree: clean. No WIP outstanding.
  • artwork/ directory: still untracked. Intentional.
  • Build: cargo clippy --workspace --all-targets -- -D warnings clean.
  • Tests: 1184 passing / 0 failing across the workspace (net +8 from v0.20.0's 1176 baseline). Detail in CHANGELOG.md § [0.21.0] § Stats.
  • Tags on origin: v0.9.0 through v0.21.0. v0.21.0 is on 04f9bf9; v0.20.0 stays on 41a009a.

Since the v0.21.0 cut

Two Resume-prompt options closed post-tag (2026-05-08):

  • Option A — App icon round (3eb3a26 + 716a025). 9-size PNG hierarchy in assets/icon/ (16/24/32/48/64/128/256/512/ 1024 px), generated by a new icon_generator example from a shared icon_svg builder (Terminal ▌RS mark on dark #151515 with brick-red accent). Runtime Window::icon wired via WinitWindows on desktop only (Android draws its launcher icon from the APK manifest). The follow-up fix 716a025 wraps NonSend<WinitWindows> in Option<...> to satisfy Bevy 0.18's stricter system-param validation — the resource doesn't exist on the first few frames before winit's Resumed event fires. New deps (target-gated non-Android): direct winit = "0.30" for Icon construction, direct tiny-skia for PNG → RGBA decode. Pin test icon_svg_pin guards future rasteriser drift.
  • Option F — Accessibility modes (c5787c6 + 07e0357). High-contrast and reduce-motion settings flags wired through the engine and surfaced as Settings panel toggles. HC boosts RED_SUIT_COLOUR to #ff8aa0 and BLACK_SUIT_COLOUR to #f5f5f5 for card text rendering; reduce-motion forces effective_slide_secs to 0 regardless of AnimSpeed. CBM and HC compose: lime CBM wins on red when both are on; HC still applies to black suits when both are on. Six new tests pin the truth tables. UI toggles sit alongside the Color-blind row in Settings → Cosmetic; tab-walk visits all three accessibility flags in one vertical run.

Three Resume-prompt options remain live: B (APK launch verification), C (replay-overlay extensions), D (Toast Warning/Error wiring), E (Phase 8 sync). The visible-payoff pieces of the post-v0.21.0 menu have shipped; what's left is Android runtime work, replay-overlay polish, sync infrastructure, and toast-event sourcing.

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 (post-v0.21.0)

The visual-identity arc is effectively complete: token system, chrome migration, splash boot screen, replay-overlay banner, card-face artwork (both rendering paths), and the ACCENT_PRIMARY palette refresh all shipped in v0.20.0 + v0.21.0. What stays open:

  • Replay-overlay screen-takeover redesign. The full mockup (docs/ui-mockups/replay-overlay-mobile.html) calls for a mini-tableau preview, playback controls, move-log scroll, and a WIN MOVE marker on the scrub bar. Banner-local pieces all shipped in v0.21.0 (c84d9f4 + 6204db8 + 54005d5 + e080b49); the screen-takeover is a multi-session redesign with data-layer impact (move-log scroller; WIN MOVE needs a win_move_index field on Replay that doesn't yet exist).
  • Floating MOVE N/M chip above the focused card during playback. Cross-plugin work — update_progress_text writes the banner chip but the card-position lookup belongs in card_plugin. Smaller scope than the screen-takeover.
  • Toast Warning / Error variants. ToastVariant has slots for Warning (gold) and Error (pink) but no in-engine event uses them yet. Wire when a warning- or error-flavoured toast event materialises.
  • High-contrast accessibility mode — closed 2026-05-08 by c5787c6 + 07e0357. Card text rendering picks up TEXT_PRIMARY_HC (#f5f5f5) and RED_SUIT_COLOUR_HC (#ff8aa0); Settings panel has a toggle. Future scope: extend HC through chrome borders (BORDER_SUBTLE_HC already defined, not yet consumed), buttons, popover edges.
  • Reduced-motion mode — closed 2026-05-08 by the same pair. effective_slide_secs forces 0 when on, regardless of the AnimSpeed setting. Future scope: gate splash scanline overlay + cursor pulse animation on the same flag, gate warning-chip pulse, gate any future card-lift z-bump animation.

Carried forward from v0.19.0

  • App icon round — closed 2026-05-08 by 3eb3a26 + 716a025. Runtime Window::icon wired (Linux/macOS/Windows); 9-size PNG hierarchy at assets/icon/icon_<size>.png covers Linux hicolor + downstream .icns/.ico packaging needs. The .ico and .icns bundle-format files themselves are not generated — both would need new crate deps (ico and icns respectively) and only matter at app-bundle time (cargo-bundle / packaging), not at cargo run. Open if the project later ships as a packaged macOS / Windows app.

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

  • The desktop-adaptation spec is the canonical reference for geometry decisions when porting any future plugin. Read docs/ui-mockups/desktop-adaptation.md first; apply the universal rules to every surface; consult the per-screen table for the priority surfaces. The 9 missing-plugin screens (splash now ported; eight remaining) inherit the universal rules without dedicated guidance.
  • Stitch generate_variants is unreliable for layout-only adaptation prompts as of 2026-05-07. The first call timed out and no variant ever landed in list_screens. If a future session wants visual desktop mockups, prefer generate_screen_from_text with a fresh narrow prompt per screen rather than generate_variants against existing mobile screens.
  • Token-port pattern. v0.20.0's chrome-migration commits set a reusable shape for "centralised 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.
  • SplashFadable scaffolding pattern (introduced in cacb19c). Any future overlay that needs to fade N >> 3 elements together should follow the same shape: one tiny marker carrying the full-alpha base colour, one global query that lerps every marker's alpha each frame, no per-element query plumbing. Cleanly outscales the Without<X>, Without<Y> query exclusion pattern that the old splash was hitting at three siblings.

Canonical remote

github.com/funman300/Rusty_Solitaire is the canonical repo. Always push there. As of v0.21.0 origin matches local; the next push happens when post-cut work accumulates and is ready to roll into a v0.21.1 / v0.22.0 cut.

Design direction (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), brick-red primary CTA (#a54242 — swapped from cyan #6fc2ef in v0.21.0 commit a292a7e), 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 swaps red → lime #acc267 (was red → cyan pre-v0.21.0; lime is the next-best non-red base16-eighties accent now that the primary itself is red).
  • Card glyphs render upright in both corners — no 180° inverted-corner-indicator rotation. Single-orientation digital play doesn't benefit from the traditional flip- readback convention. design-system.md § Game Cards documents this deliberate deviation.

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.21.0 is tagged at 04f9bf9 (cut 2026-05-08).
Working tree clean. v0.21.0 closed the visual-identity arc that
v0.20.0 deferred — full Terminal cards on both rendering paths
(asset PNGs + bundled-default theme SVGs), splash boot screen,
replay-overlay banner enrichments, and a project-wide ACCENT_PRIMARY
swap from cyan to brick red `#a54242`. See CHANGELOG.md § [0.21.0]
for full detail.

State: HEAD locally — see `git rev-parse HEAD`. All workspace tests
pass (1184+; check with `cargo test --workspace`), clippy clean.

READ FIRST (in order, before doing anything):
  1. SESSION_HANDOFF.md  — this file
  2. CHANGELOG.md        — [0.21.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 +
                           desktop-adaptation.md (the rules-based
                           companion to the mockups; read this
                           before any plugin port)
  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. *Closed 2026-05-08 by `3eb3a26` + `716a025`.* App icon
     round — runtime `Window::icon` wired plus a 9-size PNG
     hierarchy at `assets/icon/`. `.ico` / `.icns` bundle
     formats stay open if the project later ships as a
     packaged macOS / Windows app.
  B. APK launch verification on AVD / device — `adb install` +
     `adb logcat` to shake out runtime bugs the build / unit
     tests can't catch. Likely surfaces JNI ClipboardManager
     and Android Keystore stubs that need real bridges. Larger
     scope; needs an Android device or emulator running.
  C. Replay-overlay extensions — either the floating `MOVE N/M`
     chip above the focused card (smaller, cross-plugin; needs
     cursor → card-position plumbing in `card_plugin`) or the
     full screen-takeover redesign (multi-session: move-log
     scroll, mini tableau preview, WIN MOVE marker, data-layer
     impact for `Replay::win_move_index`).
  D. Toast Warning / Error variant wiring. UI infrastructure
     exists in `ToastVariant`; no in-engine event uses Warning
     (gold) or Error (pink) yet. Wire when a real warning- or
     error-flavoured event materialises.
  E. Phase 8 (sync) — local storage scaffolding, self-hosted
     Axum server, `SolitaireServerClient` impl, GPGS stub
     wired into Settings. The biggest open arc by scope; rolls
     up several Phase Android dependencies (Keystore,
     ClipboardManager).
  F. *Closed 2026-05-08 by `c5787c6` + `07e0357`.* High-contrast
     and reduced-motion accessibility modes — Settings flags
     + UI toggles + engine wiring. Card text rendering uses
     HC variants when on; card slide_secs forces to 0 when
     reduce-motion is on. Future scope: extend HC through
     chrome borders, buttons; gate splash + warning-chip
     animations on reduce-motion.

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.
  - Token-port pattern: when migrating tokens, walk every
    concrete artifact downstream of the token (PNG textures,
    embedded SVGs, hardcoded literals, comment color names),
    not just the token name. v0.21.0 surfaced three "the
    migration walked past this" follow-ups that all matched
    this shape — codified here so future similar work can
    pattern-match instead of rediscovering.

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