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

@ -0,0 +1,151 @@
# ThressGame WONT_FIX Manifest
**Status**: Closing artefact for the `thressgame-100` epic (Wave 6).
**Companion**: `packages/chess/RULES.md` § "Cross-References — ThressGame Rules as Chess Presets".
## Purpose
The ThressGame rule set (https://github.com/Ryukaki/ThressGame) defines a
collection of game-rule hooks under `ruleHooks.js`. Most have working hook
bodies that this codebase ports as either **modifier recipes** (the ~62
`recipe-*` / `tpl-*` shipped through Waves 1-5) or **chess presets** (the
8 preset-shaped rules cross-referenced in `RULES.md`).
This document catalogues the **6 ThressGame rules whose `ruleHooks.js`
entries have empty `{}` bodies** — there is no upstream behaviour to port,
no observable contract to test against, and therefore no implementation
possible. Each entry below cites the source line in `ruleHooks.js`,
explains why we cannot ship a port, and records the recommendation for
future revisits if the upstream code ever defines a body.
This is the **WONT_FIX** list: each entry is intentionally not implemented,
not deferred. A future epic can revisit any entry once upstream defines a
hook body or the design intent is documented separately.
---
## 1. `pawns_with_viagra`
- **Source**: `ruleHooks.js:1626` — `pawns_with_viagra: {}`
- **Status**: Empty `{}` stub. No hook body, no comments, no design intent
recorded upstream.
- **Reason**: With no hook body, the rule has no observable behaviour. Any
port would be a guess at what "viagra" means in the context of pawn
mechanics — and a guess is worse than nothing because it locks an
arbitrary semantic that future upstream work would have to migrate away
from.
- **Recommendation**: Revisit only if upstream defines a body OR a design
doc is added. Until then, this rule is undefined behaviour and ports
cannot be evaluated for correctness.
## 2. `estrogen`
- **Source**: `ruleHooks.js:1638` — `estrogen: {}`
- **Status**: Empty `{}` stub. No hook body, no comments, no design intent
recorded upstream.
- **Reason**: Same as `pawns_with_viagra` — no observable behaviour, no way
to author a faithful port. The name suggests piece-color or piece-type
flipping but neither is documented; making a guess would lock a wrong
semantic.
- **Recommendation**: Revisit if upstream defines a body OR adds a design
spec. No implementation possible today.
## 3. `knee_surgery`
- **Source**: `ruleHooks.js:1698` — `knee_surgery: {}`
- **Status**: Empty `{}` stub. No hook body, no comments, no design intent
recorded upstream.
- **Reason**: No observable behaviour. The name hints at knight movement
modification (knights have "knees"?) but the upstream rule list has
multiple knight-related rules with concrete bodies (e.g. `god_kings`,
shipped at line 1681 with a populated `getLegalMoveModifiers`). With
those as the established pattern, an empty body is unambiguously a
TODO upstream, not an implicit no-op.
- **Recommendation**: Revisit if upstream defines a body. No implementation
possible today.
## 4. `pawns_learned_strength`
- **Source**: `ruleHooks.js:1699` — `pawns_learned_strength: {}`
- **Status**: Empty `{}` stub. No hook body, no comments, no design intent
recorded upstream.
- **Reason**: No observable behaviour. The name suggests pawn-power
enhancement but the upstream rule list has multiple pawn-power rules
with concrete bodies (e.g. the `cash_grab` family at line 1707+) that
establish the pattern; an empty body is a TODO upstream.
- **Recommendation**: Revisit if upstream defines a body. Several
shipped recipes (e.g. `recipe-boosted-pawn`, `tpl-march-of-the-pawnguins`,
`tpl-the-rumbling`) provide modifier-surface examples of "pawn power"
patterns; if a future ThressGame body lands, port via one of those
templates.
## 5. `parry` (RPS handler portion)
- **Source**: `ruleHooks.js:1599-1601`:
```js
parry: {
// RPS logic is handled in moveHandler.js and server.js
},
```
- **Status**: Empty `{}` body **with an explanatory comment** that locates
the canonical implementation in `moveHandler.js` / `server.js` —
source files OUTSIDE the `ruleHooks.js` rule registry that this port
doesn't have access to.
- **Reason**: The `parry` semantic (rock-paper-scissors capture
resolution) is **already covered** in our codebase by the
`recipe-parry` parity recipe (shipped before this epic — exercises the
`request-choice kind:"rps"` primitive). This WONT_FIX entry exists ONLY
to document the upstream code-location pointer — the rule itself IS
implemented, just not via the `ruleHooks.js` body.
- **Recommendation**: No action needed — the parry semantic is shipped.
This entry is a citation for the upstream code-shape decision (RPS
logic lives in `moveHandler.js`, not in `ruleHooks.js`).
## 6. `pacman_style` (modifier-form body)
- **Source**: `ruleHooks.js:1670` — `pacman_style: {}`
- **Status**: Empty `{}` body. The board-topology semantics
(file-axis wrap) are implemented in `getWrapMoves` (`server.js`)
and the `wrap-board` chess preset, OUTSIDE the `ruleHooks.js` registry.
- **Reason**: Same shape as `parry` — the upstream code splits the
topology between a registered hook (empty here) and a separate
move-gen helper (`getWrapMoves`). Our codebase routes both surfaces:
- **Preset surface**: `wrap-board` (RULES.md § Cylindrical Board)
- **Modifier surface**: `tpl-pacman-style-cross-ref` (Wave 4, uses
`set-board-topology({value: "wrap-files"})`)
- **Cross-ref recipe stub**: `tpl-preset-pacman` (Wave 6, points at
the preset)
- **Recommendation**: No action needed. The `pacman_style` semantic is
fully covered by the three surfaces listed above. This entry exists
to document why the empty `ruleHooks.js` body is not a gap — the
implementation lives elsewhere upstream and we have parity on both
the preset and modifier surfaces.
---
## Summary
| Rule | Source line | Action |
|----------------------------|-------------------------|----------------------|
| `pawns_with_viagra` | `ruleHooks.js:1626` | WONT_FIX (no upstream body) |
| `estrogen` | `ruleHooks.js:1638` | WONT_FIX (no upstream body) |
| `knee_surgery` | `ruleHooks.js:1698` | WONT_FIX (no upstream body) |
| `pawns_learned_strength` | `ruleHooks.js:1699` | WONT_FIX (no upstream body) |
| `parry` (RPS handler part) | `ruleHooks.js:1599-1601`| Documented (semantic shipped via `recipe-parry`) |
| `pacman_style` (hook body) | `ruleHooks.js:1670` | Documented (semantic shipped via preset + W4 modifier + W6 stub) |
## Coverage accounting
The `thressgame-100` epic locked the effective denominator at **51 rules**
(see `decisions.md` § K):
- **65 raw ThressGame rules** (`ruleHooks.js` registry size)
- **− 6 WONT_FIX** (this manifest)
- **− 8 preset-shaped** (cross-referenced in RULES.md)
- **= 51 effective** (covered by Waves 1-5 modifier recipes)
End-of-W5 coverage: **51/51 (100%)**. Wave 6 closes the discoverability
gap by adding 8 preset-stub recipes (one per preset-shaped rule) so all
65 raw ThressGame names appear somewhere in the Templates modal — either
as a working modifier recipe, as a preset cross-ref stub, or (for the 6
WONT_FIX entries) as documented WONT_FIX in this manifest.