docs: rebrand to GSD Core and restructure docs with Diataxis (#605)

* chore: wire docs/agents config into AGENTS.md Agent skills section

Add the `## Agent skills` discovery block pointing the engineering
skills at the existing docs/agents/{issue-tracker,triage-labels,domain}.md
files (issue tracker, triage label mapping, single-context domain docs).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* docs: rebrand to GSD Core and restructure docs with Diataxis

Reorganise the root README and docs/ around the Diataxis framework
(tutorials, how-to guides, reference, explanation), add new how-to
guides and schema references (STATE.md / CONTEXT.md / PLAN.md /
planning artifacts), and cross-link the whole set. Update the lone
legacy gsd-build reference to open-gsd; keep internal get-shit-done/
filesystem paths unchanged (directory rename tracked separately in
open-gsd/gsd-core#604). Regenerate the ja-JP, ko-KR, pt-BR and zh-CN
localised trees to mirror the new structure.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* docs: backfill changeset PR number (#605)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Tom Boucher
2026-06-02 08:13:09 -04:00
committed by GitHub
parent 8c47dcb1c1
commit 3bb2f8f1c5
200 changed files with 46813 additions and 8415 deletions

View File

@@ -0,0 +1,90 @@
# Context engineering
> Why GSD Core exists, and the problem it is designed to solve.
---
## The problem: context rot
Every AI coding session starts fresh. The model reads your question, reasons over it, and replies. But a session is rarely one exchange. You ask follow-up questions, paste error messages, iterate on code, redirect the model when it drifts. Each turn adds tokens to the context window — the finite buffer of text the model can "see" at once.
As that window fills, something subtle happens. The model does not fail loudly. It keeps answering. But the quality of its answers quietly degrades. Early instructions get pushed towards the edge of what it can attend to. Nuance from the first few exchanges — the constraints you stated, the architecture you agreed on, the edge cases you flagged — competes for attention against everything that came later. Researchers call this **context rot**.
Context rot manifests in several ways:
- The model starts contradicting earlier decisions it acknowledged.
- Code style drifts away from the conventions established at session start.
- Plans begin to ignore requirements that were clearly stated but are now buried deep in the history.
- The model hallucinates file names or function signatures it had correct twenty messages ago.
None of this is a model bug. It is a fundamental property of how transformer attention works over long sequences. The model is not forgetting — it never "remembered" in the human sense. It is weighting relevance across a finite window, and as that window fills with accumulated noise, signal-to-noise degrades.
The naive response is to `/clear` and start over. But that loses continuity. You have to re-explain context, re-paste relevant files, re-state constraints. The session essentially resets to zero.
---
## GSD Core's answer: fresh-context subagents
GSD Core's central insight is that *most* of the work in a coding session does not need to happen in the main context at all. Research, planning, code writing, and verification are each discrete, bounded tasks. Each can be handed to a specialised subagent that starts with a clean, carefully scoped context window — and reports its result back to a thin orchestrator that stays lean.
This is not a workaround for context rot. It is a structural solution.
The orchestrator — your main session — never touches source files. It spawns agents, collects their results, updates shared state, and routes to the next step. Because it does very little itself, its context window grows slowly and predictably. The heavy work happens in agents that each start fresh, receive exactly the context they need for their task, and terminate when done.
Consider what this means in practice. When you run `/gsd-plan-phase`, the orchestrator:
1. Loads a compact JSON context payload (project summary, phase goal, relevant config).
2. Spawns a researcher agent with a 200k-token clean window.
3. Spawns a planner agent with the research output and phase requirements.
4. Spawns a plan-checker agent to verify the plan before execution.
Each agent operates at full capacity, unencumbered by the accumulated history of your session. When the planner writes its `PLAN.md` files to `.planning/phases/`, that output becomes a durable artefact — not a fragile memory in a shared context window.
---
## Spec-driven development and meta-prompting
Context engineering alone is not enough. If an agent starts fresh but receives vague instructions, it will produce vague output. GSD Core pairs fresh-context subagents with two complementary disciplines:
**Spec-driven development** means that every phase produces structured artefacts before execution begins. A `CONTEXT.md` captures implementation decisions from the Discuss step. A `RESEARCH.md` records what the researcher found. A `PLAN.md` breaks work into discrete, dependency-ordered tasks with explicit acceptance criteria. By the time an executor agent touches a file, it has a precise specification to work from — not a re-interpretation of a long conversation.
**Meta-prompting** means the agent definitions themselves are carefully engineered prompts, not ad-hoc instructions. The files in `get-shit-done/workflows/` and `agents/` encode hard-won knowledge about how to scope tasks, what to verify, and when to escalate to a human checkpoint. The user does not need to re-explain this knowledge in every session; it is baked into the system's own prompts.
The combination is deliberate. Fresh context ensures each agent reasons clearly. Spec-driven artefacts ensure each agent reasons about the *right* thing. Meta-prompting ensures each agent knows *how* to reason about it well.
---
## The role of `.planning/`
Context engineering requires that knowledge survive context resets. GSD Core uses the file system for this. Every meaningful output is written to `.planning/` as human-readable Markdown or JSON. This means:
- Restarting your session (or the model crashing) does not lose work.
- Any subsequent agent can read prior artefacts directly, without depending on a shared conversation history.
- You can inspect, edit, or commit planning artefacts to git — they are plain text, not opaque state in a database.
`STATE.md` is the spine of this system. It records the project's current position (which milestone, which phase, which plans are complete), active decisions and blockers, and progress metrics. When any workflow starts, it reads `STATE.md` to orient itself. When any workflow finishes a meaningful step, it writes back to `STATE.md`. Agents do not rely on memory; they rely on the file.
---
## Trade-offs
Honesty about trade-offs matters here.
**Overhead.** The phase loop introduces real friction. Running `/gsd-discuss-phase`, `/gsd-plan-phase`, and `/gsd-execute-phase` as separate steps takes more elapsed time than typing "write this feature" into a plain session. For a small, well-understood change, that overhead is not justified.
**Latency.** Spawning multiple subagents with fresh context is slower than a single in-context edit. Research, planning, and execution each incur round-trip costs.
**Ceremony for simple tasks.** If you need to rename a variable, fix a typo, or add a missing import, the phase loop is overkill. GSD Core provides `/gsd-quick` and `/gsd-fast` for ad-hoc work that does not warrant a full phase. See [Handle quick and fast tasks](../how-to/handle-quick-and-fast-tasks.md).
The phase loop pays for itself when the work is complex enough that context rot is a real risk — multi-file features, cross-cutting refactors, work that spans hours or sessions. For everything else, reach for the lighter primitive.
A useful rule of thumb: if the task could be fully specified in a single, short prompt and completed in one agent turn without further clarification, skip the phase loop. If the task requires research, involves files you have not read recently, or depends on decisions that are not yet settled, the phase loop protects you.
---
## Related
- [The phase loop](the-phase-loop.md) — how the Discuss → Plan → Execute → Verify → Ship cycle puts context engineering into practice
- [Multi-agent orchestration](multi-agent-orchestration.md) — how subagents are spawned, scoped, and coordinated
- [Architecture](../ARCHITECTURE.md) — system architecture, agent model, and data flow
- [docs index](../README.md)

View File

@@ -0,0 +1,234 @@
# Multi-agent orchestration in GSD Core
> **Explanation** — This document describes *why* GSD Core is designed around
> multi-agent orchestration and *how the pieces fit together*. It is not a
> step-by-step guide. For configuration, see
> [Configure model profiles](../how-to/configure-model-profiles.md) and the
> [Configuration reference](../CONFIGURATION.md). For the full agent roster,
> see [Inventory](../INVENTORY.md).
---
## The problem this design solves
AI coding agents degrade. Not because the model gets worse, but because the
*context window fills up*. As a conversation grows, earlier decisions and code
get pushed out or diluted by the noise of intermediate steps. By the time an
agent writes the fifth file in a complex task, it may have already forgotten
the constraint stated in the first message. This is sometimes called *context
rot*.
GSD Core's multi-agent design is a direct response to that problem. Instead of
one long-running agent carrying the whole session, a thin orchestrator spawns
short-lived specialised agents, each with a **fresh 200 K-token context window**
and *only the artifacts it needs* to do its specific job. The orchestrator
never does heavy lifting itself; it loads context, spawns the right agent,
collects the result, and updates shared state in `.planning/`.
---
## The orchestrator → agent pattern
Every workflow in `get-shit-done/workflows/` follows the same shape:
```text
Orchestrator (workflow .md file)
│
├── Load context
│ gsd-tools.cjs init <workflow> <phase>
│ → JSON: project info, config, state, phase details
│
├── Resolve model
│ gsd-tools.cjs resolve-model <agent-name>
│ → opus | sonnet | haiku | inherit
│
├── Spawn specialised agent (Task/SubAgent call)
│ ├── Agent definition (agents/*.md)
│ ├── Context payload (init JSON)
│ ├── Model assignment
│ └── Tool permissions
│
├── Collect result
│
└── Update state
gsd-tools.cjs state update / state patch / state advance-plan
```
The orchestrator is deliberately thin. It does not reason about the domain,
does not write code, and does not interpret results beyond routing them to the
next step. That boundary keeps each layer's responsibility clear and prevents
the orchestrator's context from accumulating domain noise.
### The agent roster
GSD Core's agents fall into functional categories that map onto the
research → plan → execute → verify pipeline:
| Category | Agents | Typical parallelism |
|---|---|---|
| Researchers | `gsd-project-researcher`, `gsd-phase-researcher`, `gsd-ui-researcher`, `gsd-advisor-researcher` | 4 parallel (stack, features, architecture, pitfalls) |
| Synthesisers | `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, up to 3 revision iterations |
| Executors | `gsd-executor` | Parallel within a wave, sequential across waves |
| Verifiers | `gsd-verifier` | Sequential, after all executors complete |
| Mappers | `gsd-codebase-mapper` | 4 parallel sub-probes |
| Auditors | `gsd-ui-auditor`, `gsd-security-auditor` | Sequential |
Each agent definition (in `agents/*.md`) declares its allowed tool access,
purpose, and colour for terminal output. An agent that only needs to read files
and write a single output document gets exactly those permissions — no Bash
execution, no access to broader state. That constraint is intentional: it
keeps the blast radius small if an agent behaves unexpectedly.
For the complete 31-agent roster, see [Inventory](../INVENTORY.md#agents-31-shipped).
---
## Wave-based parallel execution
The most visible expression of multi-agent design is how `/gsd-execute-phase`
handles a set of plans that may depend on one another.
Before spawning any executor, the orchestrator performs a **wave analysis**:
it reads the dependency declarations in each `PLAN.md` file and groups plans
into waves. Plans with no declared dependencies form Wave 1 and run in
parallel. Plans that depend on Wave 1 form Wave 2, and so on.
```text
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 within a wave:
- receives a fresh context window (200 K tokens, or up to 1 M on capable models)
- receives the specific `PLAN.md` it is responsible for
- receives project context (`PROJECT.md`, `STATE.md`)
- receives phase context (`CONTEXT.md`, `RESEARCH.md` if available)
- produces atomic git commits on completion
- writes a `SUMMARY.md` describing what was built
After all executors in a wave finish, the orchestrator runs the pre-commit
hook once for the wave as a whole. Executors commit with `--no-verify` to
prevent build-lock contention (for example, Cargo lock fights in Rust
projects) when multiple agents commit in parallel. The hook therefore runs
once per wave rather than once per commit.
### Parallel commit safety
Two mechanisms prevent write conflicts when multiple executors run
simultaneously:
1. **Atomic lock on `STATE.md`** — Every write to `STATE.md` uses a
lockfile (`STATE.md.lock`) with `O_EXCL` atomic creation. This prevents
the read-modify-write race where two agents each read the file, modify
different fields, and the later writer overwrites the earlier one's
changes. Stale locks (older than 10 seconds) are automatically cleared.
2. **Per-wave hook run** — Rather than each executor running pre-commit hooks
independently (which can cause file-level contention on shared build
artefacts), the orchestrator runs `git hook run pre-commit` once after
every wave completes.
---
## Adaptive context enrichment for large-window models
Standard 200 K context windows are enough for an executor to implement a
single focused plan. When the configured `context_window` is 500 K tokens or
larger (for example, when using Opus 4.6 or Sonnet 4.6 in 1 M-class mode),
the orchestrator automatically enriches subagent prompts with additional
context that would not fit in a standard window:
- **Executor agents** receive prior-wave `SUMMARY.md` files and the phase
`CONTEXT.md`/`RESEARCH.md`, giving them cross-plan awareness within the
phase
- **Verifier agents** receive all `PLAN.md`, `SUMMARY.md`, and `CONTEXT.md`
files plus `REQUIREMENTS.md`, enabling history-aware verification
This enrichment is conditional on the `context_window` value in
`config.json`. On standard-window configurations, prompts use truncated
versions with cache-friendly ordering to maximise token efficiency.
---
## Why this design — the connection to context engineering
The orchestrator → agent pattern only makes sense as part of a broader
approach to *context engineering*: the idea that what an AI agent gets in its
context window matters as much as the model tier or prompt quality. See
[Context engineering](context-engineering.md) for the full treatment.
Multi-agent orchestration operationalises context engineering in two ways:
**Context isolation.** Each agent receives only what it needs. A researcher
gets the project description and domain questions; it does not get the full
planning history. A verifier gets every plan and summary; it does not get the
raw research. Isolation keeps each agent's context dense with signal rather
than diluted by noise from other pipeline stages.
**Context hygiene across sessions.** Because all state lives in
`.planning/` as human-readable Markdown and JSON (not in any agent's context
window), GSD workflows survive context resets (`/clear`), tab switches, and
multi-day breaks. The next agent always starts from persisted, verified
artifacts rather than from a reconstructed memory of a long conversation.
---
## Trade-offs
Multi-agent orchestration is not free.
**Coordination overhead.** Each agent spawn is a round-trip: the orchestrator
must format a prompt, hand off context, wait for the subagent to complete
(typically 1–5 minutes), and then parse the result. A single capable agent
working in one context would finish faster for simple tasks. GSD mitigates
this by making parallelism the default wherever dependencies permit — the
four researchers in a `plan-phase` run simultaneously, not sequentially.
**Opacity during execution.** While a subagent is running, its work is
invisible to the parent session. There is no live progress stream. This is a
deliberate consequence of the fresh-context design: the subagent is operating
in its own context window. The orchestrator shows a liveness note on the
spawn line ("runs in a subagent — no output until it returns") to set
expectations.
**Context stitching cost.** Packaging the right artifacts for each agent
requires the orchestrator to spend tokens assembling and transmitting context
payloads. This is the cost of isolation. The `gsd-tools.cjs init` handler
produces a JSON payload that balances completeness with token budget, applying
cache-friendly ordering so that the stable parts of the payload (project
definition, config) hit the cache on repeat invocations.
**Model cost amplification.** Running five agents in parallel at Opus tier
costs more than running one. The model profile system (`model_profiles.md`,
resolved per agent by `model-profiles.cjs`) lets you assign cheaper tiers to
less critical agents. The `dynamic_routing` feature further reduces cost by
starting every agent on a cheaper tier and escalating only on a soft failure.
See [Configuration](../CONFIGURATION.md) for the full options.
In return for these costs, the design buys *consistent quality across large
phases*. An executor writing the tenth file in a 400-line plan does not
degrade because its context is fresh. A verifier checking twenty requirements
does not forget the first ten because it received all of them as structured
input rather than conversation history.
---
## Related
- [Context engineering](context-engineering.md) — the upstream principle that
motivates this design
- [Configure model profiles](../how-to/configure-model-profiles.md) — how to
assign model tiers per agent
- [Configuration reference](../CONFIGURATION.md) — full `config.json` schema
including `models`, `model_overrides`, `dynamic_routing`, and
`context_window`
- [Inventory](../INVENTORY.md) — authoritative agent roster and workflow list
- [Architecture](../ARCHITECTURE.md#agent-model) — implementation-level detail
on the orchestrator → agent pattern and wave execution model
- [Docs index](../README.md)

View File

@@ -0,0 +1,252 @@
# GSD Core security model
> **Explanation** — This document describes *why* GSD Core has the security
> posture it does and *how the layers fit together*. It is not a reference for
> every hook parameter. For the `/gsd-secure-phase` command and its options,
> see [Commands](../COMMANDS.md). For the implementation-level hook
> architecture, see [Architecture § Hook System](../ARCHITECTURE.md#hook-system).
> For the org-wide security baseline (scanner controls, incident checklists,
> ownership model), see [SECURITY.md](../../SECURITY.md).
---
## Why AI-driven development needs a dedicated security posture
A conventional code editor does not execute arbitrary packages on your behalf.
GSD Core does. The research → plan → execute pipeline automates the full path
from "name a package" to "run `npm install <package>`", from "write a
planning artifact" to "use that artifact as an LLM system prompt". Each
automation step removes a human from the loop — and each removal is a
potential attack surface.
GSD Core's security model is built around one organising principle:
**defence in depth**. No single control is assumed to be perfect. Several
overlapping layers each reduce a distinct class of risk, and together they
make the attack surface substantially harder to exploit without eliminating
it entirely. The honest summary at the end of this document explains what the
system cannot protect against.
---
## Layer 1 — Supply-chain protection: the Package Legitimacy Gate
### The threat
AI models hallucinate package names. This is not a fringe failure mode: 2025
research documents roughly 20 % of AI-generated package references as
hallucinated names that do not correspond to legitimate packages. A subset of
those hallucinated names — approximately 43 % in the same research — recur
consistently across prompts, meaning an attacker can observe which names AI
tools commonly produce and pre-register those names on npm, PyPI, or
crates.io with malicious post-install scripts. The technique is called
*slopsquatting*.
The insidious quality of slopsquatting is that a hallucinated name that passes
`npm view` *looks legitimate*. The registry entry proves only that someone
registered the name — not that the package does what the AI said it does, not
that it has any legitimate users, and not that its install scripts are safe.
Without a gate, a hallucinated name would flow undetected through GSD's
researcher → planner → executor pipeline and eventually run as
`npm install <attacker-package>` on your machine.
### How the gate works
The gate operates across three pipeline stages:
**Research stage.** When `gsd-phase-researcher` recommends external packages,
it runs `slopcheck install <pkgs> --json` against each one. The results are
written to a `## Package Legitimacy Audit` table in `RESEARCH.md`. Packages
tagged `[SLOP]` (high-confidence hallucination or attacker-registered) are
**stripped from `RESEARCH.md` entirely** before the file is saved. They never
reach the planner.
**Planning stage.** `gsd-planner` reads the Audit table. For any package
tagged `[SUS]` (suspicious: newly registered, low download count, no source
repository, or naming pattern close to a popular package) or `[ASSUMED]`
(sourced from WebSearch rather than direct registry verification), the planner
**inserts a `checkpoint:human-verify` task** before the install step. The
checkpoint includes a direct link to the registry page and specific things to
look for: maintainer history, issue-tracker activity, absence of suspicious
install scripts.
**Execution stage.** If an install fails, `gsd-executor` **surfaces a
checkpoint and stops**. It does not silently try an alternative package name —
which could itself be malicious. This is an explicit rule in the executor's
behaviour (RULE 3 in the executor agent definition).
### Why WebSearch packages are always `[ASSUMED]`
Package names discovered through WebSearch are tagged `[ASSUMED]` regardless
of whether `npm view` succeeds. A package that exists on the registry is not
the same as a package that is safe to install. `npm view` proves registration,
not legitimacy. The `[ASSUMED]` tag triggers the same human-verify checkpoint
as `[SUS]`, ensuring that any unverified web-discovered recommendation always
gets a human review before installation.
### Ecosystem coverage
The researcher uses registry-specific verification commands rather than a
single generic check:
- Node.js: `npm view`
- Python: `pip index versions`
- Rust: `cargo search`
This covers cross-ecosystem hallucination, which occurs at roughly 9 %
according to 2025 USENIX research — cases where an AI recommends a package
that exists in one ecosystem but not the one actually in use.
### Graceful degradation
If `slopcheck` is unavailable (not installed, or the pip install fails at
research time), GSD applies the strictest possible fallback: **every
recommended package is tagged `[ASSUMED]`**, and the planner gates every
install with a `checkpoint:human-verify` task. Research and planning proceed
normally — the system never hard-fails on a missing tool dependency. This
is intentionally stricter than the normal flow: slopcheck unavailability means
every package install gets a human checkpoint.
The `slopcheck` tool is MIT-licensed and pip-installable. If it is ever
abandoned, the `[ASSUMED]`-gate fallback ensures human-checkpoint coverage is
maintained regardless.
---
## Layer 2 — Prompt injection defences
### The threat
GSD Core generates Markdown files that become LLM system prompts. The
research pipeline reads external web content; the planning pipeline
incorporates user-supplied text (`--text-file`, `--prd`); the execution
pipeline writes planning artifacts that are later re-read as agent context.
Any user-controlled text flowing into these artifacts is a potential
**indirect prompt injection** vector — an attacker-controlled string that,
once inside a system prompt, attempts to override the agent's instructions or
exfiltrate information.
### How the defences work
GSD Core addresses prompt injection at three levels.
**Input validation (`security.cjs`).** The `get-shit-done/bin/lib/security.cjs`
module is the central security utility. It provides:
- Path traversal prevention: user-supplied file paths (`--text-file`, `--prd`)
are validated to resolve within the project directory, with macOS
`/var` → `/private/var` symlink resolution handled explicitly
- Prompt injection detection: known injection patterns (role overrides,
instruction bypasses, system tag injections) are scanned in user-supplied
text before it enters any planning artifact
- Safe JSON parsing: a wrapper that prevents prototype-pollution attacks via
crafted JSON payloads
- Shell argument validation: arguments passed to subshell commands are
validated before use
**Runtime hook: `gsd-prompt-guard.js`.** This hook fires on every Write or
Edit call that targets `.planning/` files. It scans the content being written
for the same injection patterns as `security.cjs` (a subset inlined directly
into the hook for independence — the hook does not `require()` the module, so
it runs even if the module path changes). Detection is **advisory-only**: the
hook logs the finding but does not block the write. The rationale is that a
false-positive block on a legitimate planning write would be more disruptive
than a missed injection in a secondary scan layer.
**Runtime hook: `gsd-read-injection-scanner.js`.** This hook fires on the
output of every Read tool call. It scans the *content that was just read* for
injected instructions in untrusted content — catching cases where an attacker
has embedded instructions in a file that GSD is about to incorporate into an
agent's context.
**CI scanner.** `prompt-injection-scan.test.cjs` scans all agent, workflow,
and command files for embedded injection vectors as part of the test suite.
This catches injection attempts in the GSD source itself — for example, a
supply-chain attack that modified a workflow file to add a role-override
instruction.
### Read Injection Scanner vs Prompt Guard
The two hooks cover complementary surfaces. `gsd-prompt-guard.js` watches
*writes to planning artifacts* — it catches injection being planted.
`gsd-read-injection-scanner.js` watches *reads of any file* — it catches
injection being ingested from external content (a dependency's README, a
third-party config file, a user-provided document). Together they bracket
the ingest → store → re-read lifecycle.
---
## Layer 3 — Repository and dependency integrity
Upstream of GSD's runtime behaviour, the `open-gsd` organisation enforces
controls at the repository and package level. These are documented in full in
[`docs/security/baseline.md`](../security/baseline.md) and are summarised
here for completeness.
**Dependency integrity.** All third-party dependencies are pinned via
`package-lock.json` and verified against published checksums before install.
A `scripts/check-npm-integrity.cjs` gate detects invalid versions, missing
packages, and extraneous packages at CI time. This mitigates dependency
confusion and typosquatting attacks against GSD's own dependencies.
**Secret scanning.** Every commit and PR is scanned for hardcoded secrets.
Intentional test fixtures must be annotated with the project-standard
exclusion grammar (see `SECURITY.md` for the annotation format). Un-annotated
suppressions fail CI.
**Locale-safe text scanning.** Output and user-facing strings are scanned for
Unicode homoglyphs, bidirectional override characters, and invisible Unicode —
the class of attacks documented in CVE-2021-42574 ("Trojan Source") that can
hide malicious content in diffs.
---
## Trade-offs and limits
The security model described here meaningfully reduces the attack surface for
AI-driven development. It does not eliminate supply-chain risk.
**What the Package Legitimacy Gate reduces:** The probability that a
hallucinated or attacker-registered package reaches `npm install` without
a human checkpoint. The `[SLOP]` gate removes high-confidence bad packages
entirely; the `[SUS]` / `[ASSUMED]` gates require human review before
execution. This substantially raises the cost of a successful slopsquatting
attack.
**What the Package Legitimacy Gate does not eliminate:** A legitimate package
that is later compromised (account takeover, dependency confusion in its own
tree) is not caught by slopcheck, which checks registration signals at
research time. Lock files and `npm audit` at the dependency-integrity layer
are the controls for that class of attack.
**What the prompt injection defences reduce:** The probability that
user-controlled text in planning artifacts successfully overrides agent
instructions. Pattern-matching on known injection forms catches the
common cases; novel jailbreaks or low-signal injections may pass undetected.
The advisory-only posture means detection is logged but not blocked — a
deliberate choice that preserves workflow continuity at the cost of
not hard-stopping on a detection.
**What the prompt injection defences do not eliminate:** A sufficiently
creative injection that does not match known patterns, or an injection that
arrives through a channel the hooks do not cover (for example, content injected
into a dependency's published README that is read by a subagent browsing
documentation). Defence in depth means each layer makes the attack harder,
not that any single layer makes it impossible.
**Reporting vulnerabilities.** Report via private GitHub security advisory at
`https://github.com/open-gsd/gsd-core/security/advisories/new`. Do not open
public issues. See [SECURITY.md](../../SECURITY.md) for the response timeline
and disclosure policy.
---
## Related
- [Commands](../COMMANDS.md) — includes `/gsd-secure-phase` and
`/gsd-code-review` with security-relevant flags
- [Architecture § Hook System](../ARCHITECTURE.md#hook-system) —
implementation detail on every hook, its event trigger, and safety properties
- [SECURITY.md](../../SECURITY.md) — vulnerability reporting, org-wide
security baseline, secret-scan exclusion governance, and dependency
integrity verification
- [Docs index](../README.md)

View File

@@ -0,0 +1,129 @@
# The phase loop
> The central mental model for how GSD Core organises work.
---
## What the loop is
GSD Core structures all development work as a repeating cycle:
```text
Discuss → (UI design) → Plan → Execute → Verify → Ship
```
Every unit of work — called a **phase** — moves through these steps in order. The loop is not a formality. Each step exists because it guards against a specific class of failure that the previous step alone cannot prevent.
This document explains *why* the loop is shaped the way it is. For instructions on running each step, see the how-to guides linked at the bottom.
---
## Why each step exists
### Discuss
Planning cannot begin until you know *how* to build the thing, not just *what* to build. The phase goal in `ROADMAP.md` describes the outcome. The Discuss step captures the implementation decisions that shape the path to that outcome: which libraries, which error-handling strategy, whether a feature is per-route or global, how edge cases should behave.
Without a Discuss step, the planner must make these calls itself. Sometimes it guesses right. Often it guesses plausibly but wrongly — producing a plan that is coherent but misaligned with your actual preferences. By the time execution is done and you realise the error, you are unwinding significant work.
The Discuss step is deliberately lightweight. It is a conversation, not a specification exercise. The output is a `CONTEXT.md` in the phase directory: a structured record of decisions that the planner, executor, and verifier can all read. The conversation takes a few minutes; it can save hours of rework.
### UI design (optional)
For phases with a visual component, there is an optional `/gsd-ui-phase` step between Discuss and Plan. It produces a `UI-SPEC.md` — a design contract that describes layout, interaction, and visual behaviour before any code is written. This step is worth running when the UI is complex enough that ambiguity in the design would produce divergent implementation choices. A clear design contract is far cheaper to write than to re-implement.
### Plan
The Plan step does the research, decomposition, and structural thinking that execution requires. It runs as a sequence of fresh-context subagents: a researcher that investigates the ecosystem and records findings in `RESEARCH.md`, a planner that reads both the research and the `CONTEXT.md` to produce `PLAN.md` files, and a plan-checker that verifies the plans are complete, consistent, and within scope.
What does a plan contain? Each `PLAN.md` describes a bounded unit of work: the files to touch, the specific changes to make, the acceptance criteria that define done. Plans are ordered into dependency waves so that parallel execution is safe — executors in the same wave touch non-overlapping concerns.
The Plan step is the moment when ambiguity is most expensive. An ambiguous plan produces an executor that makes assumptions. Multiple parallel executors making different assumptions about the same concern produce conflicts. The plan-checker's job is to catch these before execution begins, not after.
### Execute
Execution runs the plans. Each executor gets a fresh 200k-token context window loaded with exactly what it needs: the project summary, the phase context, the research, and the specific `PLAN.md` for its task. Nothing more.
Executors write code and commit atomically. Each commit corresponds to a completed task in a plan. When a wave of parallel executors finishes, the orchestrator merges their state and starts the next wave.
The executor's fresh context is not a convenience — it is the mechanism by which context rot is prevented. An executor that runs with 180k tokens of accumulated session history is a degraded executor. An executor that starts clean and reads only what its plan requires is an executor operating at full capacity.
### Verify
After all executors have completed, a verifier agent reads the phase goal, the `CONTEXT.md` decisions, the plans, and the execution summaries — and checks that what was built matches what was intended. It produces a `VERIFICATION.md` and, if there are discrepancies, generates targeted fix plans.
Verification is not just testing. It checks requirement coverage (were all the REQ-IDs addressed?), decision coverage (were the decisions captured in `CONTEXT.md` actually implemented?), and overall phase goal alignment. A phase is not done because execution finished without errors. It is done because what was built is what was planned, and what was planned is what was decided.
### Ship
The Ship step creates the pull request and archives the phase artefacts. `STATE.md` is updated to mark the phase complete. The loop then begins again for the next phase.
---
## Milestones and phases
A **milestone** is a version cycle — a meaningful, releasable increment of the project. It has a name, a version number, and a set of requirements that define what it must deliver. A milestone is complete when all its phases are shipped and its requirements are covered.
A **phase** is one unit of work within a milestone. A phase has a goal, a set of requirements it addresses, and a set of plans that implement it.
The relationship matters because milestones and phases have different scopes of concern. A milestone asks: "What does this version of the product do, and what does it not do?" A phase asks: "What is the next bounded thing we can research, plan, execute, and verify?"
Milestone boundaries are drawn at natural product boundaries — a deployable API, a working UI flow, a complete data model. Phase boundaries are drawn at the limits of what can be safely executed in one loop without the loop becoming unwieldy.
---
## What makes a good phase scope
This is worth dwelling on because it is the most common source of friction with the loop.
A phase that is too large becomes a research project unto itself. The planner struggles to decompose it into independent plans. Executors in later waves are blocked waiting for earlier waves. Verification becomes a full audit rather than a targeted review. The feedback cycle stretches from hours to days, and the risk of discovering a fundamental design mistake late — after much code has been written — rises sharply.
A phase that is too small fragments work that naturally belongs together. You end up with plan files that are half a dozen lines, phases that complete in minutes, and a planning overhead that dwarfs the execution cost. The loop feels bureaucratic rather than helpful.
A good phase scope is one where:
- The goal can be stated in a single sentence that is neither obviously trivial nor suspiciously broad.
- The research needed to plan it is bounded — the ecosystem questions have answers that do not depend on other phases completing first.
- The execution can be parallelised into a handful of non-overlapping plans, not dozens.
- There is a clear, testable definition of done that a verifier can check without reading the entire codebase.
Concretely: "Add HMAC-SHA256 signature validation middleware" is a good phase scope. "Build the authentication system" usually is not — it almost always contains multiple independent concerns that would be better as separate phases. "Fix the typo in the README" is below the threshold where the loop adds value; use `/gsd-quick` instead.
When in doubt, split. A smaller phase completes faster, verifies more confidently, and makes it easier to course-correct if a design decision turns out to be wrong.
---
## How `.planning/` carries state across the loop
The loop is not a single session. Research, planning, and execution may happen across multiple sessions, with context resets in between. The `.planning/` directory is what makes this possible.
Every step of the loop reads artefacts produced by earlier steps and writes artefacts for later steps. The CONTEXT.md that the Discuss step produces is still available when the Planner runs — even if that is in a different session hours later. The PLAN.md files that the Planner produces are still available when the Executor runs — even across a restart. The VERIFICATION.md that the Verifier writes is still available when you review the phase.
`STATE.md` is the navigation layer above all of this. It records exactly where in the loop the project currently sits: which milestone is active, which phase is in progress, which plans are complete and which are pending. Any agent or workflow that needs to orient itself reads `STATE.md` first.
For the precise structure of these files, see [Planning artifacts](../reference/planning-artifacts.md) and the [STATE.md schema](../reference/state-md.md).
---
## The loop is a rhythm, not a constraint
It is tempting to see the loop as bureaucracy — a set of required steps that you have to perform before you are allowed to write code. That framing is wrong.
The loop exists because each step prevents failures that are genuinely expensive to fix later. Discuss prevents planning on wrong assumptions. Plan prevents executing a design that is fundamentally broken. Verify prevents shipping work that missed the brief. These are not invented problems. They are the actual failure modes of AI-assisted development at the scale of real features.
When the loop works well, it feels like a rhythm: a cadence of focused, bounded work where each step is clear because the previous step did its job. The overhead is real, but it is front-loaded — paid in minutes of planning rather than hours of rework.
For work that falls below the threshold where the loop is warranted, GSD Core provides lighter primitives. The phase loop is one tool, not the only tool.
---
## Related
- [Context engineering](context-engineering.md) — why fresh-context subagents prevent the quality degradation that makes the loop necessary
- [Discuss a phase](../how-to/discuss-a-phase.md)
- [Plan a phase](../how-to/plan-a-phase.md)
- [Execute a phase](../how-to/execute-a-phase.md)
- [Verify and ship](../how-to/verify-and-ship.md)
- [Planning artifacts](../reference/planning-artifacts.md)
- [STATE.md schema](../reference/state-md.md)
- [docs index](../README.md)