docs(handoff): refresh post-v0.21.5 — anchor to new tag, reset menu state

Fold the six post-v0.21.4 commit narratives into CHANGELOG §
[0.21.5] (now the source of truth for that release's scope).
Reset the Since-cut log to "no threads in flight." Update
status (HEAD `a2432df`, tags through v0.21.5, tests still
1250/1249 passing pending the time-dependent flake clearing).
Resume prompt now anchors at v0.21.5 with the smaller post-cut
menu of next-finite-steps.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
funman300
2026-05-08 17:08:56 -07:00
parent a2432dfe7a
commit c8358f4275
+85 -220
View File
@@ -1,198 +1,79 @@
# Solitaire Quest — Session Handoff # Solitaire Quest — Session Handoff
**Last updated:** 2026-05-08 — **v0.21.4 cut and tagged at **Last updated:** 2026-05-08 — **v0.21.5 cut and tagged at
`23ff62c`**, working tree clean, all post-tag work pushed to `a2432df`**, working tree clean, all post-tag work pushed to
origin. origin.
v0.21.4 is a patch release with one through-line: v0.21.5 is a patch release with one through-line:
**replay-scrubbing accessibility**. The replay overlay used to be **replay-overlay scrubbing affordances + accessibility**.
pure-passive start, watch, wait. v0.21.4 adds the scaffolding v0.21.4 shipped pause / resume / step + the WIN MOVE marker as
for *navigating within* a replay: a WIN MOVE marker on the scrub the first scrubbing-shaped additions to the replay overlay;
bar so the player can see at a glance where the winning move v0.21.5 fills out the rest of the scrubbing UX so the player
sits, plus pause / resume / step controls (with a Space keyboard has both visual anchor points (notches + labels) and a complete
accelerator) so they can stop on any move and inspect the board. keyboard control surface (Space / Esc / ← / →) for navigating a
Also lands the additive `Replay::win_move_index: Option<usize>` paused replay.
data field that makes the marker possible — serde-default so
older on-disk replays load with `None` and simply don't get a
marker (no schema bump).
Three commits on the B-2 replay screen-takeover redesign arc Six commits on the B-2 replay screen-takeover redesign arc land
land here. The remaining sub-pieces (screen-takeover layout, here. Two of them are layout-changing — banner height grew
move-log scroller, mini-tableau preview) share a layout-reflow 60 → 76 → 92 px to make room for the notch labels and keybind
prerequisite the banner can't carry, so they're deferred to a footer. Banner geometry was fixed for every prior B-2 commit;
future cycle as a single multi-session arc. this release establishes the "grow the container, add a
flex-column child" pattern that the remaining B-2 sub-pieces
(move-log scroller, mini-tableau preview) will inherit when
they land.
Full v0.21.4 detail lives in `CHANGELOG.md` § [0.21.4]. This Full v0.21.5 detail lives in `CHANGELOG.md` § [0.21.5]. This
file from here on focuses on what's *open* post-cut and how to file from here on focuses on what's *open* post-cut and how to
resume. resume.
## Status at pause ## Status at pause
- **HEAD locally:** see `git rev-parse HEAD`. The cut commit is - **HEAD locally:** see `git rev-parse HEAD`. The cut commit is
`23ff62c`; any post-cut docs edits ride on top of that. `a2432df`; any post-cut docs edits ride on top of that.
- **HEAD on origin:** matches local. v0.21.4 is fully on origin. - **HEAD on origin:** matches local. v0.21.5 is fully on origin.
- **Working tree:** clean. No WIP outstanding. - **Working tree:** clean. No WIP outstanding.
- **`artwork/` directory:** still untracked. Intentional. - **`artwork/` directory:** still untracked. Intentional.
- **Build:** `cargo clippy --workspace --all-targets -- -D warnings` - **Build:** `cargo clippy --workspace --all-targets -- -D warnings`
clean. clean.
- **Tests:** **1250 total / 1249 passing / 1 pre-existing - **Tests:** **1250 total / 1249 passing / 1 pre-existing
time-dependent flake** across the workspace time-dependent flake** across the workspace. The flake is
(1228 in v0.21.4 + 4 from `fe68861`'s scrub-notch tests + 4
from `d322abf`'s notch-label tests + 4 from `1873b3f`'s
keybind-footer tests + 3 from `90e24d9`'s ESC-accelerator
tests + 1 from `23902cd`'s HC-marker test + 6 from
`e5c4f51`'s arrow-keyboard tests). The flake is
`daily_challenge_plugin::tests::check_system_fires_warning_event_only_once_per_day` `daily_challenge_plugin::tests::check_system_fires_warning_event_only_once_per_day`
— fails when wall-clock UTC is within 30 minutes of midnight — fails when wall-clock UTC is within 30 minutes of midnight
(the daily-expiry warning window the test asserts against). (the daily-expiry warning window the test asserts against).
Verified pre-existing. Detail in `CHANGELOG.md` § [0.21.4] Verified pre-existing by stash-and-retest before each commit
§ Stats; post-cut delta tracked here. this cycle. Will pass deterministically outside the trigger
- **Tags on origin:** `v0.9.0` through `v0.21.4`. v0.21.4 is on window. Detail in `CHANGELOG.md` § [0.21.5] § Stats.
`23ff62c`; v0.21.3 stays on `3d92a91`; v0.21.2 stays on - **Tags on origin:** `v0.9.0` through `v0.21.5`. v0.21.5 is on
`f23df3b`; v0.21.1 stays on `daa655a`; v0.21.0 stays on `a2432df`; v0.21.4 stays on `23ff62c`; v0.21.3 stays on
`04f9bf9`; v0.20.0 stays on `41a009a`.
- **Tags on origin:** `v0.9.0` through `v0.21.3`. v0.21.3 is on
`3d92a91`; v0.21.2 stays on `f23df3b`; v0.21.1 stays on `3d92a91`; v0.21.2 stays on `f23df3b`; v0.21.1 stays on
`daa655a`; v0.21.0 stays on `04f9bf9`; v0.20.0 stays on `daa655a`; v0.21.0 stays on `04f9bf9`; v0.20.0 stays on
`41a009a`. `41a009a`.
## Since the v0.21.4 cut ## Since the v0.21.5 cut
- **`fe68861` — `feat(replay): add quarter-mark notches to scrub No threads in flight. Working tree clean as of 2026-05-08. New
bar`.** First finite step toward B-2's screen-takeover layout. work since the cut would land here as commit narratives; for
Five 1px vertical ticks at 0/25/50/75/100 % give the player the v0.21.5 contents themselves, see `CHANGELOG.md` § [0.21.5].
visual anchor points without needing to mentally bisect the
bar. Pure helper `scrub_notch_positions()` returns the fixed
array; spawn loop lives next to the WIN MOVE marker spawn so
the lifecycles match. Notches paint in `BORDER_SUBTLE`
(matches unfilled-track colour) and rely on extending past the
1px track (5px tall, anchored 2px above track top) for
visibility — same trick the WIN MOVE marker uses. Spawned
*after* the WIN MOVE marker so a notch and the marker landing
on the same percentage paint the marker on top. Mirrors the
notch ladder in `docs/ui-mockups/replay-overlay-mobile.html`.
4 new tests; 1228 → 1232.
- **`d322abf` — `feat(replay): add percentage labels under
scrub-bar notches`.** First **layout-changing** commit in B-2's
screen-takeover arc. Banner height grew from 60 → 76 px to make
room for a 16 px label row beneath the 1 px scrub track; the
top row's `flex_grow: 1.0` still consumes the same 59 px so no
ripples on existing content. Pure helper `scrub_notch_labels()`
returns the fixed `["0%", "25%", "50%", "75%", "100%"]` array,
paired index-for-index with `scrub_notch_positions()`. Spawn
loop applies an "endpoints flush, middle three percent-anchored"
positioning pattern (Bevy 0.18 UI has no clean
`translate-x: -50%` primitive, so endpoints flush against
banner edges and middle three accept slight right-of-notch
offset). Label colour is `TEXT_SECONDARY` (mockup's
`BORDER_SUBTLE` reads as too low-contrast at 12 px against
`BG_ELEVATED_HI`). 4 new tests; 1232 → 1236.
- **`1873b3f` — `feat(replay): add keybind-hint footer to
overlay banner`.** Second layout-changing commit in B-2's arc.
Banner grew from 76 → 92 px to fit a 16 px footer row at the
bottom edge with a vim-style mode line on the left
(`▌ NORMAL │ replay`) and a keybind-hint on the right
(`[SPACE] pause/resume`). Surfaces the existing Space
accelerator visually so CLAUDE.md §3.3's UI-first contract
holds for keyboard accelerators too. Footer lists *only
wired* keybinds — future commits that wire ESC for stop or
← / → for prev/next will extend the right-hand text in
lockstep. Two pure helpers (`keybind_footer_mode_text`,
`keybind_footer_hint_text`) keep the static text testable;
shared `font_handle_for_labels` clone covers both label and
footer text spawns. 1px top border in `BORDER_SUBTLE`
separates the footer from the labels row. 4 new tests;
1236 → 1240.
- **`90e24d9` — `feat(replay): wire ESC accelerator for stop,
gate pause modal`.** ESC during an active replay now stops it
(mirrors the Stop button click). New `handle_stop_keyboard`
system in `replay_overlay.rs` parallels `handle_pause_keyboard`
in shape. Cross-plugin coordination via `pause_plugin::toggle_pause`:
added a fourth defer-if check
(`replay_state.is_some_and(|s| s.is_playing())`) right after
`other_modal_scrims` and before `selection`. Symmetric to the
existing modal-stack defer pattern. Footer hint extended from
`[SPACE] pause/resume` → `[SPACE] pause/resume · [ESC] stop`
in lockstep with the wiring; the only-wired-keybinds
discipline holds. 3 new tests + 1 updated helper-pin test;
1240 → 1243.
- **`23902cd` — `feat(replay): HC-mode coverage for
keybind-footer top border`.** Tag the footer's border-carrying
Node with `HighContrastBorder::with_default(BORDER_SUBTLE)` so
the existing `apply_high_contrast_borders` system bumps the
1 px top border from `#505050` → `#a0a0a0` under HC mode.
Footer text colours don't need bumps —
`TEXT_SECONDARY` (`#a0a0a0`) is already at `BORDER_SUBTLE_HC`
luminance by design (no `TEXT_SECONDARY_HC` constant exists).
The 1 px scrub track, notch ticks, and WIN MOVE marker render
via `BackgroundColor` (not `BorderColor`) so the marker
doesn't apply — HC coverage for those would need a
settings-aware paint system (precedent: `radial_rim_outline`
in `radial_menu`) and is deferred. 1 new test; 1243 → 1244.
- **`e5c4f51` — `feat(replay): wire ← / → keyboard accelerators
for paused stepping`.** New `step_backwards_replay_playback`
in `replay_playback.rs` decrements the cursor and dispatches
`UndoRequestEvent`; the game's `handle_undo` reads it next
frame to reverse its most-recent move — hooking the existing
undo system rather than replaying forward from cursor 0
(every replay-applied move pushes to the undo stack the same
way a player move would, so undo is the right reversal
primitive). Both arrow keys are paused-only via the same
destructure-gate pattern the forward step uses. Footer hint
extended in lockstep:
`[SPACE] pause/resume · [ESC] stop · [← →] step`. Footer
reads "step" not the mockup's "scrub" — single-move step is
what's wired; continuous scrub would need a key-held event
source. `ReplayOverlayPlugin` gains
`add_message::<UndoRequestEvent>()` defensively. 6 new tests
(2 hint pins + 4 keyboard scenarios) + 1 updated helper-pin
test; 1244 → 1250 total tests, 1249 passing.
**Pre-existing flake noted (verified):** Open next-step menu (B-2 keyboard accelerator coverage is now
`daily_challenge_plugin::tests:: complete; banner geometry is mutable):
check_system_fires_warning_event_only_once_per_day` is
time-dependent — fails when wall-clock UTC is within 30
minutes of midnight (the daily-expiry warning window the test
asserts against). Verified pre-existing by stashing all
changes and re-running before commit — failure persisted. Same
shape as the `winnable_seed_search` flake from earlier in the
session. Will pass deterministically when UTC isn't in the
warning window. Not introduced by recent work.
Banner geometry is now mutable — every prior B-2 commit fit
inside fixed 60 px space, but the notch-labels commit
established the "grow the container, add a new flex-column
child" precedent and the keybind-footer commit applied it
again. The next sub-pieces need significantly more vertical
room and follow the same shape.
Next finite step on B-2: keyboard accelerator coverage is now
complete (`Space` / `Esc` / `` / ``). Remaining choices:
1. **HC-mode coverage for the scrub-track / notch ticks / 1. **HC-mode coverage for the scrub-track / notch ticks /
WIN MOVE marker.** These render via `BackgroundColor` (not WIN MOVE marker.** These render via `BackgroundColor` (not
`BorderColor`) so `HighContrastBorder` doesn't apply. `BorderColor`) so `HighContrastBorder` doesn't apply.
Pattern would mirror `radial_menu::radial_rim_outline` Pattern would mirror `radial_menu::radial_rim_outline`
per-frame paint reading `Settings::high_contrast_mode`. per-frame paint reading `Settings::high_contrast_mode`.
Small commit, accessibility-progressing. Smallest next commit.
2. **Continuous scrub on key-held ← / →** instead of 2. **Continuous scrub on key-held ← / →** instead of
single-move step. Needs a key-held event source (or single-move step. Needs a key-held event source (or
accumulator timer in the keyboard handler). Medium scope; accumulator timer in the keyboard handler). Medium scope;
matches the mockup's `[← →] scrub` terminology. matches the mockup's `[← →] scrub` terminology.
3. **Move-log scroller / mini-tableau preview** — both need a 3. **Move-log scroller / mini-tableau preview** — both need a
much larger banner-height grow (effectively the takeover much larger banner-height grow (effectively the takeover
container itself). Bigger arcs; the natural place to land container itself). Multi-session arcs that close B-2.
the layout reflow that turns the banner into a takeover.
4. **Cut a v0.21.5 patch release** rolling up the four
post-cut commits (`fe68861`, `d322abf`, `1873b3f`,
`90e24d9`, `23902cd`, `e5c4f51`) under the through-line
"replay-overlay scrubbing affordances + accessibility."
Coherent narrative; six commits is a normal-sized patch
bundle for this project.
Recommended order: option 4 (cut release) is a clean next Recommended order: option 1 (HC paint for decorative pieces)
boundary — six commits with a clear through-line is the right keeps the cadence small after a release cut. Option 3 is the
size to bundle. Option 1 (HC paint for decorative pieces) is arc that closes B-2 once enough cycle has passed since v0.21.5.
the smallest next-feature commit if continuing past the cut.
## Open punch list ## Open punch list
@@ -233,30 +114,24 @@ palette refresh all shipped in v0.20.0 + v0.21.0. What stays open:
shipped in v0.21.2 (`2fb2d63`). The WIN MOVE scrub-bar marker shipped in v0.21.2 (`2fb2d63`). The WIN MOVE scrub-bar marker
shipped post-v0.21.3 in `ab857bb` (data field) + `52befa6` shipped post-v0.21.3 in `ab857bb` (data field) + `52befa6`
(UI). Playback controls (pause / resume / step + Space (UI). Playback controls (pause / resume / step + Space
accelerator) shipped post-v0.21.3 in `fbe48ac`. Quarter-mark accelerator) shipped post-v0.21.3 in `fbe48ac`. v0.21.5
scrub notches (5 ticks at 0/25/50/75/100 %) shipped bundled six more commits under "replay-overlay scrubbing
post-v0.21.4 in `fe68861` — first decoration step toward the affordances + accessibility" — scrub notches + percentage
takeover layout. Percentage labels under each notch shipped labels + keybind-hint footer + ESC and ← / → accelerators
post-v0.21.4 in `d322abf` — first **layout-changing** commit + HC marker for the footer top border. Banner height grew
(banner 60 → 76 px). Keybind-hint footer shipped in `1873b3f` 60 → 76 → 92 px across two layout-changing commits in
(banner 76 → 92 px — vim-style mode line + `[SPACE] v0.21.5; banner geometry is now mutable. Full per-commit
pause/resume`). ESC accelerator wiring (with cross-plugin detail in `CHANGELOG.md` § [0.21.5]. Keyboard accelerator
gate in `pause_plugin::toggle_pause`) shipped in `90e24d9`. coverage is complete. What still needs to land: HC-mode
HC-mode coverage for the footer's top border shipped in coverage for the scrub-track / notches / WIN MOVE marker
`23902cd`. ← / → keyboard accelerators for paused stepping (they render via `BackgroundColor` so the
shipped in `e5c4f51` (hooks the existing undo system for `HighContrastBorder` marker doesn't apply — needs a
backwards step; footer extended to settings-aware paint), continuous scrub on key-held ← / →
`[SPACE] pause/resume · [ESC] stop · [← →] step`). Banner (vs single-step), then the bigger pieces — a move-log
geometry is mutable; keyboard accelerator coverage is scroller and a mini-tableau preview — both screen-
complete. What still needs to land: HC-mode coverage for takeover-only pieces that need a much larger banner height
the scrub-track / notches / WIN MOVE marker (they render grow (effectively the takeover container itself).
via `BackgroundColor` so the `HighContrastBorder` marker Multi-session.
doesn't apply — needs a settings-aware paint), continuous
scrub on key-held ← / → (vs single-step), then the bigger
pieces — a move-log scroller and a mini-tableau preview —
both screen-takeover-only pieces that need a much larger
banner height grow (effectively the takeover container
itself). Multi-session.
- *Floating `MOVE N/M` chip above the focused card during - *Floating `MOVE N/M` chip above the focused card during
playback — closed 2026-05-08 by `2fb2d63`.* World-space playback — closed 2026-05-08 by `2fb2d63`.* World-space
`Text2d` entity sibling to the banner overlay; uses the same `Text2d` entity sibling to the banner overlay; uses the same
@@ -399,27 +274,25 @@ into a v0.21.1 / v0.22.0 cut.
``` ```
You are a senior Rust + Bevy developer working on Solitaire Quest. You are a senior Rust + Bevy developer working on Solitaire Quest.
Working directory: <Rusty_Solitaire clone path on this machine>. Working directory: <Rusty_Solitaire clone path on this machine>.
Branch: master. v0.21.4 is tagged at 23ff62c (cut 2026-05-08, a Branch: master. v0.21.5 is tagged at a2432df (cut 2026-05-08, a
patch release rolling up replay-scrubbing accessibility: WIN MOVE patch release rolling up replay-overlay scrubbing affordances +
marker on the scrub bar, pause / resume / step playback controls accessibility: scrub-bar notches with percentage labels, keybind-
with a Space keyboard accelerator, and the additive hint footer, ESC + ← / → keyboard accelerators, and HC-mode
`Replay::win_move_index: Option<usize>` data field that makes the coverage for the footer top border). v0.21.4 stays at 23ff62c,
marker possible). v0.21.3 stays at 3d92a91, v0.21.2 at f23df3b, v0.21.3 at 3d92a91, v0.21.2 at f23df3b, v0.21.1 at daa655a,
v0.21.1 at daa655a, v0.21.0 at 04f9bf9. Working tree clean. See v0.21.0 at 04f9bf9. Working tree clean. See CHANGELOG.md §
CHANGELOG.md § [0.21.4] for full detail. [0.21.5] for full detail.
State: HEAD locally — see `git rev-parse HEAD`. Post-cut HEAD is State: HEAD locally — see `git rev-parse HEAD`. The cut commit
`e5c4f51` (six carved-out commits on top of v0.21.4 — scrub-bar is a2432df; any post-cut docs edits ride on top of that.
notches `fe68861`, notch labels `d322abf`, keybind-hint footer Workspace tests: 1250 total / 1249 passing / 1 pre-existing
`1873b3f`, ESC accelerator + pause-modal gate `90e24d9`, HC time-dependent flake (`daily_challenge` warning, fails when UTC
marker for footer border `23902cd`, ← / → keyboard accelerators is within 30 min of midnight; verified not introduced by recent
`e5c4f51`). Workspace tests: 1250 total / 1249 passing / 1 work). Clippy clean.
pre-existing time-dependent flake (clock-near-midnight; verified
not introduced by recent work). Clippy clean.
READ FIRST (in order, before doing anything): READ FIRST (in order, before doing anything):
1. SESSION_HANDOFF.md — this file 1. SESSION_HANDOFF.md — this file
2. CHANGELOG.md — [0.21.4] section is the most recent cut 2. CHANGELOG.md — [0.21.5] section is the most recent cut
3. CLAUDE.md — unified-3.0 rule set 3. CLAUDE.md — unified-3.0 rule set
4. CLAUDE_SPEC.md — formal architecture spec 4. CLAUDE_SPEC.md — formal architecture spec
5. ARCHITECTURE.md — crate responsibilities + data flow 5. ARCHITECTURE.md — crate responsibilities + data flow
@@ -440,33 +313,25 @@ DECISION TO ASK THE PLAYER FIRST:
and Android Keystore stubs that need real bridges. Larger and Android Keystore stubs that need real bridges. Larger
scope; needs an Android device or emulator running. scope; needs an Android device or emulator running.
B. Replay-overlay screen-takeover redesign — multi-session B. Replay-overlay screen-takeover redesign — multi-session
work. Three sub-pieces shipped in v0.21.4: WIN MOVE work. v0.21.4 shipped WIN MOVE marker, pause / resume /
marker (data field + UI) and pause / step / Space step + Space accelerator, plus the floating-MOVE-chip
playback controls. The smaller floating-MOVE-chip piece piece from v0.21.2 (`2fb2d63`). v0.21.5 shipped scrub
shipped in v0.21.2 (`2fb2d63`). Post-v0.21.4: scrub notches + percentage labels + keybind-hint footer + ESC
notches `fe68861`, notch labels `d322abf` (banner and ← / → accelerators + HC marker for the footer top
60 → 76 px), keybind-hint footer `1873b3f` (banner border (six commits across CHANGELOG § [0.21.5]). Banner
76 → 92 px), ESC accelerator + cross-plugin gate height grew 60 → 76 → 92 px across two layout-changing
`90e24d9`, HC-mode coverage for the footer top border commits in v0.21.5; geometry is now mutable. Keyboard
`23902cd`, and ← / → keyboard accelerators for paused accelerator coverage is complete. Natural next finite
stepping `e5c4f51` (hooks the game's undo system for steps:
backwards step; footer extended to 1. **HC-mode coverage** for the scrub-track / notches /
`[SPACE] pause/resume · [ESC] stop · [← →] step`).
Keyboard accelerator coverage is complete. Natural next
finite steps:
1. **Cut a v0.21.5 patch release** rolling up the six
post-cut commits under "replay-overlay scrubbing
affordances + accessibility." Coherent narrative;
clean release boundary.
2. **HC-mode coverage** for the scrub-track / notches /
WIN MOVE marker (render via `BackgroundColor` not WIN MOVE marker (render via `BackgroundColor` not
`BorderColor`, so `HighContrastBorder` doesn't apply `BorderColor`, so `HighContrastBorder` doesn't apply
— needs a settings-aware paint, precedent — needs a settings-aware paint, precedent
`radial_rim_outline`). Small commit. `radial_rim_outline`). Smallest next commit.
3. **Continuous scrub on key-held ← / →** instead of 2. **Continuous scrub on key-held ← / →** instead of
single-step. Needs a key-held event source. Matches single-step. Needs a key-held event source. Matches
the mockup's `[← →] scrub` terminology. the mockup's `[← →] scrub` terminology.
4. **Move-log scroller / mini-tableau preview** — both 3. **Move-log scroller / mini-tableau preview** — both
need a much larger banner-height grow (effectively need a much larger banner-height grow (effectively
the takeover container itself). Multi-session arcs the takeover container itself). Multi-session arcs
that close B-2. that close B-2.