What to build
Add a hammerkit-native, runtime-agnostic task timeout so a stuck task (deadlocked process, wedged network call, sandbox that never returns) fails cleanly instead of hanging the whole run. A task accepts an optional timeout (a duration); on expiry the task is aborted via the existing abort path (checkForAbort) and reported as failed with a timeout reason. A global --timeout applies as a default to tasks that declare none; a per-task timeout takes precedence. Enforcement works consistently across the local, Docker, and Kubernetes runtimes (it is a timer that triggers the existing abort signal, not a new cancellation mechanism). A timed-out task MUST NOT write a cache entry (a hang is not a successful build), and on timeout the container/process is cleaned up (no orphaned container/volume), even if the timeout fires during the task's own cleanup. Durations use a documented format (30s, 5m); invalid values are rejected at validation time. No timeout configured → behavior is identical to today (additive). Timeout does not participate in cache identity (ADR-0002). Service readiness timeouts are a separate, deferred concern.
Together with the container-runtime-options slice, this replaces the NOTE-block + manual --test-timeout workaround on the affected sandbox test task.
References: specs/task-timeout/spec.md (US1, US2, FR-001–007); docs/adr/0002.
Acceptance criteria
Blocked by
- None - can start immediately.
What to build
Add a hammerkit-native, runtime-agnostic task
timeoutso a stuck task (deadlocked process, wedged network call, sandbox that never returns) fails cleanly instead of hanging the whole run. A task accepts an optionaltimeout(a duration); on expiry the task is aborted via the existing abort path (checkForAbort) and reported as failed with a timeout reason. A global--timeoutapplies as a default to tasks that declare none; a per-tasktimeouttakes precedence. Enforcement works consistently across the local, Docker, and Kubernetes runtimes (it is a timer that triggers the existing abort signal, not a new cancellation mechanism). A timed-out task MUST NOT write a cache entry (a hang is not a successful build), and on timeout the container/process is cleaned up (no orphaned container/volume), even if the timeout fires during the task's own cleanup. Durations use a documented format (30s,5m); invalid values are rejected at validation time. No timeout configured → behavior is identical to today (additive). Timeout does not participate in cache identity (ADR-0002). Service readiness timeouts are a separate, deferred concern.Together with the container-runtime-options slice, this replaces the NOTE-block + manual
--test-timeoutworkaround on the affected sandbox test task.References:
specs/task-timeout/spec.md(US1, US2, FR-001–007);docs/adr/0002.Acceptance criteria
timeoutfails within the timeout window rather than hanging, reported with a timeout reason (SC-001).timeoutoverrides a global--timeout; a task with no own timeout fails at the global ceiling (SC-003).Blocked by