Skip to content

Files gdd writes

Every file and folder gdd writes in a project: what gdd init leaves, the local state in .gdd/ (records, reports, the log, the Decision Inbox, the agents' outputs), which of them are committed, which only gdd may write, and what the merge commit of a change carries.

A project after gdd init

gdd init --name notes --platform cli --stack python --agents claude codex in an empty repository commits these files (the agents' commands are listed once per agent folder):

.agents/skills/gdd-<command>/SKILL.md   # Codex: the GDD commands and gdd-stack-python
.claude/skills/gdd-<command>/SKILL.md   # Claude Code: the same
.github/workflows/gdd.yml               # CI: the stack setup, gitleaks, gdd, bin/gdd ci
.gitignore                              # the stack's lines and .gdd/
AGENTS.md                               # instructions for agents, when the project had none
CLAUDE.md                               # @AGENTS.md, when the project had none
bin/gdd                                 # entry point of the agents and CI
docs/brief.md                           # the Project Brief
features/.gitkeep                       # the scenario folder
gdd/commands.toml
gdd/generated.toml
gdd/models.toml
gdd/project.toml
gdd/rules.toml
gdd/zones.toml
osv-scanner-licenses.toml               # from here on: the Python skeleton
osv-scanner.toml
pyproject.toml
src/notes/__init__.py
src/notes/greeting.py
tests/__init__.py
tests/acceptance/__init__.py
tests/acceptance/steps/__init__.py
tests/acceptance/test_features.py
tests/unit/__init__.py
tests/unit/test_greeting.py
Path What it is
gdd/ The configuration: see Configuration.
bin/gdd A shell script that runs ${GDD_BIN:-gdd} with its arguments: the gdd on the PATH, or the one GDD_BIN names.
docs/brief.md The Project Brief, from --name, --description, --platform, --stack and --sensitive. The Orchestrator completes it at Setup.
AGENTS.md, CLAUDE.md Written only when the project has none; otherwise gdd prints the line to add.
.gitignore gdd appends the stack's ignored paths and .gdd/.
Agent folders .claude/skills/<name>/SKILL.md (Claude Code), .agents/skills/<name>/SKILL.md (Codex), .opencode/commands/<name>.md (OpenCode), for the agents of --agents. gdd agents install writes them again; gdd agents check names any file missing or edited.
Skeleton Per stack, only when the folder has no project of that stack: see Stacks.

gdd init never overwrites a file, never writes through a link, and commits only what it wrote (gdd init <version>), in a new repository when the folder is in none. gdd bootstrap then commits the lock files (gdd bootstrap). gdd adopt commits gdd/debt.toml.

Committed and local

Path Committed Written by
gdd/*.toml yes gdd init, gdd adopt, gdd upgrade, a person; see Who may change them
bin/gdd, .github/workflows/gdd.yml, agent folders, AGENTS.md, CLAUDE.md yes gdd init, gdd agents install
docs/, features/, code and tests yes the Orchestrator and the Builder, through changes
CHANGELOG.md yes, when the project keeps one gdd changelog --write, gdd release
.gdd/ no: gdd init adds .gdd/ to .gitignore gdd, and a few files the Orchestrator writes

The record of each change reaches git only through its merge commit.

.gdd/

The local state. Every worktree of a repository shares the .gdd/ of its main checkout (the state root): a change runs in its own worktree and still reads and writes the same records. gdd refuses to run in a worktree of a bare repository.

.gdd/
├── log.jsonl                 # one JSON line per agent call, gate decision and machine step
├── g0.json                   # G0, opened by the machines
├── zones.json                # the human's approval of the red zones
├── selftest.json             # the last harness self-test
├── headless_sessions.txt     # sessions gdd started for its agents
├── imported_requests.json    # requests of interactive sessions already in the log
├── agents.lock  launch.lock  merge.lock  state.lock
├── adoption/<command>.txt    # gdd adopt: what each failing command said
├── learn/<tool>.txt          # gdd learn: what each Learn tool said
├── selftest/kept/            # gdd selftest: a file set aside while the check runs
├── upgrade/                  # gdd upgrade: scratch folder, removed after each run
├── bin/                      # protected; gdd does not write it
└── changes/<id>/
    ├── change.json           # the record
    ├── inbox.md              # the Decision Inbox
    ├── plan.md               # the plan of a red change (the Orchestrator)
    ├── package.md            # the minimum context package (the Orchestrator)
    ├── replan.md             # the last replan (the Orchestrator, headless)
    ├── review.md             # the last review (the Reviewer's text, kept by gdd)
    ├── g2.json  g3.json      # the last report of each gate
    ├── snapshot.json         # gdd snapshot
    ├── snapshot-build.json   # the snapshot taken after test mode
    ├── run.json              # while the change waits at G4
    ├── outputs/              # every agent call: <role>-<n>.md and <role>-<n>.raw
    └── demo/                 # what the demo step leaves for G4
Path Written by Contents
log.jsonl gdd See log.jsonl.
g0.json gdd gate G0 decision, by (machines), ts, note.
zones.json gdd gate zones decision, by (human), ts, red_hash (16 hex characters of the SHA-256 of the red zones), red (the red zones as approved, every key), note.
selftest.json gdd selftest ok, summary (harness 4/4), detail (each check's test and ok), ts.
headless_sessions.txt gdd, after each agent call that reports a session One session id per line, so gdd session leaves them out.
imported_requests.json gdd session The ids of the requests already counted, as a JSON list. A .new file holds the next list until the log has its lines.
*.lock gdd Empty lock files: merge.lock (one merge at a time), launch.lock (the cap of [parallel] max), agents.lock (held by every agent call, and alone by a person's write to shared state), state.lock (the turn to take it).
adoption/<command>.txt gdd adopt What the failing command's output keeps, for its Refactor.
learn/<tool>.txt gdd learn All a Learn tool said.
bin/ not gdd Programs a project keeps out of git, such as its own build of gdd. In [protected] all and the harness red zone, and checked around every agent call.
changes/<id>/change.json gdd only See change.json.
changes/<id>/inbox.md gdd, after every change of the record See inbox.md.
changes/<id>/plan.md, package.md the Orchestrator (gdd-change) Free text. The Builder and the Reviewer read package.md.
changes/<id>/replan.md the Orchestrator in a replan Free text; the last line that starts with NEXT: says test or build. gdd removes it before each replan.
changes/<id>/review.md gdd, from the Reviewer's final text Ends with VERDICT: OK or VERDICT: KO. gdd removes it before each review.
changes/<id>/g2.json, g3.json gdd g2, gdd g3, the recipe See Gate reports.
changes/<id>/snapshot.json gdd snapshot Path to SHA-256 (or deleted) of what the change touched: gdd guard --since-snapshot judges only what changes after it.
changes/<id>/snapshot-build.json the recipe, after test mode The same, so build mode is judged only for its own work.
changes/<id>/run.json the recipe {"paused_at": "G4"} while the change waits for gdd resume; removed after the answer.
changes/<id>/outputs/ gdd, after every agent call <role>-<n>.md: the agent's final text; <role>-<n>.raw: its whole output. <role> is builder-test, builder-build, reviewer or orchestrator; <n> counts the role's calls on the change, from 1.
changes/<id>/demo/ the project's [release] demo command Video, screenshots or the readable run of the scenarios.

change.json

The record of a change: what it plans, what its gates decided, its notes and its state. Indented JSON. Only gdd writes it: the gdd commands an agent may run (gdd note, a gate in build mode) change only inbox and out_of_scope, and gdd puts back any other change an agent makes.

The record of a change merged and promoted in a throwaway project, trimmed:

{
  "build_start": "ca7bc9c0d5369ef863aab8d6f7651f64056215ed",
  "changelog": {
    "breaking": false,
    "line": "The cart shows its total",
    "section": "Added"
  },
  "commit": "8b14c1a9ab22d8931b010ad51499c8242ff03e4a",
  "created": "2026-10-30T13:11:40+00:00",
  "decision": {
    "builder": {
      "integration": "claude",
      "model": "sonnet"
    },
    "builder_session": "separate",
    ...
    "type": "Feature"
  },
  "features": [
    "features/cart.feature"
  ],
  "gates": {
    "G1": {
      "by": "human",
      "decision": "ok",
      "hashes": {
        "features/cart.feature": "06a581fd190d4dc2e48f33c21323302a67e522e74b8bacce3dd2b51c3fdce716"
      },
      "note": "approved at the sitting",
      "ts": "2026-10-30T13:11:46+00:00"
    },
    ...
  },
  "id": "cart-total",
  "inbox": [
    {
      "kind": "decided",
      "text": "Kept the total as an integer",
      "ts": "2026-10-30T13:11:53+00:00"
    },
    ...
  ],
  "min_color": null,
  "out_of_scope": [
    "docs/extra.md"
  ],
  "paths": [
    "src/shop/**",
    "features/cart.feature"
  ],
  "resumable": false,
  "state": "closed",
  "title": "Show the cart total",
  "type": "Feature",
  "version": "0.1.0"
}
Field Type Written by Meaning
id string gdd new-change The change id: a lowercase letter or digit, then up to 40 lowercase letters, digits or hyphens. Its branch is change/<id>.
title string gdd new-change What the change is about.
type string gdd new-change Feature, Hotfix, Refactor, Migration, Spike or No-code.
paths array of strings gdd new-change The paths it plans to touch; patterns allowed.
resumable boolean gdd new-change --resumable: a condition of the Fast Lane.
min_color string or null gdd new-change --min-color: raises the color, never lowers it.
created string gdd new-change When it was created, UTC.
state string gdd See States.
gates object gdd gate, the recipe One entry per gate decided on the change: see below.
inbox array gdd note, gdd park, the recipe The notes of the Decision Inbox: see below.
variants array gdd new-change, the recipe Only a spike with variants: see below.
decision object gdd prepare What prepare decided: see below.
build_start string gdd prepare The commit where the build started: Path Guard and the scope check judge from it.
features array of strings gdd gate G1 The scenario files sealed at G1, hidden examples included.
out_of_scope array of strings the gates in build mode Paths outside the plan the scope check accepted.
reviews array the recipe Every Reviewer call: see below.
spent_usd number the recipe What the change's agent calls cost, as the agents reported it.
spent_tokens object the recipe Their tokens: in, cache, out.
changelog object gdd changelog-line {"section", "line", "breaking"}, or {"none": true} to leave the change out. Without it, the title goes under the section of the type (Feature: Added, Hotfix: Fixed, Migration: Changed); other types have no line.
commit string gdd merge The merge commit.
version string gdd release promote The version the change was released as, without its v.

Records written by an older tool may have other fields; gdd ignores them.

gates

Key Present on
plan a red change, once the human approved its plan
G1 a change with new or changed scenarios, once the human decided
G2 when recorded with gdd gate G2
G3 once the machines opened it (automatic chain and Reviewer)
G4 once the human answered, or the machines approved the promotion

Each entry has decision (ok or ko), by (human or machines), ts and note. G1 also has hashes: each sealed scenario file and its SHA-256.

inbox

Each note has kind, text and ts, and resolved (when it was resolved) once a relaunch resolved it. kind is needs (a decision for the human), decided (taken without them), parked (why it stopped) or polish (the human's notes at G4).

decision

The classification of the change when it was prepared, and the model of each role.

Key Meaning
change The id.
color, lane green, yellow or red; fast or full.
reasons One line per path: its color and why.
g1, features Whether it needs G1, and its scenario files.
tests_first, mutation, reviewer, review, g4, human_plan What its rule gives it (see Gates).
type Its kind of work.
builder, builder_test, reviewer_model, orchestrator The role tables of gdd/models.toml it got.
builder_session separate or shared.
retries Rounds of build mode against G2.
resume_green A relaunch whose code already passes G2: no Builder.

reviews

One entry per Reviewer call, in order, relaunches included.

Key Meaning
output Where its answer is kept, from the change's folder: outputs/reviewer-<n>.md.
verdict OK or KO once the call ended; null when the call stopped the recipe.
changed The paths whose hash changed since the review before; null for the first.
hashes The hash of each path the change touched, right before the call.

variants

One entry per variant of a spike: option (the option it builds, or null for the same brief), branch (change/<id>-v<n>), and once built state (ready or parked), reason, g2, adrs, decision (the first line of its ADR's decision), files, minutes, usd and tokens.

States

State Meaning
open Created, not prepared.
building Prepared and in Build, a polish pass after G4 included.
parked Stopped, with a message in its Decision Inbox.
merged Merged into main.
in-pre In pre, waiting for G4 or its promotion.
promoting Its promotion is running.
in-production Promoted, being observed.
closed Observed: done.
rejected KO at G4.
rolled-back Observation failed and production rolled back.

inbox.md

The Decision Inbox: one message per change, rendered from the record and the gate reports each time they change. gdd inbox <id> prints it.

# Decision Inbox · cart-total · Show the cart total

Color yellow · lane full · state closed

## Needs your decision
- Should the total show taxes

## Decided without you
- Kept the total as an integer
- Paths outside the package, same or lower color, accepted by rule: docs/extra.md

## Parked
- Nothing.

Its groups, in order, each only when it has something (the three note groups always show): How it works (from the Reviewer's OK), Variants, Needs your decision, Decided without you, Parked, Security exceptions this change adds, Known debt, Known debt paid, Polish; then how many earlier requests were resolved before the last launch.

Gate reports

g2.json and g3.json hold the last run of each gate on the change.

{
  "ok": true,
  "gate": "G2",
  "color": "yellow",
  "passed": [
    "lint",
    "unit",
    "path-guard",
    "scope"
  ],
  "skipped": [],
  "failures": [],
  "out_of_scope": [
    "docs/extra.md"
  ]
}
Field Meaning
ok Nothing failed.
gate, color G2 or G3; the change's color.
passed The checks that passed, in order: commands, path-guard, scope, scenarios (<n>), exceptions.
skipped The mutation* commands the change does not need.
failures Each with name and tail (what to read); a command also has ok, code (124 after a timeout) and duration_s.
out_of_scope In build mode, the paths outside the plan the scope check accepted.
added_exceptions G3 only, when any: the security exceptions the change adds.
known_debt When any: commands with known debt that failed, with name, tail, and count and known when counted.
paid_debt When any: commands with known debt that passed.
summaries When any: the last line of each mutation* command that passed.

log.jsonl

One JSON object per line, appended under a lock, so the lines of two runs never mix. gdd writes a line for every agent call, gate decision, gate command, Path Guard run and machine step. gdd session adds the interactive Claude Code sessions. Reports leave out the lines that are not gdd's (not JSON, or a cost that is not a number of zero or more) and say how many.

{"ts":"2026-10-30T13:11:46+00:00","change":"cart-total","phase":"2-build","gate":"G2","role":"machine","agent":"lint","model":"-","tokens_in":0,"tokens_cache":0,"tokens_out":0,"cost_usd":0.0,"duration_s":0.0,"result":"ok","retry":0,"note":""}
{"ts":"2026-10-30T13:11:46+00:00","change":"cart-total","phase":"2-build","gate":"G2","role":"machine","agent":"checks","model":"-","tokens_in":0,"tokens_cache":0,"tokens_out":0,"cost_usd":0.0,"duration_s":0.0,"result":"ok","retry":0,"note":""}
Field Type Meaning
ts string UTC to the second: 2026-10-30T13:11:46+00:00.
change string The change id; - for the project (G0, the red zones).
phase string 0-setup, 1-discover, 2-build, 3-integrate, 4-release, 5-learn, or -.
gate string G0, zones, plan, G1 to G4, or -.
role string orchestrator, builder-test, builder-build, reviewer, machine, human, or who recorded a gate (--by, such as machines).
agent string The agent of a call (claude, codex, opencode, claude-interactive); for machine steps what ran: a command name, checks (the gate), path-guard, selftest, verdict, merge, a release step; - otherwise.
model string The model of an agent call; - otherwise.
tokens_in integer Input tokens not read from the cache.
tokens_cache integer Input tokens read from the cache.
tokens_out integer Output tokens.
cost_usd number Cost of the call: as the agent reported it, or estimated from [prices].
duration_s number Seconds, to a tenth.
result string ok or ko; for an agent call ok, error-<code> or timeout; for a release step ok, ko or simulated; for a step, what happened: change-created, prepared, parked, changelog-line, released, polish.
retry integer For an agent call, the earlier calls of its role on the change; 0 otherwise.
note string What to read: the failed checks of a gate, the note of a decision, the command an agent ran (/gdd-build), the version released.

The merge commit

gdd merge merges a change into the main branch with a commit whose message carries its record, so what the change was and who approved it travels with the code while .gdd/ stays local. The merge commit of the same change, trimmed:

gdd(cart-total): G3 Merge Gate · Show the cart total

Color: yellow · lane full · type Feature
Approvals: G1 ok (human, 2026-10-30, 1 scenario file(s) sealed)
Decided without the human:
  - Kept the total as an integer
...
Record: .gdd/changes/cart-total/ (local)

Changelog: Added · The cart shows its total
Breaking: no
Line When
gdd(<id>): G3 Merge Gate · <title> Always.
Color: <color> · lane <lane> · type <type> Always.
Approvals: ... The red zones (red changes), G1 and the plan when the record has them; else Approvals: none needed.
Reviewer: KO -> OK, then its findings When the change was reviewed.
Decided without the human: The last eight decided notes.
Tokens: in <n> · cache <n> · out <n> · <usd> USD (estimate) · <n> agent call(s) When the log has calls for the change.
Known debt paid: ..., Known debt lowered: ... When the change paid or lowered known debt.
Record: .gdd/changes/<id>/ (local) Always.
Changelog: <section> · <line> and Breaking: yes or Breaking: no Git trailers, in a paragraph of their own, when the change has a changelog line.

gdd changelog and gdd release read the Changelog: and Breaking: trailers of the merge commits on main to write CHANGELOG.md and to pick the next version.

See also