4.2 KiB
4.2 KiB
id, title, status, wave, depends_on, plan, spec
| id | title | status | wave | depends_on | plan | spec | |
|---|---|---|---|---|---|---|---|
| 02-replacement-turn-dispatch | Orchestrate replacement-turn dispatch | done | 2 |
|
plan.md | ../../specs/ui/message-queue-send-now.md |
Task 02: Orchestrate replacement-turn dispatch
Intent
Compose the exact queue claim with Kandev's unified cancellation coordinator so Send Now safely replaces a captured busy turn or directly prompts an idle session without inheriting explicit Cancel workflow semantics.
Acceptance
message.queue.send_nowauthorizes and dispatches exactly one selected entry or the exact bulk snapshot, returning the specified response/error contract.- Busy dispatch uses backend cancellation progress but never writes the normal cancel message, moves to review, or evaluates cancelled-turn completion; promptable dispatch does not issue a cancel.
- Successor-turn, explicit-cancel, duplicate Send Now, queue-change, and prompt failure races fail closed or restore the original claim without a substitute FIFO dispatch.
Files likely touched
apps/backend/internal/orchestrator/queue_send_now.goapps/backend/internal/orchestrator/queue_send_now_test.goapps/backend/internal/orchestrator/task_operations.goapps/backend/internal/orchestrator/event_handlers_agent.goapps/backend/internal/orchestrator/service.goapps/backend/pkg/websocket/actions.goapps/backend/internal/orchestrator/handlers/queue_handlers.goapps/backend/internal/orchestrator/handlers/queue_handlers_send_now_test.goapps/backend/internal/orchestrator/handlers/queue_handlers_test.goapps/backend/internal/backendapp/gateway.go
Dependencies
- Task 01 exact queue claim, restoration, and acknowledgement contract.
Parallelism
Sequential. It changes shared cancellation ownership and the public WebSocket contract used by Task 03.
Inputs
- Spec: API Surface, State and Concurrency, Permissions, Failure Modes.
- Plan: Backend / Non-completing cancel-and-dispatch and WebSocket action.
- ADR:
2026-08-05-queue-send-now-replaces-turn. - Existing patterns:
QueueAndInterruptForPeerMessage,cancelAgentSilentWithGuardActionKind,dispatchTakenQueuedMessage, andCancellationPendingSnapshot.
Verification
cd apps/backend && go test -race ./internal/orchestrator ./internal/orchestrator/handlers -run 'SendQueuedNow|SendNow' -count=1
Also run the focused existing cancellation/peer-interrupt regressions affected by any shared coordinator edit:
cd apps/backend && go test -race ./internal/orchestrator -run 'Test(CancelAgent|CancellationSources|QueueAndInterruptForPeerMessage)' -count=1
Output contract
Report files changed, cancellation-source behavior, wire contract/error mapping,
RED and GREEN test commands/results, race cases covered, blockers/risks, and
synchronize this task plus plan.md status/results.
Results
- Added
Service.SendQueuedNow, themessage.queue.send_nowaction, stable validation/error mapping, queue status publication, exact selected/bulk dispatch, and the dedicated non-completing cancellation kind. - Busy Send Now uses the backend-owned cancellation projection and captured-turn guard without joining explicit Cancel; promptable Send Now claims and prompts directly. Duplicate/cross-owner operations fail closed, and prompt/reset failures restore the complete claim.
- GREEN:
cd apps/backend && go test -race ./internal/orchestrator -run 'SendNow|ExplicitCancellationDoesNotJoin' -count=1 -v— 6 tests passed; handler coverage with-run 'SendNow|QueueHandler'— 24 tests passed; affected existing cancellation/peer-interrupt regressions — 56 tests passed. - PR fixup: carry the validated click-time source snapshot through cancellation and compare persisted queue fields before claiming; mark every source as
user_message_recordedbefore prompt admission so ordinary and durable restoration cannot create duplicate transcript rows. Regression coverage includes changed-snapshot atomicity and a retry with a durable source. - The WS contract validates scope before dispatch and returns
{session_id, dispatched, sent_count}on success, with stable queue-empty, queue-changed, conflict, turn-changed, attachment, and reference errors.