# How gsd-build Maintains Context Efficiency Across Subagents During Phase Execution

> Discover how gsd-build ensures context efficiency across subagents by passing only file paths. Learn how this approach prevents context-window bloat for optimal performance.

- Repository: [GSD/get-shit-done](https://github.com/gsd-build/get-shit-done)
- Tags: internals
- Published: 2026-02-16

---

**gsd-build solves context-window bloat by using a thin orchestrator that passes only file paths to self-contained subagents, allowing each agent to load its own 200KB context window independently.**

The `gsd-build/get-shit-done` repository implements a sophisticated multi-agent architecture designed to maximize **context efficiency across subagents** during complex phase execution. By decoupling the orchestration logic from execution logic, the system ensures that no single agent carries the cumulative weight of entire project histories, templates, and execution plans.

## The Context Efficiency Challenge in Multi-Agent Systems

Large language model applications face a critical constraint: fixed context windows. When orchestrating multiple subagents to execute complex phases—each potentially requiring access to templates, checkpoints, and historical state—the risk of **context bloat** becomes severe. Traditional approaches embed all necessary content directly into prompts, quickly exhausting available tokens and degrading model performance.

## The Thin Orchestrator Pattern

gsd-build addresses this through a strict separation of concerns between the orchestrator and executors. The orchestrator maintains minimal state—just enough to coordinate—while pushing all heavy context loading to ephemeral subagents.

### Minimal State in the execute-phase Workflow

The `execute-phase` workflow, defined in [`get-shit-done/workflows/execute-phase.md`](https://github.com/gsd-build/get-shit-done/blob/main/get-shit-done/workflows/execute-phase.md), explicitly adheres to the principle: "Orchestrator coordinates, not executes." The workflow only retains identifiers necessary to discover plans, group them into execution waves, and spawn specialized agents.

```yaml

# get-shit-done/workflows/execute-phase.md

Task(
  subagent_type="gsd-executor",
  model="{executor_model}",
  prompt="
    <objective>
      Execute plan {plan_number} of phase {phase_number}-{phase_name}.
    </objective>

    <files_to_read>
      - Plan: {phase_dir}/{plan_file}
      - State: .planning/STATE.md
    </files_to_read>
  "
)

```

Notice that the orchestrator passes only file paths (`{phase_dir}/{plan_file}`) and state references, not the actual content of those files.

## Fresh Context Windows for Subagents

Each subagent spawned by the orchestrator receives a clean 200KB context window. This isolation prevents the accumulation of execution history that typically bloats long-running sessions.

### The gsd-executor Agent Architecture

The `gsd-executor` agent, defined in [`agents/gsd-executor.md`](https://github.com/gsd-build/get-shit-done/blob/main/agents/gsd-executor.md), operates as a self-contained unit responsible for atomic plan execution. Rather than receiving context through the prompt, it actively loads necessary resources using the `Read` tool after initialization.

```markdown

# get-shit-done/agents/gsd-executor.md

<step name="load_project_state" priority="first">
  Load execution context:
  ```bash
  INIT=$(node ~/.claude/get-shit-done/bin/gsd-tools.cjs init execute-phase "${PHASE}")
  ```

  Extract executor_model, phase_dir, and configuration from the JSON response.
</step>

<step name="load_plan">
  Read the plan file provided in your prompt context.
  Parse front-matter, objective, tasks, and dependencies.
</step>

```

### Path-Only References vs. Inline Content

The system enforces a strict "pass-paths-only" pattern. When the orchestrator spawns an executor, the `<execution_context>` block contains references to external files using the `@` prefix, but never injects their content directly.

```yaml
Task(
  subagent_type="gsd-executor",
  model="{executor_model}",
  prompt="
    <execution_context>
      @~/.claude/get-shit-done/workflows/execute-plan.md
      @~/.claude/get-shit-done/templates/summary.md
      @~/.claude/get-shit-done/references/checkpoints.md
    </execution_context>
  "
)

```

The subagent reads these files on-demand, maintaining its own context under the 200KB ceiling while the orchestrator remains lean.

## Practical Implementation Details

### Loading Context with gsd-tools.cjs

Both the orchestrator and subagents utilize the `gsd-tools.cjs` CLI utility located at `bin/gsd-tools.cjs` to fetch initialization data. This Node.js script provides a consistent interface for resolving phase directories, executor models, and state metadata without embedding large JSON payloads into prompts.

```bash

# Used by both orchestrator and executors

node ~/.claude/get-shit-done/bin/gsd-tools.cjs init execute-phase "${PHASE}"

```

### Recovery Patterns for Main Session

The [`docs/USER-GUIDE.md`](https://github.com/gsd-build/get-shit-done/blob/main/docs/USER-GUIDE.md) explicitly documents the context-efficiency design, instructing users to clear the main Claude window between large commands. Because every subagent receives a fresh 200KB window, the main session can be safely cleared with `/clear` to restore context quality without losing progress. The `/gsd:resume-work` command then restores the saved state.

This pattern ensures that **context efficiency across subagents** remains high even during long-running phase executions with multiple waves.

## Summary

- **Thin orchestrator architecture**: The `execute-phase` workflow maintains minimal state, coordinating execution without carrying full plan contents.
- **Path-only delegation**: Subagents receive file references (`@path/to/file`) rather than inline content, loading resources independently via the `Read` tool.
- **Fresh 200KB windows**: Each `gsd-executor` spawns with a clean context, preventing accumulation of execution history.
- **Shared tooling**: The `gsd-tools.cjs` utility provides consistent initialization data without bloating prompts.
- **Recovery mechanisms**: Users can `/clear` the main session and use `/gsd:resume-work` to maintain context quality across long phases.

## Frequently Asked Questions

### What is the maximum context window for subagents in gsd-build?

Each subagent, such as the `gsd-executor`, operates within a **200KB context window**. This limit is enforced by design to ensure that no single agent accumulates excessive execution history or file contents, maintaining high performance and response quality throughout the phase execution.

### How does the orchestrator avoid context bloat when spawning multiple waves?

The orchestrator follows a strict **"coordinates, not executes"** principle defined in [`get-shit-done/workflows/execute-phase.md`](https://github.com/gsd-build/get-shit-done/blob/main/get-shit-done/workflows/execute-phase.md). It only maintains identifiers for plans and wave groupings, passing **file paths rather than content** to subagents. This ensures the orchestrator's context remains lean regardless of how many execution waves are coordinated.

### What happens if the main Claude session runs out of context during a phase?

Users can safely execute `/clear` to reset the main session's context window without losing progress. Because gsd-build persists state to disk (via [`.planning/STATE.md`](https://github.com/gsd-build/get-shit-done/blob/main/.planning/STATE.md) and other checkpoints), the `/gsd:resume-work` command restores the exact execution position. This recovery pattern is documented in [`docs/USER-GUIDE.md`](https://github.com/gsd-build/get-shit-done/blob/main/docs/USER-GUIDE.md) and leverages the fact that subagents already operate in isolated context windows.

### How do subagents access templates and checkpoints without inline content?

Subagents use the **path-only reference pattern** with the `@` prefix (e.g., `@~/.claude/get-shit-done/templates/summary.md`). When spawned, the subagent receives these references in its `<execution_context>` block and then invokes the `Read` tool itself to load the content. This "lazy loading" approach keeps the orchestrator's prompts small while ensuring subagents have full access to necessary resources within their own 200KB windows.