play_canvas.spec.js covers the window.__FERROUS_DEBUG__ bridge on the
/play route (five tests): bridge availability + seed param, draw3 URL
param, applyLegalMove/undo round-trip, failureReport schema, and
autonomous autoplay invariant batch across 7 seeds.
All tests drive exclusively through the debug bridge — no DOM selectors,
because the Bevy canvas is a single <canvas> element with no HTML
controls.
Also update SESSION_HANDOFF.md to reflect post-v0.35.1 work (10 commits
since 2026-05-18 handoff), new e2e architecture notes, and HiDPI fix doc.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Delete CLAUDE_PROMPT_PACK/SPEC/WORKFLOW (superseded by CLAUDE.md),
SESSION_HANDOFF files, old android investigation notes, phase-plan docs
under docs/superpowers/, and all docs/ui-mockups/ (HTML+PNG mockups
from the pre-Terminal design pass). Also removes local artifacts:
analytics_impl_prompt.md, review_project.py, delete_runs.sh, ruvector.db
files, and the stray solitaire_wasm/solitaire_server/ build artefact.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replace all display-name occurrences across web pages, Rust source,
docs, and Cargo metadata. Update localStorage token key from sq_token
to fs_token. Tagline "Klondike Solitaire" retained as genre descriptor.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
A2: docs/ANDROID.md — remove stale "permanent fix to come" note;
clarify --lib is the canonical command; root-cause the upstream
cargo-apk bug. SESSION_HANDOFF.md closes the open item.
A3: Remove dead CARD_PLAN.md references from four source module
doc comments (theme/importer.rs, theme/plugin.rs, assets/mod.rs,
assets/svg_loader.rs). Also fix stale "future picker UI" language
in plugin.rs (picker shipped in Phase 7).
A4: ui_modal.rs spawn_modal_button — add min_height: Val::Px(48.0)
so every modal action button meets Material's 48 dp touch target
minimum. Modal button height was 42 px (2×SPACE_3 + TYPE_BODY_LG);
now clamped to 48 px minimum. Cards at 40 dp on 360 dp phones are
layout-constrained (7 columns) and cannot be widened.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds solitaire_wasm crate (§2/§3), replay API endpoints (§9), web
replay player routes, SyncProvider 7 optional methods, ThemePlugin +
SyncSetupPlugin in plugin table (§5), Settings new fields (§8), and
DB migration 002 replays table (§7). Also fixes missing [0.23.0]
section header in CHANGELOG.md.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
GPGS integration will not be implemented. Removed from Phase Android
open items and from the Phase 8 (sync) description.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Closes the APK launch verification punch-list item. Three fixes in
202a64d boot the app on Pixel_7 AVD (Android 14, x86_64). Next open
arcs: Phase 8 (sync) or Android JNI follow-ups.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Fold the six post-v0.21.5 commit narratives into CHANGELOG §
[0.21.6] (now the source of truth for that release's scope).
Reset the Since-cut log to "no threads in flight." Update
status (HEAD f63db76, tags through v0.21.6, tests 1273
passing). Resume prompt now anchors at v0.21.6.
The post-cut menu's main item is now the mini-tableau preview
— the only major B-2 sub-piece left after Move Log panel
shipped. Architectural change (touches card_plugin rendering),
best tackled in a fresh session.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Two carve-outs land on top of v0.21.5:
- d3cb1a5: HC-mode coverage for scrub track + notches via new
HighContrastBackground primitive in ui_theme + paint system
in settings_plugin.
- 2e25476: continuous scrub on key-held ← / → at 100ms cadence;
matches mockup's "[← →] scrub" terminology while keeping
single-press = single-step semantics.
Update Since-cut log, status (1250 → 1254 tests passing,
flake cleared), and next-step menu. B-2 keyboard accelerator
coverage + accessibility + scrub UX are all complete; remaining
options are notch-label centering polish (smallest), the
move-log/mini-tableau multi-session arcs that close B-2, or
WIN MOVE marker HC bump (optional).
Recommended next-step: notch label centering (small).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
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>
Two more post-v0.21.4 carve-outs land:
- 23902cd: HC-mode coverage for keybind-footer top border
(HighContrastBorder marker so apply_high_contrast_borders
bumps the 1 px top border under HC).
- e5c4f51: ← / → keyboard accelerators for paused stepping
(hooks game's undo system for backwards step; footer
extended to [SPACE] pause/resume · [ESC] stop · [← →] step).
Update Since-cut log, visual-identity bullet, B option in the
Resume menu, status (1244 → 1250 total tests / 1249 passing /
1 pre-existing flake), and HEAD hint.
Six post-v0.21.4 commits now form a coherent through-line:
replay-overlay scrubbing affordances + accessibility. Resume
menu's B option now recommends cutting v0.21.5 as the natural
next boundary.
Pre-existing flake noted: daily_challenge warning test fails
when wall-clock UTC is within 30 minutes of midnight (the
warning window the test asserts against). Verified not
introduced by recent commits via stash-and-retest.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Post-v0.21.4 fourth carve-out: 90e24d9 wires ESC for replay-stop
with a cross-plugin gate in pause_plugin to defer when replay is
playing. Footer extended in lockstep to
[SPACE] pause/resume · [ESC] stop. Update Since-cut log,
visual-identity bullet, B option in the Resume menu, status
(1240 → 1243 tests), and HEAD hint.
B option's next-step menu now has three branches: HC polish
(smallest), ← / → wiring (medium, needs backwards-step path),
and the multi-session move-log/preview arcs that close B-2.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Post-v0.21.4 third carve-out: 1873b3f ships a keybind-hint footer
(vim-style mode line + `[SPACE] pause/resume`) at the bottom of
the banner (76 → 92 px). Update Since-cut log, visual-identity
bullet, B option in the Resume menu, status (1236 → 1240 tests),
and HEAD hint.
Footer lists only wired keybinds. Next finite step on B-2: wire
ESC for stop and extend the footer to `[SPACE] pause/resume ·
[ESC] stop` — small, single-axis, surfaces another keyboard
accelerator alongside the existing Stop button.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Post-v0.21.4 second carve-out: d322abf ships percentage labels
under each scrub-bar notch (banner 60 → 76 px — first real layout
change in B-2's arc). Update Since-cut log, visual-identity
bullet, B option in the Resume menu, status (1232 → 1236 tests),
and HEAD hint.
Banner geometry is now mutable; future B-2 sub-pieces follow the
same "grow container, add flex-column child" pattern. Next
finite step: keybind-hint footer (small) before the bigger
move-log / mini-tableau pieces.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Post-v0.21.4 carve-out: fe68861 ships quarter-mark notches on the
scrub bar. Update Since-cut log, visual-identity bullet, B option
in the Resume menu, status (1228 → 1232 tests), and HEAD hint.
Next finite step on B-2: percentage labels under each notch —
forces banner height to grow from 60 px to ~76 px, making it the
first real layout change in the screen-takeover arc.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Anchors handoff to v0.21.4 at `23ff62c`, resets the "Since the cut"
section to placeholder, updates the READ FIRST CHANGELOG pointer,
bumps the Resume-prompt summary to reflect replay-scrubbing
accessibility as the v0.21.4 through-line, and identifies the
screen-takeover layout reflow as the remaining multi-session arc
on B (with move-log scroller + mini-tableau preview as small
sub-pieces inside it).
Resume menu stays at A/B/C — A and C unchanged; B's prerequisite
sub-pieces shipped in v0.21.4 so the entry now points cleanly at
the layout reflow as the single remaining multi-session piece.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Captures `fbe48ac` (pause / resume / step + Space accelerator) under
"Since the v0.21.3 cut", marks playback controls closed in the
Visual-identity follow-ups list, identifies the screen-takeover
layout itself (with move-log scroller + mini-tableau preview as its
sub-pieces) as the next finite step on B, and bumps the test count
to 1228.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Captures `52befa6` (WIN MOVE marker on the scrub bar) under "Since
the v0.21.3 cut", marks the marker piece of B-2 closed in the
Visual-identity follow-ups list, identifies playback controls
(play/pause/step) as the next bounded commit on B, and bumps the
test count to 1220.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Captures `ab857bb` (Replay::win_move_index data field) under "Since
the v0.21.3 cut". Updates the Visual-identity follow-up entry for
B-2 to flag the data-layer prerequisite as landed and identifies
the WIN MOVE scrub-bar marker UI as the natural next finite commit.
Bumps test count to 1212.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Anchors handoff to v0.21.3 at `3d92a91`, resets the "Since the cut"
section to placeholder, updates the READ FIRST CHANGELOG pointer,
and bumps the Resume-prompt summary to reflect the accessibility
arc closure as the v0.21.3 through-line. Resume menu stays at
A/B/C since v0.21.3 closes only post-v0.21.2 carve-outs (the
remaining options were already heavy / multi-session).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Marks the HC dynamic-paint rollout (`c153363`) closed under the
High-contrast accessibility entry, captures it in "Since the v0.21.2
cut", bumps the test count to 1207, and trims the Resume prompt
menu from 4 → 3 options (A Android, B replay screen-takeover,
C Phase 8 sync). All three remaining options are multi-session by
nature; the resume prompt now flags that explicitly.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Marks the daily-challenge-expiry Warning toast (`279e23d`) closed in
the Visual-identity follow-ups list, captures it in "Since the
v0.21.2 cut", bumps the test count to 1203, and trims the Resume
prompt menu from 5 → 4 options (A Android, B-2 replay takeover,
C Phase 8 sync, D HC dynamic-paint).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Mirrors the post-v0.21.0 → v0.21.1 → v0.21.2 cut-then-refresh
pattern. Cut commit (f23df3b) edited only CHANGELOG; this
follow-up resets the handoff so a fresh session picks up cleanly
post-v0.21.2.
Updated:
- Header points to v0.21.2 at f23df3b; opening paragraph
summarizes the patch's three threads (accessibility
extensions, replay polish, first real Toast Error consumer).
- Status at pause: tests bumped to 1195 (net +3 from v0.21.1's
1192); tags list extended through v0.21.2.
- "Since the v0.21.1 cut" → "Since the v0.21.2 cut" with the
closure narratives dropped (now in CHANGELOG.md § [0.21.2]).
Section reset to "no threads in flight" placeholder.
- Visual-identity follow-ups: marked floating MOVE chip closed
by v0.21.2 (`2fb2d63`), Toast Error closed by v0.21.2
(`68d50b5`); HC + reduce-motion entries updated to reflect
v0.21.2's HC chrome rollout (8 surfaces) and splash
reduce-motion gating. Toast Warning still open with a
candidate driver suggestion (daily-challenge expiry).
- Resume prompt menu retuned: A (Android) and D (Phase 8)
unchanged; B narrowed to just the screen-takeover redesign
(the floating chip piece shipped); C narrowed to just
Warning variant (Error done); new E added for
HC+reduce-motion on dynamic-paint sites (HUD action buttons,
etc — explicitly carved out of the v0.21.2 HC rollout
because of paint-cycle races).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Mirrors the post-v0.20.0 → v0.21.0 → v0.21.1 cut-then-refresh
pattern. Cut commit (daa655a) edited only CHANGELOG; this
follow-up resets the handoff so a fresh session picks up cleanly
post-v0.21.1.
Updated:
- Last-updated header points to v0.21.1 at daa655a; opening
paragraph summarizes the patch's three threads (icon,
accessibility, card-visual iteration with two bug fixes).
- Status at pause: tests bumped to 1192 (net +8 from
v0.21.0's 1184); tags list extended through v0.21.1.
- "Since the v0.21.0 cut" → "Since the v0.21.1 cut" with the
closure narratives dropped (now in CHANGELOG.md § [0.21.1]).
Section reset to "no threads in flight" placeholder so
future post-cut work has a clean starting point.
- Resume prompt menu trimmed: A and F closure entries dropped
(preserved in CHANGELOG); remaining options renumbered A-E
with the v0.21.1 closure callouts inline. New option E
added: "extend HC through chrome borders + reduce-motion to
splash/warning-chip" — both small finite items that v0.21.1
flagged as future scope.
- Workflow notes gain the doc-vs-implementation-drift pattern
observation from the pile-marker fix: when a module's
top-level doc comment claims "X happens" but no code enforces
it, the gap is invisible until a player notices the missing
behaviour. Worth checking such claims and adding tests.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Two post-v0.21.0 options closed today; "Since the v0.21.0 cut"
section now narrates both:
- A — App icon (`3eb3a26` + `716a025`). Runtime Window::icon
wired via WinitWindows on desktop, 9-size PNG hierarchy at
assets/icon/. The follow-up `716a025` wraps NonSend in
Option<...> to satisfy Bevy 0.18's stricter system-param
validation.
- F — Accessibility modes (`c5787c6` + `07e0357`). High-
contrast and reduce-motion settings flags + Settings UI
toggles + engine wiring. CBM and HC compose; reduce-motion
forces card slide_secs to 0.
Open punch list refreshed:
- Visual-identity follow-ups: HC and reduce-motion entries
marked closed with future-scope notes (HC chrome borders,
reduce-motion splash gating).
- Carried forward from v0.19.0: App icon entry marked closed
with future-scope note for .ico/.icns bundle formats (need
new deps + matter only at packaging time).
Resume prompt menu trimmed: A and F decision options now
marked closed inline (preserved for audit-trail readability).
B, C, D, E remain live.
No runtime / test changes — pure docs hygiene to keep the
handoff orientation accurate as work flows.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Mirrors the v0.20.0 → post-cut refresh pattern (commit a65e5b8):
the cut commit (04f9bf9) only edits CHANGELOG.md; this follow-up
resets the handoff so it serves a fresh session cleanly rather
than carrying forward the v0.20.0-era narrative as cruft.
Removed (now redundant with CHANGELOG.md § [0.21.0]):
- The full "Since the v0.20.0 cut (un-pushed)" section — ~300
lines of per-commit narratives for the post-tag work.
- The "What shipped in v0.20.0 (frozen at 41a009a)" section —
v0.20.0 detail lives in CHANGELOG.md § [0.20.0].
Replaced with:
- Short header pointing to CHANGELOG.md § [0.21.0] for cycle
detail.
- "Since the v0.21.0 cut" placeholder ("No threads in flight").
Refreshed:
- Status at pause: HEAD on origin matches local; latest tag
v0.21.0 at 04f9bf9; tests 1184; references to v0.20.0
baseline preserved as audit trail.
- Visual-identity follow-ups: dropped the closed entries
(card-face arc, splash polish, replay banner pieces). Added
what's still open: replay screen-takeover redesign, floating
MOVE chip above focused card, toast Warning/Error wiring,
high-contrast accessibility, reduced-motion accessibility.
- Canonical remote: dropped the "unpushed commits" warning
since origin is caught up.
- Design direction palette: brick-red primary instead of cyan,
red→lime CBM swap instead of red→cyan, glyph orientation
upright. v0.21.0 source commits cited.
- Resume prompt: rebased to v0.21.0 anchor. Decision options
rewritten — closed B/C/D dropped; live A/E/F renumbered into
fresh A/B/C plus three new candidates (Toast variants, Phase
8 sync, accessibility modes). Workflow notes gain the
token-port-pattern lesson from v0.21.0's three "fallback path
the migration walked past" follow-ups.
Net diff: −513 / +117 lines; file shrinks from 668 to 272.
v0.20.0 historical context preserved in CHANGELOG.md.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Updates SESSION_HANDOFF.md to reflect the post-2026-05-08 state:
- "Last updated" + status header rewritten — origin caught up
to local through dd101b3, 1184 tests passing (net +4 from
the 1180 baseline: splash polish +2, card-face pin +1, CBM
test consolidation -2 then +1).
- New narrative entry under "Since the v0.20.0 cut" walks
through the 9-commit Option D arc: plan + tooling
(5623368/3a4bb63/babe5cc/48b28d2), lockstep step 4+5
(e8bf9d7), the three sign-off follow-ups (a14200a default-
theme SVG override, 8719f77 backgrounds flattened, ae84dc1
top-bar overlap), the path-glyph fix (af414b6), and the
glyph-orientation tweak (dd101b3).
- "Visual-identity follow-ups" punch-list: card-face item
marked closed with the same commit chain referenced from
the narrative.
- Resume prompt header rewritten — Options B/C/D all closed,
the post-tag work is fully on origin. Option D's bullet
expanded to record the closure rather than describe pending
work.
- The "fallback path the migration walked past" pattern is
documented explicitly so a future session can pattern-match
on it (token migrations need a checklist of every concrete
artifact downstream of the tokens, not just the tokens
themselves).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Bookkeeping pass after 29136d8 (cursor pulse) and a27cf5a (scanline
overlay) shipped — both halves of the splash polish arc deferred in
cacb19c are now done.
Changes:
- "Since the v0.20.0 cut": added per-commit narratives for 29136d8
and a27cf5a with the implementation notes worth preserving past
the commit log:
- The "multiply, don't override" pattern that resolved the
cursor-pulse / fade-timeline conflict (and generalises to any
two ECS systems writing the same per-frame component).
- The texture-α × tint-α GPU-composite trick that integrates the
scanline with the fade without a new "multiplicative fadable"
abstraction.
- Two Bevy 0.18 API surprises (RenderAssetUsages module move;
pixel_size() returning Result) — pinned for next time we touch
runtime-generated images.
- The defensive period <= 0.0 guard on cursor_pulse_factor — a
cheap NaN-prevention pattern worth mirroring on every trig
helper.
- "Open punch list" → "Visual-identity follow-ups": collapsed the
two splash-polish bullets into closed pointers.
- Resume prompt → Option B: marked closed with "no further splash
work pending unless a new mockup detail surfaces" so a future
session knows it's a finished arc, not an in-flight one.
Three options now closed (A, B, C); D / E / F remain — all three
have a real blocker (D = multi-session, E = artwork PNGs missing,
F = Android hardware/AVD) so the next session starts with a
genuine commitment-vs-blocker decision rather than picking the
smallest piece.
Bookkeeping pass after 54005d5 (GAME #YYYY-DDD caption) and e080b49
(MOVE N/M chip restyle) shipped — both pieces of the Option C
banner-local enrichments arc are now done.
Changes:
- "Since the v0.20.0 cut": added per-commit narratives for 54005d5
and e080b49 with the implementation notes worth preserving past
the commit log (the BANNER_HEIGHT 48→60 bump rationale, the Bevy
0.18 BorderColor::all() correction, the "marker on the leaf, not
the wrapper" ECS-design choice).
- "Open punch list" → "Replay-overlay enrichments beyond the scrub
bar": pivoted from "tractable banner additions still open" to
"all banner-local pieces shipped; remaining are cross-plugin or
multi-session". Reflects current state without erasing the
forward-looking work.
- Resume prompt → Option C: marked closed with a forward pointer to
the cross-plugin/multi-session items that should get their own
decision tree next time.
- Resume prompt → test count: dropped the hardcoded "1180 tests
pass" (already stale at 1182) for "~1180+; check with
`cargo test --workspace`" — same dynamic-reference pattern as
44f5972's commit-count fix, applied to the next aggregate that
was vulnerable to it.