f2d2119db5
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>
206 lines
10 KiB
Markdown
206 lines
10 KiB
Markdown
# 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.md` and
|
||
`SESSION_HANDOFF.md` carry the v0.20-candidates promotion + this
|
||
refresh, ready to commit. `artwork/` remains untracked.
|
||
- **Build:** `cargo clippy --workspace --all-targets -- -D warnings`
|
||
clean (verified this session).
|
||
- **Tests:** **1170 passing / 0 failing** across the workspace
|
||
(verified this session). The previously-flaky
|
||
`pull_failure_sets_error_status` is fixed; no known flakes remain.
|
||
- **Tags on origin:** `v0.9.0` through `v0.19.0`.
|
||
|
||
## Where we are
|
||
|
||
v0.19.0's "Possible next-round candidates" list shipped 3 of 4:
|
||
|
||
- ~~**`pull_failure_sets_error_status` flake fix:**~~ shipped at
|
||
`67c150b`.
|
||
- ~~**Settings UI for smart-default-size opt-out:**~~ shipped at
|
||
`e1b8766`.
|
||
- ~~**Persistent share link URL on selector caption:**~~ shipped at
|
||
`9b065e5` (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.html` are *not* in the `artwork/` directory
|
||
any more (current `artwork/` 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`). `DiagnosticsHudPlugin`
|
||
wraps `FrameTimeDiagnosticsPlugin`; F3 toggles a top-right
|
||
readout. Hidden by default; primarily a developer affordance.
|
||
- **Android build target** (`fb8b2ac` + `59424a3`).
|
||
`solitaire_app` is now a bin + cdylib hybrid. `cargo apk build`
|
||
produces 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::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/` — re-running `artwork/Icon Export.html` is 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 install` then
|
||
`adb logcat` against 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 demands `getFilesDir()` 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. `arboard` doesn't ship an
|
||
Android backend, so this is a small custom JNI call.
|
||
- **Android Keystore for credentials.** `keyring` is target-gated
|
||
to a stub that returns `KeychainUnavailable`; replace with
|
||
Android Keystore via JNI when sync auth ships on mobile.
|
||
- **Google Play Games (gpgs) integration.** Listed in `solitaire_gpgs`
|
||
as a Phase-Android target since Phase 1; now unblocked by the
|
||
build target.
|
||
- **Cosmetic `cargo apk build --lib` workaround.** The
|
||
post-sign panic doesn't affect the APK on disk but produces
|
||
noisy stderr. Either upstream a cargo-apk fix or document the
|
||
`--lib` invocation 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.** `9b065e5` notes
|
||
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 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 `AsyncComputeTaskPool` task 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_app` split
|
||
for cargo-apk is a textbook cdylib-as-NativeActivity pattern.
|
||
Worth knowing as a reusable shape for any future Bevy-on-mobile
|
||
project: keep `main.rs` to ≤10 lines that delegate to
|
||
`pub fn run`, put all setup in `lib.rs`, and let the build
|
||
system pick which artifact (`bin` or `cdylib`) 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.
|
||
```
|