Files
kandev/docs/plans/task-completion/task-04-session-resume.md
T
2026-09-10 15:01:37 +01:00

6.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
04-session-resume Resume completed conversations safely done 4
03-runtime-completion
plan.md
REQ-TASKS-COMPLETION-002
AC-TASKS-COMPLETION-002.2
AC-TASKS-COMPLETION-002.3
AC-TASKS-COMPLETION-002.4
AC-TASKS-COMPLETION-002.6
AC-TASKS-COMPLETION-002.7
AC-TASKS-COMPLETION-002.8
AC-TASKS-COMPLETION-002.9
AC-TASKS-COMPLETION-002.10
AC-TASKS-COMPLETION-002.11
AC-TASKS-COMPLETION-002.12
AC-TASKS-COMPLETION-002.13
../../specs/tasks/system-design/task-completion.md

Task 04: Resume completed conversations safely

Summary

Admit explicit completed-session recovery through the existing lifecycle path. Keep the selected conversation and its ownership stable through messages, queue dispatch, cleanup, and failures.

In scope

  • Add a narrow internal permission for completed recovery from session.recover resume and pinned follow-up admission. Authorize task/session binding and prompt permission before side effects; keep passive ensure/status/launch terminal guards.
  • Support missing executor rows after cleanup, preserve provider identity/history and queue incarnation, and persist guarded STARTING before credential acquisition. At readiness restore input without replaying a workflow or initial prompt.
  • Persist completion_follow_up for manually revived historical sessions; exclude them from automatic profile reuse and task/workflow reconciliation until explicit ownership handoff.
  • Route completed MCP targets through the same resume admission. Keep live-session preference and pin explicit/fallback targets; preserve FAILED/CANCELLED rejection and dedicated recovery paths.
  • Cover double resume, resume/send order, old stream/exit/reclaim vs new execution, archive/delete/stop, queued prompt survival, active clarification, provider history restoration, and profile/runtime failure.

Out of scope

No new MCP tool, new queue, Office bypass, automatic completed-session revival, or fresh conversation fallback.

Acceptance

  • Explicit Resume and follow-up use the same session and conversation, preserve primary/task/workflow ownership, and cannot mutate a foreign task/session pair.
  • Completed recovery works after reclamation; duplicate and stale operations cannot clear new work or revive stopped/archived work. Queued prompts preserve FIFO and Auto-run.
  • Passive opening never starts completed work; FAILED/CANCELLED behavior and current clarification barriers remain unchanged.

TDD entry

Create completed_session_resume_test.go with TestCompletedSessionResumePreservesConversation and TestCompletedSessionResumeRaces, exercising RecoverSession and real guarded writers with slow runtime fakes. First show current completed rejection. Add TestCompletedSessionFollowUpOwnership for a retired non-primary session and protect the existing completed-sibling fallback regression.

Verification

Run from apps/backend/. PostgreSQL-dependent cases use an isolated KANDEV_TEST_POSTGRES_DSN; never point tests at the reported installation.

rtk go test -race ./internal/orchestrator -run 'Test.*(CompletedSession|ResumeTaskSession|RecoverSession|SessionKeyedEntryPoints|GetTaskSessionStatus|Reclaim|SessionStartingRecovery|WorkflowProfileSession)' -count=1
rtk go test -race ./internal/orchestrator/executor -run 'Test.*(Resume|TerminalSessionState)' -count=1
rtk go test -race ./internal/task/handlers -run 'Test.*(Message|Prompt)' -count=1
rtk go test -race ./internal/mcp/handlers -run 'Test.*(MessageTask|MessageTarget|ParentQuestion)' -count=1

Files likely touched

  • apps/backend/internal/orchestrator/session_launch.go
  • apps/backend/internal/orchestrator/task_operations.go
  • apps/backend/internal/orchestrator/executor/executor_resume.go
  • apps/backend/internal/orchestrator/event_handlers_streaming.go
  • apps/backend/internal/orchestrator/event_handlers_agent.go
  • apps/backend/internal/orchestrator/event_handlers_workflow.go
  • apps/backend/internal/orchestrator/workflow_profile_session_lifecycle.go
  • apps/backend/internal/task/models/models.go
  • apps/backend/internal/task/handlers/message_handlers.go
  • apps/backend/internal/mcp/handlers/message_target_session.go
  • apps/backend/internal/mcp/handlers/handlers.go
  • apps/backend/internal/mcp/handlers/parent_question.go
  • apps/backend/internal/orchestrator/completed_session_resume_test.go (new)
  • apps/backend/internal/mcp/handlers/message_target_session_test.go

Dependencies

Complete 03-runtime-completion first.

Risks

Use channel barriers, not sleeps, for races. State alone is insufficient against same-state replacement; retain execution/generation claims and tombstones. Avoid lock inversion between lifecycle guards, runtime cleanup, and event callbacks. Missing runtime data must not silently clear a provider resume token.

Parallelism

sequential

Inputs

  • Requirements, criteria in frontmatter.
  • System design.
  • Plan, confirmed source trace and existing reproduction tests.
  • Nearby Go repository/handler tests supply fixture conventions.
  • Follow /tdd in the primary session.

Results

The first red regression, TestCompletedSessionFollowUpTurnReturnsToWaiting, showed that a resumed completed session reached RUNNING after its follow-up instead of returning to WAITING_FOR_INPUT. The lifecycle path now recognizes the durable completion-follow-up marker and settles the same session without replaying workflow actions or changing task completion.

Final verification passed:

orchestrator completed-session/resume/reclaim gate: 153 tests
executor resume/terminal-state gate: 103 tests
task-handler message/prompt gate: 103 tests
MCP message-target/parent-question gate: 65 tests
desktop completed-chat E2E: 1 test
mobile completed-chat E2E: 1 test
desktop recovery-neighbor E2E: 23 tests
mobile recovery-neighbor E2E: 4 tests

The same-session resume preserves the selected session, provider history, primary ownership, task state, workflow step, queued prompt ordering, and non-primary historical ownership. Passive opening remains non-revivifying, and FAILED/CANCELLED recovery behavior remains unchanged.