houserules/.sisyphus/boulder.json
Joey Yakimowich-Payne a5ee07dead
fix(chess/ui): narrate.ts \u2014 V3 resolver shapes + 9 missing narrators
Fix two bugs in the Custom Modifier Editor's live preview pane that
surfaced when loading thressgame-100 epic recipes:

BUG 1 \u2014 'unknown primitive: <kind>'
The narrator dispatcher (KIND_NARRATORS) was missing entries for the 9
new primitives shipped across the thressgame-100 epic. Loading any recipe
using them showed 'unknown primitive: add-resource' (etc.) in the preview.

Added 9 narrators (alphabetically inserted into KIND_NARRATORS):
- on-attr-expire (W2)              \u2014 'When the <attr> attr on <target> expires: <children>'
- decrement-attr-each-turn (W2)    \u2014 'each turn-end, subtract 1 from <attr> on <target>'
- set-board-topology (W4)          \u2014 'set board topology to <value>'
- link-pieces (W4)                 \u2014 'link the pieces at <a> and <b>'
- unlink-pieces (W4)               \u2014 'unlink the pieces at <a> and <b>'
- on-piece-pair-link-broken (W4)   \u2014 'When a linked partner is destroyed: <children>'
- add-resource (W5)                \u2014 'give <player> +<amount> score' (or 'subtract from')
- spend-resource (W5)              \u2014 'If <player> has <amount> score, spend it, then: <then>; otherwise: <else>'
- on-resource-changed (W5)         \u2014 'When <player>'s score crosses <threshold> <direction>: <children>'

BUG 2 \u2014 '[object Object]' for V3 resolver shapes
fmtPieceTarget (line 125) and inline square handling fell through to
String(t) when the field carried a V3 resolver shape ({$var}, {ctx-self-id},
{ctx-self-marker-id}, {ctx-attr}, {ctx-build}, {add/sub/mul/mod}).
User-reported case: tpl-treasure-chest's destroy-marker arm rendered as
'destroy [object Object]'.

Added fmtResolverShape(v) helper rendering the 9 V3 shapes as plain English:
- {$var: 'p'}                              \u2192 'p'
- {ctx-self-id: null}                      \u2192 'this piece'
- {ctx-self-marker-id: null}               \u2192 'this marker'
- {ctx-attr: {entity, attr}}               \u2192 "<entity>'s <attr>" (recursive)
- {ctx-build: {col, row}}                  \u2192 'e4' (algebraic if both literal) or
                                            'the square at column <c>, row <r>'
- {add: [a, b]}                            \u2192 '<a> + <b>' (recursive)
- {sub/mul/mod: [a, b]}                    \u2192 same pattern, '-' / '\u00d7' / 'mod'

Added fmtSquareValue(v) helper for square-typed fields. fmtPieceTarget
extended to call fmtResolverShape before falling back to String.

Updated existing narrators to use fmtSquareValue for square fields:
- spawn-marker.square, spawn-marker-pair.{squareA,squareB}
- move-piece.to, place-piece.square, must-class.square
- destroy-marker.target now routes through fmtResolverShape

Test surface:
- narrate.test.ts: 69 \u2192 90 tests (+21)
  - V3 resolver shapes describe block: 8 tests
  - thressgame-100 primitives describe block: 12 tests
  - tpl-treasure-chest end-to-end regression test: 1 test
    asserts the user-reported failure is fixed (no '[object Object]',
    no 'unknown primitive', expected English phrases present)

bun run check: 3291 tests pass (was 3270, +21). 0 regressions.

USER-REPORTED CASE NOW RENDERS:
  Before: 'When this piece captures: spawn a treasure marker on <square>
           (permanent). When a piece enters a treasure marker: unknown
           primitive: add-resource; destroy [object Object].'
  After:  'When this piece captures: spawn a treasure marker on this
           piece's Position (permanent). When a piece enters a treasure
           marker: give white +5 score; destroy this marker.'

Spot-check on 5 recipes (all render sensible English):
- tpl-treasure-chest \u2713 (see above)
- tpl-time-bomb \u2713
- tpl-down-with-the-ship \u2713
- tpl-summoning-ritual \u2713
- tpl-bouncing-ricochet \u2713

CALLOUT FOR FUTURE EPICS (recorded in learnings.md):
narrate.ts has zero engine/registry imports by design. When a new primitive
or resolver shape lands, the narrator must be updated MANUALLY \u2014 there
is no static link to detect drift. Add a registry-count-style sentinel
test in a follow-up to catch this earlier (e.g. compare KIND_NARRATORS
keys against PRIMITIVE_REGISTRY.list()).
2026-04-27 18:04:19 -06:00

160 lines
No EOL
5.8 KiB
JSON

