The v0.19.0 handoff had drifted material across seven commits: HEAD pointer was wrong (still claimed 6037596; actually59424a3), "Tags on origin" still claimed v0.19.0 wasn't pushed, the known-flake list still mentioned `pull_failure_sets_error_status` (fixed in67c150b), and three of four v0.19.0 punch-list "candidates" had silently shipped without the doc tracking it. The Android build target landing infb8b2acwasn't mentioned at all despite being the largest single change in the cycle. CHANGELOG [Unreleased] populated with all seven commits grouped into Added / Fixed: Added: - Android build target — first working APK (fb8b2ac) - Android developer setup + build runbook (59424a3) - F3 FPS / frame-time overlay (690e1d2) - "Smart window size" Settings toggle (e1b8766) - "Shareable" badge on Latest-win caption (9b065e5) - Help: M / P / Win-Summary-Enter rows (35516d3) Fixed: - pull_failure_sets_error_status flake (67c150b) SESSION_HANDOFF.md fully rewritten: - Status section reflects HEAD59424a3, clean working tree (apart from this commit's docs), 1170 passing tests, no known flakes - "Where we are" tracks v0.19.0 candidates' close status (3 of 4 shipped, App icon still open and now blocked on a re-export) - New v0.20 candidates table covers all seven commits - New "Phase Android" punch-list section captures the unblocked- by-fb8b2ac work: APK launch verification, dirs::data_dir port, JNI ClipboardManager, Android Keystore, gpgs integration, the cosmetic cargo-apk panic workaround - Process notes call out the async-test starvation pattern (seen twice now), the bin→lib+shim refactor as a reusable pattern, and target-gating-by-default for cross-platform deps - Resume prompt's A–D menu refreshed to reflect actually-open work: APK verification, Phase-Android persistence, app icon, and a v0.20 cut Build: cargo clippy --workspace --all-targets -- -D warnings clean. Tests: 1170 passing / 0 failing. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
10 KiB
Solitaire Quest — Session Handoff
Last updated: 2026-05-07 — [Unreleased] accumulating v0.20
candidates. Seven commits sit on top of v0.19.0: three close items
from v0.19.0's punch list (pull-failure flake, smart-window-size
opt-out, Shareable badge), one extends Help cheat-sheet coverage,
and three open a new performance / portability arc — F3 FPS
overlay, Android build target (first working APK), and the matching
developer-setup runbook. The Android build is the load-bearing
change: solitaire_app now compiles into both a desktop bin and
an Android cdylib from the same source.
Status at pause
- HEAD on origin:
59424a3(post-Android-runbook commit). - Working tree: modified —
CHANGELOG.mdandSESSION_HANDOFF.mdcarry the v0.20-candidates promotion + this refresh, ready to commit.artwork/remains untracked. - Build:
cargo clippy --workspace --all-targets -- -D warningsclean (verified this session). - Tests: 1170 passing / 0 failing across the workspace
(verified this session). The previously-flaky
pull_failure_sets_error_statusis fixed; no known flakes remain. - Tags on origin:
v0.9.0throughv0.19.0.
Where we are
v0.19.0's "Possible next-round candidates" list shipped 3 of 4:
shipped atpull_failure_sets_error_statusflake fix:67c150b.Settings UI for smart-default-size opt-out:shipped ate1b8766.Persistent share link URL on selector caption:shipped at9b065e5(as a "Shareable" badge on the Latest-win caption — the Prev/Next selector chips don't have a live spawn site yet, so the badge attaches to the existing single-replay caption).- App icon round — still open. 11 PNGs generated by
artwork/Icon Export.htmlare not in theartwork/directory any more (currentartwork/holds the reverted Rusty Pixel card PNGs); icon-export needs to be re-run before this item can be picked up.
Two new threads opened that weren't on any prior punch list:
- F3 FPS / frame-time overlay (
690e1d2).DiagnosticsHudPluginwrapsFrameTimeDiagnosticsPlugin; F3 toggles a top-right readout. Hidden by default; primarily a developer affordance. - Android build target (
fb8b2ac+59424a3).solitaire_appis now a bin + cdylib hybrid.cargo apk buildproduces a 54 MB APK with full assets. Five gating points resolved (split, manifest, bevy feature, arboard target-gate, keyring target-gate). What's not yet verified: APK launch on AVD/phone,dirs::data_dir()Android behaviour for the persistence/sync layer.
Design direction (unchanged)
- Tone: Balatro — chunky readable type, theatrical hierarchy, satisfying micro-interactions.
- Palette: Midnight Purple base + Balatro yellow primary + warm magenta secondary.
Canonical remote
github.com/funman300/Rusty_Solitaire is the canonical repo.
Always push there.
v0.20 candidates ([Unreleased] in CHANGELOG)
| Area | Commit | What landed |
|---|---|---|
| Async-pull flake fix | 67c150b |
pull_failure_sets_error_status swaps a fixed 5-update budget for a 5-second wall-clock deadline + yield_now between pumps. Closes the last v0.19-era flake. |
| Smart window size opt-out | e1b8766 |
New Settings::disable_smart_default_size: bool (#[serde(default)]). solitaire_app::main reads the flag at startup and skips apply_smart_default_window_size registration when set. Settings → Gameplay row toggles it; tooltip notes saved geometry always wins. |
| Shareable badge | 9b065e5 |
Stats overlay's Latest-win caption gains \u{2022} Shareable when the displayed replay carries a share_url. Badge appears on the single-replay caption (no Prev/Next live spawn site yet). |
| Help: M / P / Win-Summary-Enter | 35516d3 |
Three rows added to F1 Help → Overlays. Closes coverage drift on post-v0.18 keys. |
| F3 FPS overlay | 690e1d2 |
DiagnosticsHudPlugin + FrameTimeDiagnosticsPlugin. Hidden by default; F3 toggle is not gated by pause/modal state. Smoothed FPS / frame_time. Anchored top-right at Z_SPLASH + 100. |
| Android first APK | fb8b2ac |
solitaire_app split into bin + lib (cdylib). [package.metadata.android] pins SDK 34 / 26. Bevy gains android-native-activity. arboard and keyring/keyring-core target-gated to non-Android. 54 MB APK builds; launch on device not yet verified. |
| Android runbook | 59424a3 |
Debian 13 toolchain install, cargo apk build invocation, post-sign panic workaround, wired-vs-stubbed table. Fresh-clone runnable. |
Open punch list
Carried forward from v0.19.0
- App icon round.
Window::iconnot yet wired; no.icns/.ico/ Linux hicolor PNG hierarchy. The 11-size icon export the v0.19 handoff referenced is not currently inartwork/— re-runningartwork/Icon Export.htmlis the prerequisite. Half-day task once the PNGs are back in place. No cert dependency.
New — Phase Android (opened by fb8b2ac + 59424a3)
- APK launch verification on AVD / device.
adb installthenadb logcatagainst the bevy_test AVD. Shakes out any Bevy/winit Android-specific runtime bugs not caught by the build alone. dirs::data_dir()Android port. Persistence (settings, stats, achievements, replays, progress) all route through this function. Android sandboxing usually demandsgetFilesDir()via JNI. Until verified, the APK may launch but fail to persist anything across cold starts.- JNI ClipboardManager bridge. Replaces the Android stub for
the Stats "Copy share link" toast.
arboarddoesn't ship an Android backend, so this is a small custom JNI call. - Android Keystore for credentials.
keyringis target-gated to a stub that returnsKeychainUnavailable; replace with Android Keystore via JNI when sync auth ships on mobile. - Google Play Games (gpgs) integration. Listed in
solitaire_gpgsas a Phase-Android target since Phase 1; now unblocked by the build target. - Cosmetic
cargo apk build --libworkaround. The post-sign panic doesn't affect the APK on disk but produces noisy stderr. Either upstream a cargo-apk fix or document the--libinvocation as canonical in the runbook.
Other small candidates
- Cut v0.20.0 — the seven commits are a coherent bundle (3 punch-list closes, 1 docs polish, 1 perf tool, 2 Android arc starters). Tag whenever feels right; the Android arc has more surface to land before it's "done", but the build-works state is a defensible release point.
- Prev/Next selector chips spawn site.
9b065e5notes Prev/Next markers exist instats_pluginbut no spawn site renders them today — the Shareable badge therefore lands on the single-replay caption. If/when Prev/Next is plumbed to the Stats overlay, the badge will need to follow.
Process notes (from this round)
- Async-test starvation pattern (resolved twice now).
Auto-save flake (v0.19) and pull-failure flake
(v0.20-candidates) shared the same root cause: a fixed
N-update budget for an
AsyncComputeTaskPooltask to surface its result, which starves under cargo-test parallelism. The wall-clock-bounded loop pattern (std::thread::yield_now()between pumps, deadline =Instant::now() + Duration::from_secs(5)) is the canonical fix. Future async-test work should reach for this shape on the first commit, not after a flake materialises. - Bin → lib + thin shim refactor. The
solitaire_appsplit for cargo-apk is a textbook cdylib-as-NativeActivity pattern. Worth knowing as a reusable shape for any future Bevy-on-mobile project: keepmain.rsto ≤10 lines that delegate topub fn run, put all setup inlib.rs, and let the build system pick which artifact (binorcdylib) it needs. - Target-gating defensive defaults. Three of v0.20-candidates'
Android-arc commits had to disable a default-on dependency
(
arboard,keyring,keyring-core) for the new target. When a future contributor adds a desktop-implicit dependency, reaching for[target.'cfg(not(target_os = "android"))'.dependencies]preemptively is cheaper than rediscovering the gating during the next platform port.
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.19.0 is tagged on origin; seven commits sit on
top opening the v0.20 cycle (3 punch-list closes + a perf tool +
the Android build target).
State: HEAD at 59424a3 + the v0.20-candidates docs commit on top
(this session). Working tree may carry the doc updates if not yet
committed.
READ FIRST (in order, before doing anything):
1. SESSION_HANDOFF.md — this file
2. CHANGELOG.md — [Unreleased] holds the v0.20 draft
3. CLAUDE.md — unified-3.0 rule set
4. CLAUDE_SPEC.md — formal architecture spec
5. ARCHITECTURE.md — crate responsibilities + data flow
6. docs/android/* — Android setup + build runbook (59424a3)
7. ~/.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. APK launch verification — `adb install` + `adb logcat` on
bevy_test AVD or a physical x86_64 device. Shakes out
runtime bugs the build can't catch.
B. Phase-Android persistence — port dirs::data_dir() through a
JNI getFilesDir() bridge so the APK can survive a cold
start. Largest unblocked Android piece.
C. App icon — re-run artwork/Icon Export.html, then wire
Window::icon + generate .icns / .ico. Half-day task. No
cert dependency.
D. Cut v0.20.0 — promote [Unreleased] to [0.20.0], tag,
push. Mechanical close-out; the Android arc has more
surface to land but the build-works state is a defensible
release point.
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 A–D. Don't pick unilaterally.