This guide is the source-based reference for the architecture, configuration, deployment, security, and internals of GSD (get-shit-done-cc) — a meta-prompting, context-engineering, and spec-driven development system for AI coding agents, authored by TÂCHES and licensed MIT. It is written for the people who operate, extend, debug, or fork GSD: administrators rolling it out across a team's runtimes, developers contributing to the SDK, and architects evaluating how the system holds together.
For task-oriented usage (the slash commands and the phase workflow), see the companion User Guide. This document assumes that material and goes one level deeper.
Important
Archived repository. This guide documents
gsd-build/get-shit-doneat commitbdcaab2(version1.50.0-canary.0), which is now archived. Development continues as GSD Core atgithub.com/open-gsd/gsd-core. Every fact below is derived from the source at the documented commit. Where the source itself carries transitional naming (theget-shit-done-ccpackage vs. the@opengsd/get-shit-done-reduxpackage referenced in the bundled docs), both are reported.
Table of Contents
- Executive Summary
- System Architecture
- The Layered Model
- Agent Orchestration Model
- The SDK & CLI Tools Layer
- Requirements & Runtime Support
- Installation & Deployment
- Configuration Mastery
- Filesystem Layout
- Hook System
- Security Architecture
- Operations & Maintenance
- Versioning & Release Strategy
- Repository Structure & Internals
- Testing Strategy
- Code Quality & Conventions
- Known Issues & Improvement Areas
- Quick Reference
Executive Summary
GSD sits between a developer and an AI coding agent and imposes structure on what would otherwise be an unstructured chat. It ships four capabilities:
- Context engineering — structured
.planning/artifacts give each agent exactly what it needs per task. - Multi-agent orchestration — thin Markdown orchestrators spawn ~33 specialized agents, each in a fresh context window.
- Spec-driven development — a requirements → research → plan → execute → verify pipeline.
- File-based state management — all state is human-readable Markdown/JSON; no database, server, or external dependency.
Surface area at the documented commit: 67 slash commands, 33 agents, ~90 workflow files, 13 hooks (11 canonical in the shipped roster), a TypeScript SDK (@gsd-build/sdk), and a CJS CLI (gsd-tools.cjs). The installer (bin/install.js, ~485 KB / ~10,700 lines, generated) targets 15 AI runtimes.
Runtime dependencies are deliberately minimal: @anthropic-ai/claude-agent-sdk and ws, plus synckit in the SDK and an optional fallow integration. Node >= 22 is required.
Note
GSD never calls an LLM API directly. It produces prompts and orchestration instructions that the host runtime (Claude Code, Codex, etc.) executes. This is why GSD has no API-key requirement of its own and why "model selection" is really about which tier the host should use for each agent.
System Architecture
┌──────────────────────────────────────────────────────┐
│ USER │
│ /gsd-command [args] │
└────────────────────────┬─────────────────────────────┘
│
┌────────────────────────▼─────────────────────────────┐
│ COMMAND LAYER commands/gsd/*.md (67 commands) │
│ Prompt-based command files / skills per runtime │
└────────────────────────┬─────────────────────────────┘
│
┌────────────────────────▼─────────────────────────────┐
│ WORKFLOW LAYER get-shit-done/workflows/*.md │
│ Thin orchestrators: load context, spawn agents, │
│ manage gates, update state │
└──────┬─────────────────┬──────────────────┬──────────┘
│ │ │
┌──────▼─────┐ ┌──────▼─────┐ ┌──────▼─────┐
│ AGENT │ │ AGENT │ │ AGENT │ 33 agents,
│ (fresh ctx)│ │ (fresh ctx)│ │ (fresh ctx)│ fresh 200K–1M
└──────┬─────┘ └──────┬─────┘ └──────┬─────┘ windows each
│ │ │
┌──────▼─────────────────▼──────────────────▼──────────┐
│ CLI TOOLS LAYER │
│ gsd-sdk query (sdk/src/query) + gsd-tools.cjs │
│ Bridged by query-runtime-bridge.ts (GSDTools) │
└────────────────────────┬─────────────────────────────┘
│
┌────────────────────────▼─────────────────────────────┐
│ FILE SYSTEM .planning/ │
│ PROJECT.md | REQUIREMENTS.md | ROADMAP.md │
│ STATE.md | config.json | phases/ | research/ │
└──────────────────────────────────────────────────────┘
Design principles
| Principle | Consequence |
|---|---|
| Fresh context per agent | Every spawned agent gets a clean window (up to 200K, or 1M on 1M-class models). Eliminates context rot. |
| Thin orchestrators | Workflow .md files only load context, spawn agents, and route results. No heavy logic lives in prompts. |
| File-based state | State survives /clear, is human- and agent-inspectable, and is git-committable. |
| Absent = enabled | Missing workflow flags default to true. Users disable features; they never enable defaults. |
| Defense in depth | Plan-check before execution → atomic commits → post-execution verification → human UAT. |
The Layered Model
Command layer — commands/gsd/*.md
User-facing entry points. Each file has YAML frontmatter (name, description, allowed-tools, argument-hint) and a prompt body that bootstraps a workflow. The installer materializes these per runtime (Claude slash commands, Codex skills, Gemini colon-namespaced commands, etc.).
Two-stage hierarchical routing (v1.40). Six namespace meta-skills (gsd-workflow, gsd-project, gsd-quality, gsd-context, gsd-manage, gsd-ideate, sourced from commands/gsd/ns-*.md) sit above the concrete commands. The model sees ~6 routers (~120 tokens) instead of a flat ~86-skill listing (~2,150 tokens), selects a namespace, then routes to the concrete sub-skill. Namespace skills are additive — every concrete command remains directly invocable.
Note
Skill
description:fields are injected into every session's system prompt, so they are budget-constrained to ≤ 100 chars and lint-enforced bynpm run lint:descriptions(andtests/enh-2789-description-budget.test.cjs). This is why descriptions read like keyword-dense tags rather than prose.
Workflow layer — get-shit-done/workflows/*.md
Orchestration logic that commands reference. Workflows load context via gsd-sdk query init.<workflow>, spawn agents with resolved models, enforce gates/checkpoints, update state, and handle recovery.
Workflow files are loaded verbatim into the host context on each invocation, so they carry a line budget (enforced by tests/workflow-size-budget.test.cjs):
| Tier | Per-file line limit | Examples |
|---|---|---|
XL |
1700 | execute-phase, plan-phase, new-project |
LARGE |
1500 | multi-step planners, large feature workflows |
DEFAULT |
1000 | focused single-purpose workflows (target tier) |
When a workflow exceeds its tier, per-mode bodies are extracted to workflows/<workflow>/modes/<mode>.md, templates to workflows/<workflow>/templates/, and shared knowledge to get-shit-done/references/. The canonical example is workflows/discuss-phase/ (held to a stricter < 500-line ceiling), whose parent dispatches to mode files (power.md, all.md, auto.md, chain.md, text.md, batch.md, analyze.md, default.md, advisor.md).
Agent layer — agents/*.md
33 specialized agent definitions. Frontmatter declares name, description, tools (allowed tool access), and color. See Agent Orchestration Model.
References & templates
get-shit-done/references/*.md— shared knowledge@-referenced by workflows and agents:gates.md(4 canonical gate types),model-profiles.md,model-profile-resolution.md,verification-patterns.md,tdd.md,context-budget.md, thethinking-models-*.mdfamily, and more.get-shit-done/templates/— Markdown templates for every planning artifact (project.md,roadmap.md,state.md,phase-prompt.md, granularity-awaresummary*.md,UI-SPEC.md,UAT.md,VALIDATION.md, pluscodebase/andresearch-project/subtrees), filled bygsd-sdk query template.fill/phase.scaffold.
Agent Orchestration Model
Orchestrator → agent pattern
Orchestrator (workflow .md)
│
├── Load context: gsd-sdk query init.<workflow> <phase> → JSON (project, config, state, phase)
├── Resolve model: gsd-sdk query resolve-model <agent> → opus | sonnet | haiku | inherit
├── Spawn agent (Task/SubAgent): prompt + context payload + model + tool permissions
├── Collect result
└── Update state: gsd-sdk query state.update / state.patch / state.advance-plan
Agent categories
| Category | Agents | Parallelism |
|---|---|---|
| Researchers | gsd-project-researcher, gsd-phase-researcher, gsd-ui-researcher, gsd-advisor-researcher |
4 parallel (stack, features, architecture, pitfalls) |
| Synthesizers | gsd-research-synthesizer |
Sequential (after researchers) |
| Planners | gsd-planner, gsd-roadmapper |
Sequential |
| Checkers | gsd-plan-checker, gsd-integration-checker, gsd-ui-checker, gsd-nyquist-auditor |
Sequential (verify loop, max 3) |
| Executors | gsd-executor |
Parallel within waves, sequential across waves |
| Verifiers | gsd-verifier |
Sequential (after executors) |
| Mappers | gsd-codebase-mapper |
4 parallel (tech, arch, quality, concerns) |
| Auditors | gsd-ui-auditor, gsd-security-auditor |
Sequential |
| Doc | gsd-doc-writer, gsd-doc-verifier, gsd-doc-classifier, gsd-doc-synthesizer |
Sequential (writer → verifier) |
| Specialized | gsd-debugger, gsd-code-reviewer, gsd-code-fixer, gsd-pattern-mapper, gsd-user-profiler, gsd-assumptions-analyzer, gsd-domain-researcher, gsd-framework-selector, gsd-ai-researcher, gsd-eval-planner, gsd-eval-auditor, gsd-intel-updater, gsd-debug-session-manager |
Varies |
Wave execution model
During execute-phase, plans are grouped into dependency waves:
Plan 01 (no deps) ─┐
Plan 02 (no deps) ─┤── Wave 1 (parallel)
Plan 03 (depends: 01) ─┤── Wave 2 (waits for Wave 1)
Plan 04 (depends: 02) ─┘
Plan 05 (depends: 03,04) ── Wave 3 (waits for Wave 2)
Each executor receives a fresh 200K window (or up to 1M), the specific PLAN.md, project context (PROJECT.md, STATE.md), and phase context (CONTEXT.md, RESEARCH.md).
Adaptive context enrichment (1M models). When context_window >= 500000, executor prompts are enriched with prior-wave SUMMARY.md files and the phase CONTEXT.md/RESEARCH.md; verifier prompts receive all PLAN.md/SUMMARY.md/CONTEXT.md plus REQUIREMENTS.md. For standard 200K windows, prompts use truncated, cache-friendly ordering.
Parallel commit safety
Two mechanisms prevent corruption when multiple executors run in one wave:
--no-verifycommits — parallel agents skip pre-commit hooks (which can cause build-lock contention, e.g. cargo lock fights). The orchestrator runsgit hook run pre-commitonce after each wave.- STATE.md file locking — all
writeStateMd()calls use lockfile mutual exclusion (STATE.md.lock,O_EXCLatomic creation, 10s stale detection, spin-wait with jitter), preventing read-modify-write races between agents.
Warning
If your pre-commit hooks must run on every commit, set
parallelization.enabled: false. Otherwise, hooks validate once per wave against the merged result, and per-commit hook side effects will not fire on intermediate commits.
The SDK & CLI Tools Layer
GSD has a dual command surface: a modern TypeScript SDK (@gsd-build/sdk, invoked as gsd-sdk query) and a legacy CJS CLI (gsd-tools.cjs). They are converging — CJS family routers increasingly dispatch into the SDK in-process.
SDK structure (sdk/src/)
The SDK's heart is the query engine (sdk/src/query/, 192 files, ~1.68M chars) — a registry of native query handlers covering init.*, state.*, phase.*, phases.*, roadmap.*, config.*, frontmatter.*, validate.*, milestone.*, and more. Key classes (from sdk/src/):
| Class | File | Role |
|---|---|---|
GSD |
index.ts |
Top-level milestone runner (GSD.run()); discovers phases, runs each, emits lifecycle events |
GSDTools |
gsd-tools.ts |
Programmatic SDK entry; routes through the runtime bridge |
QueryRegistry |
query/registry.ts |
Native query handler registry |
QueryRuntimeBridge |
query-runtime-bridge.ts |
Single dispatch seam: native-preference, subprocess-fallback policy, strict-SDK mode, dispatch observability |
PhaseRunner / PromptFactory |
phase-runner.ts / phase-prompt.ts |
Phase execution driver and prompt construction |
InitRunner |
init-runner.ts |
New-project synthesis pipeline (PROJECT → research → requirements → roadmap) |
ContextEngine |
context-engine.ts |
Context assembly for agent prompts |
GSDEventStream |
event-stream.ts |
Typed lifecycle event emitter |
PlanningJournal / PlanningRuntime |
planning-journal.ts / planning-runtime.ts |
Idempotent planning operations + runtime |
CLITransport / WSTransport / GSDTransport |
*-transport.ts |
Transport adapters (CLI, WebSocket via ws) |
GSDError / GSDToolsError / PhaseRunnerError |
errors.ts, etc. |
Typed error hierarchy |
Sync Runtime Bridge
sdk/src/runtime-bridge-sync/ exposes executeForCjs(input) — a synchronous-friendly entry point on top of the async bridge, letting the CJS dispatcher invoke SDK handlers in-process (no subprocess hop) while preserving the synchronous contract ~21 CJS test files and 100+ consumers depend on. It uses synckit (Atomics.wait on a SharedArrayBuffer in a pooled worker). First-call cost ~80ms (worker startup); steady-state ~0.1ms per call. It maps exceptions to a typed sync result aligned with the dispatch error taxonomy.
Command Routing Hub
get-shit-done/bin/lib/command-routing-hub.cjs centralizes three cross-cutting concerns that each CJS family router previously duplicated: (1) mode selection (sdk when tryLoadSdk() succeeds and no GSD_WORKSTREAM is active, else cjs), fixed at construction; (2) a no-throw pure-result contract (hub.dispatch() returns { ok: false, errorKind, message, details } instead of throwing); and (3) a closed six-value errorKind enum (UnknownCommand, InvalidArgs, HandlerRefusal, HandlerFailure, SdkLoadFailed, SdkDispatchFailed). There is no transparent SDK→CJS fallback: an SDK-mode hub that fails returns SdkLoadFailed/SdkDispatchFailed. phase-command-router.cjs is the first migration (issue #3788); ADR docs/adr/0012-command-routing-hub.md.
Dispatch error taxonomy (ADR-0001)
The canonical error kind set used across dispatch policy: unknown_command, native_failure, native_timeout, fallback_failure, validation_error, internal_error.
Shared CJS/SDK modules (generator pattern)
Several modules exist as a single TypeScript source of truth that is generated into a CJS twin, with check:*-fresh scripts guarding drift in CI: state-document (STATE.md transforms), configuration (config load/normalize/merge/migrate), workstream-inventory-builder, project-root (ancestor-walk root resolution, max depth 10), plan-scan, secrets, schema-detect, decisions, and workstream-name-policy. This structurally eliminates the recurring CJS/SDK drift bug class.
Tip
For automation, prefer
gsd-sdk query <subcommand>overgsd-tools.cjs. A few operations remain CJS-only (e.g.graphify,gsd2-import, and thestate loadshape). The--json-errorsmode yields machine-readable failure envelopes (seedocs/json-errors.md).
Requirements & Runtime Support
System requirements
| Item | Requirement |
|---|---|
| Node.js | >= 22.0.0 |
| Runtime dependencies | @anthropic-ai/claude-agent-sdk ^0.2.84, ws 8.20.1 |
| SDK dependencies | + synckit ^0.11.12 |
| Optional | fallow ^2.70.0 (structural code-review pre-pass), slopcheck (Python, supply-chain gate) |
| Host runtime | One of the 15 supported AI coding agents |
Supported runtimes (15)
claude, antigravity, augment, cline, codebuddy, codex, copilot, cursor, gemini, hermes, kilo, opencode, qwen, trae, windsurf.
Runtime install contract matrix
| Runtime | Global root | Invocation surface | Config & hooks |
|---|---|---|---|
| Claude Code | ~/.claude |
global skills/gsd-*/SKILL.md; local commands/gsd/*.md |
settings.json hooks + statusLine |
| OpenCode | ~/.config/opencode |
command/gsd-*.md |
opencode.json[c]; no GSD hooks |
| Kilo | ~/.config/kilo |
command/gsd-*.md |
kilo.json[c]; no GSD hooks |
| Gemini CLI | ~/.gemini |
commands/gsd/*.toml (colon form) |
settings.json flag + hooks + statusline |
| Codex | ~/.codex |
skills/gsd-*/SKILL.md |
config.toml [agents.gsd-*], [features].hooks |
| GitHub Copilot | ~/.copilot |
skills/gsd-*/SKILL.md + copilot-instructions.md |
No GSD hooks |
| Antigravity | ~/.gemini/antigravity |
skills/gsd-*/SKILL.md |
Gemini-style settings.json |
| Cursor / Windsurf / Trae | ~/.cursor / ~/.codeium/windsurf / ~/.trae |
skills/gsd-*/SKILL.md |
Rule references under rules/; no GSD hooks |
| Augment | ~/.augment |
skills/gsd-*/SKILL.md |
No GSD hooks |
| Qwen / CodeBuddy | ~/.qwen / ~/.codebuddy |
skills/gsd-*/SKILL.md |
Common settings/hooks where supported |
| Hermes | ~/.hermes |
nested skills/gsd/gsd-*/SKILL.md |
Common settings/hooks where supported |
| Cline | ~/.cline |
.clinerules (rules only) |
No GSD hooks |
Each runtime also accepts a <RUNTIME>_CONFIG_DIR environment variable to redirect the install path (used for prerelease channels and custom layouts).
Installation & Deployment
Installer architecture (bin/install.js)
The installer is a single generated production file (~485 KB, ~10,700 lines) that handles:
- Runtime detection — interactive prompt or CLI flags (
--claude,--codex, …--all). - Location selection —
--globalor--local. - File deployment — copies commands, skills, workflows, references, templates, agents, hooks.
- Runtime adaptation — transforms file content per runtime: tool-name mapping (Claude
Bash→ Copilotexecute), hook-event renaming (PostToolUse→ GeminiAfterTool), command-format conversion (OpenCode flat commands, Codex TOML + skills, Gemini colon namespacing, Cline.clinerules), model-equivalent substitution. - Path normalization — replaces
~/.claude/paths with runtime-specific paths. - Settings integration — registers hooks in the runtime's
settings.json. - Patch backup — backs up locally modified files to
gsd-local-patches/(since v1.17) for/gsd-update --reapply. - Manifest tracking — writes
gsd-file-manifest.jsonfor clean uninstall. - Uninstall —
--uninstallremoves all GSD files, hooks, and settings.
Install-time file moves, stale-artifact cleanup, config rewrites, and user-data preservation are governed by the Installer Migration Module (ADR-0008; docs/installer-migrations.md), which also runs a gated first-time baseline scan for legacy installs before any migration removes or rewrites anything.
Install profiles & surface budgets
get-shit-done/bin/lib/install-profiles.cjs defines named profiles (core, standard, full), computes the transitive closure over each skill's requires: frontmatter, stages the chosen subset to the runtime config dir, and persists the choice in a .gsd-profile marker. Resolution precedence: explicit --profile= > .gsd-profile marker > full. --minimal/--core-only are back-compat aliases for --profile=core. At runtime, /gsd-surface (backed by surface.cjs + clusters.cjs) enables/disables clusters without reinstall, persisting per-runtime state in .gsd-surface.json. See ADR-0011.
Platform handling
| Platform | Handling |
|---|---|
| Windows | windowsHide on child processes; EPERM/EACCES protection on protected dirs; path-separator normalization; Windows shim triples for gsd-sdk/gsd-tools |
| WSL | Detects Windows Node on WSL and warns about path mismatches |
| Docker / CI | Honors CLAUDE_CONFIG_DIR (and per-runtime *_CONFIG_DIR) env vars |
Deployment notes for administrators
- Global vs local.
--globalwrites to the runtime's home config and applies to every project;--localwrites to the project directory only. Prefer local for repo-pinned, reproducible toolchains. gsd-sdkPATH callability.npx-based installs self-symlink thegsd-sdkshim into~/.local/binwhen needed and verify PATH callability before reporting readiness (issue #2775).- Uninstall is one pass.
npx get-shit-done-cc --uninstallremoves scripts, hook registrations, and the update-banner SessionStart entry together.
Configuration Mastery
All project settings live in .planning/config.json, created by /gsd-new-project and edited via /gsd-settings or /gsd-config. Configuration loading is pure (loadConfig(cwd) never writes disk); legacy keys are normalized into their canonical nested locations; defaults come from sdk/shared/config-defaults.manifest.json and the schema from sdk/shared/config-schema.manifest.json.
Full schema (defaults shown)
{
"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,
"human_verify_mode": "end-of-phase", "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
},
"code_quality": { "fallow": { "enabled": false, "scope": "phase", "profile": "standard", "mcp": false } },
"ship": { "pr_body_sections": [] },
"hooks": { "context_warnings": true, "workflow_guard": false },
"statusline": { "context_position": "end" },
"review": { "default_reviewers": null, "models": {} },
"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", "create_tag": true,
"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
| Setting | Options | Default | Purpose |
|---|---|---|---|
mode |
interactive, yolo |
interactive |
yolo auto-approves decisions |
granularity |
coarse, standard, fine |
standard |
Phase count: 3–5 / 5–8 / 8–12 |
model_profile |
quality, balanced, budget, adaptive, inherit |
balanced |
Model tier per agent |
runtime |
claude, codex, any string |
(none) | Active runtime for runtime-aware profile resolution |
models.<phase_type> |
opus/sonnet/haiku/inherit |
(none) | Per-phase-type tier: planning/discuss/research/execution/verification/completion |
context_window |
integer | 200000 |
Set 1000000 for 1M models; >= 500000 enables adaptive enrichment |
claude_md_path |
path | ./CLAUDE.md |
Output path for the generated CLAUDE.md (monorepo-friendly) |
response_language |
language code | (none) | Propagates response language to all agents |
project_code |
string | (none) | Phase-dir prefix (e.g. ABC → ABC-01-setup/) |
Model selection layers (precedence)
From highest to lowest: model_overrides.<agent> > models.<phase_type> > model_profile. When dynamic_routing.enabled is true, agents start at tier_models[default_tier] and escalate one tier on orchestrator-detected soft failure (capped by max_escalations, default 1). For non-Claude runtimes the installer sets resolve_model_ids: "omit" so the runtime picks its own model; model_profile_overrides.<runtime>.<tier> overrides the runtime-aware tier mapping.
Workflow toggles (absent = enabled)
Key toggles (all default true unless noted):
| Setting | Default | Purpose |
|---|---|---|
workflow.research |
true |
Domain research before planning |
workflow.plan_check |
true |
Plan verification loop (≤ 3 iterations) |
workflow.verifier |
true |
Post-execution verification |
workflow.nyquist_validation |
true |
Map test coverage to requirements at plan time |
workflow.discuss_mode |
discuss |
discuss (Q&A) vs assumptions (codebase-first) |
workflow.use_worktrees |
true |
Git-worktree isolation for parallel execution |
workflow.human_verify_mode |
end-of-phase |
end-of-phase (embedded checks) vs mid-flight (blocking checkpoints) |
workflow.tdd_mode |
false |
Enforce RED/GREEN/REFACTOR gate sequence |
workflow.code_review_depth |
standard |
quick / standard / deep |
workflow.subagent_timeout |
600 |
Seconds per subagent invocation |
workflow.build_command / test_command |
(auto) | Post-merge build/test gates; auto-detected per stack when unset |
workflow.drift_threshold / drift_action |
3 / warn |
Post-execute codebase-drift gate (#2003) |
Other namespaces
planning.*—commit_docs(auto-falseif.planning/is gitignored),search_gitignored,sub_repos(multi-repo project-root resolution; walks ancestors up to depth 10).parallelization.*—enabled,max_concurrent_agents(3),min_plans_for_parallel(2),task_level(false).git.*—branching_strategy(none/phase/milestone),base_branch(main),create_tag, branch templates.gates.*/safety.*— interactive confirmation gates;always_confirm_destructive/always_confirm_external_servicesdefaulttrue.features.*—thinking_partner,global_learnings(cross-project learnings pipeline). The namespace is a dynamic key pattern; new flags need no schema change.intel.enabled,graphify.enabled/build_timeout/auto_update— queryable codebase intel and the knowledge-graph integration (.planning/intel/,.planning/graphs/).code_quality.fallow.*— optional structural pre-pass for/gsd-code-review(enabled,scope,profile;mcpis reserved/no-op).agent_skills.<agent>— inject project-localSKILL.mdfiles into a given agent's prompt (path-validated, no traversal).- Integration keys —
brave_search,firecrawl,exa_search(masked as****<last-4>in all output bysecrets.cjs; plaintext only on disk), andreview.models.<cli>for cross-AI review routing.
Caution
API keys written to
.planning/config.jsonare stored in plaintext — that file is the security boundary. The CLI, logs, and confirmation tables mask them, but if you commit.planning/to git, you commit those keys. Keep keys in env vars /~/.gsd/*_api_keyfiles, or setplanning.commit_docs: false.
Setting config programmatically
gsd-sdk query config-set features.global_learnings true
gsd-sdk query config-set review.default_reviewers '["gemini","codex"]'
gsd-sdk query config-set agent_skills.gsd-executor '["skills/testing-standards"]'
Filesystem Layout
Installed files (Claude Code global)
~/.claude/
├── skills/gsd-*/SKILL.md # Global skills
├── commands/gsd/*.md # (local installs use slash commands)
├── get-shit-done/
│ ├── bin/gsd-tools.cjs # CJS CLI
│ ├── bin/lib/*.cjs # Domain modules
│ ├── workflows/*.md # Orchestration logic
│ ├── references/*.md # Shared knowledge
│ └── templates/ # Artifact templates
├── agents/*.md # 33 agent definitions
├── hooks/*.js, hooks/*.sh # Runtime hooks
├── settings.json # Hook registrations
└── VERSION # Installed version
Project state (.planning/)
.planning/
├── PROJECT.md # Vision, constraints, decisions, evolution rules
├── REQUIREMENTS.md # Scoped requirements (v1/v2/out-of-scope), REQ-IDs
├── ROADMAP.md # Phase breakdown + status
├── STATE.md # Living memory (+ YAML frontmatter for the statusline)
├── config.json # Workflow configuration
├── MILESTONES.md # Completed-milestone archive
├── research/ # New-project research (SUMMARY/STACK/FEATURES/ARCHITECTURE/PITFALLS)
├── codebase/ # Brownfield mapping (frontmatter carries last_mapped_commit)
├── phases/XX-name/
│ ├── XX-CONTEXT.md XX-RESEARCH.md XX-YY-PLAN.md XX-YY-SUMMARY.md
│ ├── XX-VERIFICATION.md XX-VALIDATION.md XX-UI-SPEC.md XX-UI-REVIEW.md XX-UAT.md
├── quick/ todos/{pending,done}/ threads/ seeds/ debug/{,resolved}/
├── spikes/ sketches/ intel/ graphs/ ui-reviews/ forensics/ reports/
└── continue-here.md # Context handoff (from pause-work)
Data-flow summary
PROJECT.md ───────────────────► all agents
REQUIREMENTS.md ──────────────► planner, verifier, auditor
STATE.md ─────────────────────► all agents (decisions, blockers)
CONTEXT.md (per phase) ───────► researcher, planner, executor
RESEARCH.md (per phase) ──────► planner, plan-checker
PLAN.md (per plan) ───────────► executor, plan-checker
SUMMARY.md (per plan) ────────► verifier, state tracking
Note
The post-execute codebase-drift gate (#2003) compares
last_mapped_commit..HEADagainst.planning/codebase/STRUCTURE.md, counting new directories, barrel exports, migrations, and route modules. At/aboveworkflow.drift_threshold(3) it either warns or auto-remaps. It is non-blocking — any error is logged and the phase continues.
Hook System
Hooks integrate GSD with the host runtime's event model. The shipped canonical roster is 11 hooks.
| Hook | Event | Purpose |
|---|---|---|
gsd-statusline.js |
statusLine |
Model, task, dir, context-usage bar; writes /tmp/claude-ctx-{session}.json bridge |
gsd-context-monitor.js |
PostToolUse / AfterTool |
Injects context warnings at 35% / 25% remaining |
gsd-check-update.js |
SessionStart |
Foreground trigger for background update check |
gsd-check-update-worker.js |
(helper) | Background update-check worker |
gsd-prompt-guard.js |
PreToolUse |
Scans .planning/ writes for injection patterns (advisory, always on) |
gsd-read-injection-scanner.js |
PostToolUse |
Scans Read output for injected instructions in untrusted content |
gsd-workflow-guard.js |
PreToolUse |
Warns on edits outside GSD workflow context (opt-in, hooks.workflow_guard) |
gsd-read-guard.js |
PreToolUse |
Advisory guard against Edit/Write on unread files |
gsd-session-state.sh |
PostToolUse |
Session-state tracking (shell runtimes) |
gsd-validate-commit.sh |
PostToolUse |
Conventional-commit enforcement |
gsd-phase-boundary.sh |
PostToolUse |
Phase-boundary detection |
The repository also ships gsd-graphify-update.sh (detached graph rebuild after HEAD-advancing git ops when graphify.auto_update=true) and gsd-update-banner.js (opt-in SessionStart update banner).
Context-monitor thresholds
| Remaining context | Level | Agent behavior |
|---|---|---|
| > 35% | Normal | No warning |
| ≤ 35% | WARNING | "Avoid starting new complex work" |
| ≤ 25% | CRITICAL | "Context nearly exhausted, inform user" |
Debounce: 5 tool uses between repeats; severity escalation bypasses debounce.
Safety properties
All hooks wrap in try/catch and exit silently on error; a 3s stdin timeout guard prevents hangs; metrics older than 60s are ignored; missing bridge files are handled gracefully; the context monitor is advisory and never issues imperative overrides. Community hooks (gsd-validate-commit.sh, gsd-session-state.sh, gsd-phase-boundary.sh) are no-ops unless hooks.community: true.
Security Architecture
GSD's threat model recognizes that generated Markdown becomes LLM system-prompt input, so user-controlled text is an indirect-prompt-injection vector, and that an automated research → plan → execute pipeline can carry a hallucinated package all the way to npm install.
Defense-in-depth (v1.27)
- Path-traversal prevention —
--text-file/--prdpaths are validated to resolve inside the project directory (macOS/var→/private/varsymlink handling included). - Prompt-injection detection —
security.cjsscans user-supplied text for role overrides, instruction bypasses, and system-tag injection before it enters planning artifacts. - Runtime hooks —
gsd-prompt-guard.js(always on, advisory) andgsd-workflow-guard.js(opt-in). - CI scanner —
prompt-injection-scan.test.cjsscans all agent/workflow/command files for embedded injection vectors; adversarial fixtures live undertests/fixtures/adversarial/{frontmatter,roadmap,security}/.
Package-legitimacy gate (v1.42.1, anti-slopsquatting)
| Layer | Component | Action |
|---|---|---|
| Research | gsd-phase-researcher |
Runs slopcheck install <pkgs> --json; writes a Package Legitimacy Audit table; strips [SLOP] before RESEARCH.md is written |
| Planning | gsd-planner |
Inserts checkpoint:human-verify before any [ASSUMED]/[SUS] install; adds a T-{phase}-SC STRIDE supply-chain row |
| Execution | gsd-executor |
Excludes package installation from auto-fix; failed installs surface as checkpoints, never silent substitutions |
slopcheck (MIT, pip-installable) checks npm/PyPI/crates.io/RubyGems/Go/Maven/Packagist using registry age, download count, source-repo linkage, and naming distance. WebSearch-sourced names are always tagged [ASSUMED]. If slopcheck is unavailable, every package is [ASSUMED] and gated — the system never silently degrades to pre-v1.42.1 behavior.
Vulnerability reporting
Per SECURITY.md: do not file public issues. Acknowledgment within 48 hours; initial assessment within 1 week; fix targets — Critical 24–48h, High 1 week, Medium/Low next release. In-scope issues are arbitrary code execution, secret/credential exposure, and compromise of generated plan/code integrity.
Operations & Maintenance
Health & integrity
/gsd-health # Validate .planning/ integrity
/gsd-health --repair # Auto-fix recoverable issues
/gsd-health --context # Probe context-window utilization (warn 60% / critical 70%)
node gsd-tools.cjs state validate # Detect STATE.md drift
node gsd-tools.cjs state sync # Reconstruct STATE.md from disk
Diagnostics
/gsd-forensics "<problem>" # Post-mortem: git anomalies, artifact integrity, state inconsistencies
/gsd-stats # Project metrics
Executor stall detection
The execute-phase orchestrator inspects recent commits on a cadence to avoid waiting forever on a silent agent: executor.stall_detect_interval_minutes (default 5) and executor.stall_threshold_minutes (default 10). Background execute-phase runs emit [checkpoint] markers at every wave/plan boundary so the SSE stream never idles into a timeout; grep the transcript for [checkpoint] to find the last confirmed boundary after a partial failure.
Backup, update, rollback
- Local-patch backup — modified GSD files are backed up to
gsd-local-patches/; restore with/gsd-update --reapply. - Manual update — if npm is unreachable, follow
docs/manual-update.md. - Uninstall —
npx get-shit-done-cc --uninstallremoves files, hooks, and settings in one pass.
Versioning & Release Strategy
GSD follows SemVer 2.0.0 with three tiers mapped to two npm dist-tags.
| Tier | Ships | Version | npm tag | Install |
|---|---|---|---|---|
| Patch | Bug fixes | 1.27.1 |
latest |
npx get-shit-done-cc@latest |
| Minor | Fixes + enhancements | 1.28.0 |
latest (after -rc.N) |
npx get-shit-done-cc@next (RC) |
| Major | + features / breaking | 2.0.0 |
latest (after -beta.N) |
npx get-shit-done-cc@next (beta) |
Only two dist-tags exist: latest (stable) and next (opt-in pre-release). Users never receive pre-releases unless they explicitly request @next. Pre-release progression uses -rc.N for minors and -beta.N for majors. Branch types map to Conventional Commits: fix/ → PATCH, feat/ → MINOR, chore//docs//refactor/ → none. A separate canary stream publishes dev cuts under @canary (the documented version is 1.50.0-canary.0; see docs/CANARY.md).
Note
Release automation lives in GitHub Actions workflows (
release.yml,hotfix.yml,release-sdk.yml). Hotfixes branch from the highest prior patch tag and auto-cherry-pick onlyfix:/chore:commits (neverfeat:/refactor:), gated byinstall-smokecross-platform checks before publishing.
Repository Structure & Internals
get-shit-done/
├── bin/ install.js (generated), gsd-sdk.js, gsd-tools shim, lib/
├── commands/gsd/ 67 slash-command definitions
├── agents/ 33 agent definitions
├── get-shit-done/
│ ├── bin/lib/ ~33 CJS domain modules (state, phase, roadmap, config, …)
│ ├── workflows/ ~90 orchestration files (+ modes/, templates/)
│ ├── references/ shared knowledge docs
│ ├── templates/ planning-artifact templates
│ └── contexts/ curated context bundles
├── hooks/ 11 canonical hooks (+ lib/)
├── scripts/ lint/build/changeset/test tooling (.cjs)
├── sdk/
│ ├── src/ TypeScript SDK (CLI, query engine, runtime bridge, configuration, …)
│ ├── shared/ config-defaults/-schema manifests (CJS/SDK source of truth)
│ └── prompts/ SDK prompt templates
├── docs/ ARCHITECTURE, COMMANDS, CONFIGURATION, USER-GUIDE, FEATURES, ADRs, i18n
├── tests/ vitest (SDK) + node CJS suites; adversarial fixtures
└── package.json name: get-shit-done-cc, bin: get-shit-done-cc / gsd-sdk / gsd-tools
Key CJS domain modules (get-shit-done/bin/lib/)
| Module | Responsibility |
|---|---|
core.cjs |
Error handling, output formatting, planning-helper re-exports |
planning-workspace.cjs |
.planning path resolution, active-workstream routing, .lock |
state.cjs |
STATE.md parse/update/progression/metrics |
phase.cjs / roadmap.cjs |
Phase ops + decimal numbering / ROADMAP parsing + progress |
config.cjs / config-schema.cjs |
config.json read/write, schema |
verify.cjs / template.cjs / frontmatter.cjs |
Validation / template fill / YAML CRUD |
init.cjs / milestone.cjs / uat.cjs |
Compound context loading / milestone archival / UAT parsing |
security.cjs |
Path-traversal prevention, injection detection, safe JSON, shell-arg validation |
workstream.cjs / schema-detect.cjs |
Workstream CRUD / ORM schema-drift detection |
graphify.cjs |
Knowledge-graph integration (config gate, query, status, diff, build) |
worktree-safety.cjs |
Worktree lifecycle safety (porcelain parse, prune plans, health inspection) |
command-routing-hub.cjs |
Centralized CJS dispatch seam |
Important
Several
bin/lib/*.cjsfiles are generated from TypeScript sources (*.generated.cjs, with thin re-export wrappers). Do not hand-edit them — edit the SDK source and regenerate. Thecheck:*-freshnpm scripts fail CI if a generated file drifts from its source.
Testing Strategy
Tests run through node scripts/run-tests.cjs, which exposes suites: unit, integration, install, security, and slow. The SDK uses vitest (vitest.config.ts, projects unit and integration). Coverage is enforced via c8 (--check-coverage --lines 70) on get-shit-done/bin/lib/*.cjs.
| Command | Scope |
|---|---|
npm test |
Full suite (with pretest building the SDK + skill-dep lint) |
npm run test:unit / test:integration |
Targeted suites |
npm run test:install |
Cross-runtime install smoke tests |
npm run test:security |
Prompt-injection + adversarial-fixture suite |
npm run test:coverage |
Coverage gate (≥ 70% lines on CLI libs) |
A family of lint gates guards systemic quality: lint:descriptions (≤ 100-char skill descriptions), lint:skill-deps, lint:tests (no source-grep in tests), lint:test-file-count, lint:docs, lint:changeset, plus drift guards (check:*-fresh, check:alias-drift). The adversarial corpora (tests/fixtures/adversarial/{frontmatter,roadmap,security}/) feed parser- and injection-hardening tests so the corpus can grow without test-code changes.
Code Quality & Conventions
- Generator pattern for shared logic. Single TypeScript source → generated CJS twin, drift-guarded in CI. This structurally eliminates CJS/SDK divergence (the #3523 bug class).
- Module-as-seam architecture.
CONTEXT.mddocuments the codebase as a glossary of named modules with explicit seams (Dispatch Pipeline, Command Topology, Configuration, Project-Root Resolution, Workstream Inventory, Worktree Safety, etc.), each with a source-of-truth file and typed contracts. Agent briefs cite predicate IDs verbatim rather than paraphrasing. - No-throw dispatch contract. The Command Routing Hub and Sync Runtime Bridge return typed result objects rather than throwing, with a closed
errorKindenum. - Conventional Commits drive versioning; ADRs under
docs/adr/record architectural decisions (e.g. ADR-0001 error taxonomy, ADR-0008 installer migrations, ADR-0011 surface budgets, ADR-0012 routing hub, ADR-3660 runtime artifact layout). - Progressive disclosure budgets (workflow line tiers, agent ≤ 50K-char limits handled by reference-module decomposition) keep per-turn token cost bounded.
Tip
When extending GSD, the highest-leverage rule is: add a query handler in
sdk/src/query/rather than new CJS logic, then let the CJS surface route through it via the Sync Runtime Bridge / Command Routing Hub. This keeps the dual surface convergent instead of duplicating handlers.
Known Issues & Improvement Areas
These are drawn from the repository's own issue tracker (all community issues at the documented commit were CLOSED) and source observations. They are useful context for anyone forking or operating GSD.
- Namespace migration (colon → hyphen). A long tail of issues (#3862, #3865, #3868, #3873, #3874) tracked stale
/gsd:cmdcolon references in workflow templates, completion messages, and shell hooks after the hyphen-form migration. Verify any custom templates use the hyphen form (except Gemini, which uses colon). gsd-surfaceno-op on 1.42.3 (#3879). The surface fix merged to main but was not released to npm on that version — a reminder to validate that/gsd-surfaceactually toggles on your installed version.- Read-injection scanner vs extended thinking (#3878). The
gsd-read-injection-scannerPostToolUse hook could crash extended-thinking sessions with a 400 "thinking blocks cannot be modified". Confirm hook compatibility with your runtime's thinking mode. - STATE.md milestone counter corruption (#3880, #3881, #3866). Several edge cases where
state planned-phase/state.complete-phasestomped milestone progress counters. If milestone progress looks wrong, runstate validatethenstate sync. - Codex CLI version floor. Codex
< 0.130.0discovers GSD skills from alternate roots and can show duplicate listings;>= 0.130.0is the supported floor. code_quality.fallow.mcpis reserved and currently a no-op (emits a runtime warning if settrue).- Generated-file discipline. Because
bin/lib/*.generated.cjsfiles are machine-emitted, contributors must regenerate rather than hand-edit; thecheck:*-freshgates exist precisely because this is easy to get wrong.
Quick Reference
CLI entry points
| Binary | Resolves to | Use |
|---|---|---|
get-shit-done-cc |
bin/install.js |
Install / uninstall |
gsd-sdk / gsd-tools |
sdk/dist/cli.js (via shim) |
Programmatic query CLI |
Operational commands
| Need | Command |
|---|---|
| Validate install state | /gsd-health (--repair, --context) |
| Repair STATE.md | node gsd-tools.cjs state sync |
| Diagnose a failed workflow | /gsd-forensics |
| Switch model cost profile | /gsd-config --profile budget|quality|inherit |
| Toggle surfaced skills | /gsd-surface profile|disable|enable|reset |
| Update / reapply patches | /gsd-update --sync|--reapply |
| Uninstall | npx get-shit-done-cc --uninstall |
Key facts
| Fact | Value |
|---|---|
| Package | get-shit-done-cc v1.50.0-canary.0 (SDK: @gsd-build/sdk) |
| Author / License | TÂCHES / MIT |
| Node | >= 22.0.0 |
| Surface | 67 commands · 33 agents · ~90 workflows · 11 canonical hooks · 15 runtimes |
| Runtime deps | @anthropic-ai/claude-agent-sdk, ws (+ synckit in SDK) |
| State | .planning/ (Markdown + JSON, no DB) |
| Successor | github.com/open-gsd/gsd-core |