feat(profiles): add model profiles for GSD agents

Adds switchable model profiles (quality/balanced/budget) to control
which Claude model each agent uses, balancing quality vs token spend.

New files:
- get-shit-done/references/model-profiles.md - profile lookup table
- commands/gsd/set-profile.md - runtime profile switching

Updated orchestrators to resolve model before spawning agents:
- new-project, new-milestone (7 calls each)
- plan-phase (4 calls)
- execute-phase (3 calls)
- audit-milestone, debug, research-phase, quick (1-2 calls each)
- workflows: execute-phase, execute-plan, verify-work, map-codebase

Profile stored in .planning/config.json as model_profile.
Default: "balanced" (Opus for planning, Sonnet for execution).

Closes #160

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Lex Christopherson
2026-01-20 01:26:02 -06:00
parent 9099d48495
commit 4218f8666a
17 changed files with 498 additions and 39 deletions

View File

@@ -485,7 +485,8 @@ You're never locked in. The system adapts.
| Command | What it does |
|---------|--------------|
| `/gsd:settings` | Toggle workflow agents (research, plan checker, verifier) |
| `/gsd:settings` | Configure model profile and workflow agents |
| `/gsd:set-profile <profile>` | Switch model profile (quality/balanced/budget) |
| `/gsd:add-todo [desc]` | Capture idea for later |
| `/gsd:check-todos` | List pending todos |
| `/gsd:debug [desc]` | Systematic debugging with persistent state |
@@ -506,6 +507,23 @@ GSD stores project settings in `.planning/config.json`. Configure during `/gsd:n
| `mode` | `yolo`, `interactive` | `interactive` | Auto-approve vs confirm at each step |
| `depth` | `quick`, `standard`, `comprehensive` | `standard` | Planning thoroughness (phases × plans) |
### Model Profiles
Control which Claude model each agent uses. Balance quality vs token spend.
| Profile | Planning | Execution | Verification |
|---------|----------|-----------|--------------|
| `quality` | Opus | Opus | Sonnet |
| `balanced` (default) | Opus | Sonnet | Sonnet |
| `budget` | Sonnet | Sonnet | Haiku |
Switch profiles:
```
/gsd:set-profile budget
```
Or configure via `/gsd:settings`.
### Workflow Agents
These spawn additional agents during planning/execution. They improve quality but add tokens and time.

View File

@@ -39,6 +39,24 @@ Glob: .planning/phases/*/*-VERIFICATION.md
<process>
## 0. Resolve Model Profile
Read model profile for agent spawning:
```bash
MODEL_PROFILE=$(cat .planning/config.json 2>/dev/null | grep -o '"model_profile"[[:space:]]*:[[:space:]]*"[^"]*"' | grep -o '"[^"]*"$' | tr -d '"' || echo "balanced")
```
Default to "balanced" if not set.
**Model lookup table:**
| Agent | quality | balanced | budget |
|-------|---------|----------|--------|
| gsd-integration-checker | sonnet | sonnet | haiku |
Store resolved model for use in Task call below.
## 1. Determine Milestone Scope
```bash
@@ -83,7 +101,8 @@ Phase exports: {from SUMMARYs}
API routes: {routes created}
Verify cross-phase wiring and E2E user flows.",
subagent_type="gsd-integration-checker"
subagent_type="gsd-integration-checker",
model="{integration_checker_model}"
)
```

View File

@@ -28,6 +28,24 @@ ls .planning/debug/*.md 2>/dev/null | grep -v resolved | head -5
<process>
## 0. Resolve Model Profile
Read model profile for agent spawning:
```bash
MODEL_PROFILE=$(cat .planning/config.json 2>/dev/null | grep -o '"model_profile"[[:space:]]*:[[:space:]]*"[^"]*"' | grep -o '"[^"]*"$' | tr -d '"' || echo "balanced")
```
Default to "balanced" if not set.
**Model lookup table:**
| Agent | quality | balanced | budget |
|-------|---------|----------|--------|
| gsd-debugger | opus | sonnet | sonnet |
Store resolved model for use in Task calls below.
## 1. Check Active Sessions
If active sessions exist AND no $ARGUMENTS:
@@ -82,6 +100,7 @@ Create: .planning/debug/{slug}.md
Task(
prompt=filled_prompt,
subagent_type="gsd-debugger",
model="{debugger_model}",
description="Debug {slug}"
)
```
@@ -134,6 +153,7 @@ goal: find_and_fix
Task(
prompt=continuation_prompt,
subagent_type="gsd-debugger",
model="{debugger_model}",
description="Continue debug {slug}"
)
```

View File

@@ -38,6 +38,24 @@ Phase: $ARGUMENTS
</context>
<process>
0. **Resolve Model Profile**
Read model profile for agent spawning:
```bash
MODEL_PROFILE=$(cat .planning/config.json 2>/dev/null | grep -o '"model_profile"[[:space:]]*:[[:space:]]*"[^"]*"' | grep -o '"[^"]*"$' | tr -d '"' || echo "balanced")
```
Default to "balanced" if not set.
**Model lookup table:**
| Agent | quality | balanced | budget |
|-------|---------|----------|--------|
| gsd-executor | opus | sonnet | sonnet |
| gsd-verifier | sonnet | sonnet | haiku |
Store resolved models for use in Task calls below.
1. **Validate phase exists**
- Find phase directory matching argument
- Count PLAN.md files
@@ -248,9 +266,9 @@ STATE_CONTENT=$(cat .planning/STATE.md)
Spawn all plans in a wave with a single message containing multiple Task calls, with inlined content:
```
Task(prompt="Execute plan at {plan_01_path}\n\nPlan:\n{plan_01_content}\n\nProject state:\n{state_content}", subagent_type="gsd-executor")
Task(prompt="Execute plan at {plan_02_path}\n\nPlan:\n{plan_02_content}\n\nProject state:\n{state_content}", subagent_type="gsd-executor")
Task(prompt="Execute plan at {plan_03_path}\n\nPlan:\n{plan_03_content}\n\nProject state:\n{state_content}", subagent_type="gsd-executor")
Task(prompt="Execute plan at {plan_01_path}\n\nPlan:\n{plan_01_content}\n\nProject state:\n{state_content}", subagent_type="gsd-executor", model="{executor_model}")
Task(prompt="Execute plan at {plan_02_path}\n\nPlan:\n{plan_02_content}\n\nProject state:\n{state_content}", subagent_type="gsd-executor", model="{executor_model}")
Task(prompt="Execute plan at {plan_03_path}\n\nPlan:\n{plan_03_content}\n\nProject state:\n{state_content}", subagent_type="gsd-executor", model="{executor_model}")
```
All three run in parallel. Task tool blocks until all complete.

View File

@@ -122,6 +122,26 @@ git add .planning/PROJECT.md .planning/STATE.md
git commit -m "docs: start milestone v[X.Y] [Name]"
```
## Phase 6.5: Resolve Model Profile
Read model profile for agent spawning:
```bash
MODEL_PROFILE=$(cat .planning/config.json 2>/dev/null | grep -o '"model_profile"[[:space:]]*:[[:space:]]*"[^"]*"' | grep -o '"[^"]*"$' | tr -d '"' || echo "balanced")
```
Default to "balanced" if not set.
**Model lookup table:**
| Agent | quality | balanced | budget |
|-------|---------|----------|--------|
| gsd-project-researcher | opus | sonnet | haiku |
| gsd-research-synthesizer | sonnet | sonnet | haiku |
| gsd-roadmapper | opus | sonnet | sonnet |
Store resolved models for use in Task calls below.
## Phase 7: Research Decision
Use AskUserQuestion:
@@ -198,7 +218,7 @@ Your STACK.md feeds into roadmap creation. Be prescriptive:
Write to: .planning/research/STACK.md
Use template: ~/.claude/get-shit-done/templates/research-project/STACK.md
</output>
", subagent_type="gsd-project-researcher", description="Stack research")
", subagent_type="gsd-project-researcher", model="{researcher_model}", description="Stack research")
Task(prompt="
<research_type>
@@ -239,7 +259,7 @@ Your FEATURES.md feeds into requirements definition. Categorize clearly:
Write to: .planning/research/FEATURES.md
Use template: ~/.claude/get-shit-done/templates/research-project/FEATURES.md
</output>
", subagent_type="gsd-project-researcher", description="Features research")
", subagent_type="gsd-project-researcher", model="{researcher_model}", description="Features research")
Task(prompt="
<research_type>
@@ -281,7 +301,7 @@ Your ARCHITECTURE.md informs phase structure in roadmap. Include:
Write to: .planning/research/ARCHITECTURE.md
Use template: ~/.claude/get-shit-done/templates/research-project/ARCHITECTURE.md
</output>
", subagent_type="gsd-project-researcher", description="Architecture research")
", subagent_type="gsd-project-researcher", model="{researcher_model}", description="Architecture research")
Task(prompt="
<research_type>
@@ -319,7 +339,7 @@ Your PITFALLS.md prevents mistakes in roadmap/planning. For each pitfall:
Write to: .planning/research/PITFALLS.md
Use template: ~/.claude/get-shit-done/templates/research-project/PITFALLS.md
</output>
", subagent_type="gsd-project-researcher", description="Pitfalls research")
", subagent_type="gsd-project-researcher", model="{researcher_model}", description="Pitfalls research")
```
After all 4 agents complete, spawn synthesizer to create SUMMARY.md:
@@ -343,7 +363,7 @@ Write to: .planning/research/SUMMARY.md
Use template: ~/.claude/get-shit-done/templates/research-project/SUMMARY.md
Commit after writing.
</output>
", subagent_type="gsd-research-synthesizer", description="Synthesize research")
", subagent_type="gsd-research-synthesizer", model="{synthesizer_model}", description="Synthesize research")
```
Display research complete banner and key findings:
@@ -548,7 +568,7 @@ Create roadmap for milestone v[X.Y]:
Write files first, then return. This ensures artifacts persist even if context is lost.
</instructions>
", subagent_type="gsd-roadmapper", description="Create roadmap")
", subagent_type="gsd-roadmapper", model="{roadmapper_model}", description="Create roadmap")
```
**Handle roadmapper return:**
@@ -615,7 +635,7 @@ Use AskUserQuestion:
Update the roadmap based on feedback. Edit files in place.
Return ROADMAP REVISED with changes made.
</revision>
", subagent_type="gsd-roadmapper", description="Revise roadmap")
", subagent_type="gsd-roadmapper", model="{roadmapper_model}", description="Revise roadmap")
```
- Present revised roadmap
- Loop until user approves

View File

@@ -373,6 +373,26 @@ EOF
**Note:** Run `/gsd:settings` anytime to update these preferences.
## Phase 5.5: Resolve Model Profile
Read model profile for agent spawning:
```bash
MODEL_PROFILE=$(cat .planning/config.json 2>/dev/null | grep -o '"model_profile"[[:space:]]*:[[:space:]]*"[^"]*"' | grep -o '"[^"]*"$' | tr -d '"' || echo "balanced")
```
Default to "balanced" if not set.
**Model lookup table:**
| Agent | quality | balanced | budget |
|-------|---------|----------|--------|
| gsd-project-researcher | opus | sonnet | haiku |
| gsd-research-synthesizer | sonnet | sonnet | haiku |
| gsd-roadmapper | opus | sonnet | sonnet |
Store resolved models for use in Task calls below.
## Phase 6: Research Decision
Use AskUserQuestion:
@@ -453,7 +473,7 @@ Your STACK.md feeds into roadmap creation. Be prescriptive:
Write to: .planning/research/STACK.md
Use template: ~/.claude/get-shit-done/templates/research-project/STACK.md
</output>
", subagent_type="gsd-project-researcher", description="Stack research")
", subagent_type="gsd-project-researcher", model="{researcher_model}", description="Stack research")
Task(prompt="
<research_type>
@@ -492,7 +512,7 @@ Your FEATURES.md feeds into requirements definition. Categorize clearly:
Write to: .planning/research/FEATURES.md
Use template: ~/.claude/get-shit-done/templates/research-project/FEATURES.md
</output>
", subagent_type="gsd-project-researcher", description="Features research")
", subagent_type="gsd-project-researcher", model="{researcher_model}", description="Features research")
Task(prompt="
<research_type>
@@ -531,7 +551,7 @@ Your ARCHITECTURE.md informs phase structure in roadmap. Include:
Write to: .planning/research/ARCHITECTURE.md
Use template: ~/.claude/get-shit-done/templates/research-project/ARCHITECTURE.md
</output>
", subagent_type="gsd-project-researcher", description="Architecture research")
", subagent_type="gsd-project-researcher", model="{researcher_model}", description="Architecture research")
Task(prompt="
<research_type>
@@ -570,7 +590,7 @@ Your PITFALLS.md prevents mistakes in roadmap/planning. For each pitfall:
Write to: .planning/research/PITFALLS.md
Use template: ~/.claude/get-shit-done/templates/research-project/PITFALLS.md
</output>
", subagent_type="gsd-project-researcher", description="Pitfalls research")
", subagent_type="gsd-project-researcher", model="{researcher_model}", description="Pitfalls research")
```
After all 4 agents complete, spawn synthesizer to create SUMMARY.md:
@@ -594,7 +614,7 @@ Write to: .planning/research/SUMMARY.md
Use template: ~/.claude/get-shit-done/templates/research-project/SUMMARY.md
Commit after writing.
</output>
", subagent_type="gsd-research-synthesizer", description="Synthesize research")
", subagent_type="gsd-research-synthesizer", model="{synthesizer_model}", description="Synthesize research")
```
Display research complete banner and key findings:
@@ -799,7 +819,7 @@ Create roadmap:
Write files first, then return. This ensures artifacts persist even if context is lost.
</instructions>
", subagent_type="gsd-roadmapper", description="Create roadmap")
", subagent_type="gsd-roadmapper", model="{roadmapper_model}", description="Create roadmap")
```
**Handle roadmapper return:**
@@ -875,7 +895,7 @@ Use AskUserQuestion:
Update the roadmap based on feedback. Edit files in place.
Return ROADMAP REVISED with changes made.
</revision>
", subagent_type="gsd-roadmapper", description="Revise roadmap")
", subagent_type="gsd-roadmapper", model="{roadmapper_model}", description="Revise roadmap")
```
- Present revised roadmap
- Loop until user approves

View File

@@ -42,7 +42,7 @@ Normalize phase input in step 2 before any directory lookups.
<process>
## 1. Validate Environment
## 1. Validate Environment and Resolve Model Profile
```bash
ls .planning/ 2>/dev/null
@@ -50,6 +50,24 @@ ls .planning/ 2>/dev/null
**If not found:** Error - user should run `/gsd:new-project` first.
**Resolve model profile for agent spawning:**
```bash
MODEL_PROFILE=$(cat .planning/config.json 2>/dev/null | grep -o '"model_profile"[[:space:]]*:[[:space:]]*"[^"]*"' | grep -o '"[^"]*"$' | tr -d '"' || echo "balanced")
```
Default to "balanced" if not set.
**Model lookup table:**
| Agent | quality | balanced | budget |
|-------|---------|----------|--------|
| gsd-phase-researcher | opus | sonnet | haiku |
| gsd-planner | opus | opus | sonnet |
| gsd-plan-checker | sonnet | sonnet | haiku |
Store resolved models for use in Task calls below.
## 2. Parse and Normalize Arguments
Extract from $ARGUMENTS:
@@ -190,6 +208,7 @@ Write research findings to: {phase_dir}/{phase}-RESEARCH.md
Task(
prompt=research_prompt,
subagent_type="gsd-phase-researcher",
model="{researcher_model}",
description="Research Phase {phase}"
)
```
@@ -298,6 +317,7 @@ Before returning PLANNING COMPLETE:
Task(
prompt=filled_prompt,
subagent_type="gsd-planner",
model="{planner_model}",
description="Plan Phase {phase}"
)
```
@@ -369,6 +389,7 @@ Return one of:
Task(
prompt=checker_prompt,
subagent_type="gsd-plan-checker",
model="{checker_model}",
description="Verify Phase {phase} plans"
)
```
@@ -426,6 +447,7 @@ Return what changed.
Task(
prompt=revision_prompt,
subagent_type="gsd-planner",
model="{planner_model}",
description="Revise Phase {phase} plans"
)
```

View File

@@ -52,6 +52,7 @@ If missing both ROADMAP.md and PROJECT.md: suggest `/gsd:new-project`.
- Read `.planning/STATE.md` for living memory (position, decisions, issues)
- Read `.planning/ROADMAP.md` for phase structure and objectives
- Read `.planning/PROJECT.md` for current state (What This Is, Core Value, Requirements)
- Read `.planning/config.json` for settings (model_profile, workflow toggles)
</step>
<step name="recent">
@@ -80,6 +81,7 @@ If missing both ROADMAP.md and PROJECT.md: suggest `/gsd:new-project`.
# [Project Name]
**Progress:** [████████░░] 8/10 plans complete
**Profile:** [quality/balanced/budget]
## Recent Work
- [Phase X, Plan Y]: [what was accomplished - 1 line]

View File

@@ -34,6 +34,27 @@ Orchestration is inline - no separate workflow file. Quick mode is deliberately
</context>
<process>
**Step 0: Resolve Model Profile**
Read model profile for agent spawning:
```bash
MODEL_PROFILE=$(cat .planning/config.json 2>/dev/null | grep -o '"model_profile"[[:space:]]*:[[:space:]]*"[^"]*"' | grep -o '"[^"]*"$' | tr -d '"' || echo "balanced")
```
Default to "balanced" if not set.
**Model lookup table:**
| Agent | quality | balanced | budget |
|-------|---------|----------|--------|
| gsd-planner | opus | opus | sonnet |
| gsd-executor | opus | sonnet | sonnet |
Store resolved models for use in Task calls below.
---
**Step 1: Pre-flight validation**
Check that an active GSD project exists:
@@ -145,6 +166,7 @@ Return: ## PLANNING COMPLETE with plan path
</output>
",
subagent_type="gsd-planner",
model="{planner_model}",
description="Quick plan: ${DESCRIPTION}"
)
```
@@ -178,6 +200,7 @@ Project state: @.planning/STATE.md
</constraints>
",
subagent_type="gsd-executor",
model="{executor_model}",
description="Execute: ${DESCRIPTION}"
)
```

View File

@@ -31,6 +31,24 @@ Normalize phase input in step 1 before any directory lookups.
<process>
## 0. Resolve Model Profile
Read model profile for agent spawning:
```bash
MODEL_PROFILE=$(cat .planning/config.json 2>/dev/null | grep -o '"model_profile"[[:space:]]*:[[:space:]]*"[^"]*"' | grep -o '"[^"]*"$' | tr -d '"' || echo "balanced")
```
Default to "balanced" if not set.
**Model lookup table:**
| Agent | quality | balanced | budget |
|-------|---------|----------|--------|
| gsd-phase-researcher | opus | sonnet | haiku |
Store resolved model for use in Task calls below.
## 1. Normalize and Validate Phase
```bash
@@ -132,6 +150,7 @@ Write to: .planning/phases/${PHASE}-{slug}/${PHASE}-RESEARCH.md
Task(
prompt=filled_prompt,
subagent_type="gsd-phase-researcher",
model="{researcher_model}",
description="Research Phase {phase}"
)
```
@@ -165,6 +184,7 @@ Research file: @.planning/phases/${PHASE}-{slug}/${PHASE}-RESEARCH.md
Task(
prompt=continuation_prompt,
subagent_type="gsd-phase-researcher",
model="{researcher_model}",
description="Continue research Phase {phase}"
)
```

106
commands/gsd/set-profile.md Normal file
View File

@@ -0,0 +1,106 @@
---
name: set-profile
description: Switch model profile for GSD agents (quality/balanced/budget)
arguments:
- name: profile
description: "Profile name: quality, balanced, or budget"
required: true
---
<objective>
Switch the model profile used by GSD agents. This controls which Claude model each agent uses, balancing quality vs token spend.
</objective>
<profiles>
| Profile | Description |
|---------|-------------|
| **quality** | Opus everywhere except read-only verification |
| **balanced** | Opus for planning, Sonnet for execution/verification (default) |
| **budget** | Sonnet for writing, Haiku for research/verification |
</profiles>
<process>
## 1. Validate argument
```
if $ARGUMENTS.profile not in ["quality", "balanced", "budget"]:
Error: Invalid profile "$ARGUMENTS.profile"
Valid profiles: quality, balanced, budget
STOP
```
## 2. Check for project
```bash
ls .planning/config.json 2>/dev/null
```
If no `.planning/` directory:
```
Error: No GSD project found.
Run /gsd:new-project first to initialize a project.
```
## 3. Update config.json
Read current config:
```bash
cat .planning/config.json
```
Update `model_profile` field (or add if missing):
```json
{
"model_profile": "$ARGUMENTS.profile"
}
```
Write updated config back to `.planning/config.json`.
## 4. Confirm
```
✓ Model profile set to: $ARGUMENTS.profile
Agents will now use:
[Show table from model-profiles.md for selected profile]
Next spawned agents will use the new profile.
```
</process>
<examples>
**Switch to budget mode:**
```
/gsd:set-profile budget
✓ Model profile set to: budget
Agents will now use:
| Agent | Model |
|-------|-------|
| gsd-planner | sonnet |
| gsd-executor | sonnet |
| gsd-verifier | haiku |
| ... | ... |
```
**Switch to quality mode:**
```
/gsd:set-profile quality
✓ Model profile set to: quality
Agents will now use:
| Agent | Model |
|-------|-------|
| gsd-planner | opus |
| gsd-executor | opus |
| gsd-verifier | sonnet |
| ... | ... |
```
</examples>

View File

@@ -1,6 +1,6 @@
---
name: gsd:settings
description: Configure GSD workflow toggles (research, plan checker, verifier)
description: Configure GSD workflow toggles and model profile
allowed-tools:
- Read
- Write
@@ -8,9 +8,9 @@ allowed-tools:
---
<objective>
Allow users to toggle workflow agents on/off via interactive settings.
Allow users to toggle workflow agents on/off and select model profile via interactive settings.
Updates `.planning/config.json` with workflow preferences that control whether research, plan checking, and verification agents are spawned.
Updates `.planning/config.json` with workflow preferences and model profile selection.
</objective>
<process>
@@ -33,6 +33,7 @@ Parse current values (default to `true` if not present):
- `workflow.research` — spawn researcher during plan-phase
- `workflow.plan_check` — spawn plan checker during plan-phase
- `workflow.verifier` — spawn verifier during execute-phase
- `model_profile` — which model each agent uses (default: `balanced`)
## 3. Present Settings
@@ -40,6 +41,16 @@ Use AskUserQuestion with current values shown:
```
AskUserQuestion([
{
question: "Which model profile for agents?",
header: "Model",
multiSelect: false,
options: [
{ label: "Quality", description: "Opus everywhere except verification (highest cost)" },
{ label: "Balanced (Recommended)", description: "Opus for planning, Sonnet for execution/verification" },
{ label: "Budget", description: "Sonnet for writing, Haiku for research/verification (lowest cost)" }
]
},
{
question: "Spawn Plan Researcher? (researches domain before planning)",
header: "Research",
@@ -74,11 +85,12 @@ AskUserQuestion([
## 4. Update Config
Merge new workflow settings into existing config.json:
Merge new settings into existing config.json:
```json
{
...existing_config,
"model_profile": "quality" | "balanced" | "budget",
"workflow": {
"research": true/false,
"plan_check": true/false,
@@ -100,23 +112,25 @@ Display:
| Setting | Value |
|----------------------|-------|
| Model Profile | {quality/balanced/budget} |
| Plan Researcher | {On/Off} |
| Plan Checker | {On/Off} |
| Execution Verifier | {On/Off} |
These settings apply to future /gsd:plan-phase and /gsd:execute-phase runs.
Override per-invocation with flags:
- /gsd:plan-phase --research (force research)
- /gsd:plan-phase --skip-research (skip research)
- /gsd:plan-phase --skip-verify (skip plan check)
Quick commands:
- /gsd:set-profile <profile> — switch model profile
- /gsd:plan-phase --research — force research
- /gsd:plan-phase --skip-research — skip research
- /gsd:plan-phase --skip-verify — skip plan check
```
</process>
<success_criteria>
- [ ] Current config read
- [ ] User presented with 3 toggle questions
- [ ] Config updated with workflow section
- [ ] User presented with 4 settings (profile + 3 toggles)
- [ ] Config updated with model_profile and workflow section
- [ ] Changes confirmed to user
</success_criteria>

View File

@@ -0,0 +1,73 @@
# Model Profiles
Model profiles control which Claude model each GSD agent uses. This allows balancing quality vs token spend.
## Profile Definitions
| Agent | `quality` | `balanced` | `budget` |
|-------|-----------|------------|----------|
| gsd-planner | opus | opus | sonnet |
| gsd-roadmapper | opus | sonnet | sonnet |
| gsd-executor | opus | sonnet | sonnet |
| gsd-phase-researcher | opus | sonnet | haiku |
| gsd-project-researcher | opus | sonnet | haiku |
| gsd-research-synthesizer | sonnet | sonnet | haiku |
| gsd-debugger | opus | sonnet | sonnet |
| gsd-codebase-mapper | sonnet | haiku | haiku |
| gsd-verifier | sonnet | sonnet | haiku |
| gsd-plan-checker | sonnet | sonnet | haiku |
| gsd-integration-checker | sonnet | sonnet | haiku |
## Profile Philosophy
**quality** - Maximum reasoning power
- Opus for all decision-making agents
- Sonnet for read-only verification
- Use when: quota available, critical architecture work
**balanced** (default) - Smart allocation
- Opus only for planning (where architecture decisions happen)
- Sonnet for execution and research (follows explicit instructions)
- Sonnet for verification (needs reasoning, not just pattern matching)
- Use when: normal development, good balance of quality and cost
**budget** - Minimal Opus usage
- Sonnet for anything that writes code
- Haiku for research and verification
- Use when: conserving quota, high-volume work, less critical phases
## Resolution Logic
Orchestrators resolve model before spawning:
```
1. Read .planning/config.json
2. Get model_profile (default: "balanced")
3. Look up agent in table above
4. Pass model parameter to Task call
```
## Switching Profiles
Runtime: `/gsd:set-profile <profile>`
Per-project default: Set in `.planning/config.json`:
```json
{
"model_profile": "balanced"
}
```
## Design Rationale
**Why Opus for gsd-planner?**
Planning involves architecture decisions, goal decomposition, and task design. This is where model quality has the highest impact.
**Why Sonnet for gsd-executor?**
Executors follow explicit PLAN.md instructions. The plan already contains the reasoning; execution is implementation.
**Why Sonnet (not Haiku) for verifiers in balanced?**
Verification requires goal-backward reasoning - checking if code *delivers* what the phase promised, not just pattern matching. Sonnet handles this well; Haiku may miss subtle gaps.
**Why Haiku for gsd-codebase-mapper?**
Read-only exploration and pattern extraction. No reasoning required, just structured output from file contents.

View File

@@ -13,7 +13,27 @@ Read config.json for planning behavior settings.
<process>
<step name="load_project_state" priority="first">
<step name="resolve_model_profile" priority="first">
Read model profile for agent spawning:
```bash
MODEL_PROFILE=$(cat .planning/config.json 2>/dev/null | grep -o '"model_profile"[[:space:]]*:[[:space:]]*"[^"]*"' | grep -o '"[^"]*"$' | tr -d '"' || echo "balanced")
```
Default to "balanced" if not set.
**Model lookup table:**
| Agent | quality | balanced | budget |
|-------|---------|----------|--------|
| gsd-executor | opus | sonnet | sonnet |
| gsd-verifier | sonnet | sonnet | haiku |
| general-purpose | — | — | — |
Store resolved models for use in Task calls below.
</step>
<step name="load_project_state">
Before any operation, read project state:
```bash
@@ -274,7 +294,7 @@ Plans with `autonomous: false` require user interaction.
1. **Spawn agent for checkpoint plan:**
```
Task(prompt="{subagent-task-prompt}", subagent_type="general-purpose")
Task(prompt="{subagent-task-prompt}", subagent_type="gsd-executor", model="{executor_model}")
```
2. **Agent runs until checkpoint:**
@@ -313,7 +333,8 @@ Plans with `autonomous: false` require user interaction.
```
Task(
prompt=filled_continuation_template,
subagent_type="general-purpose"
subagent_type="gsd-executor",
model="{executor_model}"
)
```
@@ -389,7 +410,8 @@ Phase goal: {goal from ROADMAP.md}
Check must_haves against actual codebase. Create VERIFICATION.md.
Verify what actually exists in the code.",
subagent_type="gsd-verifier"
subagent_type="gsd-verifier",
model="{verifier_model}"
)
```

View File

@@ -11,7 +11,25 @@ Read config.json for planning behavior settings.
<process>
<step name="load_project_state" priority="first">
<step name="resolve_model_profile" priority="first">
Read model profile for agent spawning:
```bash
MODEL_PROFILE=$(cat .planning/config.json 2>/dev/null | grep -o '"model_profile"[[:space:]]*:[[:space:]]*"[^"]*"' | grep -o '"[^"]*"$' | tr -d '"' || echo "balanced")
```
Default to "balanced" if not set.
**Model lookup table:**
| Agent | quality | balanced | budget |
|-------|---------|----------|--------|
| gsd-executor | opus | sonnet | sonnet |
Store resolved model for use in Task calls below.
</step>
<step name="load_project_state">
Before any operation, read project state:
```bash
@@ -219,7 +237,7 @@ No segmentation benefit - execute entirely in main
```
1. Run init_agent_tracking step first (see step below)
2. Use Task tool with subagent_type="gsd-executor":
2. Use Task tool with subagent_type="gsd-executor" and model="{executor_model}":
Prompt: "Execute plan at .planning/phases/{phase}-{plan}-PLAN.md
@@ -371,7 +389,7 @@ For Pattern A (fully autonomous) and Pattern C (decision-dependent), skip this s
B. If routing = Subagent:
```
Spawn Task tool with subagent_type="gsd-executor":
Spawn Task tool with subagent_type="gsd-executor" and model="{executor_model}":
Prompt: "Execute tasks [task numbers/names] from plan at [plan path].

View File

@@ -22,7 +22,25 @@ Documents are reference material for Claude when planning/executing. Always incl
<process>
<step name="check_existing" priority="first">
<step name="resolve_model_profile" priority="first">
Read model profile for agent spawning:
```bash
MODEL_PROFILE=$(cat .planning/config.json 2>/dev/null | grep -o '"model_profile"[[:space:]]*:[[:space:]]*"[^"]*"' | grep -o '"[^"]*"$' | tr -d '"' || echo "balanced")
```
Default to "balanced" if not set.
**Model lookup table:**
| Agent | quality | balanced | budget |
|-------|---------|----------|--------|
| gsd-codebase-mapper | sonnet | haiku | haiku |
Store resolved model for use in Task calls below.
</step>
<step name="check_existing">
Check if .planning/codebase/ already exists:
```bash
@@ -73,7 +91,7 @@ Continue to spawn_agents.
<step name="spawn_agents">
Spawn 4 parallel gsd-codebase-mapper agents.
Use Task tool with `subagent_type="gsd-codebase-mapper"` and `run_in_background=true` for parallel execution.
Use Task tool with `subagent_type="gsd-codebase-mapper"`, `model="{mapper_model}"`, and `run_in_background=true` for parallel execution.
**CRITICAL:** Use the dedicated `gsd-codebase-mapper` agent, NOT `Explore`. The mapper agent writes documents directly.
@@ -82,6 +100,7 @@ Use Task tool with `subagent_type="gsd-codebase-mapper"` and `run_in_background=
Task tool parameters:
```
subagent_type: "gsd-codebase-mapper"
model: "{mapper_model}"
run_in_background: true
description: "Map codebase tech stack"
```
@@ -104,6 +123,7 @@ Explore thoroughly. Write documents directly using templates. Return confirmatio
Task tool parameters:
```
subagent_type: "gsd-codebase-mapper"
model: "{mapper_model}"
run_in_background: true
description: "Map codebase architecture"
```
@@ -126,6 +146,7 @@ Explore thoroughly. Write documents directly using templates. Return confirmatio
Task tool parameters:
```
subagent_type: "gsd-codebase-mapper"
model: "{mapper_model}"
run_in_background: true
description: "Map codebase conventions"
```
@@ -148,6 +169,7 @@ Explore thoroughly. Write documents directly using templates. Return confirmatio
Task tool parameters:
```
subagent_type: "gsd-codebase-mapper"
model: "{mapper_model}"
run_in_background: true
description: "Map codebase concerns"
```

View File

@@ -20,6 +20,25 @@ No Pass/Fail buttons. No severity questions. Just: "Here's what should happen. D
<process>
<step name="resolve_model_profile" priority="first">
Read model profile for agent spawning:
```bash
MODEL_PROFILE=$(cat .planning/config.json 2>/dev/null | grep -o '"model_profile"[[:space:]]*:[[:space:]]*"[^"]*"' | grep -o '"[^"]*"$' | tr -d '"' || echo "balanced")
```
Default to "balanced" if not set.
**Model lookup table:**
| Agent | quality | balanced | budget |
|-------|---------|----------|--------|
| gsd-planner | opus | opus | sonnet |
| gsd-plan-checker | sonnet | sonnet | haiku |
Store resolved models for use in Task calls below.
</step>
<step name="check_active_session">
**First: Check for active UAT sessions**
@@ -389,6 +408,7 @@ Plans must be executable prompts.
</downstream_consumer>
""",
subagent_type="gsd-planner",
model="{planner_model}",
description="Plan gap fixes for Phase {phase}"
)
```
@@ -434,6 +454,7 @@ Return one of:
</expected_output>
""",
subagent_type="gsd-plan-checker",
model="{checker_model}",
description="Verify Phase {phase} fix plans"
)
```
@@ -474,6 +495,7 @@ Do NOT replan from scratch unless issues are fundamental.
</instructions>
""",
subagent_type="gsd-planner",
model="{planner_model}",
description="Revise Phase {phase} plans"
)
```