Ecs rightsized planning
Right-sized ECS task def for read-only planning
Section titled “Right-sized ECS task def for read-only planning”Status: IMPLEMENTED. Built as designed below: a second 8 GB / 2 vCPU planning Fargate task def in
EcsAgentCluster, selected byworkflowIsReadOnlyin the ECS compute strategy. Full CDK build green (2999 tests). Deployed to a dev stack with--context compute_type=ecsand verified end-to-end on an ECS-substrate project (a read-only workflow runs on the planning def; a normal coding task still runs on the build def). Prompted by a read-only task on an ECS-substrate project failing at session-start because that stack had no ECS substrate provisioned — and, more fundamentally, by the question “does a clone-and-read task need the build box?” The sections below describe the shipped design; a few.ts:NNNline anchors are from the design snapshot and may have drifted.
1. Problem
Section titled “1. Problem”An ECS-configured repo (compute_type: ecs) runs every task on the one Fargate task
definition in EcsAgentCluster — the BUILD tier. Its size is measured, not guessed: a fully
parallel mise run build of this repo (agent:quality ‖ cdk:build ‖ cli:build ‖ docs:build, each
fanning out worker fleets) peaks ~31.6 GB and OOM-killed a 32 GB task. The build tier serialises
with MISE_JOBS=1, which brings the measured peak down to ~3.1 GB, so the shipped default is
4 vCPU / 16 GB — roughly 5x headroom over what it actually uses.
But a read-only workflow such as coding/pr-review-v1 clones and reads/greps to reach a
conclusion. It never builds. Running it on the build box is a large over-allocation for a
clone-and-read workload (and, on a stack that hasn’t provisioned ECS at all, it just fails at
session-start).
The current code has an explicit decision against the naive fix (orchestrator.ts:242–252): “do
NOT special-case read-only workflows to agentcore … a repo big enough to need the ECS build tier for
building is also big enough to OOM the fixed AgentCore microVM just reading it.” That reasoning is
about not routing a read-only task to the wrong substrate FAMILY (ECS repo → AgentCore). It
does not say reading needs the same size as building. This proposal threads that needle: same family
(ECS repo → ECS planning, so the OOM concern is respected), right-sized (a smaller task def, since
planning doesn’t build).
2. Proposal
Section titled “2. Proposal”Add a second, smaller Fargate task definition to EcsAgentCluster for read-only workflows,
and route by workflowIsReadOnly in the ECS compute strategy. Keep the 64 GB def for build
workflows.
2a. Construct — ecs-agent-cluster.ts
Section titled “2a. Construct — ecs-agent-cluster.ts”- Add a
planningTaskDefinition(a secondFargateTaskDefinition) alongside the existingtaskDefinition. Suggested size: 8 GB / 2 vCPU (valid ARM64 Fargate combo). Rationale: a clone + read + a bounded set of file reads into the model context; no parallel build storm. If 8 GB proves tight for a very large clone, 16 GB / 4 vCPU is the next step — but start small and size up on evidence (mirror the existing sizing-history discipline in the file).- It reuses the SAME container image, log group, task role, execution role, session role,
payload-bucket + artifacts-bucket grants, and env as the build def — the ONLY difference is
cpu/memoryLimitMiB. Factor the container definition into a small helper so both task defs share it (avoid drift in grants/env — the ECS-parity bugs in the history all came from one task role/env missing something the other had). - Do NOT set
BUILD_VERIFY_TIMEOUT_S: '3600'on the planning def (that’s a build-tier concern; a read-only planner never runs the post-agent build verify).
- It reuses the SAME container image, log group, task role, execution role, session role,
payload-bucket + artifacts-bucket grants, and env as the build def — the ONLY difference is
- Expose
planningTaskDefinition.taskDefinitionArnfrom the construct (new public field, mirrortaskDefinition).
2b. Stack wiring — agent.ts + task-orchestrator.ts
Section titled “2b. Stack wiring — agent.ts + task-orchestrator.ts”- Pass the new ARN into the orchestrator’s
ecsConfigasplanningTaskDefinitionArn(alongside the existingtaskDefinitionArnatagent.ts:704). - Orchestrator construct (
task-orchestrator.ts:271) injects a new env varECS_PLANNING_TASK_DEFINITION_ARNnext toECS_TASK_DEFINITION_ARN.
2c. Routing — strategies/ecs-strategy.ts
Section titled “2c. Routing — strategies/ecs-strategy.ts”startSessionalready receivesblueprintConfig; thread the workflow id (or a pre-computedreadOnlyboolean) into the strategy input.orchestrate-task.tsalready computesworkflowIsReadOnly(workflowId)for preflight (line 121) — pass that same boolean down.- In
RunTaskCommand(ecs-strategy.ts:206–208), select the task def:taskDefinition: readOnly ? ECS_PLANNING_TASK_DEFINITION_ARN ?? ECS_TASK_DEFINITION_ARN : ECS_TASK_DEFINITION_ARN. The?? ECS_TASK_DEFINITION_ARNfallback keeps it safe if the planning def isn’t wired (older deploy) — it just runs on the build def as today, never worse. - The session-start guard (
ecs-strategy.ts:100) stays as-is (it already fails honestly, with a clear message, when the ECS substrate isn’t provisioned at all).
3. What this does NOT change
Section titled “3. What this does NOT change”- Substrate family routing is unchanged — an ECS repo still plans on ECS (honors
orchestrator.ts:242); an AgentCore repo still plans on AgentCore. This is purely “which ECS task def,” not “which substrate.” - AgentCore repos are untouched — the AgentCore project this was verified on doesn’t go near this.
- No workflow logic changes. Read-only behaviour is substrate-agnostic; this only affects the box an ECS-repo planning task runs on.
4. Why it’s a separate workstream
Section titled “4. Why it’s a separate workstream”- It edits
ecs-agent-cluster.ts,agent.ts,task-orchestrator.ts,ecs-strategy.ts— all owned by the ECS-substrate workstream, which carries the context-gatedcompute_type=ecsdeploy. - It resolves a tension in
orchestrator.ts:242that that workstream authored — so that workstream should own the change + the sizing call. - Verifying it requires a
--context compute_type=ecsdeploy (provisions the Fargate substrate). The dev stack is currentlyComputeSubstrate: agentcore(no ECS resources), so this is a net-new infra deploy — appropriately that workstream’s call, not a side effect of this one.
5. Verification (done)
Section titled “5. Verification (done)”- Deployed with
--context compute_type=ecs(provisions both task defs). ✅ - A read-only workflow on the ECS-substrate project → the task ran on the 8 GB planning def
(confirmed via the ECS task’s
taskDefinitionArn), emitted a plan, proposal posted. No OOM. ✅ - A normal coding task on the same repo → ran on the build def (build def still selected for non-read-only workflows). ✅
- Shared container helper (
makeTaskDef+ onebaseEnvironment) keeps env/grants identical across both defs, so the two stay at parity (Linear OAuth reaction fires, artifact delivers, payload fetches). Enforced by construction and asserted inecs-agent-cluster.test.ts. ✅ - AgentCore regression: a read-only workflow on an AgentCore repo still runs on the microVM,
unaffected by the
readOnlyflag (AgentCore ignores it). ✅
6. Open sizing question (starting point: 8 GB)
Section titled “6. Open sizing question (starting point: 8 GB)”8 GB / 2 vCPU is the initial size. If a very large ECS-onboarded repo makes a read-only
clone + read approach the cap, size up in 8 GB steps on Container Insights MemoryUtilized evidence
(the same empirical method the build def was arrived at) — bump the PlanningTaskDef cpu/mem
in ecs-agent-cluster.ts. No code path change is needed to grow it.