What to build
Let tasks and services declare an optional resources block (cpus, memory), enforced on both container runtimes. Enforcement-only for this release. On Docker, translate to host-config CPU (NanoCpus) and memory limits; on Kubernetes, translate to container resources.requests and resources.limits (request set equal to limit — no split requests/limits form for now). Units follow Kubernetes conventions: CPU as cores or millicores (2, 500m), memory as Mi/Gi. A local (non-container) task with resources must not fail — enforcement is best-effort/none and the value serves only as a scheduling hint (dry-run/explain should note non-enforcement). Invalid values (unparseable units, requests > limits) are rejected at validation time. cpus over host/cluster capacity → warn-and-run, never clamp (on k8s an over-capacity request leaves the pod Pending — k8s's own behavior, surfaced by the existing running-state wait). No resources declared → byte-identical behavior to today (additive). Resources do not participate in cache identity (ADR-0002).
Out of scope: Layer-2 resource-aware local scheduling (CPU-budget admission) is deferred — --concurrency is unchanged. Do not implement it in this slice.
References: specs/task-resources/spec.md (US1, US2, FR-001–005, 007, 008; US3/FR-006 explicitly deferred); docs/adr/0002.
Acceptance criteria
Blocked by
- None - can start immediately.
What to build
Let tasks and services declare an optional
resourcesblock (cpus,memory), enforced on both container runtimes. Enforcement-only for this release. On Docker, translate to host-config CPU (NanoCpus) and memory limits; on Kubernetes, translate to containerresources.requestsandresources.limits(request set equal to limit — no split requests/limits form for now). Units follow Kubernetes conventions: CPU as cores or millicores (2,500m), memory asMi/Gi. A local (non-container) task withresourcesmust not fail — enforcement is best-effort/none and the value serves only as a scheduling hint (dry-run/explainshould note non-enforcement). Invalid values (unparseable units, requests > limits) are rejected at validation time.cpusover host/cluster capacity → warn-and-run, never clamp (on k8s an over-capacity request leaves the pod Pending — k8s's own behavior, surfaced by the existing running-state wait). Noresourcesdeclared → byte-identical behavior to today (additive). Resources do not participate in cache identity (ADR-0002).Out of scope: Layer-2 resource-aware local scheduling (CPU-budget admission) is deferred —
--concurrencyis unchanged. Do not implement it in this slice.References:
specs/task-resources/spec.md(US1, US2, FR-001–005, 007, 008; US3/FR-006 explicitly deferred);docs/adr/0002.Acceptance criteria
resourcesproduces a container whose CPU (NanoCpus) and memory limits match the declaration (SC-001).resourcesproduces a container spec with matchingrequests/limits(request = limit) (SC-002).resourcesblock applies to services on both runtimes (US2).2/500m,Mi/Gi); invalid values and requests > limits are rejected at validation time.resourcesdoes not fail; the value is treated as a hint only.cpusover capacity warns and runs (no clamp).--concurrencybehavior is unchanged.resourcesbehaves identically to the prior version (SC-004).Blocked by