Files
msd-core/docs/ARCHITECTURE.md
Jeremy McSpadden 4d394a249d fix(commands): normalize gsd slash namespace drift (#2858)
* fix(commands): normalize gsd slash namespace drift

* fix(#2855): address CodeRabbit findings on namespace drift PR

Three CR findings, all valid:

1. autonomous.md line 783 still had `gsd:discuss-phase` (the PR's own
   normalization missed this line). Switched to `gsd-discuss-phase` and
   updated the matching test in autonomous-interactive.test.cjs that was
   asserting the now-retired colon form.

2. tests/bug-2543-gsd-slash-namespace.test.cjs source-grepped the
   fix-slash-commands.cjs script with .includes() rather than driving
   its transform behaviour. Refactored fix-slash-commands.cjs to export
   a pure transformContent(src, cmdNames) function, kept the CLI behaviour
   unchanged via require.main, and replaced the source-grep block with
   five behavioural cases: rewrite, multi-occurrence, idempotence on
   canonical input, no-op on gsd-sdk/gsd-tools, and word-boundary safety.

3. tests/bug-2808-skill-hyphen-name.test.cjs matched `name:` anywhere
   in SKILL.md; a stray name: in the body could satisfy the assertion.
   Scoped the lookup to the YAML frontmatter block via the suggested
   diff (parse the leading --- ... --- region first, then find name:
   inside it).

Full suite: 5854/5854 passing.

* fix(#2855): address remaining CodeRabbit findings on PR #2858

Three structural concerns flagged on the namespace-drift fix PR:

1. scripts/fix-slash-commands.cjs:24 — `buildPattern([])` compiled
   `/gsd:()(?=[^a-zA-Z0-9_-]|$)/g`. The empty capture group still
   matches any `/gsd:` token followed by a non-word boundary
   (whitespace, EOL, punctuation), rewriting it to a stray `/gsd-`.
   Verified live: `transformContent("/gsd:", [])` → `"/gsd-"`. Added
   a guard returning null from `buildPattern` on empty input and
   updated `transformContent` and `processDir` to no-op when the
   pattern is null.

2. tests/autonomous-interactive.test.cjs:44-47 — assertion was
   `content.includes('gsd-discuss-phase') && content.includes('INTERACTIVE')`,
   which would false-pass on any unrelated co-occurrence (e.g.
   `INTERACTIVE=""` initialization plus a stray `gsd-discuss-phase`
   prose mention). Replaced with a structural extraction: locate the
   `**If \`INTERACTIVE\` is set:**` branch, bound it by the next
   `**If` / `<step>` boundary, and assert the
   `Skill(skill="gsd-discuss-phase", ...)` invocation lives inside
   that region. Tolerates whitespace around `(`, `skill`, and `=`.

3. tests/bug-2808-skill-hyphen-name.test.cjs:104 — colon-call regex
   was `Skill\(skill=...` and missed valid formatting like
   `Skill(skill = "gsd:cmd")` or `Skill( skill = ...)`. Loosened to
   `Skill\(\s*skill\s*=\s*...` so reformatting drift can't slip past
   the namespace guard.

Verification: 5854/5854 pass on `npm test` from the rebased branch.

* fix(#2855): drop pre-validation filter that hid namespace drift

CR finding on tests/bug-2808-skill-hyphen-name.test.cjs:128: the test
collected generated skill directories with
`.filter(entry => entry.isDirectory() && entry.name.startsWith('gsd-'))`,
then validated namespace invariants over that filtered list. Anything
that violated the prefix invariant — `gsd:extract-learnings` (colon
form), `extract_learnings` without prefix, `Gsd-foo` mis-cased — would
silently disappear from the iteration and the test would falsely pass.

Drop the `startsWith('gsd-')` filter so every generated directory shows
up. Add explicit assertions before the existing per-skill loop:
  - directory list is non-empty (catches a broken converter that
    produces nothing)
  - every directory begins with `gsd-`
  - every directory contains no `:`
  - every directory contains no `_`

Re-audited the full PR diff for the same anti-pattern: only this one
site filtered before validating the namespace; bug-2643 and
commands-doc-parity also use `readdirSync().filter()` but only by file
extension, which is correct.

5854/5854 on `npm test`.

* fix(#2855): address remaining CR findings (1 active + 2 nitpicks)

Three findings on PR #2858, all the same root cause: input narrowing
before validation lets drift slip past the guards.

1. tests/bug-2808-...:104 (active) — `colonCallRe` captured local names
   with `[a-z0-9-]+`, which excluded the underscore. A drift like
   `Skill(skill="gsd:extract_learnings")` (deprecated colon syntax with
   the old underscore filename) silently slid through. Broadened the
   capture to `[^'"\s)]+` so any malformed local name is surfaced; surrounding pattern (whitespace tolerance, escape support, flags)
   unchanged.

2. tests/bug-2643-...:43 (nitpick) — `extractSkillNamesHyphen` and
   `extractSkillNamesColon` had the same over-strict capture plus
   relied on a single regex over raw bytes, which the project test-
   rigor memory bans (`feedback_no_source_grep_tests.md`). Replaced
   with `extractSkillCalls(content)` — a small structural extractor
   that walks `Skill(` openers, locates each call's matching `)`,
   parses the body's `skill = "..."` keyword argument with permissive
   whitespace + quoting + escape handling, and returns
   `{ name, raw }` records. The two namespace-form helpers become
   thin filters over the structured output. Tightened the body class
   to `[^'"\\]+` so a trailing escape `\` before the closing quote
   (as in `Skill(skill=\"gsd-foo\", …)` written inside another string
   context) doesn't get included in the captured name.

3. tests/bug-2543-...:44 (nitpick) — `DOC_SEARCH_FILES` was a hand-
   curated 7-entry array. Every doc added in the future would silently
   weaken drift detection until someone remembered to extend the list.
   Replaced with `discoverDocSearchFiles(ROOT)`: globs every `.md`
   under `docs/` and adds `README.md` if present. New docs are picked
   up automatically.

Re-audited the diff surface for similar narrowings; no other sites
filter or constrain before validating namespace invariants.

5854/5854 on `npm test`.

* fix(#2855): recurse docs/ tree so localized translations are scanned too

CR finding: discoverDocSearchFiles() stopped at docs/*.md, leaving
localized translation trees (docs/ja-JP/, docs/zh-CN/, docs/ko-KR/,
docs/pt-BR/) and other nested doc collections (docs/skills/,
docs/superpowers/) invisible to the namespace-drift invariant.

Verified the gap: docs/ has 6 nested directories with ~30 .md files
that the previous top-level-only scan was skipping. None contain
/gsd: references today, but a future translation update or new
doc subdir could leak drift.

Switch to an iterative stack walk so every .md under docs/ is scanned
regardless of depth. Stack form (rather than recursion) avoids the
risk of running into the call-stack limit on deep doc trees.

5854/5854 on `npm test`.

---------

Co-authored-by: Tom Boucher <trekkie@nomorestars.com>
2026-04-29 22:56:59 -04:00

37 KiB

GSD Architecture

System architecture for contributors and advanced users. For user-facing documentation, see Feature Reference or User Guide.


Table of Contents


System Overview

GSD is a meta-prompting framework that sits between the user and AI coding agents (Claude Code, Gemini CLI, OpenCode, Kilo, Codex, Copilot, Antigravity, Trae, Cline, Augment Code). It provides:

  1. Context engineering — Structured artifacts that give the AI everything it needs per task
  2. Multi-agent orchestration — Thin orchestrators that spawn specialized agents with fresh context windows
  3. Spec-driven development — Requirements → research → plans → execution → verification pipeline
  4. State management — Persistent project memory across sessions and context resets
┌──────────────────────────────────────────────────────┐
│                      USER                            │
│            /gsd-command [args]                        │
└─────────────────────┬────────────────────────────────┘
                      │
┌─────────────────────▼────────────────────────────────┐
│              COMMAND LAYER                            │
│   commands/gsd/*.md — Prompt-based command files      │
│   (Claude Code custom commands / Codex skills)        │
└─────────────────────┬────────────────────────────────┘
                      │
┌─────────────────────▼────────────────────────────────┐
│              WORKFLOW LAYER                           │
│   get-shit-done/workflows/*.md — Orchestration logic  │
│   (Reads references, spawns agents, manages state)    │
└──────┬──────────────┬─────────────────┬──────────────┘
       │              │                 │
┌──────▼──────┐ ┌─────▼─────┐ ┌────────▼───────┐
│  AGENT      │ │  AGENT    │ │  AGENT         │
│  (fresh     │ │  (fresh   │ │  (fresh        │
│   context)  │ │   context)│ │   context)     │
└──────┬──────┘ └─────┬─────┘ └────────┬───────┘
       │              │                 │
┌──────▼──────────────▼─────────────────▼──────────────┐
│              CLI TOOLS LAYER                          │
│   gsd-sdk query (sdk/src/query) + gsd-tools.cjs       │
│   (State, config, phase, roadmap, verify, templates)  │
└──────────────────────┬───────────────────────────────┘
                       │
┌──────────────────────▼───────────────────────────────┐
│              FILE SYSTEM (.planning/)                 │
│   PROJECT.md | REQUIREMENTS.md | ROADMAP.md          │
│   STATE.md | config.json | phases/ | research/       │
└──────────────────────────────────────────────────────┘

Design Principles

1. Fresh Context Per Agent

Every agent spawned by an orchestrator gets a clean context window (up to 200K tokens). This eliminates context rot — the quality degradation that happens as an AI fills its context window with accumulated conversation.

2. Thin Orchestrators

Workflow files (get-shit-done/workflows/*.md) never do heavy lifting. They:

  • Load context via gsd-sdk query init.<workflow> (or legacy gsd-tools.cjs init <workflow>)
  • Spawn specialized agents with focused prompts
  • Collect results and route to the next step
  • Update state between steps

3. File-Based State

All state lives in .planning/ as human-readable Markdown and JSON. No database, no server, no external dependencies. This means:

  • State survives context resets (/clear)
  • State is inspectable by both humans and agents
  • State can be committed to git for team visibility

4. Absent = Enabled

Workflow feature flags follow the absent = enabled pattern. If a key is missing from config.json, it defaults to true. Users explicitly disable features; they don't need to enable defaults.

5. Defense in Depth

Multiple layers prevent common failure modes:

  • Plans are verified before execution (plan-checker agent)
  • Execution produces atomic commits per task
  • Post-execution verification checks against phase goals
  • UAT provides human verification as final gate

Component Architecture

Commands (commands/gsd/*.md)

User-facing entry points. Each file contains YAML frontmatter (name, description, allowed-tools) and a prompt body that bootstraps the workflow. Commands are installed as:

  • Claude Code: Custom slash commands (/gsd-command-name)
  • OpenCode / Kilo: Slash commands (/gsd-command-name)
  • Codex: Skills ($gsd-command-name)
  • Copilot: Slash commands (/gsd-command-name)
  • Antigravity: Skills

Total commands: see docs/INVENTORY.md for the authoritative count and full roster.

Workflows (get-shit-done/workflows/*.md)

Orchestration logic that commands reference. Contains the step-by-step process including:

  • Context loading via gsd-sdk query init handlers (or legacy gsd-tools.cjs init)
  • Agent spawn instructions with model resolution
  • Gate/checkpoint definitions
  • State update patterns
  • Error handling and recovery

Total workflows: see docs/INVENTORY.md for the authoritative count and full roster.

Progressive disclosure for workflows

Workflow files are loaded verbatim into Claude's context every time the corresponding /gsd-* command is invoked. To keep that cost bounded, the workflow size budget enforced by tests/workflow-size-budget.test.cjs mirrors the agent budget from #2361:

Tier Per-file line limit
XL 1700 — top-level orchestrators (execute-phase, plan-phase, new-project)
LARGE 1500 — multi-step planners and large feature workflows
DEFAULT 1000 — focused single-purpose workflows (the target tier)

workflows/discuss-phase.md is held to a stricter <500-line ceiling per issue #2551. When a workflow grows beyond its tier, extract per-mode bodies into workflows/<workflow>/modes/<mode>.md, templates into workflows/<workflow>/templates/, and shared knowledge into get-shit-done/references/. The parent file becomes a thin dispatcher that Reads only the mode and template files needed for the current invocation.

workflows/discuss-phase/ is the canonical example of this pattern — parent dispatches, modes/ holds per-flag behavior (power.md, all.md, auto.md, chain.md, text.md, batch.md, analyze.md, default.md, advisor.md), and templates/ holds CONTEXT.md, DISCUSSION-LOG.md, and checkpoint.json schemas that are read only when the corresponding output file is being written.

Agents (agents/*.md)

Specialized agent definitions with frontmatter specifying:

  • name — Agent identifier
  • description — Role and purpose
  • tools — Allowed tool access (Read, Write, Edit, Bash, Grep, Glob, WebSearch, etc.)
  • color — Terminal output color for visual distinction

Total agents: 33

References (get-shit-done/references/*.md)

Shared knowledge documents that workflows and agents @-reference (see docs/INVENTORY.md for the authoritative count and full roster):

Core references:

  • checkpoints.md — Checkpoint type definitions and interaction patterns
  • gates.md — 4 canonical gate types (Confirm, Quality, Safety, Transition) wired into plan-checker and verifier
  • model-profiles.md — Per-agent model tier assignments
  • model-profile-resolution.md — Model resolution algorithm documentation
  • verification-patterns.md — How to verify different artifact types
  • verification-overrides.md — Per-artifact verification override rules
  • planning-config.md — Full config schema and behavior
  • git-integration.md — Git commit, branching, and history patterns
  • git-planning-commit.md — Planning directory commit conventions
  • questioning.md — Dream extraction philosophy for project initialization
  • tdd.md — Test-driven development integration patterns
  • ui-brand.md — Visual output formatting patterns
  • common-bug-patterns.md — Common bug patterns for code review and verification

Workflow references:

  • agent-contracts.md — Formal interface between orchestrators and agents
  • context-budget.md — Context window budget allocation rules
  • continuation-format.md — Session continuation/resume format
  • domain-probes.md — Domain-specific probing questions for discuss-phase
  • gate-prompts.md — Gate/checkpoint prompt templates
  • revision-loop.md — Plan revision iteration patterns
  • universal-anti-patterns.md — Common anti-patterns to detect and avoid
  • artifact-types.md — Planning artifact type definitions
  • phase-argument-parsing.md — Phase argument parsing conventions
  • decimal-phase-calculation.md — Decimal sub-phase numbering rules
  • workstream-flag.md — Workstream active pointer conventions
  • user-profiling.md — User behavioral profiling methodology
  • thinking-partner.md — Conditional thinking partner activation at decision points

Thinking model references:

References for integrating thinking-class models (o3, o4-mini, Gemini 2.5 Pro) into GSD workflows:

  • thinking-models-debug.md — Thinking model patterns for debugging workflows
  • thinking-models-execution.md — Thinking model patterns for execution agents
  • thinking-models-planning.md — Thinking model patterns for planning agents
  • thinking-models-research.md — Thinking model patterns for research agents
  • thinking-models-verification.md — Thinking model patterns for verification agents

Modular planner decomposition:

The planner agent (agents/gsd-planner.md) was decomposed from a single monolithic file into a core agent plus reference modules to stay under the 50K character limit imposed by some runtimes:

  • planner-gap-closure.md — Gap closure mode behavior (reads VERIFICATION.md, targeted replanning)
  • planner-reviews.md — Cross-AI review integration (reads REVIEWS.md from /gsd-review)
  • planner-revision.md — Plan revision patterns for iterative refinement

Templates (get-shit-done/templates/)

Markdown templates for all planning artifacts. Used by gsd-sdk query template.fill / phase.scaffold (and legacy gsd-tools.cjs template fill / top-level scaffold) to create pre-structured files:

  • project.md, requirements.md, roadmap.md, state.md — Core project files
  • phase-prompt.md — Phase execution prompt template
  • summary.md (+ summary-minimal.md, summary-standard.md, summary-complex.md) — Granularity-aware summary templates
  • DEBUG.md — Debug session tracking template
  • UI-SPEC.md, UAT.md, VALIDATION.md — Specialized verification templates
  • discussion-log.md — Discussion audit trail template
  • codebase/ — Brownfield mapping templates (stack, architecture, conventions, concerns, structure, testing, integrations)
  • research-project/ — Research output templates (SUMMARY, STACK, FEATURES, ARCHITECTURE, PITFALLS)

Hooks (hooks/)

Runtime hooks that integrate with the host AI agent:

Hook Event Purpose
gsd-statusline.js statusLine Displays model, task, directory, and context usage bar
gsd-context-monitor.js PostToolUse / AfterTool Injects agent-facing context warnings at 35%/25% remaining
gsd-check-update.js SessionStart Foreground trigger for the background update check
gsd-check-update-worker.js (helper) Background worker spawned by gsd-check-update.js; no direct event registration
gsd-prompt-guard.js PreToolUse Scans .planning/ writes for prompt injection patterns (advisory)
gsd-read-injection-scanner.js PostToolUse Scans Read tool output for injected instructions in untrusted content
gsd-workflow-guard.js PreToolUse Detects file edits outside GSD workflow context (advisory, opt-in via hooks.workflow_guard)
gsd-read-guard.js PreToolUse Advisory guard preventing Edit/Write on files not yet read in the session
gsd-session-state.sh PostToolUse Session state tracking for shell-based runtimes
gsd-validate-commit.sh PostToolUse Commit validation for conventional commit enforcement
gsd-phase-boundary.sh PostToolUse Phase boundary detection for workflow transitions

See docs/INVENTORY.md for the authoritative 11-hook roster.

CLI Tools (get-shit-done/bin/)

Node.js CLI utility (gsd-tools.cjs) with domain modules split across get-shit-done/bin/lib/ (see docs/INVENTORY.md for the authoritative roster):

Module Responsibility
core.cjs Error handling, output formatting, shared utilities
state.cjs STATE.md parsing, updating, progression, metrics
phase.cjs Phase directory operations, decimal numbering, plan indexing
roadmap.cjs ROADMAP.md parsing, phase extraction, plan progress
config.cjs config.json read/write, section initialization
verify.cjs Plan structure, phase completeness, reference, commit validation
template.cjs Template selection and filling with variable substitution
frontmatter.cjs YAML frontmatter CRUD operations
init.cjs Compound context loading for each workflow type
milestone.cjs Milestone archival, requirements marking
commands.cjs Misc commands (slug, timestamp, todos, scaffolding, stats)
model-profiles.cjs Model profile resolution table
security.cjs Path traversal prevention, prompt injection detection, safe JSON parsing, shell argument validation
uat.cjs UAT file parsing, verification debt tracking, audit-uat support
docs.cjs Docs-update workflow init, Markdown scanning, monorepo detection
workstream.cjs Workstream CRUD, migration, session-scoped active pointer
schema-detect.cjs Schema-drift detection for ORM patterns (Prisma, Drizzle, etc.)
profile-pipeline.cjs User behavioral profiling data pipeline, session file scanning
profile-output.cjs Profile rendering, USER-PROFILE.md and dev-preferences.md generation

Agent Model

Orchestrator → Agent Pattern

Orchestrator (workflow .md)
    │
    ├── Load context: gsd-sdk query init.<workflow> <phase> (or legacy gsd-tools.cjs init)
    │   Returns JSON with: project info, config, state, phase details
    │
    ├── Resolve model: gsd-sdk query resolve-model <agent-name>
    │   Returns: opus | sonnet | haiku | inherit
    │
    ├── Spawn Agent (Task/SubAgent call)
    │   ├── Agent prompt (agents/*.md)
    │   ├── Context payload (init JSON)
    │   ├── Model assignment
    │   └── Tool permissions
    │
    ├── Collect result
    │
    └── Update state: gsd-sdk query state.update / state.patch / state.advance-plan (or legacy gsd-tools.cjs)

Primary Agent Spawn Categories

Conceptual spawn-pattern taxonomy for the 21 primary agents. For the authoritative 31-agent roster (including the 10 advanced/specialized agents such as gsd-pattern-mapper, gsd-code-reviewer, gsd-code-fixer, gsd-ai-researcher, gsd-domain-researcher, gsd-eval-planner, gsd-eval-auditor, gsd-framework-selector, gsd-debug-session-manager, gsd-intel-updater), see docs/INVENTORY.md.

Category Agents Parallelism
Researchers gsd-project-researcher, gsd-phase-researcher, gsd-ui-researcher, gsd-advisor-researcher 4 parallel (stack, features, architecture, pitfalls); advisor spawns during discuss-phase
Synthesizers gsd-research-synthesizer Sequential (after researchers complete)
Planners gsd-planner, gsd-roadmapper Sequential
Checkers gsd-plan-checker, gsd-integration-checker, gsd-ui-checker, gsd-nyquist-auditor Sequential (verification loop, max 3 iterations)
Executors gsd-executor Parallel within waves, sequential across waves
Verifiers gsd-verifier Sequential (after all executors complete)
Mappers gsd-codebase-mapper 4 parallel (tech, arch, quality, concerns)
Debuggers gsd-debugger Sequential (interactive)
Auditors gsd-ui-auditor, gsd-security-auditor Sequential
Doc Writers gsd-doc-writer, gsd-doc-verifier Sequential (writer then verifier)
Profilers gsd-user-profiler Sequential
Analyzers gsd-assumptions-analyzer Sequential (during discuss-phase)

Wave Execution Model

During execute-phase, plans are grouped into dependency waves:

Wave Analysis:
  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 gets:

  • Fresh 200K context window (or up to 1M for models that support it)
  • The specific PLAN.md to execute
  • Project context (PROJECT.md, STATE.md)
  • Phase context (CONTEXT.md, RESEARCH.md if available)

Adaptive Context Enrichment (1M Models)

When the context window is 500K+ tokens (1M-class models like Opus 4.6, Sonnet 4.6), subagent prompts are automatically enriched with additional context that would not fit in standard 200K windows:

  • Executor agents receive prior wave SUMMARY.md files and the phase CONTEXT.md/RESEARCH.md, enabling cross-plan awareness within a phase
  • Verifier agents receive all PLAN.md, SUMMARY.md, CONTEXT.md files plus REQUIREMENTS.md, enabling history-aware verification

The orchestrator reads context_window from config (gsd-sdk query config-get context_window, or legacy gsd-tools.cjs config-get) and conditionally includes richer context when the value is >= 500,000. For standard 200K windows, prompts use truncated versions with cache-friendly ordering to maximize context efficiency.

Parallel Commit Safety

When multiple executors run within the same wave, two mechanisms prevent conflicts:

  1. --no-verify commits — Parallel agents skip pre-commit hooks (which can cause build lock contention, e.g., cargo lock fights in Rust projects). The orchestrator runs git hook run pre-commit once after each wave completes.
  2. STATE.md file locking — All writeStateMd() calls use lockfile-based mutual exclusion (STATE.md.lock with O_EXCL atomic creation). This prevents the read-modify-write race condition where two agents read STATE.md, modify different fields, and the last writer overwrites the other's changes. Includes stale lock detection (10s timeout) and spin-wait with jitter.

Data Flow

New Project Flow

User input (idea description)
    │
    ▼
Questions (questioning.md philosophy)
    │
    ▼
4x Project Researchers (parallel)
    ├── Stack → STACK.md
    ├── Features → FEATURES.md
    ├── Architecture → ARCHITECTURE.md
    └── Pitfalls → PITFALLS.md
    │
    ▼
Research Synthesizer → SUMMARY.md
    │
    ▼
Requirements extraction → REQUIREMENTS.md
    │
    ▼
Roadmapper → ROADMAP.md
    │
    ▼
User approval → STATE.md initialized

Phase Execution Flow

discuss-phase → CONTEXT.md (user preferences)
    │
    ▼
ui-phase → UI-SPEC.md (design contract, optional)
    │
    ▼
plan-phase
    ├── Research gate (blocks if RESEARCH.md has unresolved open questions)
    ├── Phase Researcher → RESEARCH.md
    ├── Planner (with reachability check) → PLAN.md files
    ├── Plan Checker → Verify loop (max 3x)
    ├── Requirements coverage gate (REQ-IDs → plans)
    └── Decision coverage gate (CONTEXT.md `<decisions>` → plans, BLOCKING — #2492)
    │
    ▼
state planned-phase → STATE.md (Planned/Ready to execute)
    │
    ▼
execute-phase (context reduction: truncated prompts, cache-friendly ordering)
    ├── Wave analysis (dependency grouping)
    ├── Executor per plan → code + atomic commits
    ├── SUMMARY.md per plan
    └── Verifier → VERIFICATION.md
        └── Decision coverage gate (CONTEXT.md decisions → shipped artifacts, NON-BLOCKING — #2492)
    │
    ▼
verify-work → UAT.md (user acceptance testing)
    │
    ▼
ui-review → UI-REVIEW.md (visual audit, optional)

Context Propagation

Each workflow stage produces artifacts that feed into subsequent stages:

PROJECT.md ────────────────────────────────────────────► All agents
REQUIREMENTS.md ───────────────────────────────────────► Planner, Verifier, Auditor
ROADMAP.md ────────────────────────────────────────────► Orchestrators
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
UI-SPEC.md (per phase) ────────────────────────────────► Executor, UI Auditor

File System Layout

Installation Files

~/.claude/                          # Claude Code (global install)
├── commands/gsd/*.md               # Slash commands (authoritative roster: docs/INVENTORY.md)
├── get-shit-done/
│   ├── bin/gsd-tools.cjs           # CLI utility
│   ├── bin/lib/*.cjs               # Domain modules (authoritative roster: docs/INVENTORY.md)
│   ├── workflows/*.md              # Workflow definitions (authoritative roster: docs/INVENTORY.md)
│   ├── references/*.md             # Shared reference docs (authoritative roster: docs/INVENTORY.md)
│   └── templates/                  # Planning artifact templates
├── agents/*.md                     # Agent definitions (authoritative roster: docs/INVENTORY.md)
├── hooks/*.js                      # Node.js hooks (statusline, guards, monitors, update check)
├── hooks/*.sh                      # Shell hooks (session state, commit validation, phase boundary)
├── settings.json                   # Hook registrations
└── VERSION                         # Installed version number

Equivalent paths for other runtimes:

  • OpenCode: ~/.config/opencode/ or ~/.opencode/
  • Kilo: ~/.config/kilo/ or ~/.kilo/
  • Gemini CLI: ~/.gemini/
  • Codex: ~/.codex/ (uses skills instead of commands)
  • Copilot: ~/.github/
  • Antigravity: ~/.gemini/antigravity/ (global) or ./.agent/ (local)

Project Files (.planning/)

.planning/
├── PROJECT.md              # Project vision, constraints, decisions, evolution rules
├── REQUIREMENTS.md         # Scoped requirements (v1/v2/out-of-scope)
├── ROADMAP.md              # Phase breakdown with status tracking
├── STATE.md                # Living memory: position, decisions, blockers, metrics
├── config.json             # Workflow configuration
├── MILESTONES.md           # Completed milestone archive
├── research/               # Domain research from /gsd-new-project
│   ├── SUMMARY.md
│   ├── STACK.md
│   ├── FEATURES.md
│   ├── ARCHITECTURE.md
│   └── PITFALLS.md
├── codebase/               # Brownfield mapping (from /gsd-map-codebase)
│   ├── STACK.md            # YAML frontmatter carries `last_mapped_commit`
│   ├── ARCHITECTURE.md     # for the post-execute drift gate (#2003)
│   ├── CONVENTIONS.md
│   ├── CONCERNS.md
│   ├── STRUCTURE.md
│   ├── TESTING.md
│   └── INTEGRATIONS.md
├── phases/
│   └── XX-phase-name/
│       ├── XX-CONTEXT.md       # User preferences (from discuss-phase)
│       ├── XX-RESEARCH.md      # Ecosystem research (from plan-phase)
│       ├── XX-YY-PLAN.md       # Execution plans
│       ├── XX-YY-SUMMARY.md    # Execution outcomes
│       ├── XX-VERIFICATION.md  # Post-execution verification
│       ├── XX-VALIDATION.md    # Nyquist test coverage mapping
│       ├── XX-UI-SPEC.md       # UI design contract (from ui-phase)
│       ├── XX-UI-REVIEW.md     # Visual audit scores (from ui-review)
│       └── XX-UAT.md           # User acceptance test results
├── quick/                  # Quick task tracking
│   └── YYMMDD-xxx-slug/
│       ├── PLAN.md
│       └── SUMMARY.md
├── todos/
│   ├── pending/            # Captured ideas
│   └── done/               # Completed todos
├── threads/               # Persistent context threads (from /gsd-thread)
├── seeds/                 # Forward-looking ideas (from /gsd-plant-seed)
├── debug/                  # Active debug sessions
│   ├── *.md                # Active sessions
│   ├── resolved/           # Archived sessions
│   └── knowledge-base.md   # Persistent debug learnings
├── ui-reviews/             # Screenshots from /gsd-ui-review (gitignored)
└── continue-here.md        # Context handoff (from pause-work)

Post-Execute Codebase Drift Gate (#2003)

After the last wave of /gsd-execute-phase commits, the workflow runs a non-blocking codebase_drift_gate step (between schema_drift_gate and verify_phase_goal). It compares the diff last_mapped_commit..HEAD against .planning/codebase/STRUCTURE.md and counts four kinds of structural elements:

  1. New directories outside mapped paths
  2. New barrel exports at (packages|apps)/<name>/src/index.*
  3. New migration files
  4. New route modules under routes/ or api/

If the count meets workflow.drift_threshold (default 3), the gate either warns (default) with the suggested /gsd-map-codebase --paths … command, or auto-remaps (workflow.drift_action = auto-remap) by spawning gsd-codebase-mapper scoped to the affected paths. Any error in detection or remap is logged and the phase continues — drift detection cannot fail verification.

last_mapped_commit lives in YAML frontmatter at the top of each .planning/codebase/*.md file; bin/lib/drift.cjs provides readMappedCommit and writeMappedCommit round-trip helpers.


Installer Architecture

The installer (bin/install.js, ~3,000 lines) handles:

  1. Runtime detection — Interactive prompt or CLI flags (--claude, --opencode, --gemini, --kilo, --codex, --copilot, --antigravity, --cursor, --windsurf, --trae, --cline, --augment, --all)
  2. Location selection — Global (--global) or local (--local)
  3. File deployment — Copies commands, workflows, references, templates, agents, hooks
  4. Runtime adaptation — Transforms file content per runtime:
  • Claude Code: Uses as-is
  • OpenCode: Converts commands/agents to OpenCode-compatible flat command + subagent format
  • Kilo: Reuses the OpenCode conversion pipeline with Kilo config paths
  • Codex: Generates TOML config + skills from commands
  • Copilot: Maps tool names (Read→read, Bash→execute, etc.)
  • Gemini: Adjusts hook event names (AfterTool instead of PostToolUse)
  • Antigravity: Skills-first with Google model equivalents
  • Trae: Skills-first install to ~/.trae / ./.trae with no settings.json or hook integration
  • Cline: Writes .clinerules for rule-based integration
  • Augment Code: Skills-first with full skill conversion and config management
  1. Path normalization — Replaces ~/.claude/ paths with runtime-specific paths
  2. Settings integration — Registers hooks in runtime's settings.json
  3. Patch backup — Since v1.17, backs up locally modified files to gsd-local-patches/ for /gsd-reapply-patches
  4. Manifest tracking — Writes gsd-file-manifest.json for clean uninstall
  5. Uninstall mode — --uninstall removes all GSD files, hooks, and settings

Platform Handling

  • Windows: windowsHide on child processes, EPERM/EACCES protection on protected directories, path separator normalization
  • WSL: Detects Windows Node.js running on WSL and warns about path mismatches
  • Docker/CI: Supports CLAUDE_CONFIG_DIR env var for custom config directory locations

Hook System

Architecture

Runtime Engine (Claude Code / Gemini CLI)
    │
    ├── statusLine event ──► gsd-statusline.js
    │   Reads: stdin (session JSON)
    │   Writes: stdout (formatted status), /tmp/claude-ctx-{session}.json (bridge)
    │
    ├── PostToolUse/AfterTool event ──► gsd-context-monitor.js
    │   Reads: stdin (tool event JSON), /tmp/claude-ctx-{session}.json (bridge)
    │   Writes: stdout (hookSpecificOutput with additionalContext warning)
    │
    └── SessionStart event ──► gsd-check-update.js
        Reads: VERSION file
        Writes: ~/.claude/cache/gsd-update-check.json (spawns background process)

Context Monitor Thresholds

Remaining Context Level Agent Behavior
> 35% Normal No warning injected
≤ 35% WARNING "Avoid starting new complex work"
≤ 25% CRITICAL "Context nearly exhausted, inform user"

Debounce: 5 tool uses between repeated warnings. Severity escalation (WARNING→CRITICAL) bypasses debounce.

Safety Properties

  • All hooks wrap in try/catch, exit silently on error
  • stdin timeout guard (3s) prevents hanging on pipe issues
  • Stale metrics (>60s old) are ignored
  • Missing bridge files handled gracefully (subagents, fresh sessions)
  • Context monitor is advisory — never issues imperative commands that override user preferences

Security Hooks (v1.27)

Prompt Guard (gsd-prompt-guard.js):

  • Triggers on Write/Edit to .planning/ files
  • Scans content for prompt injection patterns (role override, instruction bypass, system tag injection)
  • Advisory-only — logs detection, does not block
  • Patterns are inlined (subset of security.cjs) for hook independence

Workflow Guard (gsd-workflow-guard.js):

  • Triggers on Write/Edit to non-.planning/ files
  • Detects edits outside GSD workflow context (no active /gsd- command or Task subagent)
  • Advises using /gsd-quick or /gsd-fast for state-tracked changes
  • Opt-in via hooks.workflow_guard: true (default: false)

Runtime Abstraction

GSD supports multiple AI coding runtimes through a unified command/workflow architecture:

Runtime Command Format Agent System Config Location
Claude Code /gsd-command Task spawning ~/.claude/
OpenCode /gsd-command Subagent mode ~/.config/opencode/
Kilo /gsd-command Subagent mode ~/.config/kilo/
Gemini CLI /gsd-command Task spawning ~/.gemini/
Codex $gsd-command Skills ~/.codex/
Copilot /gsd-command Agent delegation ~/.github/
Antigravity Skills Skills ~/.gemini/antigravity/
Trae Skills Skills ~/.trae/
Cline Rules Rules .clinerules
Augment Code Skills Skills Augment config

Abstraction Points

  1. Tool name mapping — Each runtime has its own tool names (e.g., Claude's Bash → Copilot's execute)
  2. Hook event names — Claude uses PostToolUse, Gemini uses AfterTool
  3. Agent frontmatter — Each runtime has its own agent definition format
  4. Path conventions — Each runtime stores config in different directories
  5. Model references — inherit profile lets GSD defer to runtime's model selection

The installer handles all translation at install time. Workflows and agents are written in Claude Code's native format and transformed during deployment.