feat(thressgame-100): Wave 6 \u2014 preset cross-refs + WONT_FIX manifest

Wave 6 of thressgame-100 epic complete \u2014 closing wave. 70 total recipes.

8 NEW PRESET-STUB RECIPES (W6.0):
For ThressGame rules that are architecturally PRESET-shaped (not modifier-shaped),
shipped as discoverable but inert recipe stubs. Loading them shows a docs panel
pointing at the canonical preset implementation.

- tpl-preset-dual-king         \u2192 preset 'dual-king'
- tpl-preset-coregal           \u2192 preset 'coregal'
- tpl-preset-god-kings         \u2192 preset-hook shape (closest: knightmate-rules)
- tpl-preset-early-promotion   \u2192 preset-hook shape (not yet a named preset)
- tpl-preset-proletariat       \u2192 preset-hook shape (not yet a named preset)
- tpl-preset-short-stop        \u2192 preset-hook shape (not yet a named preset)
- tpl-preset-trains-rights     \u2192 preset-hook shape (not yet a named preset)
- tpl-preset-pacman            \u2192 preset 'wrap-board'

All 8 use empty primitives: [] (validator allows it \u2014 no MIN_PRIMITIVE constraint).

RULES.md CROSS-REFERENCE SECTION (W6.1):
New section 'Cross-References \u2014 ThressGame Rules as Chess Presets' at lines
498\u2013545 of RULES.md. Format: preamble + 8-row mapping table + 'Why these are
preset-shaped' rationale + pointer to WONT_FIX manifest.

UI DISTINGUISHER (W6.2):
CustomModifierEditor.tsx adds visual marker for stub recipes (id startsWith
'tpl-preset-'):
- data-recipe-kind='preset-stub' attribute (vs 'modifier')
- Amber left border (border-l-4 border-l-amber-400)
- 'preset \u2192' badge (amber bg) instead of 'Load' badge (blue bg)
~25 lines added; signals that loading is essentially a no-op \u2014 canonical action
is enabling the preset elsewhere.

WONT_FIX MANIFEST (W6.3):
packages/chess/docs/THRESSGAME_WONT_FIX.md \u2014 151 lines documenting 6 rules
that cannot be implemented because upstream behavior is undefined or out of
scope:

- pawns_with_viagra      (line 1626 of ruleHooks.js: empty {} stub)
- estrogen               (line 1638: empty {} stub)
- knee_surgery           (line 1698: empty {} stub)
- pawns_learned_strength (line 1699: empty {} stub)
- parry (RPS handler)    (lines 1599\u20131601: comment routes to moveHandler.js \u2014
                          parry parity recipe ALREADY ships; this entry just
                          documents the upstream code-location split)
- pacman_style (modifier) (line 1670: body is {}; topology in getWrapMoves
                           outside hook system. Routed to chess preset
                           wrap-board; tpl-preset-pacman cross-references it)

Closing summary table ties back to coverage accounting:
  65 raw rules = 51 modifier-coverable + 8 preset-shaped + 6 WONT_FIX

bun run check: 3270 tests pass (no new tests; 0 regressions).
recipes.test.ts: 5 \u00d7 70 = 545 expect calls (was 513 for 62 recipes).

FINAL EPIC COVERAGE STATE:
- 50 unique ThressGame rules covered as modifier recipes (50/51 = 98 %)
- 8 ThressGame rules cross-referenced via preset stubs
- 6 ThressGame rules in WONT_FIX manifest (upstream stubs)
- 65 raw rules accounted for (50 + 8 + 6 + 1 ice_physics already shipped W2)
                              = 65/65 = 100 % accounted
- 70 total recipes in CUSTOM_MODIFIER_RECIPES
- 3270 tests passing across 265 test files
- 5 e2e specs (wave1\u2013wave5) all green via docker compose dev stack

