6.0 KiB
spec, created, status
| spec | created | status |
|---|---|---|
| docs/specs/platform/setup-launch-timeout.md | 2026-08-12 | completed |
Implementation Plan: Setup and Launch Timeout
Overview
Issue #2574 exposes two competing deadlines. Repository setup can continue past
the lifecycle manager's one-minute shared-launch limit, so runtime creation
receives an expired context and reports an agentctl readiness error. The
repair first creates one process-start setup-timeout policy and applies it to
all prepare paths. It then derives runtime launch-phase deadlines from that
policy, keeps preparation in an independent context, and documents the
operator contract.
Backend
Process timeout policy
- Update
apps/backend/internal/common/constants/timeouts.goto resolveKANDEV_TASK_PREPARATION_TIMEOUTonce at process start. Keep the exportedSetupScriptTimeoutvalue for existing consumers, change its default to 10 minutes, and deriveAgentLaunchTimeoutasSetupScriptTimeout + 5m. - Add a pure parser helper so
apps/backend/internal/common/constants/timeouts_test.gocan cover missing, valid, invalid, zero, and negative values without changing process-global state.
Setup-path alignment
- In
apps/backend/internal/agent/runtime/lifecycle/env_preparer_local.go, give each profile prepare script a child context bounded byconstants.SetupScriptTimeout. - Keep the worktree repository-script handler in
apps/backend/internal/backendapp/worktree.goon the same value. - Replace
spritePrepareTimeoutandsshPrepareTimeoutwith the common setup value inexecutor_sprites_operations.goandexecutor_ssh_scripts.go. - Update the Docker bootstrap and
ContainerManager.waitForHealthincontainer.go: enforce the common setup limit around the prepare command so a timeout remains non-fatal, then giveagentctlreadiness the derived launch budget. Preserve caller cancellation and the last health error.
Launch-phase deadlines
- Keep the coalesced manager context independent of the launch-phase deadline so environment resolution cannot consume the runtime launch budget.
- Start a fresh
constants.AgentLaunchTimeoutcontext after environment resolution, and let each runtime give its setup script an independentconstants.SetupScriptTimeoutcontext. - Update comments and timeout assertions that still describe a single shared wall-clock launch.
Tests
- What: timeout parsing and the 10-minute and 15-minute defaults.
File:
apps/backend/internal/common/constants/timeouts_test.goHow: table-driven unit tests for empty, valid, malformed, zero, and negative values. - What: coalesced environment preparation can cross the old one-minute
boundary without consuming the runtime launch-phase budget.
File:
apps/backend/internal/agent/runtime/lifecycle/execution_context_test.goHow:testing/synctestadvances virtual time through preparation, then verifies a fresh launch-phase deadline and an independent setup deadline. - What: a blocked runtime launch phase ends at the derived launch deadline
and releases its activity lease.
File:
apps/backend/internal/agent/runtime/lifecycle/manager_execution_test.goHow: update the existing manager-deadlinetesting/synctestassertion. - What: local prepare scripts and Docker bootstrap readiness use the common
setup limit while preserving cancellation and setup-failure behavior.
Files:
env_preparer_setup_script_test.goand a focused newcontainer_health_test.gobesidecontainer.go. How: focused context-deadline tests with virtual time or a short injected context. Do not add a real 10-minute test. - What: existing launch phases use the derived agent-launch value while
preparation retains its full independent setup value.
Files: existing backend tests that assert
constants.AgentLaunchTimeout. How: run the affected package tests after the constant change.
Verification Results
- Task 01:
cd apps/backend && go test ./internal/common/constants ./internal/agent/runtime/lifecycle ./internal/backendapppassed with 1,844 tests across 3 packages. - Task 02:
cd apps/backend && go test -count=1 ./internal/agent/runtime/lifecycle ./internal/orchestrator ./internal/task/handlers ./internal/mcp/handlerspassed with 4,587 tests across 4 packages. - Focused lifecycle regressions passed under
go test -race, covering setup-script timeout, container health timeout, independent launch/preparation contexts, and launch-phase deadline behavior. - The host-mode Docker launch E2E suite passed 12 tests with one pre-existing
fixmeskipped; the Alpine BusyBox preparation test passed three consecutive repetitions without retries. - The web typecheck, E2E fixture Prettier check, focused Go vet, public-doc validation, and public-doc validation tests passed.
git diff --checkpassed.
Implementation Waves And Parallel Candidates
Execution is sequential because Task 02 depends on the common policy from Task 01 and both tasks touch lifecycle timeout behavior.
- Task 01: Unify setup timeout paths (completed)
- Task 02: Align shared launch and docs (completed)
Documentation Impact
Update docs/public/configuration.md with the exact environment variable,
duration syntax, fallback behavior, restart requirement, and derived 15-minute
default launch-phase limit. Update docs/public/executors.md to state that
prepare scripts use the common setup limit while their fatal or non-fatal
behavior remains runtime-specific.
Risks
- Docker runs its prepare script before
agentctl, so the bootstrap timeout and readiness phase are separate boundaries that can stop a hung launch. - The setup timeout is process-global. Tests must not depend on changing the environment after package initialization.
- A longer correct launch-phase deadline delays failure for a truly blocked runtime. The derived 15-minute phase bound and activity-lease regression keep that case finite.