Commit Graph

4 Commits

Author SHA1 Message Date
david raistrick c72b88f8bb WIP turn.js: computeTurnOrderAfterRemoval bumps round on wrap
Removal of current participant when no active after → advance to order[0]
+ bump round. Without bump, nextTurn replays whole round (BUG-5 pattern).

Parser 500-40b: 24 skips/1 double (was 46/64). Down not zero. Remaining
skips = replay async stale read (getDoc between turns), not turn.js.
2026-07-01 12:00:23 -04:00
david raistrick 0473eacc1d WIP: BUG-5 slot-array fix + FEAT-1 dead-not-skipped + skip parser
WORK IN PROGRESS — fix not complete. analyze-turns.js on 500-round
replay still finds 46 real skips + 64 double-acts.

turn.js changes:
- computeTurnOrderAfterAddition: insert by initiative (not append end)
- nextTurn wrap: no re-sort, cycle pointer
- togglePause resume: no re-sort, order stable
- addParticipant: patches turnOrderIds when started
- applyHpChange: death no longer flips isActive or touches turnOrderIds
  (FEAT-1 dead-not-skipped)

Tests:
- shared/tests/turn.skip.test.js (NEW): deterministic skip invariants
  pure 100 rounds + 540 rounds w/ mutations, both green
- shared/tests/turn.dead-skip.test.js: 4 green (FEAT-1)
- turn.characterization.test.js: 3 sites updated to new behavior
- turn.combat.test.js: boundary count fixed (wrap-turn attributed to
  new round), debug dump removed

scripts/analyze-turns.js (NEW): deterministic replay-stdout parser.
Reconstructs rounds, reports real skips + double-acts. Exit 1 on issue.
Catches bugs unit tests miss (46 skips/64 double-acts in 500 rounds).

TODO: FEAT-1 marked done, FEAT-2 added (upgrade app logs parseable).
2026-07-01 11:42:43 -04:00
david raistrick d35a730e12 fix(turn): BUG-2 addParticipant rejects duplicate id
Root cause: addParticipant appended participant to participants[] without
checking id uniqueness. Two participants with same id in array. On
togglePause resume, turnOrderIds rebuilt via sort → dup id appears twice.
nextTurn then stuck repeating that id (rotation breaks).

This was the enabling step for BUG-1's full corruption (audit chain):
  pause blocks advance → totalTurns frozen → addParticipant re-adds
  same r${totalTurns} id → resume dup → nextTurn stuck.

Fix: throw on duplicate id in addParticipant. Caller must use fresh id
(crypto.randomUUID in App, replay already does).

Evidence:
- Test: 'addParticipant rejects duplicate id' (was test.skip, now live).
- Pre-fix: 1 RED (Received function did not throw).
- Post-fix: 50 green (shared), 23 green (server), 62 green (FE).
- Reachability in normal app: low (App uses crypto.randomUUID) but no
  guard existed before. Defensive + unblocks BUG-1 isolation.

No other behavior changed.
2026-06-29 16:25:39 -04:00
david raistrick e06adaa081 M1: shared turn logic + characterization tests (39 green)
- npm workspaces: shared/, server/
- shared/turn.js: port turn logic verbatim from App.js (bugs preserved)
- 39 characterization tests lock current behavior
- gitignore: sqlite data, logs
2026-06-28 16:57:43 -04:00