{
"active_plan": "/home/joey/Projects/rules/.sisyphus/plans/thressgame-coverage.md",
"started_at": "2026-04-26T06:16:27.976Z",
"session_ids": [
"ses_237915a5bffeSdqajT9h0xNSOw",
"ses_2378f187cffeYNxeH5yoqBIR96",
"ses_2378879c7ffebbxu8yZx9ZafSB",
"ses_23787ac28ffeViseRvpVkHGu6a",
"ses_23783ab16ffeCNSrXoK1oU7I8s",
"ses_2378026c8ffeZz47LuDzc1yyOK",
"ses_237814da3ffetUoZjKTSOO0cB6",
"ses_23780806affeiG673hb1eMrpsc",
"ses_235d8c6cbffekI3rCHS6rLNdo6",
"ses_235d7c8c3ffevhSDIGLSkMrwNO",
"ses_235cfe743ffe2N5FSM90MQYuDD",
"ses_235d08175ffeRq75plcCft0ZUN",
"ses_235cf01bbffeGESSEHcB5t15WC",
"ses_235c8fea7ffevojZ0J0zr2Zn3h",
"ses_235c802e1ffe932t8Qwm6GILer",
"ses_235b3ae54ffeDjc32WJJEi91I2",
"ses_235b4a11fffeTysghRpnEw1zm1",
"ses_235a623edffe21fs3XZx4PeUwi",
"ses_235a6f921ffeaIzvrGGx9WTYho",
"ses_23597b9d4ffeCpsXUNeTVJdfV7",
"ses_2359867c3ffe466SWYlhCbvZEQ",
"ses_2358d7a82ffeKiEG0dR1dFOyFq",
"ses_2358cb310ffeJZX2DKGIBpMHU3",
"ses_2357fa71fffeHqeNXgXTtw24Iy",
"ses_235806b2cffeumryspoou0AlPO",
"ses_2357fe8c7ffexhJQD6igSnvQxY",
"ses_235714ec9ffeSWji2tbMppVVbq",
"ses_235717e9fffeFSaIjU5NW3E0gP",
"ses_23570f69effe4dsaVR8os1DSLt",
"ses_235708647ffeO6BxMMd9LuXrpm",
"ses_2356294f8ffeBOlgE6BrEi2AFJ",
"ses_23561c1bdffeZRftCYw7vm4fGL",
"ses_235612ec9ffe6IGVG3oXA8dKQb",
"ses_23561f811fferp0KvVdRXCXdTM",
"ses_23552d008ffeWpj9wJbHeHFtCi",
"ses_23552196dffe4y0RAnIt3ZVMlN",
"ses_235529f7cffe3hEu1Zg4bCXkWj",
"ses_235524bdeffevbzmdzjNrlYQU2",
"ses_23551e581ffepk0Fd0fBvTT8zl",
"ses_235432315ffe3QqApGeYfIQhDC",
"ses_23542810dffeCeEN7a6QTC7euD",
"ses_23542b136ffeHzVyuRHQ3bGdIr",
"ses_2353d0fb9ffe344OSbUt2h4DUg",
"ses_23542e700ffeaNZ38Gu2rB4AMn",
"ses_235435127ffem08ucCdVjXUvrX",
"ses_2353a7e10ffen7xf6isCaWxTSx",
"ses_23532bdf8ffe10tzyDRFnbKYmK",
"ses_235327422ffea3XMbiMtidzoLl",
"ses_235332417ffeG8us5EUAdJTLg6",
"ses_2353249ebffeJsqU1tzcLwUjIw",
"ses_23525bc2dffe2BqHbsMG5X7EHn",
"ses_23526101fffeonGIpO7HY1na2X",
"ses_235254abeffe5rnNrqeb7sDsgd",
"ses_235251f33ffeXIhn18D3PFrX04",
"ses_235117916ffeVIqFPhwOaX9AFG",
"ses_235115205ffeSz44RxSp2ceFek",
"ses_235111588ffe2CDfEN7cBiY2Tf",
"ses_2351133beffeWP9yUObY2S64ag",
"ses_234efcbd3ffe8BuHY2u90Wz1rK",
"ses_234efdeafffe08yS4JRWZ7S4uD",
"ses_234f006feffefL5q6WEqDYJtCf",
"ses_234eff09effed1uGpw4ugug3Yv",
"ses_234ead2eeffe5Zkywtv8XYTIL5",
"ses_234eab9afffeZM2ThzxvFbS7we",
"ses_234cf3732ffeG6qApsZze3p4CL",
"ses_234ea9ed5ffe3LO8eIohGogxE1",
"ses_234eaeabaffeUxClwG9AhyELI5",
"ses_234cf1fbbffepuEU0T4t2zL7vl",
"ses_234d69497ffeDpUTy4YmOP9Vzq",
"ses_234cf71d4ffeqORkJSGYcrCRNf",
"ses_234cf894dffef5jKrFXEXL5WaH",
"ses_234b28fafffe6oqUjKGisITV54",
"ses_234b26e14ffeuEORqZKKNh2byv",
"ses_234a6fb95ffeM3IHl6Ejoty4rI",
"ses_234a71fb6ffexvyikAILJb5T5V",
"ses_234a6dabaffeuQB1zQgChArKtq",
"ses_234a740d3ffe9EIQvGhSVIprrg",
"ses_2349f31ffffesMHCS2O8YUYzaB",
"ses_23488f9dcffeFtCzBn3gxtN7KV",
"ses_23487dd88ffeEDMNwvBDLByD9N",
"ses_23488a4a2ffeG7nzsoF7nsvKHC",
"ses_234882ba1ffeMwDf2VAt2fGKaM",
"ses_23470e618ffeKuOqxTyN3WMJmm",
"ses_23470aeb5ffen8G71F1kKLXWE4",
"ses_234704ca2ffexGa7YYzkVJ7XQy",
"ses_234714154ffePk1XQUSvX1tcat",
"ses_2346243beffeatri9EFKougtx4",
"ses_2342ca7c3ffe40BnC0Thwejgjg",
"ses_2341a04eeffeiOv4T2Q3rqknl7",
"ses_23413031dffesUm5HBc24bf63F",
"ses_2341377a8ffejodIDjnwXpyIHp",
"ses_23413e9bdffemN8WkabmXJVK5t",
"ses_233f787b9ffeYWzzTLHpG5VJks",
"ses_233f7318effe2R0Vt2ad27KzEZ",
"ses_233cc34d1ffe9ys7V39oRNCcO0",
"ses_233bcb2b3ffeI06xdt1zAAeqig",
"ses_233bc366effeMrTyc60acFDGv1",
"ses_233bbae40ffeT1NSqk255jg4hM",
"ses_233064ca7ffeXlINJom4KihOqH",
"ses_23305e63fffeSljlU1lOZqw7VE",
"ses_232db4030ffe4qSJ11bprMpb2P",
"ses_232d7893fffeMyL3c29fsKCXqJ",
"ses_232d83674ffeOshGzMV2yamHQ5",
"ses_232d6c9c3ffexrdPHlgxrZCCq5",
"ses_232cc391fffeMW18TkuiNQu4rW",
"ses_232c88792ffeOsLbkHGRxE9SyM",
"ses_232bb5b97ffe5mQvLYaw3xUa74",
"ses_232bbc958ffeL2SwBJ8dNnG6tQ",
"ses_232b69b9fffeWbSfSwazQxHu45",
"ses_232b4f507ffepR4NFW9sX7brH1",
"ses_232b5c928ffegqm51y1RU60eSN",
"ses_232b63a3effepJTIFUBdsW3jfV",
"ses_232b5a1bbffeqsTBCrogl2i6GT",
"ses_232b6079dffeeFtvF0kok59IOk",
"ses_232b539a1ffesCqPJL5kK0MuHu",
"ses_232a8b843ffeuObnumylAfbiQq",
"ses_232a93622ffeFopxVQ1ZHQtCco",
"ses_2329d0031ffei7Iu3Stjv0Ld6E",
"ses_2329395fdffe3CYdCA2ZB5qp6C",
"ses_232945a3bffek5VbcsuhulORse",
"ses_2328dd92affe0TUA5EZGJiJtis",
"ses_2328d72f0ffe2ZOHQgBl3GlU6d",
"ses_2328cca83ffe89h8Gnl00tD1JD",
"ses_2328e2828ffe9UycO58k0onwkJ",
"ses_2313f30cbffezgUIabEnco2AoO",
"ses_23124b513ffeDQ4o521Dtzz62a",
"ses_2312520bdffe1KrhnCQf2yCxqG",
"ses_22f81204effee4x6ABs4SASnmh",
"ses_22f712eabffeza2cy0L23Dvf17",
"ses_22f71ae88ffeLxrb27NM4mBJoF",
"ses_22f5f3792ffeNYKT2W6PDXXbGQ",
"ses_22f443947ffeqxxdMQ1N9x9H26",
"ses_22f360d41ffeDcc17l6fPwcWOr",
"ses_22f358609ffekrF7uFjsJEyxu6",
"ses_22f2b6cbdffe8YcUpThdI6JHfM",
"ses_22f21845affeRgoo73nIvI1GUa",
"ses_22f20fba6ffe5fJyOi7HJg8CZQ",
"ses_22f1823c1ffek8p7La3fBMqslC",
"ses_22efe07c7ffe1eTZ6kvrkGLVYl",
"ses_22ef4380affeXjumRiXI4u1KSK",
"ses_22ef3b48bffeJQKH6xj5U4fuTi",
"ses_22ee9db6effe5AVbe40BDqIT9y",
"ses_22ed7ead4ffe0ku37F9Y6qIO9s",
"ses_22ed735fdffeyscON4NRPNOrz5",
"ses_22ec6f8a8ffeaZwK7e1GUo035a",
"ses_22ec791c3ffeMYLw6bTdYIxPNm",
"ses_22ebd2f4fffe5gTdsn3wPb0u6D",
"ses_22eb3422affe0WXwp2RUpnBMbi",
"ses_22eb4c13effeq1D5R0Hv64kDKi",
"ses_22eb45670ffeTp5TTjGXMPI7SC",
"ses_22eb3dab2ffeuR0mQzUofl5SpW",
"ses_22ea014d4ffesgY7jcuHeSi25L"
],
"plan_name": "thressgame-coverage",
"agent": "atlas"
}