Back to Get Shit Done

GSD Configuration Reference

docs/CONFIGURATION.md

1.40.055.4 KB
Original Source

GSD Configuration Reference

Full configuration schema, workflow toggles, model profiles, and git branching options. For feature context, see Feature Reference.


Configuration File

GSD stores project settings in .planning/config.json. Created during /gsd-new-project, updated via /gsd-settings.

Full Schema

json
{
  "mode": "interactive",
  "granularity": "standard",
  "model_profile": "balanced",
  "model_overrides": {},
  "models": {},
  "dynamic_routing": null,
  "planning": {
    "commit_docs": true,
    "search_gitignored": false,
    "sub_repos": []
  },
  "context": null,
  "workflow": {
    "research": true,
    "plan_check": true,
    "verifier": true,
    "auto_advance": false,
    "nyquist_validation": true,
    "ui_phase": true,
    "ui_safety_gate": true,
    "ui_review": true,
    "node_repair": true,
    "node_repair_budget": 2,
    "research_before_questions": false,
    "discuss_mode": "discuss",
    "max_discuss_passes": 3,
    "skip_discuss": false,
    "tdd_mode": false,
    "text_mode": false,
    "use_worktrees": true,
    "code_review": true,
    "code_review_depth": "standard",
    "plan_bounce": false,
    "plan_bounce_script": null,
    "plan_bounce_passes": 2,
    "plan_chunked": false,
    "code_review_command": null,
    "cross_ai_execution": false,
    "cross_ai_command": null,
    "cross_ai_timeout": 300,
    "security_enforcement": true,
    "security_asvs_level": 1,
    "security_block_on": "high",
    "post_planning_gaps": true,
    "build_command": null,
    "test_command": null
  },
  "hooks": {
    "context_warnings": true,
    "workflow_guard": false
  },
  "parallelization": {
    "enabled": true,
    "plan_level": true,
    "task_level": false,
    "skip_checkpoints": true,
    "max_concurrent_agents": 3,
    "min_plans_for_parallel": 2
  },
  "git": {
    "branching_strategy": "none",
    "phase_branch_template": "gsd/phase-{phase}-{slug}",
    "milestone_branch_template": "gsd/{milestone}-{slug}",
    "quick_branch_template": null
  },
  "gates": {
    "confirm_project": true,
    "confirm_phases": true,
    "confirm_roadmap": true,
    "confirm_breakdown": true,
    "confirm_plan": true,
    "execute_next_plan": true,
    "issues_review": true,
    "confirm_transition": true
  },
  "safety": {
    "always_confirm_destructive": true,
    "always_confirm_external_services": true
  },
  "project_code": null,
  "agent_skills": {},
  "response_language": null,
  "features": {
    "thinking_partner": false,
    "global_learnings": false
  },
  "learnings": {
    "max_inject": 10
  },
  "intel": {
    "enabled": false
  },
  "claude_md_path": "./CLAUDE.md"
}

Core Settings

