Files
Ferrous-Solitaire/SESSION_HANDOFF.md
T
funman300 f2d2119db5 docs: refresh handoff + populate CHANGELOG [Unreleased] for v0.20
The v0.19.0 handoff had drifted material across seven commits:
HEAD pointer was wrong (still claimed 6037596; actually 59424a3),
"Tags on origin" still claimed v0.19.0 wasn't pushed, the
known-flake list still mentioned `pull_failure_sets_error_status`
(fixed in 67c150b), and three of four v0.19.0 punch-list
"candidates" had silently shipped without the doc tracking it.
The Android build target landing in fb8b2ac wasn'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 HEAD 59424a3, 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>
2026-05-07 13:28:04 -07:00

206 lines
10 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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 AD. Don't pick unilaterally.
```