Diff v1 → v2
v1: bot backfill · 2026-06-09 09:31:56
v2: bot legacy · 2026-07-28T06:30:55Z
# Subagents and Context Injection The most expensive resource in an agentic workflow isn't money or tokens — it's **context-window real estate.** Subagents isolate it; context injection keeps it clean. ## Why subagents **Focused, fresh context.** The orchestrator accumulates spec, plan, retrospectives, tool outputs. Past a threshold, attention dilutes — the orchestrator's own version of [[The One-Shot Problem]]. A subagent starts clean: one task, its files, its constraints. It finishes, returns, disappears. **Parallelism.** `### Wave N (parallel)` dispatches several tasks at once. Wall-clock = slowest task in the wave, not sum. **Specialised reviewers.** An adversarial reviewer subagent doesn't share context with the implementer it reviews. See [[Trust but Verify]]. ## The failure mode: re-exploration Naive invocation: "Implement `Foo.Bar`. Figure out what you need." The subagent then burns 30-70% of its budget rediscovering things the orchestrator already knows: greps, file reads, "what's the existing pattern?" By the time it writes code, its context is two-thirds full of files it didn't need. The orchestrator has the map. The map should be _handed down_, not rediscovered. ## Context injection Each task in `tasks.md` carries a `[ctx: ...]` annotation: ``` - [ ] T012 [P] [deps: T003] @sonnet [ctx: src/foo.ts:10-40, src/types.ts:1-30] Implement Foo.Bar ``` - The orchestrator (`/implement`) does: + The orchestrator (`/speckit.implement`) does: ```mermaid sequenceDiagram participant Orch participant FS participant Sub Orch->>FS: Read src/foo.ts:10-40 FS-->>Orch: 30 lines Orch->>FS: Read src/types.ts:1-30 FS-->>Orch: 30 lines Orch->>Sub: Prompt + ## Pre-Fetched Context (60 lines inlined) Note over Sub: No grep, no glob, no extra reads Sub->>Sub: Implement Foo.Bar Sub-->>Orch: Diff ``` Subagent prompt contains the **actual file contents** under `## Pre-Fetched Context`, not paths. Instruction: > "This is your complete context. Do NOT grep, glob, or read files outside the listed paths. If genuinely insufficient, ABORT with `CONTEXT_INSUFFICIENT: <reason>`." Token usage drops 30-70%. Latency drops. Output focuses. Cost falls. ## The escape hatch If the orchestrator picked the wrong ranges, the subagent must be able to say so: 1. Returns `CONTEXT_INSUFFICIENT: <reason>`, stops. 2. Orchestrator widens `[ctx: ...]`, retries once. 3. Second `CONTEXT_INSUFFICIENT` → escalate to user. Silent scope-expansion is the only failure mode this rules out. Both other outcomes (success, honest abort) are useful. ## Sizing `[ctx: ...]` **Include**: the exact function being changed (or its sibling), the types it references, one call-site demonstrating usage, any relevant schema/contract. **Exclude**: whole files, all tests, the README, adjacent unrelated functions. Aim 30-150 lines total. 500+ → break the task in two. ## Anti-patterns - **Whole-file context** — defeats the purpose; attention dilutes. - **No `[ctx]` for trivial tasks** — even trivial tasks over-read without a leash. - **"Let the subagent grep, it knows best"** — it has less information than the orchestrator, which read the spec and plan. > The orchestrator has the map. Hand it to the subagent. Don't make them redraw it.