feat(thressgame-coverage): Wave 8 (WS protocol v2 + suspended execution + request-choice)
- T43: WS protocol v2 schema; protocolVersion field; RequestChoice/SubmitChoice/ProtocolVersionMismatch messages; v1 backward-compat - T44: server-side request-choice broadcast on push; submit-choice validation (kind/forPlayer/value-type); ordered LIFO matching - T45: PendingChoices stack on GAME_ENTITY; pushPendingChoice/popPendingChoice/peekPendingChoice helpers; serializePendingChoice (Map<->Array roundtrip); MAX_CHOICE_DEPTH=8 enforced - T46: submitChoiceAndResume(engine, choiceId, value); descriptor-by-id lookup; bindings restored; remaining primitives executed via runPrimitives from primitiveIndex+1 - T47: request-choice primitive; SuspendedExecution exception mechanism; dispatcher catches and stops sibling iteration; deterministic choiceId via session counter - T48: AutoChoiceResolver test transport (answersByKind / answersById); drainPendingChoices LIFO walk - T49: server-side choice timeout enforcement; auto-resolve to first-option-per-kind; disconnect handler (forfeit / pause) - T50: ChoiceTimeoutPolicy on GAME_ENTITY (timeout-with-default | no-timeout); CreateGameRequest extended; default 60s Tests: 2533 -> 2658 (+125). bun run check exit 0.
This commit is contained in:
parent
778ebc4129
commit
d4931a50ee
37 changed files with 6841 additions and 295 deletions
|
|
@ -1434,7 +1434,7 @@ Max Concurrent: 8 (Waves 5+6+7+9 overlap)
|
|||
|
||||
> **WAVE 8 — WS PROTOCOL v2 + SUSPENDED EXECUTION**: highest-risk wave. Each task is its own commit; integration tests at the end.
|
||||
|
||||
- [ ] 43. WS protocol v2 schema
|
||||
- [x] 43. WS protocol v2 schema
|
||||
|
||||
**What to do**:
|
||||
- Edit `packages/server/src/protocol.ts`: add new message types `RequestChoiceMessage` (server→client: `{ kind: "request-choice", choiceId: string, prompt: { kind: "piece"|"square"|"column"|"row"|"coin-flip"|"rps", filter?, forPlayer: Color, timeout?: number } }`) and `SubmitChoiceMessage` (client→server: `{ kind: "submit-choice", choiceId: string, value: unknown }`)
|
||||
|
|
@ -1449,7 +1449,7 @@ Max Concurrent: 8 (Waves 5+6+7+9 overlap)
|
|||
**QA Scenarios**: `.sisyphus/evidence/task-43-protocol-v2.txt`
|
||||
**Commit**: YES — `feat(server): WS protocol v2 schema (request-choice + version negotiation)`
|
||||
|
||||
- [ ] 44. Server-side request-choice broadcast + validation
|
||||
- [x] 44. Server-side request-choice broadcast + validation
|
||||
|
||||
**What to do**:
|
||||
- Edit `packages/server/src/ws.ts` (or equivalent ws handler): when game state has a pendingChoices entry, server sends `RequestChoiceMessage` to the targeted player on connect/reconnect
|
||||
|
|
@ -1463,7 +1463,7 @@ Max Concurrent: 8 (Waves 5+6+7+9 overlap)
|
|||
**QA Scenarios**: `.sisyphus/evidence/task-44-server-choice.txt`
|
||||
**Commit**: YES — `feat(server): request-choice broadcast + validation`
|
||||
|
||||
- [ ] 45. Stack-based pendingChoices state on GAME_ENTITY + serializer
|
||||
- [x] 45. Stack-based pendingChoices state on GAME_ENTITY + serializer
|
||||
|
||||
**What to do**:
|
||||
- Add attr `PendingChoices: readonly PendingChoice[]` to ChessAttrMap. PendingChoice = `{ choiceId: string, descriptorId: string, triggerPath: readonly number[], primitiveIndex: number, bindings: Record<string, JsonValue>, kind, prompt, forPlayer, timeout?: number, expiresAtTimestamp?: number }`
|
||||
|
|
@ -1477,7 +1477,7 @@ Max Concurrent: 8 (Waves 5+6+7+9 overlap)
|
|||
**QA Scenarios**: `.sisyphus/evidence/task-45-pending-choices.txt`
|
||||
**Commit**: YES — `feat(chess): pendingChoices stack on GAME_ENTITY`
|
||||
|
||||
- [ ] 46. Suspended-execution resume in integration preset
|
||||
- [x] 46. Suspended-execution resume in integration preset
|
||||
|
||||
**What to do**:
|
||||
- Edit integration preset's `performAction` hook: when action is `submit-choice`, pop top PendingChoice, restore bindings into a fresh PrimitiveApplyContext, resume runPrimitives at saved `triggerPath` + `primitiveIndex + 1` (skip past the request-choice that caused suspension), inject the submitted value as binding (key matches request-choice's `bind` param)
|
||||
|
|
@ -1490,7 +1490,7 @@ Max Concurrent: 8 (Waves 5+6+7+9 overlap)
|
|||
**QA Scenarios**: `.sisyphus/evidence/task-46-resume.txt`
|
||||
**Commit**: YES — `feat(chess): suspended execution resume`
|
||||
|
||||
- [ ] 47. request-choice primitive
|
||||
- [x] 47. request-choice primitive
|
||||
|
||||
**What to do**:
|
||||
- Create `packages/chess/src/modifiers/primitives/request-choice.ts`: kind "request-choice", schema `{ kind: "piece"|"square"|"column"|"row"|"coin-flip"|"rps", forPlayer: "chooser"|"opponent"|"both", filter?, bind: string, then: NodeArray }`
|
||||
|
|
@ -1505,7 +1505,7 @@ Max Concurrent: 8 (Waves 5+6+7+9 overlap)
|
|||
**QA Scenarios**: `.sisyphus/evidence/task-47-request-choice.txt`
|
||||
**Commit**: YES — `feat(chess): request-choice primitive`
|
||||
|
||||
- [ ] 48. Deterministic auto-resolver test transport
|
||||
- [x] 48. Deterministic auto-resolver test transport
|
||||
|
||||
**What to do**:
|
||||
- Create `packages/chess/src/__fixtures__/test-choice-resolver.ts`: a test-only WS transport mock that auto-resolves PendingChoices according to a deterministic policy:
|
||||
|
|
@ -1522,7 +1522,7 @@ Max Concurrent: 8 (Waves 5+6+7+9 overlap)
|
|||
**QA Scenarios**: `.sisyphus/evidence/task-48-test-resolver.txt`
|
||||
**Commit**: YES — `test(chess): deterministic auto-resolver test transport`
|
||||
|
||||
- [ ] 49. Choice timeout + disconnect handler
|
||||
- [x] 49. Choice timeout + disconnect handler
|
||||
|
||||
**What to do**:
|
||||
- Edit ws.ts: when PendingChoice has `timeout` field, server schedules a timer; on expiry, server auto-submits the "first valid option" as the choice and resumes
|
||||
|
|
@ -1536,7 +1536,7 @@ Max Concurrent: 8 (Waves 5+6+7+9 overlap)
|
|||
**QA Scenarios**: `.sisyphus/evidence/task-49-timeout-disconnect.txt`
|
||||
**Commit**: YES — `feat(server): choice timeout + disconnect handler`
|
||||
|
||||
- [ ] 50. Game settings: choiceTimeout in CreateGameRequest
|
||||
- [x] 50. Game settings: choiceTimeout in CreateGameRequest
|
||||
|
||||
**What to do**:
|
||||
- Edit `packages/server/src/protocol.ts` CreateGameRequest schema: add `choiceTimeout: { mode: "timeout-with-default", seconds: number } | { mode: "no-timeout" }` field; default = `{ mode: "timeout-with-default", seconds: 60 }`
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue