Files
kandev/docs/plans/runtime-task-state-client-reconciliation/plan.md
T
2026-08-30 14:10:22 +00:00

111 lines
4.1 KiB
Markdown

---
created: 2026-08-29
status: complete
requirements:
- REQ-TASKS-RUNTIME-STATE-PUBLICATION-ORDER-001
system_design:
- ../../specs/tasks/system-design/runtime-state-publication-order.md
legacy_specs: []
---
# Implementation Plan: Runtime Task-State Client Reconciliation
## Overview
Preserve the newest task state across delayed workflow snapshots and active
task aggregation. The snapshot merge changes first because it is the stale
write source. The aggregator then provides a second consistency boundary.
## Scope
### In scope
- Preserve a newer live `state` and `updatedAt` during workflow snapshot merge.
- Use task update time to select task-level data during sidebar aggregation.
- Select status-summary data through its independent revision contract.
- Add deterministic regression tests for both race boundaries.
### Out of scope
- Backend task-state publication changes.
- New state values, event payloads, or database fields.
- Changes to State grouping, labels, icons, or task-row layout.
- New desktop or mobile interaction behavior.
## Technical approach
### Workflow snapshot merge
Update `mergeFetchedTask` in
`apps/web/hooks/domains/kanban/use-all-workflow-snapshots.ts`.
Compare the mapped snapshot task with the current cached task by `updatedAt`.
If the cached task is newer, preserve its `state` and `updatedAt`. Keep the
existing independent merge rules for placement, status summary, executor
binding, autopilot, and auto-start errors.
### Sidebar aggregation
Update the task precedence logic in
`apps/web/components/task/task-session-sidebar-aggregate.ts`.
Use `updatedAt` to choose task-level data. Use status-summary revision only to
choose the status summary. On equal task update times, keep the current active
fallback behavior.
### Mobile parity
Desktop and mobile already share `aggregateSidebarTasks` and `applyView`.
`session-task-switcher-sheet.tsx` is the nearest mobile surface.
This change does not alter composition, navigation, scrolling, safe areas,
pointer behavior, or touch targets. The shared unit tests satisfy the mobile
parity rule for state-only normalization.
## Tests
- **AC-TASKS-RUNTIME-STATE-PUBLICATION-ORDER-001.3:** Add a deferred snapshot
test in
`apps/web/hooks/domains/kanban/use-all-workflow-snapshots-inflight.test.ts`.
The response has `REVIEW` with an older update time. The live projection has
`IN_PROGRESS` with a newer update time.
- **AC-TASKS-RUNTIME-STATE-PUBLICATION-ORDER-001.4:** Add aggregation tests in
`apps/web/components/task/task-session-sidebar-aggregate.test.ts`. Equal
status-summary revisions must not make an older `REVIEW` snapshot win, and
equal task timestamps must retain the active projection.
- **AC-TASKS-RUNTIME-STATE-PUBLICATION-ORDER-001.6:** The same aggregation tests
cover the data path that the desktop sidebar and mobile task switcher share.
- Add the inverse freshness case so a newer snapshot remains authoritative.
- Add failed-refresh coverage for both placeholder and resolved snapshots.
## E2E tests
The existing scenario in `apps/web/e2e/tests/chat/clarification.spec.ts` covers
`AC-TASKS-RUNTIME-STATE-PUBLICATION-ORDER-001.5`. It proves that State grouping
moves a running task without a reload.
No new Playwright test will simulate the HTTP and WebSocket race. The deferred
unit test controls that order without scheduler timing. This change qualifies
for the mobile-parity state-normalization exception.
## Work orders
- [x] [Task 01: Reconcile task-state projections](task-01-reconcile-task-state-projections.md)
## Verification results
- Focused Vitest suite: 29 tests passed.
- Focused ESLint: passed with no warnings.
- Web TypeScript typecheck: passed.
- Existing clarification Playwright scenario: 1 Chromium test passed.
- Specification lint suite and diff checks: passed.
## Risks
- Missing or invalid update times can make freshness ambiguous. The existing
fallback behavior must remain stable.
- A whole-task precedence change can erase independently newer summary data.
The implementation must merge status summary separately.
- Over-preserving task state can block a legitimate newer snapshot. The
regression tests must cover both timestamp directions.