diff --git a/TODO.md b/TODO.md index afbadf3..08103a9 100644 --- a/TODO.md +++ b/TODO.md @@ -3,6 +3,20 @@ Backlog of bugs + long-term items, from user. Milestones live in REWORK_PLAN.md. +## Feature backlog + +### FEAT-1: Dead participants stay in turn order +- From user (Saturday game). Moved out of REWORK_PLAN (not milestone). +- Dead (HP=0) participants must NOT be skipped. +- Current: dead → `isActive=false` → removed from turn order → skipped. +- Desired: dead occupy initiative slot, turn still comes up. PCs get + death-save turn. +- Affects: `shared/turn.js` `nextTurn` (filters `isActive`), `applyHpChange` + (sets isActive=false on death), `computeTurnOrderAfterRemoval`. +- Characterization tests (`src/tests/Combat.characterization.test.js`) lock + CURRENT behavior — UPDATE to desired when implementing. +- RED test locked (desired state): `shared/tests/turn.dead-skip.test.js`. + ## Confirmed bugs (tests written, NOT fixed) ### BUG-1: addParticipant + pause/resume corrupts turn rotation diff --git a/docs/REWORK_PLAN.md b/docs/REWORK_PLAN.md index eb4ba39..08df892 100644 --- a/docs/REWORK_PLAN.md +++ b/docs/REWORK_PLAN.md @@ -119,7 +119,7 @@ Each milestone = independently mergeable PR upstream (unless marked ❌). | 1 | build backend (Node+Express+ws+better-sqlite3) | unit tests as built | | 2 | frontend WS adapter — app runs vs backend, cross-device works | yes | | 3 | characterization tests lock current behavior | yes | -| 4 | dead participants not skipped (M4 below) | yes | +| 4 | resolve initiative rotation corruption (BUG-5) | yes | | 5 | docker compose in-house | smoke | | 6 | undo rework (tx events) | unit | | 7 | playwright multi-window e2e (deferred) | e2e | @@ -159,19 +159,17 @@ Each milestone = independently mergeable PR upstream (unless marked ❌). - **Exit criteria:** characterization suite green. Baseline locked. ✅ DONE. - **Upstream-PRable:** ✅ if kept storage-agnostic (tests target turn logic shape). -### Milestone 4 — Dead participants stay in turn order -- **The one feature request:** dead (HP=0) participants must NOT be skipped. -- Current: dead → `isActive=false` → removed from turn order → skipped. -- Desired: dead occupy initiative slot, turn still comes up. PCs get - death-save turn. -- Affects: `shared/turn.js` `nextTurn` (filters `isActive`), `applyHpChange` - (sets isActive=false on death), `computeTurnOrderAfterRemoval`. -- Characterization tests (`src/tests/Combat.characterization.test.js`) lock - CURRENT behavior — UPDATE to desired when implementing. -- RED test locked (desired state): `shared/tests/turn.dead-skip.test.js`. -- Uses M1/M3 characterization as foundation. -- **Exit criteria:** dead participant turn comes up, RED tests go green. -- **Upstream-PRable:** ✅ beneficial feature. +### Milestone 4 — Resolve initiative rotation corruption (BUG-5) +- **Real bug.** Mid-round add/revive corrupts rotation. +- 13 dupes / 100 rounds (deterministic seeded test). +- Root cause: `computeTurnOrderAfterAddition` appends id to turnOrderIds + end. Round wrap re-sorts by initiative. `currentTurnParticipantId` + pointer stale → nextTurn revisits. +- RED test locked: `shared/tests/turn.combat.test.js`. +- Detail in `TODO.md` BUG-5. +- **Exit criteria:** RED green. Rotation invariant holds across + add/remove/revive. +- **Upstream-PRable:** ✅ bug fix. ### Milestone 5 — Docker compose - `docker-compose.yml`: @@ -234,7 +232,7 @@ Each milestone = independently mergeable PR upstream (unless marked ❌). | 1 backend | ❌ | divergence (friend stays Firebase) | | 2 WS adapter | ⚠️ partial | interface + firebase extract ✅, WS ❌ | | 3 characterization tests | ✅ | if storage-agnostic | -| 4 dead-not-skipped | ✅ | beneficial feature | +| 4 BUG-5 rotation fix | ✅ | bug fix | | 5 docker compose | ❌ | divergence | | 6 undo rework | ⚠️ partial | turn-logic-level ✅, events table ❌ | | 7 playwright | ✅ | if test infra shared |