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 optionalmodel_overrides, and map to concrete models viaget-shit-done/references/model-profiles.md. - Default profile is
balancedwhen 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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →