Feature 3 of post-epic-deferrals. Adds en-passant to berolina-pawns
and berolina-pawns-2 following the Parton 1952 variant — the most
common published ruleset. Reflects standard ep semantics through
Berolina's reversed geometry (diagonal push, orthogonal capture).
Engine:
- MoveHookContext extended with pieceId + from + to. Existing
presets (piece-hp, poisoned-squares, etc.) are purely additive
on the new fields and don't need changes. Dispatch site in
applyMove populates them from the resolved move.
berolina-pawns + berolina-pawns-2:
- overridePieceMoves: after emitting normal Berolina moves, read
the preset's ep latch (namespaced preset state). If the mover's
orthogonal-forward square equals the stored skipped square AND
the capturer color matches, emit a capture move onto that
square. Note destination is empty by construction — the engine's
getPieceAt returns null there, so the default capture path is a
no-op; onAfterMove below does the actual retraction.
- onAfterMove: two responsibilities. (1) If the mover just
accepted a latched ep (move.to === skippedSquare) retract the
stored capturedPieceId. (2) Clear the latch. (3) If THIS move
was a Berolina double-diagonal push from the home rank, record
skippedSquare + capturedPieceId (the mover's own pieceId, since
that's what the opponent can remove next turn) + capturer color.
- Scope-flip semantics preserved — scope='white' means only white
pawns emit ep moves; the latch still records for downstream, but
the opposing black pawns follow FIDE rules and don't emit it.
- berolina-pawns-2: sideways captures do NOT trigger or accept
ep (only the orthogonal-forward direction participates).
Tests:
- 5 new berolina-pawns.test.ts cases: (r) latch + ep emission,
(s) accept-ep retracts the double-pushed pawn, (t) one-half-move
window expiry, (u) single-push doesn't latch, (v) scope='white'
latch set on white's double-push.
- 3 new berolina-pawns-2.test.ts cases: (l) ep through the
extended preset, (m) retraction on accept, (n) sideways capture
does NOT set the latch.
- All 31 pre-existing Berolina tests unchanged and still pass.
Docs:
- RULES.md gallery entries: remove 'en-passant deferred' language;
document the Parton 1952 rule and the sideways-ep exclusion.
- PRESET-API.md post-landing-backlog: drop the berolina ep
deferral.
- Preset docblocks: rewrite the en-passant section to describe
the shipped mechanism + plan reference.
Verification: 1671 unit tests (+8 ep). Typecheck + lint clean.
Plan: .sisyphus/plans/post-epic-deferrals.md Feature 3 complete.