SettingTypeOptionsDefaultDescription
modeenuminteractive, yolointeractiveyolo auto-approves decisions; interactive confirms at each step
granularityenumcoarse, standard, finestandardControls phase count: coarse (3-5), standard (5-8), fine (8-12)
model_profileenumquality, balanced, budget, adaptive, inheritbalancedModel tier for each agent (see Model Profiles). adaptive was added per #1713 / #1806 and resolves the same way as the other tiers under runtime-aware profiles.
runtimestringclaude, codex, or any string(none)Active runtime for runtime-aware profile resolution. When set, profile tiers (opus/sonnet/haiku) resolve to runtime-native model IDs. Today only the Codex install path emits per-agent model IDs from this resolver; other runtimes (opencode, gemini, qwen, copilot, …) consume the resolver at spawn time and gain dedicated install-path support in #2612. When unset (default), behavior is unchanged from prior versions. Added in v1.39
model_profile_overrides.<runtime>.<tier>string | objectper-runtime tier override(none)Override the runtime-aware tier mapping for a specific (runtime, tier). Tier is one of opus, sonnet, haiku. Value is either a model ID string (e.g. "gpt-5-pro") or { model, reasoning_effort }. See Runtime-Aware Profiles. Added in v1.39
models.<phase_type>enumopus, sonnet, haiku, inherit(none)Per-phase-type model tier. Six accepted slots: planning, discuss, research, execution, verification, completion. Lets you tune at the phase level ("Opus for planning, Sonnet for the rest") without learning agent names. Resolves between model_overrides (higher) and model_profile (lower); see Per-Phase-Type Models. Added in v1.40 (#3023)
dynamic_routing.enabledbooleantrue, falsefalseMaster switch for dynamic routing with failure-tier escalation. When true, agents resolve to tier_models[default_tier] and escalate one tier up on orchestrator-detected soft failure. Added in v1.40 (#3024)
dynamic_routing.tier_models.<tier>enumopus, sonnet, haiku(none)Tier alias for light, standard, or heavy. Used when dynamic_routing.enabled: true. Added in v1.40
dynamic_routing.escalate_on_failurebooleantrue, falsetrueWhen false, escalation is disabled even if enabled: true — every attempt uses the default tier. Added in v1.40
dynamic_routing.max_escalationsinteger0, 1, 2, …1Hard cap on retries per agent invocation. Beyond the cap the resolver returns the cap-tier model. Added in v1.40
project_codestringany short string(none)Prefix for phase directory names (e.g., "ABC" produces ABC-01-setup/). Added in v1.31
response_languagestringlanguage code(none)Language for agent responses (e.g., "pt", "ko", "ja"). Propagates to all spawned agents for cross-phase language consistency. Added in v1.32
context_windownumberany integer200000Context window size in tokens. Set 1000000 for 1M-context models (e.g., claude-opus-4-7[1m]). Values >= 500000 enable adaptive context enrichment (full-body reads of prior SUMMARY.md, deeper anti-pattern reads). Configured via /gsd-settings-advanced.
context_profilestringdev, research, review(none)Execution context preset that applies a pre-configured bundle of mode, model, and workflow settings for the current type of work. Added in v1.34
claude_md_pathstringany file path./CLAUDE.mdCustom output path for the generated CLAUDE.md file. Useful for monorepos or projects that need CLAUDE.md in a non-root location. Defaults to ./CLAUDE.md at the project root. Added in v1.36
claude_md_assembly.modeenumembed, linkembedControls how managed sections are written into CLAUDE.md. embed (default) inlines content between GSD markers. link writes @.planning/<source-path> instead — Claude Code expands the reference at runtime, reducing CLAUDE.md size by ~65% on typical projects. link only applies to sections that have a real source file; workflow and fallback sections always embed. Per-block overrides: claude_md_assembly.blocks.<section> (e.g. claude_md_assembly.blocks.architecture: link). Added in v1.38
contextstringany text(none)Custom context string injected into every agent prompt for the project. Use to provide persistent project-specific guidance (e.g., coding conventions, team practices) that every agent should be aware of
phase_namingstringany string(none)Custom prefix for phase directory names. When set, overrides the auto-generated phase slug (e.g., "feature" produces feature-01-setup/ instead of the roadmap-derived slug)
brave_searchbooleantrue/falseauto-detectedOverride auto-detection of Brave Search API availability. When unset, GSD checks for BRAVE_API_KEY env var or ~/.gsd/brave_api_key file
firecrawlbooleantrue/falseauto-detectedOverride auto-detection of Firecrawl API availability. When unset, GSD checks for FIRECRAWL_API_KEY env var or ~/.gsd/firecrawl_api_key file
exa_searchbooleantrue/falseauto-detectedOverride auto-detection of Exa Search API availability. When unset, GSD checks for EXA_API_KEY env var or ~/.gsd/exa_api_key file
search_gitignoredbooleantrue/falsefalseLegacy top-level alias for planning.search_gitignored. Prefer the namespaced form; this alias is accepted for backward compatibility

Note: granularity was renamed from depth in v1.22.3. Existing configs are auto-migrated.


Integration Settings

Configured interactively via /gsd-settings-integrations. These are connectivity settings — API keys and cross-tool routing — and are intentionally kept separate from /gsd-settings (workflow toggles).

Search API keys

API key fields accept a string value (the key itself). They can also be set to the sentinels true/false/null to override auto-detection from env vars / ~/.gsd/*_api_key files (legacy behavior, see rows above).

SettingTypeDefaultDescription
brave_searchstring | boolean | nullnullBrave Search API key used for web research. Displayed as ****<last-4> in all UI / config-set output; never echoed plaintext
firecrawlstring | boolean | nullnullFirecrawl API key for deep-crawl scraping. Masked in display
exa_searchstring | boolean | nullnullExa Search API key for semantic search. Masked in display

Masking convention (get-shit-done/bin/lib/secrets.cjs): keys 8+ characters render as ****<last-4>; shorter keys render as ****; null/empty renders as (unset). Plaintext is written as-is to .planning/config.json — that file is the security boundary — but the CLI, confirmation tables, logs, and AskUserQuestion descriptions never display the plaintext. This applies to the config-set command output itself: config-set brave_search <key> returns a JSON payload with the value masked.

Code-review CLI routing

review.models.<cli> maps a reviewer flavor to a shell command. The code-review workflow shells out using this command when a matching flavor is requested.

SettingTypeDefaultDescription
review.models.claudestring(session model)Command for Claude-flavored review. Defaults to the session model when unset
review.models.codexstringnullCommand for Codex review, e.g. "codex exec --model gpt-5"
review.models.geministringnullCommand for Gemini review, e.g. "gemini -m gemini-2.5-pro"
review.models.opencodestringnullCommand for OpenCode review, e.g. "opencode run --model claude-sonnet-4"

The <cli> slug is validated against [a-zA-Z0-9_-]+. Empty or path-containing slugs are rejected by config-set.

Agent-skill injection (dynamic)

agent_skills.<agent-type> extends the agent_skills map documented below. Slug is validated against [a-zA-Z0-9_-]+ — no path separators, no whitespace, no shell metacharacters. Configured interactively via /gsd-settings-integrations.


Workflow Toggles

All workflow toggles follow the absent = enabled pattern. If a key is missing from config, it defaults to true.

SettingTypeDefaultDescription
workflow.researchbooleantrueDomain investigation before planning each phase
workflow.plan_checkbooleantruePlan verification loop (up to 3 iterations)
workflow.verifierbooleantruePost-execution verification against phase goals
workflow.auto_advancebooleanfalseAuto-chain discuss → plan → execute without stopping
workflow.nyquist_validationbooleantrueTest coverage mapping during plan-phase research
workflow.ui_phasebooleantrueGenerate UI design contracts for frontend phases
workflow.ui_safety_gatebooleantruePrompt to run /gsd-ui-phase for frontend phases during plan-phase
workflow.ui_reviewbooleantrueRun visual quality audit (/gsd-ui-review) after phase execution in autonomous mode. When false, the UI audit step is skipped.
workflow.node_repairbooleantrueAutonomous task repair on verification failure
workflow.node_repair_budgetnumber2Max repair attempts per failed task
workflow.research_before_questionsbooleanfalseRun research before discussion questions instead of after
workflow.discuss_modestring'discuss'Controls how /gsd-discuss-phase gathers context. 'discuss' (default) asks questions one-by-one. 'assumptions' reads the codebase first, generates structured assumptions with confidence levels, and only asks you to correct what's wrong. Added in v1.28
workflow.max_discuss_passesnumber3Maximum number of question rounds in discuss-phase before the workflow stops asking. Useful in headless/auto mode to prevent infinite discussion loops.
workflow.skip_discussbooleanfalseWhen true, /gsd-autonomous bypasses the discuss-phase entirely, writing minimal CONTEXT.md from the ROADMAP phase goal. Useful for projects where developer preferences are fully captured in PROJECT.md/REQUIREMENTS.md. Added in v1.28
workflow.text_modebooleanfalseReplaces AskUserQuestion TUI menus with plain-text numbered lists. Required for Claude Code remote sessions (/rc mode) where TUI menus don't render. Can also be set per-session with --text flag on discuss-phase. Added in v1.28
workflow.use_worktreesbooleantrueWhen false, disables git worktree isolation for parallel execution. Users who prefer sequential execution or whose environment does not support worktrees can disable this. Added in v1.31
workflow.worktree_skip_hooksbooleanfalseWhen true, executor agents in worktree mode pass --no-verify (skipping pre-commit hooks) and post-wave hook validation runs against the merged result instead. Opt-in escape hatch for projects whose hooks cannot run in agent worktrees. Default false runs hooks on every commit (#2924).
workflow.code_reviewbooleantrueEnable /gsd-code-review and /gsd-code-review --fix commands. When false, the commands exit with a configuration gate message. Added in v1.34
workflow.code_review_depthstringstandardDefault review depth for /gsd-code-review: quick (pattern-matching only), standard (per-file analysis), or deep (cross-file with import graphs). Can be overridden per-run with --depth=. Added in v1.34
workflow.plan_bouncebooleanfalseRun external validation script against generated plans. When enabled, the plan-phase orchestrator pipes each PLAN.md through the script specified by plan_bounce_script and blocks on non-zero exit. Added in v1.36
workflow.plan_bounce_scriptstring(none)Path to the external script invoked for plan bounce validation. Receives the PLAN.md path as its first argument. Required when plan_bounce is true. Added in v1.36
workflow.plan_bounce_passesnumber2Number of sequential bounce passes to run. Each pass feeds the previous pass's output back into the validator. Higher values increase rigor at the cost of latency. Added in v1.36
workflow.post_planning_gapsbooleantrueUnified post-planning gap report (#2493). After all plans are generated and committed, scans REQUIREMENTS.md and CONTEXT.md <decisions> against every PLAN.md in the phase directory, then prints one Source | Item | Status table. Word-boundary matching (REQ-1 vs REQ-10) and natural sort (REQ-02 before REQ-10). Non-blocking — informational report only. Set to false to skip Step 13e of plan-phase.
workflow.plan_review_convergencebooleanfalseEnable the /gsd-plan-review-convergence command. Disabled by default — the command exits with an enable instruction when this key is false. The command automates the manual plan→review→replan loop: it spawns configured reviewers (Codex, Gemini, Claude, OpenCode, Ollama, LM Studio, llama.cpp), counts unresolved HIGH concerns via the CYCLE_SUMMARY contract, replans with --reviews feedback, and repeats until converged or max cycles reached. Enable with gsd config-set workflow.plan_review_convergence true. Added in v1.39
workflow.plan_chunkedbooleanfalseEnable chunked planning mode. When true (or when --chunked flag is passed to /gsd-plan-phase), the orchestrator splits the single long-lived planner Task into a short outline Task followed by N short per-plan Tasks (~3-5 min each). Each plan is committed individually for crash resilience. If a Task hangs and the terminal is force-killed, rerunning with --chunked resumes from the last completed plan. Particularly useful on Windows where long-lived Tasks may hang on stdio. Added in v1.38
workflow.code_review_commandstring(none)Shell command for external code review integration in /gsd-ship. Receives changed file paths via stdin. Non-zero exit blocks the ship workflow. Added in v1.36
workflow.tdd_modebooleanfalseEnable TDD pipeline as a first-class execution mode. When true, the planner aggressively applies type: tdd to eligible tasks (business logic, APIs, validations, algorithms) and the executor enforces RED/GREEN/REFACTOR gate sequence. An end-of-phase collaborative review checkpoint verifies gate compliance. Added in v1.36
workflow.cross_ai_executionbooleanfalseDelegate phase execution to an external AI CLI instead of spawning local executor agents. Useful for leveraging a different model's strengths for specific phases. Added in v1.36
workflow.cross_ai_commandstring(none)Shell command template for cross-AI execution. Receives the phase prompt via stdin. Must produce SUMMARY.md-compatible output. Required when cross_ai_execution is true. Added in v1.36
workflow.cross_ai_timeoutnumber300Timeout in seconds for cross-AI execution commands. Prevents runaway external processes. Added in v1.36
workflow.ai_integration_phasebooleantrueEnable the /gsd-ai-integration-phase command. When false, the command exits with a configuration gate message
workflow.auto_prune_statebooleanfalseWhen true, automatically prune stale entries from STATE.md at phase boundaries instead of prompting
workflow.pattern_mapperbooleantrueRun the gsd-pattern-mapper agent between research and planning to map new files to existing codebase analogs
workflow.subagent_timeoutnumber600Timeout in seconds for individual subagent invocations. Increase for long-running research or execution phases
workflow.inline_plan_thresholdnumber3Maximum number of tasks in a phase before the planner generates a separate PLAN.md file instead of inlining tasks in the prompt
workflow.drift_thresholdnumber3Minimum number of new structural elements (new directories, barrel exports, migrations, route modules) introduced during a phase before the post-execute codebase-drift gate takes action. See #2003. Added in v1.39
workflow.drift_actionstringwarnWhat to do when workflow.drift_threshold is exceeded after /gsd-execute-phase. warn prints a message suggesting /gsd-map-codebase --paths …; auto-remap spawns gsd-codebase-mapper scoped to the affected paths. Added in v1.39
workflow.build_commandstring(none)Shell command to build the project in the post-merge build gate (Step A of step 5.6 in execute-phase). When unset, the gate auto-detects: Xcode (.xcodeproj present) → xcodebuild build, Makefile with build: target → make build, Justfile → just build, Cargo.tomlcargo build, go.modgo build ./..., Python → python -m py_compile, package.json with build script → npm run build. Runs with a 5-minute timeout; failure increments WAVE_FAILURE_COUNT. Added in v1.39
workflow.test_commandstring(none)Shell command to run the project's test suite in the post-merge test gate (Step B of step 5.6 in execute-phase) and the regression gate. When unset, the gate auto-detects: Xcode (.xcodeproj present) → xcodebuild test, Makefile with test: target → make test, Justfile → just test, package.jsonnpm test, Cargo.tomlcargo test, go.modgo test ./..., Python → python -m pytest. Runs with a 5-minute timeout; failure increments WAVE_FAILURE_COUNT. Added in v1.39
Scenariomodegranularityprofileresearchplan_checkverifier
Prototypingyolocoarsebudgetfalsefalsefalse
Normal developmentinteractivestandardbalancedtruetruetrue
Production releaseinteractivefinequalitytruetruetrue

Planning Settings

SettingTypeDefaultDescription
planning.commit_docsbooleantrueWhether .planning/ files are committed to git
planning.search_gitignoredbooleanfalseAdd --no-ignore to broad searches to include .planning/
planning.sub_reposarray of strings[]Paths of nested sub-repos relative to the project root. When set, GSD-aware tooling scopes phase-lookup, path-resolution, and commit operations per sub-repo instead of treating the outer repo as a monorepo

Project-Root Resolution in Multi-Repo Workspaces

When sub_repos is set and gsd-tools.cjs or gsd-sdk query is invoked from inside a listed child repo, both CLIs walk up to the parent workspace that owns .planning/ before dispatching handlers. Resolution order (checked at each ancestor up to 10 levels, never above $HOME):

  1. If the starting directory already has its own .planning/, it is the project root (no walk-up).
  2. Parent has .planning/config.json listing the starting directory's top-level segment in sub_repos (or the legacy planning.sub_repos shape).
  3. Parent has .planning/config.json with legacy multiRepo: true and the starting directory is inside a git repo.
  4. Parent has .planning/ and an ancestor up to the candidate parent contains .git (heuristic fallback).

If none match, the starting directory is returned unchanged. Explicit --project-dir /path/to/workspace is idempotent under this resolution.

Auto-Detection

If .planning/ is in .gitignore, commit_docs is automatically false regardless of config.json. This prevents git errors.


Hook Settings

SettingTypeDefaultDescription
hooks.context_warningsbooleantrueShow context window usage warnings via context monitor hook
hooks.workflow_guardbooleanfalseWarn when file edits happen outside GSD workflow context (advises using /gsd-quick or /gsd-fast)
statusline.show_last_commandbooleanfalseAppend last: /<cmd> suffix to the statusline showing the most recently invoked slash command. Opt-in; reads the active session transcript to extract the latest <command-name> tag (closes #2538)

The prompt injection guard hook (gsd-prompt-guard.js) is always active and cannot be disabled — it's a security feature, not a workflow toggle.

Private Planning Setup

To keep planning artifacts out of git:

  1. Set planning.commit_docs: false and planning.search_gitignored: true
  2. Add .planning/ to .gitignore
  3. If previously tracked: git rm -r --cached .planning/ && git commit -m "chore: stop tracking planning docs"

Agent Skills Injection

Inject custom skill files into GSD subagent prompts. Skills are read by agents at spawn time, giving them project-specific instructions beyond what CLAUDE.md provides.

SettingTypeDefaultDescription
agent_skillsobject{}Map of agent types to skill directory paths

Configuration

Add an agent_skills section to .planning/config.json mapping agent types to arrays of skill directory paths (relative to project root):

json
{
  "agent_skills": {
    "gsd-executor": ["skills/testing-standards", "skills/api-conventions"],
    "gsd-planner": ["skills/architecture-rules"],
    "gsd-verifier": ["skills/acceptance-criteria"]
  }
}

Each path must be a directory containing a SKILL.md file. Paths are validated for safety (no traversal outside project root).

Supported Agent Types

Any GSD agent type can receive skills. Common types:

  • gsd-executor -- executes implementation plans
  • gsd-planner -- creates phase plans
  • gsd-checker -- verifies plan quality
  • gsd-verifier -- post-execution verification
  • gsd-researcher -- phase research
  • gsd-project-researcher -- new-project research
  • gsd-debugger -- diagnostic agents
  • gsd-codebase-mapper -- codebase analysis
  • gsd-advisor -- discuss-phase advisors
  • gsd-ui-researcher -- UI design contract creation
  • gsd-ui-checker -- UI spec verification
  • gsd-roadmapper -- roadmap creation
  • gsd-synthesizer -- research synthesis

How It Works

At spawn time, workflows call gsd-sdk query agent-skills <type> (or legacy node gsd-tools.cjs agent-skills <type>) to load configured skills. If skills exist for the agent type, they are injected as an <agent_skills> block in the Task() prompt:

xml
<agent_skills>
Read these user-configured skills:
- @skills/testing-standards/SKILL.md
- @skills/api-conventions/SKILL.md
</agent_skills>

If no skills are configured, the block is omitted (zero overhead).

CLI

Set skills via the CLI:

bash
gsd-sdk query config-set agent_skills.gsd-executor '["skills/my-skill"]'

Feature Flags

Toggle optional capabilities via the features.* config namespace. Feature flags default to false (disabled) — enabling a flag opts into new behavior without affecting existing workflows.

SettingTypeDefaultDescription
features.thinking_partnerbooleanfalseEnable thinking partner analysis at workflow decision points
features.global_learningsbooleanfalseEnable cross-project learnings pipeline (auto-copy at phase completion, planner injection)
learnings.max_injectnumber10Maximum number of cross-project learnings injected into each planner prompt. Lower values reduce prompt size; higher values provide broader historical context
intel.enabledbooleanfalseEnable queryable codebase intelligence system. When true, /gsd-intel commands build and query a JSON index in .planning/intel/. Added in v1.34

<a id="graphify-settings"></a>

Graphify Settings

SettingTypeDefaultDescription
graphify.enabledbooleanfalseEnable the project knowledge graph. When true, /gsd-graphify builds and queries a graph in .planning/graphs/. Added in v1.36
graphify.build_timeoutnumber (seconds)300Maximum seconds allowed for a /gsd-graphify build run before it aborts. Added in v1.36

Usage

bash
# Enable a feature
gsd-sdk query config-set features.global_learnings true

# Disable a feature
gsd-sdk query config-set features.thinking_partner false

The features.* namespace is a dynamic key pattern — new feature flags can be added without modifying VALID_CONFIG_KEYS. Any key matching features.<name> is accepted by the config system.


Parallelization Settings

SettingTypeDefaultDescription
parallelizationbooleantrueShorthand for parallelization.enabled. Setting parallelization false disables parallel execution without changing other sub-keys
parallelization.enabledbooleantrueRun independent plans simultaneously
parallelization.plan_levelbooleantrueParallelize at plan level
parallelization.task_levelbooleanfalseParallelize tasks within a plan
parallelization.skip_checkpointsbooleantrueSkip checkpoints during parallel execution
parallelization.max_concurrent_agentsnumber3Maximum simultaneous agents
parallelization.min_plans_for_parallelnumber2Minimum plans to trigger parallel execution

Pre-commit hooks and parallel execution: When parallelization is enabled, executor agents commit with --no-verify to avoid build lock contention (e.g., cargo lock fights in Rust projects). The orchestrator validates hooks once after each wave completes. STATE.md writes are protected by file-level locking to prevent concurrent write corruption. If you need hooks to run per-commit, set parallelization.enabled: false.


Git Branching

SettingTypeDefaultDescription
git.branching_strategyenumnonenone, phase, or milestone
git.base_branchstringmainThe integration branch that phase/milestone branches are created from and merged back into. Override when your repo uses master or a release branch
git.phase_branch_templatestringgsd/phase-{phase}-{slug}Branch name template for phase strategy
git.milestone_branch_templatestringgsd/{milestone}-{slug}Branch name template for milestone strategy
git.quick_branch_templatestring or nullnullOptional branch name template for /gsd-quick tasks

Strategy Comparison

StrategyCreates BranchScopeMerge PointBest For
noneNeverN/AN/ASolo development, simple projects
phaseAt execute-phase startOne phaseUser merges after phaseCode review per phase, granular rollback
milestoneAt first execute-phaseAll phases in milestoneAt complete-milestoneRelease branches, PR per version

Template Variables

VariableAvailable InExample
{phase}phase_branch_template03 (zero-padded)
{slug}Both templatesuser-authentication (lowercase, hyphenated)
{milestone}milestone_branch_templatev1.0
{num} / {quick}quick_branch_template260317-abc (quick task ID)

Example quick-task branching:

json
"git": {
  "quick_branch_template": "gsd/quick-{num}-{slug}"
}

Merge Options at Milestone Completion

OptionGit CommandResult
Squash merge (recommended)git merge --squashSingle clean commit per branch
Merge with historygit merge --no-ffPreserves all individual commits
Delete without merginggit branch -DDiscard branch work
Keep branches(none)Manual handling later

Gate Settings

Control confirmation prompts during workflows.

SettingTypeDefaultDescription
gates.confirm_projectbooleantrueConfirm project details before finalizing
gates.confirm_phasesbooleantrueConfirm phase breakdown
gates.confirm_roadmapbooleantrueConfirm roadmap before proceeding
gates.confirm_breakdownbooleantrueConfirm task breakdown
gates.confirm_planbooleantrueConfirm each plan before execution
gates.execute_next_planbooleantrueConfirm before executing next plan
gates.issues_reviewbooleantrueReview issues before creating fix plans
gates.confirm_transitionbooleantrueConfirm phase transition

Safety Settings

SettingTypeDefaultDescription
safety.always_confirm_destructivebooleantrueConfirm destructive operations (deletes, overwrites)
safety.always_confirm_external_servicesbooleantrueConfirm external service interactions

Security Settings

Settings for the security enforcement feature (v1.31). All follow the absent = enabled pattern. These keys live under workflow.* in .planning/config.json — matching the shipped template and the runtime reads in workflows/plan-phase.md, workflows/execute-phase.md, workflows/secure-phase.md, and workflows/verify-work.md.

These keys live under workflow.* — that is where the workflows and installer write and read them. Setting them at the top level of config.json is silently ignored.

SettingTypeDefaultDescription
workflow.security_enforcementbooleantrueEnable threat-model-anchored security verification via /gsd-secure-phase. When false, security checks are skipped entirely
workflow.security_asvs_levelnumber (1-3)1OWASP ASVS verification level. Level 1 = opportunistic, Level 2 = standard, Level 3 = comprehensive
workflow.security_block_onstring"high"Minimum severity that blocks phase advancement. Options: "high", "medium", "low"

Decision Coverage Gates (workflow.context_coverage_gate)

When discuss-phase writes implementation decisions into CONTEXT.md <decisions>, two gates ensure those decisions survive the trip into plans and shipped code (issue #2492).

SettingTypeDefaultDescription
workflow.context_coverage_gatebooleantrueToggle for both decision-coverage gates. When false, both the plan-phase translation gate and the verify-phase validation gate skip silently.

What the gates do

Plan-phase translation gate (BLOCKING). Runs immediately after the existing requirements coverage gate, before plans are committed. For each trackable decision in <decisions>, it checks that the decision id (D-NN) or its text appears in at least one plan's must_haves, truths, or body. A miss surfaces the missing decision by id and refuses to mark the phase planned.

Verify-phase validation gate (NON-BLOCKING). Runs alongside the other verify steps. Searches every shipped artifact (PLAN.md, SUMMARY.md, files modified, recent commit subjects) for each trackable decision. Misses are written to VERIFICATION.md as a warning section but do not flip the overall verification status. The asymmetry is deliberate — by verify time the work is done, and a fuzzy substring miss should not fail an otherwise green phase.

How to write decisions the gates accept

The discuss-phase template already produces D-NN-numbered decisions. The gate is happiest when:

  1. Every plan that implements a decision cites the id somewhere — must_haves.truths: ["D-12: bit offsets exposed"] or a D-12: mention in the plan body. Strict id match is the cheapest, deterministic path.
  2. Soft phrase matching is a fallback for paraphrases — if a 6+-word slice of the decision text appears verbatim in a plan/summary, it counts.

Opt-outs

A decision is not subject to the gates when any of the following apply:

  • It lives under the ### Claude's Discretion heading inside <decisions>.
  • It is tagged [informational], [folded], or [deferred] in its bullet (e.g., - **D-08 [informational]:** Naming style for internal helpers).

Use these escape hatches when a decision genuinely doesn't need plan coverage — implementation discretion, future ideas captured for the record, or items already deferred to a later phase.


Review Settings

Configure per-CLI model selection for /gsd-review. When set, overrides the CLI's default model for that reviewer.

SettingTypeDefaultDescription
review.models.geministring(CLI default)Model used when --gemini reviewer is invoked
review.models.claudestring(CLI default)Model used when --claude reviewer is invoked
review.models.codexstring(CLI default)Model used when --codex reviewer is invoked
review.models.opencodestring(CLI default)Model used when --opencode reviewer is invoked
review.models.qwenstring(CLI default)Model used when --qwen reviewer is invoked
review.models.cursorstring(CLI default)Model used when --cursor reviewer is invoked
review.models.ollamastring(server default)Model name passed to Ollama when --ollama reviewer is invoked. If unset, the first available model reported by the server is used (e.g. llama3). Set to a specific tag: gsd config-set review.models.ollama codellama
review.models.lm_studiostring(server default)Model name passed to LM Studio when --lm-studio reviewer is invoked. If unset, the first available model reported by the server is used.
review.models.llama_cppstring(server default)Model name passed to llama.cpp when --llama-cpp reviewer is invoked. If unset, the first model reported by /v1/models is used.
review.ollama_hoststringhttp://localhost:11434Base URL of the Ollama server. Override when running Ollama on a non-default port or remote host: gsd config-set review.ollama_host http://192.168.1.10:11434
review.lm_studio_hoststringhttp://localhost:1234Base URL of the LM Studio local server. Override when using a non-default port.
review.llama_cpp_hoststringhttp://localhost:8080Base URL of the llama.cpp server (llama-server). Override when using a non-default port.

Example

json
{
  "review": {
    "models": {
      "gemini": "gemini-2.5-pro",
      "qwen": "qwen-max"
    }
  }
}

Falls back to each CLI's configured default when a key is absent. Added in v1.35.0 (#1849).


Manager Passthrough Flags

Configure per-step flags that /gsd-manager appends to each dispatched command. This allows customizing how the manager runs discuss, plan, and execute steps without manual flag entry.

SettingTypeDefaultDescription
manager.flags.discussstring(none)Flags appended to discuss-phase commands (e.g., "--auto")
manager.flags.planstring(none)Flags appended to plan-phase commands (e.g., "--skip-research")
manager.flags.executestring(none)Flags appended to execute-phase commands (e.g., "--validate")

Example:

json
{
  "manager": {
    "flags": {
      "discuss": "--auto",
      "plan": "--skip-research",
      "execute": "--validate"
    }
  }
}

Invalid flag tokens are sanitized and logged as warnings. Only recognized GSD flags are passed through.


Model Profiles

Profile Definitions

Agentqualitybalancedbudgetinherit
gsd-plannerOpusOpusSonnetInherit
gsd-roadmapperOpusSonnetSonnetInherit
gsd-executorOpusSonnetSonnetInherit
gsd-phase-researcherOpusSonnetHaikuInherit
gsd-project-researcherOpusSonnetHaikuInherit
gsd-research-synthesizerSonnetSonnetHaikuInherit
gsd-debuggerOpusSonnetSonnetInherit
gsd-codebase-mapperSonnetHaikuHaikuInherit
gsd-verifierSonnetSonnetHaikuInherit
gsd-plan-checkerSonnetSonnetHaikuInherit
gsd-integration-checkerSonnetSonnetHaikuInherit
gsd-nyquist-auditorSonnetSonnetHaikuInherit
gsd-pattern-mapperSonnetSonnetHaikuInherit
gsd-ui-researcherOpusSonnetHaikuInherit
gsd-ui-checkerSonnetSonnetHaikuInherit
gsd-ui-auditorSonnetSonnetHaikuInherit
gsd-doc-writerOpusSonnetHaikuInherit
gsd-doc-verifierSonnetSonnetHaikuInherit

Fallback semantics for unlisted agents. The profiles table above covers 18 of 31 shipped agents. Agents without an explicit profile row (gsd-advisor-researcher, gsd-assumptions-analyzer, gsd-security-auditor, gsd-user-profiler, and the nine advanced agents — gsd-ai-researcher, gsd-domain-researcher, gsd-eval-planner, gsd-eval-auditor, gsd-framework-selector, gsd-code-reviewer, gsd-code-fixer, gsd-debug-session-manager, gsd-intel-updater) inherit the runtime default model for the selected profile. To pin a specific model for any of these agents, use model_overrides (next section) — model_overrides accepts any shipped agent name regardless of whether it has a profile row here. The authoritative profile table lives in get-shit-done/bin/lib/model-profiles.cjs; the authoritative 31-agent roster lives in docs/INVENTORY.md.

Per-Agent Overrides

Override specific agents without changing the entire profile:

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

Valid override values: opus, sonnet, haiku, inherit, or any fully-qualified model ID (e.g., "openai/o3", "google/gemini-2.5-pro").

model_overrides can be set in either .planning/config.json (per-project) or ~/.gsd/defaults.json (global). Per-project entries win on conflict and non-conflicting global entries are preserved, so you can tune a single agent's model in one repo without re-setting global defaults. This applies uniformly across Claude Code, Codex, OpenCode, Kilo, and the other supported runtimes. On Codex and OpenCode, the resolved model is embedded into each agent's static config at install time — spawn_agent and OpenCode's task interface do not accept an inline model parameter, so running gsd install <runtime> after editing model_overrides is required for the change to take effect. See issue #2256.

Per-Phase-Type Models (models) — added in v1.40

Express tuning at the phase level (planning, research, execution, verification) without learning the agent taxonomy. Added in #3023.

model_overrides is per-agent (precise but verbose; you have to know that gsd-codebase-mapper is research and gsd-doc-writer is execution). The models block lets you say "Opus for planning and execution, Sonnet for the rest" in two lines:

json
{
  "model_profile": "balanced",
  "models": {
    "planning": "opus",
    "discuss": "opus",
    "research": "sonnet",
    "execution": "opus",
    "verification": "sonnet",
    "completion": "sonnet"
  },
  "model_overrides": {
    "gsd-codebase-mapper": "haiku"
  }
}

Phase-type → agent mapping

Phase typeAgents
planninggsd-planner, gsd-roadmapper, gsd-pattern-mapper
discuss(reserved — no subagent today)
researchgsd-phase-researcher, gsd-project-researcher, gsd-research-synthesizer, gsd-codebase-mapper, gsd-ui-researcher
executiongsd-executor, gsd-debugger, gsd-doc-writer
verificationgsd-verifier, gsd-plan-checker, gsd-integration-checker, gsd-nyquist-auditor, gsd-ui-checker, gsd-ui-auditor, gsd-doc-verifier
completion(reserved — no subagent today)

discuss and completion are accepted by the schema for forward compatibility; setting them today is a no-op until a subagent maps to them.

Resolution precedence (highest → lowest)

text
1. model_overrides[<agent>]              ← per-agent; full IDs; targeted exception
2. dynamic_routing.tier_models[<tier>]   ← when enabled (see §Dynamic Routing)
3. models[<phase_type>]                  ← coarse phase-level tier (this section)
4. model_profile (per-agent col)         ← global tier strategy
5. Runtime default                       ← when nothing else applies

The five layers compose top-down: model_profile is the base tier, models[<phase_type>] overrides at the phase level, dynamic_routing (when enabled) escalates per-attempt on soft failure, model_overrides[<agent>] carves per-agent exceptions at the top, and the runtime default applies when nothing else does. In the example above, all five research agents resolve to sonnet except gsd-codebase-mapper, which the per-agent override pins to haiku. dynamic_routing is disabled by default — when off (enabled: false or block omitted), this section's behavior is unchanged from today.

Accepted values

models.<phase_type> accepts only tier aliases:

ValueEffect
"opus" / "sonnet" / "haiku"Standard tier — runtime resolution maps to the active runtime's model for that tier
"inherit"Agents in this phase follow the session model (same semantics as model_profile: "inherit")

If you need a fully-qualified model ID ("openai/gpt-5", "google/gemini-2.5-pro"), use model_overrides per agent instead. models.* is intentionally tier-only so the runtime-aware mapping stays correct on Codex / OpenCode / Gemini CLI installs.

When to use which

You wantUse
One global tier strategy ("balanced everywhere")model_profile
Coarse phase-level tuning ("Opus for planning")models.<phase_type>
Per-agent precision ("force haiku on the codebase mapper")model_overrides[<agent>]
Full model ID for a specific agentmodel_overrides[<agent>]: "openai/gpt-5"

Mix freely — the precedence rule above resolves any overlap deterministically.

Validation

config-set rejects unknown phase-types:

bash
$ gsd config-set models.deployment opus
Error: 'models.deployment' is not a valid config key

# Valid:
$ gsd config-set models.research sonnet

Direct edits to .planning/config.json are looser — the resolver simply ignores values it doesn't recognize and falls through to the profile tier — so a typo doesn't silently break tier resolution.

Dynamic Routing with Failure-Tier Escalation (dynamic_routing) — added in v1.40

Start cheap, escalate only when the agent fails the gate. Added in #3024.

dynamic_routing lets you pay for the cheap tier by default and only escalate to the more expensive tier when the orchestrator detects a soft failure (verification inconclusive, plan-check FLAG, etc.).

json
{
  "dynamic_routing": {
    "enabled": true,
    "tier_models": {
      "light":    "haiku",
      "standard": "sonnet",
      "heavy":    "opus"
    },
    "escalate_on_failure": true,
    "max_escalations": 1
  }
}

Agent default tiers

Each agent in MODEL_PROFILES declares one of three default tiers. The resolver picks tier_models[default_tier] for the first attempt.

TierAgentsUse case
lightgsd-codebase-mapper, gsd-pattern-mapper, gsd-research-synthesizer, gsd-plan-checker, gsd-integration-checker, gsd-nyquist-auditor, gsd-ui-checker, gsd-ui-auditor, gsd-doc-verifierCheap/fast — pure mappers, scanners, low-stakes audits
standardgsd-executor, gsd-phase-researcher, gsd-project-researcher, gsd-verifier, gsd-doc-writer, gsd-ui-researcherDefault workhorse — research, writing, primary verification
heavygsd-planner, gsd-roadmapper, gsd-debuggerDeep reasoning — already at top, can't escalate further

Escalation flow

text
1. Orchestrator spawns agent → resolver returns tier_models[default_tier]
2. Soft failure?
   ├─ no → ✓ done (cheap path)
   └─ yes → orchestrator re-spawns at attempt+1
            → resolver returns tier_models[next_tier_up]
            → cap at max_escalations
3. Hard failure (exception/crash) → bypass escalation, surface immediately

If dynamic_routing.escalate_on_failure: false, soft failures do not advance the tier — every respawn keeps using tier_models[default_tier] regardless of the attempt counter. The kill-switch overrides the soft-failure branch above.

light → standard → heavy → heavy (heavy stays at heavy; can't go further).

Resolution precedence (highest → lowest)

  1. model_overrides[<agent>] — full IDs accepted; targeted exception
  2. dynamic_routing.tier_models[<tier>] (when enabled: true)
  3. models[<phase_type>] — coarse phase-level (#3023)
  4. model_profile — per-agent column from active profile
  5. Runtime default

The dynamic_routing block is disabled by defaultenabled: false (or omitting the block) preserves today's static resolution exactly.

Settings

KeyTypeDefaultDescription
dynamic_routing.enabledbooleanfalseMaster switch. When true, the dynamic-routing resolver is used for tier selection.
dynamic_routing.tier_models.lightenum(none)Tier alias for the light tier. Typically haiku.
dynamic_routing.tier_models.standardenum(none)Tier alias for standard. Typically sonnet.
dynamic_routing.tier_models.heavyenum(none)Tier alias for heavy. Typically opus.
dynamic_routing.escalate_on_failurebooleantrueWhen false, escalation is disabled (every attempt uses the default tier).
dynamic_routing.max_escalationsinteger1Hard cap on retries per agent invocation. Prevents runaway loops.

When to use which

You wantUse
One tier strategy across all agentsmodel_profile
Coarse phase-level tuningmodels.<phase_type>
Per-agent precision (full IDs)model_overrides
Cheap-by-default, escalate only on failuredynamic_routing

dynamic_routing is structurally a cost lever: you pay Opus rates only for the hard cases that warrant Opus. Compose with model_overrides for per-agent exceptions (override always wins).

Non-Claude Runtimes (Codex, OpenCode, Gemini CLI, Kilo)

When GSD is installed for a non-Claude runtime, the installer automatically sets resolve_model_ids: "omit" in ~/.gsd/defaults.json. This causes GSD to return an empty model parameter for all agents, so each agent uses whatever model the runtime is configured with. No additional setup is needed for the default case.

If you want different agents to use different models, use model_overrides with fully-qualified model IDs that your runtime recognizes:

json
{
  "resolve_model_ids": "omit",
  "model_overrides": {
    "gsd-planner": "o3",
    "gsd-executor": "o4-mini",
    "gsd-debugger": "o3",
    "gsd-codebase-mapper": "o4-mini"
  }
}

The intent is the same as the Claude profile tiers -- use a stronger model for planning and debugging (where reasoning quality matters most), and a cheaper model for execution and mapping (where the plan already contains the reasoning).

When to use which approach:

ScenarioSettingEffect
Non-Claude runtime, single modelresolve_model_ids: "omit" (installer default)All agents use the runtime's default model
Non-Claude runtime, tiered modelsresolve_model_ids: "omit" + model_overridesNamed agents use specific models, others use runtime default
Claude Code with OpenRouter/local providermodel_profile: "inherit"All agents follow the session model
Claude Code with OpenRouter, tieredmodel_profile: "inherit" + model_overridesNamed agents use specific models, others inherit

resolve_model_ids values:

ValueBehaviorUse When
false (default)Returns Claude aliases (opus, sonnet, haiku)Claude Code with native Anthropic API
trueMaps aliases to full Claude model IDs (claude-opus-4-6)Claude Code with API that requires full IDs
"omit"Returns empty string (runtime picks its default)Non-Claude runtimes (Codex, OpenCode, Gemini CLI, Kilo)

Runtime-Aware Profiles (#2517)

When runtime is set, profile tiers (opus/sonnet/haiku) resolve to runtime-native model IDs instead of Claude aliases. This lets a single shared .planning/config.json work cleanly across Claude and Codex.

Built-in tier maps:

Runtimeopussonnethaikureasoning_effort
claudeclaude-opus-4-6claude-sonnet-4-6claude-haiku-4-5(not used)
codexgpt-5.4gpt-5.3-codexgpt-5.4-minixhigh / medium / medium

Codex example — one config, tiered models, no large model_overrides block:

json
{
  "runtime": "codex",
  "model_profile": "balanced"
}

This resolves gsd-plannergpt-5.4 (xhigh), gsd-executorgpt-5.3-codex (medium), gsd-codebase-mappergpt-5.4-mini (medium). The Codex installer embeds model = "..." and model_reasoning_effort = "..." in each generated agent TOML.

Claude example — explicit opt-in resolves to full Claude IDs (no resolve_model_ids: true needed):

json
{
  "runtime": "claude",
  "model_profile": "quality"
}

Per-runtime overrides — replace one or more tier defaults:

json
{
  "runtime": "codex",
  "model_profile": "quality",
  "model_profile_overrides": {
    "codex": {
      "opus": "gpt-5-pro",
      "haiku": { "model": "gpt-5-nano", "reasoning_effort": "low" }
    }
  }
}

Precedence (highest to lowest):

  1. model_overrides[<agent>] — explicit per-agent ID always wins.
  2. Runtime-aware tier resolution (this section) — when runtime is set and profile is not inherit.
  3. resolve_model_ids: "omit" — returns empty string when no runtime is set.
  4. Claude-native default — model_profile tier as alias (current default).
  5. inherit — propagates literal inherit for Task(model="inherit") semantics.

Backwards compatibility. Setups without runtime set see zero behavior change — every existing config continues to work identically. Codex installs that auto-set resolve_model_ids: "omit" continue to omit the model field unless the user opts in by setting runtime: "codex".

Unknown runtimes. If runtime is set to a value with no built-in tier map and no model_profile_overrides[<runtime>], GSD falls back to the Claude-alias safe default rather than emit a model ID the runtime cannot accept. To support a new runtime, populate model_profile_overrides.<runtime>.{opus,sonnet,haiku} with valid IDs.

Profile Philosophy

ProfilePhilosophyWhen to Use
qualityOpus for all decision-making, Sonnet for verificationQuota available, critical architecture work
balancedOpus for planning only, Sonnet for everything elseNormal development (default)
budgetSonnet for code-writing, Haiku for research/verificationHigh-volume work, less critical phases
inheritAll agents use current session modelDynamic model switching, non-Anthropic providers (OpenRouter, local models)

Environment Variables

VariablePurpose
CLAUDE_CONFIG_DIROverride default config directory (~/.claude/)
GEMINI_API_KEYDetected by context monitor to switch hook event name
WSL_DISTRO_NAMEDetected by installer for WSL path handling
GSD_SKIP_SCHEMA_CHECKSkip schema drift detection during execute-phase (v1.31)
GSD_PROJECTOverride project root for multi-project workspace support (v1.32)

Global Defaults

Save settings as global defaults for future projects:

Location: ~/.gsd/defaults.json

When /gsd-new-project creates a new config.json, it reads global defaults and merges them as the starting configuration. Per-project settings always override globals.