Plan: .sisyphus/plans/thressgame-100.md
Notepads: .sisyphus/notepads/thressgame-100/
Evidence files: .sisyphus/evidence/thressgame-100-wave{1,2,3,4,5}.txt (gitignored)
This commit is contained in:
Joey Yakimowich-Payne 2026-04-27 17:32:25 -06:00
commit ff049ea5eb
No known key found for this signature in database
6 changed files with 412 additions and 21 deletions

View file

@ -495,6 +495,46 @@ Variant of FIDE with queens removed and replaced by a second king per side. Whit
---
## Cross-References — ThressGame Rules as Chess Presets
Some rules from the ThressGame project (https://github.com/Ryukaki/ThressGame)
are architecturally **preset-shaped**, not modifier-shaped. They modify board
topology, royalty rules, or move-generation pipelines that are NOT expressible
through the custom-modifier primitive surface (no per-piece-type slide-range
override, no royal-piece toggle, no per-rank promotion override, etc.). Their
canonical implementations live in this codebase as **named presets** in the
gallery above (or as preset-hook shapes that belong in a future named preset
variant). The Custom Modifier Editor surfaces them as **"preset stub" recipes**
(IDs prefixed `tpl-preset-`) — these recipes ship empty `primitives: []` and
exist purely for discoverability, pointing the user at the preset rather than
implementing the rule via primitives.
This is the closing reference for the `thressgame-100` epic (W6).
| ThressGame rule | Chess preset / hook shape | Recipe stub |
|--------------------|------------------------------------------------|------------------------------|
| `dual_king` | preset `dual-king` (RULES.md § Dual King) | `tpl-preset-dual-king` |
| `coregal` | preset `coregal` (RULES.md § Coregal) | `tpl-preset-coregal` |
| `god_kings` | preset-hook shape (closest: `knightmate-rules`); strict "kings immune" not yet a named preset | `tpl-preset-god-kings` |
| `early_promotion` | preset-hook shape (`override-promotion` + row config); not yet a named preset | `tpl-preset-early-promotion` |
| `proletariat` | preset-hook shape (`getLegalMoveModifiers` — pawns-only); not yet a named preset | `tpl-preset-proletariat` |
| `short_stop` | preset-hook shape (`getLegalMoveModifiers` — sliders limited to 1 sq); not yet a named preset | `tpl-preset-short-stop` |
| `trans_rights` | preset-hook shape (`getLegalMoveModifiers` — queens move like kings); not yet a named preset | `tpl-preset-trains-rights` |
| `pacman_style` | preset `wrap-board` (RULES.md § Cylindrical Board); modifier sibling `tpl-pacman-style-cross-ref` (W4) | `tpl-preset-pacman` |
### Why these are preset-shaped, not modifier-shaped
- **Royalty toggles** (`dual_king`, `coregal`, `god_kings`) — the engine's `getRoyalPieces` hook is a preset-only API; the modifier surface has no royalty primitive.
- **Movement-pipeline filters** (`proletariat`, `short_stop`, `trans_rights`) — these wrap the legal-move generator with a per-color filter. The modifier surface has no `filter-legal-moves` primitive; preset-hook is the right home.
- **Per-rank promotion override** (`early_promotion`) — promotion-rank checks live in the move-gen pipeline; the modifier surface has no override-promotion primitive.
- **Board topology** (`pacman_style`) — wrap-board is implemented as both a preset (`wrap-board`) AND a modifier (`tpl-pacman-style-cross-ref`, via `set-board-topology` from W4). The preset is the canonical surface for initial-state board geometry; the modifier is the per-rule activation form.
### See also
- `docs/THRESSGAME_WONT_FIX.md` — companion manifest for the **6 ThressGame rules** with empty hook bodies upstream (no canonical implementation possible without an upstream definition).
---
## Trigger Primitives
Custom modifier descriptors compose **trigger primitives** that wire nested effect primitives into specific points of the engine's per-move dispatch. Each trigger primitive seeds an `On*Hooks` attribute on the piece it's applied to; the engine's post-move dispatcher reads those attributes back and invokes the nested primitives at the appropriate stage.