Files
kandev/docs/plans/frontend-runtime-cpu/task-02-batch-message-frame-mutations.md
T
2026-08-27 16:04:59 +00:00

4.2 KiB

id, title, status, wave, depends_on, plan, requirements, acceptance_criteria, system_design
id title status wave depends_on plan requirements acceptance_criteria system_design
02-batch-message-frame-mutations Batch message frame mutations completed 2
01-coalesce-browser-diagnostic-work
plan.md
REQ-PLATFORM-BOUNDED-TASK-STATUS-DELIVERY-001
AC-PLATFORM-BOUNDED-TASK-STATUS-DELIVERY-001.7
AC-PLATFORM-BOUNDED-TASK-STATUS-DELIVERY-001.9
../../specs/platform/system-design/bounded-task-status-delivery.md

Task 02: Batch Message Frame Mutations

Summary

Apply all accepted replacement messages from one animation frame in one Zustand and Immer transaction. Preserve message merge and barrier behavior.

Failing regression first

Add a scheduler test named applies different message keys with one bulk store action. Enqueue two message keys, flush one frame, and prove that the store receives one ordered array instead of two updateMessage calls.

Add a real-store test named notifies subscribers once for one replacement frame. Seed two messages, subscribe to the session message array, apply the bulk action, and prove that both messages change after one notification.

In scope

  • Add updateMessages(messages) to the session slice type and implementation.
  • Share partial-field merge logic with updateMessage(message).
  • Convert, settle, and stale-filter frame payloads before one store action.
  • Preserve first-key insertion order from the scheduler map.
  • Preserve add, delete, and turn-settle barriers.
  • Keep unaffected session arrays and message objects stable.
  • Extend scheduler and slice tests for multi-session frames.

Out of scope

  • Backend lifecycle or gateway coalescing changes.
  • Protocol payload or timestamp changes.
  • Incremental transcript grouping or virtualization.
  • A replacement for Zustand or Immer.

Acceptance

  • Several accepted message keys in one frame cause one bulk store call.
  • A real store emits at most one subscriber notification for that frame.
  • Final message fields match the current single-update behavior.
  • Stale payloads remain rejected.
  • Add and delete events cannot be reordered around pending replacements.

Verification

cd apps && pnpm --filter @kandev/web test -- lib/ws/handlers/messages.test.ts lib/state/slices/session/session-slice.update-messages.test.ts lib/state/slices/session/session-slice.merge-messages.test.ts
cd apps && pnpm --filter @kandev/web run typecheck
cd apps/web && pnpm exec eslint lib/ws/handlers/messages.ts lib/ws/handlers/messages.test.ts lib/state/slices/session/types.ts lib/state/slices/session/session-slice.ts lib/state/slices/session/session-slice.update-messages.test.ts

Files likely touched

  • apps/web/lib/ws/handlers/messages.ts
  • apps/web/lib/ws/handlers/messages.test.ts
  • apps/web/lib/state/slices/session/types.ts
  • apps/web/lib/state/slices/session/session-slice.ts
  • apps/web/lib/state/slices/session/session-slice.update-messages.test.ts

Dependencies

  • Task 01 completes first so the later comparison trace can attribute logger and store work separately.

Risks

  • Payload conversion inside the mutation can observe different turn state.
  • A multi-session frame can accidentally replace an unaffected session array.
  • Partial updates can clear known fields if undefined values are merged.
  • Barrier tests can pass with mocks while real subscriber count still grows.

Parallelism

sequential

Inputs

  • Bounded task status delivery acceptance criteria 7 and 9.
  • The accepted replaceable session stream decision.
  • Existing message scheduler and session slice tests.

Results

Implemented the bulk replacement action and scheduler batching. Accepted replacement payloads are converted and settled before one updateMessages transaction, while add, delete, and turn-settle events remain ordered barriers. The shared merge helper preserves partial-field behavior and unaffected session state remains stable. The stale-snapshot regression now asserts that neither the legacy single-update action nor the production bulk action is called.

Targeted verification passed:

  • lib/ws/handlers/messages.test.ts
  • lib/state/slices/session/session-slice.update-messages.test.ts

The broader work-order verification remains in the package-level check.