No description
Find a file
Joey Yakimowich-Payne 0bd65e0a73
feat(server): turn-boundary queue for modifier profile updates
Replace T1 immediate-apply semantics with a single-slot pending
queue (T2-ADR-1). On `modifier-profile.update` receipt the server
validates shape + layout legality, stashes the profile on
`Room.pendingProfile` with the proposer's token, and acks the
sender with a new `modifier-profile.queued` message. The actual
`reconcileProfileSwap` + version bump + `modifier-profile.updated`
broadcast now runs in `applyPendingProfileIfAny` after the next
successful `applyMove` — either player's move triggers it.

- `Room` gains `pendingProfile` and `pendingProposerToken`
  (token-keyed for reconnect-safe NACK routing).
- `game-session.ts` exposes `setPendingProfile`,
  `applyPendingProfile`, `clearPendingProfile`. Apply re-runs
  `validateProfile` as defence in depth; rejections clear the
  slot and surface the validator error code.
- New `modifier-profile.queued` wire schema (server\u2192client ack
  carrying the expected post-apply version).
- Last-write-wins: a second update overwrites the pending slot
  because the server's `profileVersion` only bumps on apply, so
  the second request legitimately carries the same version.
- Existing early-rejection paths (non-host, stale version,
  invalid profile) remain unchanged.

Tests updated: 7 scenarios covering queued ACK, deferred apply,
last-write-wins, opponent-move-drains-queue, and all original
rejection paths. 1220 unit tests + 18 modifier Playwright tests
green (e2e specs never used `modifier-profile.update` at
runtime so were unaffected).
2026-04-19 09:06:15 -06:00
.github/workflows chore(root): scaffold monorepo — Phase 0 complete 2026-04-16 13:32:21 -06:00
.sisyphus feat(ui): modifier editor undo/redo + conflict resolution panel + copy/paste modifiers 2026-04-19 08:55:48 -06:00
docs docs(adr): T2 polish architecture decisions 2026-04-19 08:43:40 -06:00
packages feat(server): turn-boundary queue for modifier profile updates 2026-04-19 09:06:15 -06:00
scripts feat(rete): add replay engine + state-hash determinism verifier (P3.3) 2026-04-16 15:25:13 -06:00
.gitignore chore: remove Playwright cache dirs from tracking, ignore them 2026-04-19 08:26:15 -06:00
eslint.config.js feat(engine): damage-resistance modifier descriptor 2026-04-18 22:22:31 -06:00
lefthook.yml chore(root): scaffold monorepo — Phase 0 complete 2026-04-16 13:32:21 -06:00
LICENSE chore(root): scaffold monorepo — Phase 0 complete 2026-04-16 13:32:21 -06:00
package.json feat(rete): add replay engine + state-hash determinism verifier (P3.3) 2026-04-16 15:25:13 -06:00
playwright.config.ts fix(rete): inject clock into EventLog; use tsc for DTS; fix cycle.test.ts private access; add Playwright worker limit 2026-04-16 18:25:49 -06:00
README.md chore(root): scaffold monorepo — Phase 0 complete 2026-04-16 13:32:21 -06:00
tsconfig.base.json chore(root): scaffold monorepo — Phase 0 complete 2026-04-16 13:32:21 -06:00
tsconfig.json chore(root): scaffold monorepo — Phase 0 complete 2026-04-16 13:32:21 -06:00
vitest.workspace.ts chore(root): scaffold monorepo — Phase 0 complete 2026-04-16 13:32:21 -06:00

@paratype

A Doorenbos-style Rete II rules engine for TypeScript games, with an authoritative WebSocket chess demo.

Packages

Docs

Getting Started

bun install && bun run check