How Model Profiles Are Resolved Across GSD Agents: A Complete Guide

GSD-Build resolves the model profile once at orchestration startup by reading .planning/config.json, applying optional per-agent overrides, and mapping the result to concrete Claude models via a lookup table, ensuring consistent AI tier usage across all spawned sub-agents.

The gsd-build/get-shit-done repository implements a deterministic model profile resolution system that governs which Claude model tier each agent uses during workflow execution. Understanding this resolution mechanism is essential for optimizing both performance and API costs across complex multi-agent orchestrations.

The Three-Step Model Profile Resolution Process

GSD-Build follows a strict three-step pipeline to determine which model every agent will use. This process is documented in get-shit-done/references/model-profile-resolution.md and executed once at the beginning of each orchestration run.

Step 1: Reading the Project-Wide Configuration

The system first attempts to read the model_profile field from .planning/config.json. If the file is missing or the field is absent, it defaults to balanced.

MODEL_PROFILE=$(cat .planning/config.json 2>/dev/null \
  | grep -o '"model_profile"[[:space:]]*:[[:space:]]*"[^"]*"' \
  | grep -o '"[^"]*"$' | tr -d '"' || echo "balanced")

This resolution happens once and the value is cached for the lifetime of the run.

Step 2: Applying Per-Agent Overrides

If the configuration contains a model_overrides map, the system checks for an entry matching the specific agent being spawned. This allows fine-grained control without changing the global profile.

{
  "model_profile": "balanced",
  "model_overrides": {
    "gsd-executor": "opus",
    "gsd-planner": "haiku"
  }
}

In this example, gsd-executor would use the Opus tier despite the global balanced setting, while gsd-planner would use Haiku.

Step 3: Mapping to Concrete Models

Finally, the system consults the lookup table defined in get-shit-done/references/model-profiles.md to translate the abstract profile name into a specific Claude model identifier.

Agent quality balanced budget
gsd-planner opus opus sonnet
gsd-executor opus sonnet sonnet

For agents that normally run on Opus-tier models, GSD-Build substitutes the special value "inherit" instead of a hardcoded model name. This ensures the agent inherits the specific Opus version configured for the user's session, avoiding organization-level blocks on older Opus versions.

How the Resolution Pattern Ensures Consistency

The Resolution Pattern documented in get-shit-done/references/model-profile-resolution.md mandates that model profile resolution occurs exactly once at orchestration startup. This design prevents model switching mid-workflow, which could cause context window inconsistencies or unexpected API cost spikes.

When the orchestrator spawns sub-agents, it passes the resolved model value through the model parameter of the Task constructor:

resolved_model = resolve_model_profile(agent_type)   # executes steps 1-3

Task(
    prompt="Analyze the codebase structure...",
    subagent_type="gsd-planner",
    model=resolved_model   # "inherit", "sonnet", "haiku", etc.

)

This cached approach ensures that a balanced profile selected at startup remains balanced for every agent spawned during that run, regardless of when the Task is created.

Configuring Model Profiles in Practice

Resolving the Profile in Bash Scripts

For custom tooling that interacts with GSD-Build, you can implement the same resolution logic used by the core system:

#!/bin/bash

# Resolve once at orchestration start

MODEL_PROFILE=$(cat .planning/config.json 2>/dev/null \
  | grep -o '"model_profile"[[:space:]]*:[[:space:]]*"[^"]*"' \
  | grep -o '"[^"]*"$' | tr -d '"' || echo "balanced")

echo "Using model profile: $MODEL_PROFILE"
export MODEL_PROFILE

Spawning Agents with Profile-Aware Models

When implementing custom workflow steps, map the abstract profile to concrete models using the same logic as get-shit-done/references/model-profiles.md:


# Pseudo-code used in workflow files

def get_planner_model(profile):
    if profile == "quality":
        return "inherit"  # Inherits user's Opus version

    elif profile == "balanced":
        return "sonnet"
    else:  # budget

        return "haiku"

planner_model = get_planner_model(os.environ["MODEL_PROFILE"])

Task(
    prompt="Plan the next milestone...",
    subagent_type="gsd-planner",
    model=planner_model
)

Using Model Overrides for Specific Agents

To force a specific agent to use a different tier without changing the global profile, edit .planning/config.json:

{
  "model_profile": "balanced",
  "model_overrides": {
    "gsd-executor": "opus",
    "gsd-planner": "haiku"
  }
}

The orchestrator checks model_overrides before consulting the profile table, so gsd-executor will use Opus while other agents use the standard balanced mappings.

Summary

  • GSD-Build resolves model profiles once at orchestration startup and caches the result for the entire workflow run.
  • The resolution follows a three-step pipeline: read .planning/config.json, apply optional model_overrides, and map to concrete models via get-shit-done/references/model-profiles.md.
  • Default profile is balanced when no configuration is found.
  • Per-agent overrides allow specific agents to use different model tiers without affecting the global profile.
  • Special "inherit" value prevents Opus-tier agents from being blocked by organization policies, allowing them to use the user's configured Opus version.

Frequently Asked Questions

Where is the model profile configuration stored?

The primary configuration lives in .planning/config.json at the project root. This JSON file contains the model_profile field (defaulting to balanced if missing) and optionally a model_overrides map for per-agent customizations. The resolution logic is documented in get-shit-done/references/model-profile-resolution.md.

Can I override the model profile for specific agents only?

Yes. Add a model_overrides object to .planning/config.json with keys matching agent names (e.g., gsd-executor, gsd-planner). These entries take precedence over the global model_profile when spawning those specific agents, allowing you to force high-quality models for critical agents while keeping others on budget tiers.

What happens if the config.json file is missing?

If .planning/config.json is absent or unreadable, the system defaults to the balanced profile. This fallback behavior ensures workflows continue running without manual configuration, using mid-tier models defined in the get-shit-done/references/model-profiles.md lookup table.

How does GSD-Build handle Opus-tier model restrictions?

For agents that normally require Claude Opus, GSD-Build uses the special value "inherit" instead of a hardcoded model name. This allows the agent to inherit the specific Opus version configured for the user's session, preventing organization-level blocks that might occur if the system requested a specific older Opus version. This behavior is defined in the model profiles reference documentation.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →