4df962ee07
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
339 lines
17 KiB
Markdown
339 lines
17 KiB
Markdown
# Solitaire Quest — Session Handoff
|
||
|
||
**Last updated:** 2026-05-08 — **v0.21.8 tagged at `c50eaf8`**;
|
||
nine post-cut commits on master. Push pending.
|
||
|
||
v0.21.8 closes the last optional polish items in the B-2
|
||
replay screen-takeover arc: **notch-label centering** (middle
|
||
three scrub-bar labels now centred on their notch ticks via the
|
||
CSS `translateX(-50%)` pattern for Bevy 0.18 UI) and **WIN
|
||
MOVE HC legibility** (lime stays lime under HC mode via the
|
||
extended `HighContrastBackground::with_hc` constructor and a
|
||
new `STATE_SUCCESS_HC` brighter-lime constant). The replay
|
||
overlay arc is now fully closed with no known open items.
|
||
|
||
Full v0.21.8 detail lives in `CHANGELOG.md` § [0.21.8]. This
|
||
file from here on focuses on what's *open* post-cut and how to
|
||
resume.
|
||
|
||
## Status at pause
|
||
|
||
- **HEAD locally:** `f281425` (Android Keystore JNI).
|
||
Docs ride on top; push pending.
|
||
- **HEAD on origin:** `395a322` (double-tap commit — last pushed).
|
||
- **Working tree:** clean (docs uncommitted). No WIP outstanding.
|
||
- **`artwork/` directory:** still untracked. Intentional.
|
||
- **Build:** `cargo clippy --workspace --all-targets -- -D warnings`
|
||
clean.
|
||
- **Tests:** **1292 passing / 0 failing** across the workspace.
|
||
- **Tags on origin:** `v0.9.0` through `v0.21.8`.
|
||
- **Android:** APK verified booting on Pixel_7 AVD (Android 14,
|
||
x86_64). All desktop-only systems (handle_fullscreen) now gated.
|
||
See Phase Android punch list for remaining work.
|
||
|
||
## Since the v0.21.8 cut
|
||
|
||
Seven commits since the v0.21.8 tag:
|
||
- `a449f60` — Stats Prev/Next selector spawn site
|
||
- `202a64d` — Android launch fixes (android_main, resize_constraints,
|
||
apply_smart_default_window_size) — **closes APK launch verification**
|
||
- `16242e6` — Ignore .idea/ IDE files
|
||
- `395a322` — double-tap auto-move for touch input
|
||
- `0cb1587` — Play-by-Seed dialog + HomeMode card
|
||
- `2062bd0` — 75 new challenge seeds + gen_seeds binary
|
||
- `45436d0` — gate handle_fullscreen to non-Android
|
||
- `2c822ba` — JNI clipboard bridge for Android Stats share-link
|
||
- `f281425` — Android Keystore AES-GCM token storage via JNI
|
||
|
||
CHANGELOG + SESSION_HANDOFF docs ride on top; push pending.
|
||
|
||
Open next-step menu:
|
||
1. **Phase 8 (sync)** — the biggest open arc. Local storage
|
||
scaffolding, self-hosted Axum server, GPGS stub.
|
||
2. **Android follow-ups** — JNI ClipboardManager, Android Keystore,
|
||
GPGS. Launch verification and double-tap both closed; these
|
||
are the remaining Phase Android items.
|
||
3. **Move Log auto-scroll** — only relevant if the panel
|
||
row count grows beyond the current 5-row fixed window.
|
||
|
||
## Open punch list
|
||
|
||
### Phase Android (build + persistence shipped; runtime gaps remain)
|
||
|
||
- *APK launch verification — closed 2026-05-08 by `202a64d`.*
|
||
Three fixes shipped: `android_main` export (missing NativeActivity
|
||
entry point), `resize_constraints` gated to non-Android (max=0
|
||
panic), `apply_smart_default_window_size` gated to non-Android
|
||
(clamp panic on zero-dimension window event). Verified booting on
|
||
Pixel_7 AVD (Android 14, x86_64, SwiftShader Vulkan), 2+ min
|
||
runtime without crash. B0004 ECS hierarchy warnings remain
|
||
(non-fatal; entity parent/child component mismatch); investigate
|
||
if they surface gameplay bugs.
|
||
- *Double-tap auto-move — closed 2026-05-08 by `395a322`.*
|
||
`handle_double_tap` fires `MoveRequestEvent` on two rapid
|
||
`TouchPhase::Ended` events within 0.5 s. Prefers foundation;
|
||
falls back to tableau stack move. Fires `MoveRejectedEvent` when
|
||
no legal destination exists. System runs before `touch_end_drag`
|
||
in the chain so drag state is readable.
|
||
- *F11 fullscreen gate — closed 2026-05-08 by `45436d0`.*
|
||
`handle_fullscreen` and its `MonitorSelection`/`WindowMode`
|
||
imports are `#[cfg(not(target_os = "android"))]`-gated. The
|
||
`add_systems` call is a separate statement (not mid-chain).
|
||
- *JNI ClipboardManager bridge — closed 2026-05-08 by `2c822ba`.*
|
||
`android_clipboard::set_text(url)` calls `ClipboardManager` via
|
||
JNI. Stats share-link button now writes to the clipboard with a
|
||
"Copied: {url}" toast; falls back to "Share link: {url}" on JNI
|
||
error. Requires AVD functional test (see verification steps in
|
||
the approved plan).
|
||
- *Android Keystore for credentials — closed 2026-05-08 by `f281425`.*
|
||
`android_keystore` module: AES-256/GCM/NoPadding device-bound key,
|
||
tokens serialised to JSON and stored atomically at
|
||
`{data_dir}/auth_tokens.bin` as `[12-byte IV][ciphertext+tag]`.
|
||
`auth_tokens.rs` Android stubs now delegate to it. Key
|
||
invalidation (biometric reset) → `TokenError::KeychainUnavailable`.
|
||
Requires AVD functional test before Phase 8 sync goes live on
|
||
Android.
|
||
- **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 — closed 2026-05-08
|
||
across 13 commits (v0.21.4–v0.21.7).* The full mockup
|
||
(`docs/ui-mockups/replay-overlay-mobile.html`) has shipped:
|
||
banner chrome (v0.21.0), floating MOVE chip (v0.21.2), WIN
|
||
MOVE scrub-bar marker (post-v0.21.3), playback controls /
|
||
Space accelerator (post-v0.21.3), scrub notches + labels +
|
||
keybind footer + ESC / ← / → accelerators + HC border
|
||
(v0.21.5), Move Log panel + HC scrub track + continuous
|
||
scrub (v0.21.6), and full-screen 50 % opacity dim layer
|
||
(v0.21.7). Every major B-2 sub-piece is now closed. The
|
||
only remaining items are minor polish: notch-label centering
|
||
and WIN MOVE HC contrast bump (see Open next-step menu).*
|
||
- *Floating `MOVE N/M` chip above the focused card during
|
||
playback — closed 2026-05-08 by `2fb2d63`.* World-space
|
||
`Text2d` entity sibling to the banner overlay; uses the same
|
||
`LayoutResource` pile coordinates so it survives window
|
||
resizes without UI/camera math.
|
||
- *Toast Warning variant wiring — closed 2026-05-08 by `279e23d`.*
|
||
Daily-challenge-expiry toast fires once per `daily.date` when
|
||
within 30 min of UTC midnight reset and today is incomplete.
|
||
`ToastVariant` is now fully load-bearing (every variant has at
|
||
least one real driver). Future Warning drivers can either reuse
|
||
the generic `WarningToastEvent(String)` carrier or add their
|
||
own domain message + `animation_plugin` handler.
|
||
- *Toast Error variant wiring — closed 2026-05-08 by `68d50b5`.*
|
||
`MoveRejectedEvent` now fires a 2-second pink-bordered
|
||
"Invalid move" toast as the third leg of the
|
||
audio + visual + text rejection-feedback stool.
|
||
- *High-contrast accessibility mode — closed 2026-05-08 by
|
||
`c5787c6` + `07e0357` (engine + UI) + v0.21.2's HC chrome
|
||
rollout (`c9af1ea` + `d87761d` + `ec804d5`) + post-cut
|
||
dynamic-paint rollout (`c153363`).* Card text rendering plus
|
||
8 static-border chrome surfaces (modal scaffold, tooltip,
|
||
onboarding key chips, help panel key chips, stats panel
|
||
cells, home Level/XP/Score row, home mode buttons, home
|
||
mode-hotkey chips, 4 settings panel surfaces) all boost
|
||
borders to `BORDER_SUBTLE_HC` under HC via the
|
||
`HighContrastBorder` marker. The previously-carved-out
|
||
dynamic-paint sites are now also covered: HUD action buttons
|
||
and modal buttons take the same marker (their paint cycles
|
||
only mutate `BackgroundColor`, so no race); the radial menu
|
||
rim folds HC into its per-frame spawn via
|
||
`radial_rim_outline` so the focused rim boosts to
|
||
`BORDER_SUBTLE_HC` under HC (preserving focused-vs-resting
|
||
hierarchy that naive marker substitution would invert).
|
||
- *Reduced-motion mode — closed 2026-05-08 by `c5787c6` +
|
||
v0.21.2's `ed152e2`.* `effective_slide_secs` forces 0 on
|
||
card animations; `pulse_splash_cursor` skips the per-frame
|
||
pulse multiplier; `spawn_splash` skips the scanline overlay
|
||
entirely. Future scope: gate any future card-lift z-bump
|
||
animation, warning-chip pulse (when one materialises).
|
||
|
||
### 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
|
||
|
||
- *Play-by-Seed dialog — closed 2026-05-08 by `0cb1587`.*
|
||
`PlayBySeedPlugin` adds a numeric-input modal with async solver
|
||
preview (debounced 500 ms). `HomeMode::PlayBySeed` card fires
|
||
`StartPlayBySeedRequestEvent`. 5 unit tests. 75 new verified-win
|
||
seeds (`2062bd0`) expand `CHALLENGE_SEEDS` via the new
|
||
`solitaire_assetgen::gen_seeds` binary.
|
||
- *Prev/Next selector chips spawn site — closed 2026-05-08 by
|
||
`a449f60`.* `ReplayPrevButton` / `ReplayNextButton` /
|
||
`ReplaySelectorCaption` / `ReplaySelectorDetail` now spawn in
|
||
`spawn_stats_screen` as a compact chip row above the Watch
|
||
Replay action. The Shareable badge is in the detail line.
|
||
The click handler and repaint systems were already live since
|
||
v0.19.0; this was purely the missing spawn site.
|
||
- **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_DEFAULT` ↔
|
||
`PILE_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.8 is tagged at c50eaf8 (cut 2026-05-08,
|
||
replay-overlay polish). Seven post-cut commits are on master (see
|
||
"Since the v0.21.8 cut" above); push of the last four pending.
|
||
v0.21.7 stays at da3e542, v0.21.6 at f63db76, v0.21.5 at a2432df,
|
||
v0.21.4 at 23ff62c, v0.21.3 at 3d92a91, v0.21.2 at f23df3b,
|
||
v0.21.1 at daa655a, v0.21.0 at 04f9bf9.
|
||
Working tree: uncommitted CHANGELOG + SESSION_HANDOFF docs; push
|
||
pending. See CHANGELOG.md § [0.21.9] for full detail.
|
||
|
||
State: HEAD locally — see `git rev-parse HEAD`. Workspace
|
||
tests: 1292 passing / 0 failing. Clippy clean.
|
||
|
||
READ FIRST (in order, before doing anything):
|
||
1. SESSION_HANDOFF.md — this file
|
||
2. CHANGELOG.md — [0.21.9] section has the pending-cut items
|
||
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. Android follow-ups — JNI ClipboardManager bridge (arboard
|
||
has no Android backend), Android Keystore (blocked on Phase 8).
|
||
Launch verification + double-tap are closed.
|
||
B. Phase 8 (sync) — local storage scaffolding, self-hosted
|
||
Axum server, `SolitaireServerClient` impl. The biggest open
|
||
arc by scope; rolls up Android dependencies (Keystore,
|
||
ClipboardManager).
|
||
C. Play-by-Seed polish — the dialog is functional but has no
|
||
visual preview of the solver verdict in the UI yet; the
|
||
HomeMode card is wired but the dialog spawn site and verdict
|
||
display could use a second pass.
|
||
|
||
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.
|
||
- Doc-vs-implementation drift pattern: v0.21.1's pile-marker
|
||
visibility fix (`4d48cad`) implemented an invariant that
|
||
had been declared in a module doc comment but was never
|
||
enforced in code. When future work touches a module with
|
||
a "this does X" doc comment, verify the code actually does
|
||
X and add a test if not. Two layers, two checks.
|
||
|
||
OPEN AT THE START: ask which of A–C. Don't pick unilaterally.
|
||
Note: every remaining option is multi-session by nature (A is
|
||
gated on Android tooling; B and C are explicitly multi-session
|
||
arcs). A fresh session is a better fit for any of them than the
|
||
tail of a long working stretch.
|
||
```
|