docs: session handoff — duplicate chess v1 built and merged
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,209 @@
|
||||
# Handoff: Duplicate Chess v1 — built, tested, merged to main
|
||||
|
||||
## Session Metadata
|
||||
- Created: 2026-05-19 06:01:41
|
||||
- Project: /home/claude/bin/duplicate_chess
|
||||
- Branch: main (all work merged and pushed to `git.sethpc.xyz/Seth/duplicate_chess`)
|
||||
- Session duration: one long session — brainstorm → spec → plan → full 14-task implementation → merge.
|
||||
|
||||
### Recent Commits (for context)
|
||||
- 5047ad7 docs: update CLAUDE.md — v1 implemented and merged
|
||||
- fae9f8d docs: correct Task 4 test move data in the plan
|
||||
- 5db0410 fix: real project README and save-file version validation
|
||||
- ead4839 feat(ui): assemble the duplicate chess sandbox app
|
||||
- bedb5a0 feat(ui): promotion dialog
|
||||
- Full implementation range: `9611c0a` (scaffold + spec) → `5047ad7`. 18 commits.
|
||||
|
||||
## Handoff Chain
|
||||
|
||||
- **Continues from**: None (first handoff — this is a brand-new project).
|
||||
- **Supersedes**: None.
|
||||
|
||||
## Current State Summary
|
||||
|
||||
`duplicate_chess` is a **brand-new project created this session** — a local browser
|
||||
sandbox for "duplicate chess", a four-player chess variant invented by Andrew
|
||||
Freiberg (Seth's father; also the inventor behind the sibling `blind_chess`
|
||||
project). The session ran the full superpowers pipeline: brainstorming → design
|
||||
spec → implementation plan → subagent-driven execution of all 14 plan tasks → final
|
||||
review → merge. **v1 is code-complete, all 27 engine tests pass, the build and
|
||||
typecheck are clean, and it is merged to `main` and pushed.** The one thing not
|
||||
done: a human interactive browser test (clicking through a real game). The app
|
||||
mounts and renders correctly (verified via a headless smoke render).
|
||||
|
||||
## Codebase Understanding
|
||||
|
||||
### Architecture Overview
|
||||
|
||||
Single Vite + Svelte 5 + TypeScript app, **no server** (duplicate chess is
|
||||
perfect-information, so everything runs client-side — this is the key difference
|
||||
from `blind_chess`, which needs a server as its trusted view boundary).
|
||||
|
||||
- **Engine** (`src/engine/`, pure TypeScript, DOM-free, vitest-tested): four
|
||||
`chess.js` games (NW/NE/SW/SE). A player's legal moves = the **intersection** of
|
||||
the moves legal on their two boards, keyed by `(from,to,promotion)`. Ghost
|
||||
immobility, the synchronized-checkmate definition, and en-passant/castling
|
||||
divergence all fall out of the intersection — no special-case code.
|
||||
- **UI** (`src/lib/`): a reactive store wraps the engine; the compass renders the
|
||||
four boards as a 45°-rotated pinwheel; the triple-highlight (green = playable on
|
||||
both boards, grey = legal on one only) is the teaching feature.
|
||||
|
||||
### Critical Files
|
||||
|
||||
| File | Purpose | Relevance |
|
||||
|------|---------|-----------|
|
||||
| `docs/superpowers/specs/2026-05-19-duplicate-chess-design.md` | The full design spec | Read first — variant rules, engine model, provisional rules |
|
||||
| `docs/superpowers/plans/2026-05-19-duplicate-chess-sandbox.md` | The 14-task implementation plan | What was built, task by task |
|
||||
| `src/engine/legality.ts` | `legalSyncedMoves` + `selectionHighlight` | The intersection — the heart of the variant |
|
||||
| `src/engine/game.ts` | `DuplicateGame` — 4 chess.js, history, undo, draw clocks | The single source of truth for game state |
|
||||
| `src/engine/ghosts.ts` | Ghost derivation by cross-board comparison | |
|
||||
| `src/engine/endgame.ts` | checkmate/stalemate/threefold/fifty-move; **PROVISIONAL rules** | Andrew can revise the provisional rulings — grep `PROVISIONAL` |
|
||||
| `src/lib/stores/game.svelte.ts` | Reactive store wrapping the engine | `#game` is plain (non-reactive); `view` is the `$state` snapshot |
|
||||
| `src/lib/Compass.svelte` | The four-board pinwheel + click-to-move wiring | |
|
||||
|
||||
### Key Patterns Discovered
|
||||
|
||||
- **The engine is DOM-free and the single source of truth.** The UI never computes
|
||||
legality; it calls the engine and renders the result.
|
||||
- **Store reactivity:** `chess.js` objects must NOT be wrapped in a Svelte `$state`
|
||||
proxy. The store keeps `DuplicateGame` in a plain private `#game` field and
|
||||
exposes a plain-data `view` snapshot in `$state`, rebuilt after every change.
|
||||
- **The pinwheel rotations** (NW 225°, NE 135°, SW 315°, SE 45°) put each player's
|
||||
army on the board edge facing their seat. Confirmed against Andrew's sketch.
|
||||
- **Tests reach real positions** via `playSymmetric` (test-helpers.ts): when all
|
||||
four players move symmetrically the four boards stay identical, so each board is
|
||||
an ordinary chess game — that is how the checkmate/stalemate/threefold tests
|
||||
reach real terminal positions.
|
||||
|
||||
## Work Completed
|
||||
|
||||
### Tasks Finished
|
||||
|
||||
- [x] All 14 tasks of the implementation plan, executed via subagent-driven
|
||||
development (fresh implementer subagent per task + a combined spec/quality review
|
||||
per task + a final whole-implementation review by an opus reviewer).
|
||||
- [x] Engine: `types, boards, game, legality, ghosts, endgame, notation` + an
|
||||
integration test. 27 vitest tests, all passing.
|
||||
- [x] UI: the reactive store + `Board`, `Compass`, `Panel`, `PromotionDialog`,
|
||||
`App` components.
|
||||
- [x] Two post-review fixes: a real project README, and save-file `version`
|
||||
validation in `deserialize`.
|
||||
- [x] Merged `build-sandbox` → `main`, pushed, feature branch deleted.
|
||||
|
||||
### Files Modified
|
||||
|
||||
The whole project was created this session. See `git log` on `main`. New trees:
|
||||
`src/engine/` (7 modules + 6 test files), `src/lib/` (store + 4 components),
|
||||
`src/App.svelte`, `src/app.css`, plus the Vite scaffold and project docs.
|
||||
|
||||
### Decisions Made
|
||||
|
||||
All recorded in `DECISIONS.md`. Key ones: local sandbox first (not networked);
|
||||
single Vite app, no server; engine = 4× chess.js + intersection; compass UI as a
|
||||
pinwheel of diamonds; coordinate notation; provisional endgame rules picked by
|
||||
Claude and marked `PROVISIONAL`. One decision surfaced during the build and is NOT
|
||||
yet in DECISIONS.md — see "Blockers/Open Questions".
|
||||
|
||||
## Pending Work
|
||||
|
||||
## Immediate Next Steps
|
||||
|
||||
1. **Manual interactive browser test.** Run `pnpm install && pnpm dev`, open the
|
||||
URL, and play a real game: click a piece on a glowing board → confirm the
|
||||
green/grey triple-highlight → click a green square → move applies to both that
|
||||
player's boards → turn advances. Verify ghosts appear after a one-sided capture,
|
||||
promotion dialog fires, undo / Prev / Next / Live work, Save downloads JSON and
|
||||
Load restores it. The engine is well-tested; the UI interaction is verified only
|
||||
by `svelte-check` + a headless smoke render so far.
|
||||
2. **Decide the scrubbing semantics** (see Open Questions) and reconcile spec §4.3.
|
||||
3. (Optional) The remaining minor follow-ups below, if they matter.
|
||||
|
||||
### Blockers/Open Questions
|
||||
|
||||
- [ ] **Scrub semantics — spec vs shipped code disagree.** Spec §4.3 says "making a
|
||||
new move while scrubbed truncates history." The shipped code instead makes
|
||||
scrubbing **view-only** (you must click "● Live" before moving). The final review
|
||||
flagged this; the view-only behaviour is arguably cleaner. Seth to confirm which
|
||||
to keep; then update spec §4.3 (or the code) to match.
|
||||
- [ ] **The provisional endgame rules** (spec §6) are Claude's defaults, not
|
||||
Andrew's rulings — double-board-mate = two winners, any stalemate ends the game
|
||||
all-draw, threefold/50-move tracked on the whole system. Andrew should confirm.
|
||||
|
||||
### Deferred Items
|
||||
|
||||
- `deserialize` trusts the `player` field in a save file rather than recomputing it
|
||||
from turn order — a corrupt/hand-edited save could desync. App-written saves are
|
||||
always consistent, so this is robustness-only. Fix: have `DuplicateGame`'s
|
||||
constructor ignore `entry.player` and use the turn-order default.
|
||||
- Move log has no round-number column (within spec, but a nicety).
|
||||
- Spec §4.3 names a `replayTo(n)` primitive; the code uses
|
||||
`new DuplicateGame(history.slice(0,n))` instead — functionally equivalent,
|
||||
cosmetic naming mismatch only.
|
||||
- Networking / AI / position editor — explicitly out of v1 scope (spec §7).
|
||||
|
||||
## Context for Resuming Agent
|
||||
|
||||
## Important Context
|
||||
|
||||
- **The project is DONE for v1 and merged to `main`.** There is nothing half-built.
|
||||
A resuming agent's job is the manual browser test (#1 above) and then deciding
|
||||
whether to ship/deploy or extend.
|
||||
- **`blind_chess` is the sibling project** (`~/bin/blind_chess`) — same inventor,
|
||||
same homelab conventions, similar shared-engine + view-filter shape. The original
|
||||
inventor conversation that defines duplicate chess is
|
||||
`~/bin/blind_chess/USERFILES/4-person-chess.txt`, and Andrew's compass sketch is
|
||||
`~/bin/blind_chess/USERFILES/4personchess.png`.
|
||||
- **Provisional rules** are isolated in `src/engine/endgame.ts` and commented
|
||||
`PROVISIONAL (spec §6)` — grep for it to find every spot a future ruling lands.
|
||||
- v1 is **local only** — no deploy. Hosting the static `pnpm build` output behind
|
||||
Caddy is a trivial later option (it is just static files), not done.
|
||||
|
||||
### Assumptions Made
|
||||
|
||||
- The interactive browser test passing is assumed but unverified — the headless
|
||||
smoke render confirmed the app mounts and renders all four boards with no console
|
||||
errors, but no clicks were exercised.
|
||||
- 27 is the expected test count (all in `src/engine/`; the UI has no test harness
|
||||
by design — `svelte-check` + manual, same as `blind_chess`).
|
||||
|
||||
### Potential Gotchas
|
||||
|
||||
- `pnpm test` uses `--passWithNoTests` (vitest 4.x exits 1 on no test files) — a
|
||||
deliberate scaffold choice; harmless now that tests exist.
|
||||
- A `.secrets.baseline` file exists for the global `detect-secrets` pre-commit hook
|
||||
(it flags `pnpm-lock.yaml` SHA-512 integrity hashes as false positives).
|
||||
- `svelte-check` reports **5 warnings** — all pre-existing Vite-template `tsconfig`
|
||||
warnings (deprecated `moduleResolution`, missing `composite`). 0 errors. The
|
||||
warnings are not defects; ignore them or fix the template tsconfig if desired.
|
||||
- The brainstorming visual-companion mockups for the compass live under
|
||||
`~/bin/blind_chess/.superpowers/brainstorm/.../content/` (`layout-v6.html` is the
|
||||
approved layout) — they are in the `blind_chess` repo, not this one.
|
||||
|
||||
## Environment State
|
||||
|
||||
### Tools/Services Used
|
||||
|
||||
- pnpm workspace tooling (Node 22, pnpm 10). `gitea` CLI for push.
|
||||
- Subagent-driven development for the build (sonnet implementers/reviewers, an opus
|
||||
final reviewer).
|
||||
|
||||
### Active Processes
|
||||
|
||||
- None. No dev server left running.
|
||||
|
||||
### Environment Variables
|
||||
|
||||
- None added or required.
|
||||
|
||||
## Related Resources
|
||||
|
||||
- Spec: `docs/superpowers/specs/2026-05-19-duplicate-chess-design.md`
|
||||
- Plan: `docs/superpowers/plans/2026-05-19-duplicate-chess-sandbox.md`
|
||||
- `DECISIONS.md`, `IDEA.md`
|
||||
- Repo: https://git.sethpc.xyz/Seth/duplicate_chess (`main` at `5047ad7`)
|
||||
- Inventor conversation + sketch: `~/bin/blind_chess/USERFILES/4-person-chess.txt`,
|
||||
`~/bin/blind_chess/USERFILES/4personchess.png`
|
||||
|
||||
---
|
||||
|
||||
**Security Reminder**: No credentials or secrets are included in this handoff.
|
||||
Reference in New Issue
Block a user