@pmelab/gtd 2.7.0 β†’ 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,86 +1,42 @@
1
1
  # gi[t]hings.**done**
2
2
 
3
- > [!WARNING] This project is an experiment in unapologetic vibe coding. Code
4
- > might be terrible, I don't even know πŸ€·β€β™‚οΈ But otherwise I wouldn't have built it
5
- > in the first place. Now I have something that actually helps me.
6
-
7
- A git-aware CLI that drives a turn-taking loop between a human and an autonomous
8
- coding agent: capture an idea, grill it into a product-level plan, grill that
9
- into a technical architecture, decompose it into work packages, execute with
10
- parallel subagents, test, agentically review each package, walk a human through
11
- a review, distill durable lessons from the cycle into the project's own docs,
12
- and finally squash the whole cycle into one conventional-commits commit at the
13
- end.
14
-
15
- Internally, gtd is a **pure fold** over git history. The decision core
16
- (`src/Machine.ts`) is a single IO-free function, `resolve(events)` β€” **no
17
- xstate, no actor, no Effect**. The Effect "edge" (`src/Events.ts`) does all the
18
- git/filesystem IO: it reads the **first-parent** commit subjects since the
19
- merge-base with the default branch (whole-history fallback when there is no
20
- default branch, when HEAD equals the merge-base, or when there is no merge-base)
21
- plus the working tree, turns them into a `COMMIT[]` + single terminal `RESOLVE`
22
- event stream, and folds them through the machine. The fold lands on exactly
23
- **one** of 21 states, plus which actor (human or agent) is awaited there. A
24
- single call resolves to a single state.
25
-
26
- Steering is entirely **machine-authored commit subjects** β€” there are no marker
27
- files, sentinels, or auto-advance tails to parse. A turn commit looks like
28
- `gtd(human): grilling` or `gtd(agent): building`; a routing commit (bookkeeping
29
- the machine performs itself between turns) looks like `gtd: tests green`.
30
- `src/Subjects.ts` is the closed grammar both the machine and the edge read.
31
-
32
- All workflow state lives under **`.gtd/`**: the product plan (`.gtd/TODO.md`),
33
- the technical architecture it converges into (`.gtd/ARCHITECTURE.md`), work
34
- packages (`.gtd/01-…/`), review records (`.gtd/REVIEW.md`, `.gtd/FEEDBACK.md`),
35
- and loop bookkeeping (`.gtd/ERRORS.md`, `.gtd/HEALTH.md`, `.gtd/LEARNINGS.md`,
36
- `.gtd/SQUASH_MSG.md`). One rule follows for every agent in the loop: **never
37
- touch `.gtd/`** except the single file a prompt explicitly grants. A `TODO.md`
38
- or `REVIEW.md` at the repository root is the project's own file β€” gtd never
39
- reads, consumes, or deletes it. (Corollary: don't gitignore `.gtd/` β€” the
40
- workflow commits its state through it.)
41
-
42
- A squash commit's message can carry a `## Decisions` section β€” one entry per
43
- architecture/product question resolved that cycle. Grilling/architecting read
44
- every past squash commit's `## Decisions` section back as "Prior decisions"
45
- context, oldest to newest. See `decisionLog` under Configuration.
46
-
47
- ## Quick start: the two-beat loop
48
-
49
- gtd splits what used to be one mutating command into three:
50
-
51
- - **`gtd step`** β€” advance the workflow as the **human** actor, to fixpoint.
52
- - **`gtd step-agent`** β€” advance the workflow as the **agent** actor, to
53
- fixpoint.
54
- - **`gtd next`** β€” print the prompt for whichever actor is currently awaited,
55
- without mutating anything.
56
-
57
- An agent loop is a two-beat protocol repeated forever:
58
-
59
- 1. Run `gtd step-agent` to advance any agent-owned bookkeeping to a fixpoint.
60
- 2. Run `gtd next --json` and read the `actor` field. If it is `"human"`,
61
- **halt** β€” the human owns the next move, and the agent's job is done for this
62
- turn. If it is `"agent"`, feed `prompt` (when non-null) to the agent, let it
63
- act, then go back to step 1; at a pending checkpoint (`prompt` is null) go
64
- straight back to step 1.
65
-
66
- A human acts by editing files (answering questions in `.gtd/TODO.md` or
67
- `.gtd/ARCHITECTURE.md`, annotating `.gtd/REVIEW.md`, fixing code) and then
68
- running `gtd step` to capture the edit as their turn and hand control back to
69
- the agent side of the loop.
70
-
71
- ```bash
72
- gtd step-agent # advance the machine's own bookkeeping
73
- gtd next --json # ask who's up and what they should do
74
- ```
75
-
76
- See [The reference loop driver](#the-reference-loop-driver) for a full script
77
- implementing this protocol, and [`skills/loop/SKILL.md`](skills/loop/SKILL.md)
78
- for the agent-facing instructions that follow the same pinned contract.
79
- `gtd-loop`, installed alongside `gtd` (see below), is the packaged, ready-to-run
80
- implementation of that same script for anyone who doesn't want to drive the loop
81
- by hand.
82
-
83
- ## Installation
3
+ > β€žFix all the tests." β€žβœ… All tests pass!" β€žThe E2E suite is red." β€žAh, you
4
+ > mean _those_ tests."
5
+
6
+ **Chat is a terrible source of truth. Git isn't.**
7
+
8
+ **gtd** is a git-aware CLI that derives the entire agentic workflow β€” capture,
9
+ plan, build, test, review β€” from your repository state, and prints the next
10
+ prompt for whatever agent you point at it. Every step is a commit. Tests are run
11
+ by the tool and branched on by exit code, so the agent never grades its own
12
+ homework.
13
+
14
+ No chat scrollback. No lost sessions. No infinite fix loops. Just git.
15
+
16
+ ## Why
17
+
18
+ - **Durable & replayable.** The workflow state _is_ your git history β€” a pure
19
+ fold over commit subjects and the working tree. Kill the session, reboot, come
20
+ back next week: run `gtd` and it resumes exactly where it stopped.
21
+ - **Shareable.** Push the branch, and the workflow travels with it β€” the state
22
+ lives in the commits, so another machine (or another person) picks up exactly
23
+ where you left off.
24
+ - **Files, not chat.** Plans live in `.gtd/TODO.md`. Request changes by editing
25
+ it, approve by leaving the tree clean β€” all in your own editor. There is no
26
+ chat UI to lose.
27
+ - **Harness agnostic.** gtd emits prompts to stdout (or JSON). Claude Code, a
28
+ bash loop, a CI job, or you reading it out loud β€” the workflow doesn't care
29
+ who executes it.
30
+ - **Bounded, not runaway.** Fix attempts are capped (`retry` on a state). When
31
+ the cap is hit, gtd redirects to a human gate instead of burning tokens
32
+ rewriting the same test for the 47th time.
33
+ - **Your call on history.** Every intermediate `gtd(actor): state` commit is a
34
+ real, attributed commit β€” nothing hidden in chat. Squash them into one
35
+ conventional commit if you want that (an interactive rebase, an amend, a PR's
36
+ squash-merge, or a custom workflow with a `commit:` finale), or don't β€” gtd
37
+ makes no assumption.
38
+
39
+ ## Install
84
40
 
85
41
  ```bash
86
42
  npm install -g @pmelab/gtd
@@ -93,1036 +49,75 @@ npx @pmelab/gtd
93
49
  ```
94
50
 
95
51
  No config file, no setup subcommand β€” `gtd` auto-initializes a `.gtdrc.json`
96
- schema stub on first run (see [Auto-init](#auto-init)).
97
-
98
- ## Command reference
99
-
100
- ```
101
- Usage: gtd [command] [options]
102
-
103
- Commands:
104
- step Advance the workflow as the human actor (to fixpoint)
105
- step-agent Advance the workflow as the agent actor (to fixpoint)
106
- next Print the prompt for whichever actor is awaited (no mutation)
107
- status Predict the next commit and state from the working tree (no mutation)
108
- review <target> Anchor an ad-hoc human review against a git ref or branch
109
- questions List open questions from the active grilling/architecting doc
110
- changesets List changesets/files from the active review doc
111
- format <file> Format a markdown file in place
112
-
113
- Options:
114
- --json Output structured JSON instead of plain text
115
- --version, -v Print version and exit
116
- --help, -h Print this help and exit
117
- ```
118
-
119
- `--version` (`-v`) and `--help` (`-h`) short-circuit before any git or
120
- repository-state work β€” they run outside a repo and in any repo state. Bare
121
- `gtd` (no subcommand) is a usage error: it prints the help text and exits 1
122
- without touching the repository. Every other command must be run from the
123
- **repository root** β€” gtd derives steering files, diffs, and pathspecs relative
124
- to cwd, so it refuses with a clear error if invoked from a subdirectory.
125
-
126
- `--json` is the only long option. Any other `--` option (including a typo like
127
- `--jsn`) is rejected with a usage error rather than silently ignored, so a
128
- mistyped flag can never degrade a JSON caller to plain-text mode.
129
-
130
- One nuance to "(no mutation)": `next` and `status` never author commits or
131
- change workflow state, but while a human review is pending they do maintain the
132
- review checkout window (closing it to read state, re-arming it on the way out β€”
133
- see [Human review gate](#human-review-gate)), which transiently moves HEAD and
134
- the index. The working tree is never touched.
135
-
136
- ### `gtd step` / `gtd step-agent`
137
-
138
- Both drive the **same fixpoint loop** β€” gather β†’ resolve β†’ perform the returned
139
- edge action β†’ repeat β€” differing only in which actor's turn they are allowed to
140
- capture:
141
-
142
- - **`gtd step`** captures the **human** turn at whichever gate is awaiting one.
143
- - **`gtd step-agent`** captures the **agent** turn.
144
-
145
- **Fixpoint advance.** A single invocation may author several commits: it authors
146
- the awaited actor's turn commit, then keeps performing any further mid-chain
147
- routing (a test run, a routing commit, a package close, …) until it reaches a
148
- rest where a prompt would be shown, or a fixpoint where nothing changed.
149
- `gtd step`/`gtd step-agent` never print a prompt themselves β€” that's
150
- `gtd next`'s job.
151
-
152
- **Idempotence.** Re-running the same command again once the tree is settled at a
153
- rest authors **zero** new commits. It exits 0 while the rest still awaits that
154
- command's actor (an inert empty agent turn, the idle health check); once the
155
- rest awaits the _other_ actor, the re-run is an out-of-turn refusal β€” still zero
156
- commits, but non-zero exit.
157
-
158
- **Out-of-turn refusal.** Human and agent turns are strictly separated: the wrong
159
- mutator always errors, at every state, on clean and dirty trees alike.
160
- `gtd step-agent` while a human turn is awaited refuses with
161
- `"<state> awaits a human turn β€” run \`gtd step\`"`; `gtd
162
- step`while an agent turn is awaited refuses with`"<state> awaits an agent turn β€”
163
- run \`gtd
164
- step-agent\`"`β€” exit non-zero, zero commits either way. Human edits made while the agent is awaited (e.g. amendment notes in`.gtd/`package files after the`gtd:
165
- planning` commit lands) stay pending in the working tree and ride along as input
166
- to the agent's next captured turn; left unamended, the build proceeds.
167
-
168
- **Red-test fixpoints exit 0.** A red test run below the fix-attempt cap (or the
169
- health-fix cap) still writes its findings and commits β€” it is a normal,
170
- successful step of the loop, not a failure of the `step`/`step-agent`
171
- invocation. `step`/`step-agent` only exit non-zero for a genuine refusal or an
172
- operational error (bad config, missing test binary, corrupted state).
173
-
174
- **Output.** Plain mode prints one `committed: <subject>` line per commit this
175
- invocation authored (oldest→newest), then a final `state: <state>` line:
176
-
177
- ```
178
- committed: gtd(human): grilling
179
- committed: gtd: architecting
180
- state: architecting
181
- ```
182
-
183
- `--json` emits `{state, actions, commits}` instead (see
184
- [JSON schemas](#json-schemas)).
185
-
186
- ### `gtd next`
187
-
188
- Pure prompt emitter β€” it **never mutates** the repository. It reports whichever
189
- actor is currently awaited and, if the tree is at a genuine rest, the full
190
- prompt for that actor.
191
-
192
- **Purity.** No commits, no file writes, no test runs β€” `gtd next` only gathers
193
- and resolves.
194
-
195
- **Dirty-tree refusal.** If the working tree has pending changes outside the
196
- steering-file set, `gtd next` refuses rather than guess at a prompt for a state
197
- that hasn't been captured yet:
198
-
199
- ```
200
- gtd next: working tree is dirty β€” run `gtd status` to inspect it, then advance with `gtd step` or `gtd step-agent` (whichever actor is awaited)
201
- ```
202
-
203
- **Pending.** If HEAD is mid-chain β€” bookkeeping the next `step`/`step-agent`
204
- invocation would perform before reaching a rest β€” `gtd next` reports
205
- `pending: true` with no prompt. Mid-chain bookkeeping is invoker-agnostic, so
206
- either mutator resumes it; the report names the actor whose chain it is. In
207
- plain mode an agent-driven checkpoint prints `"mid-chain checkpoint β€” run \`gtd
208
- step-agent\` to continue, then run \`gtd next\`
209
- again"`, a human-driven one prints `"mid-chain checkpoint β€” run \`gtd step\` to
210
- continue"`.
211
-
212
- **Agent tail lines.** In plain-mode output, a prompt for the **agent** actor
213
- ends with the pinned tail:
214
-
215
- ```
216
- Finish your turn by running `gtd step-agent`. Then run `gtd next` and follow
217
- its output β€” repeat this cycle as long as the output is addressed to you (the
218
- agent); when it awaits the human, stop and hand off.
219
- ```
220
-
221
- The first sentence closes the current turn; the second closes the outer loop β€”
222
- it is what lets a plain-text agent chain multiple iterations (e.g. successive
223
- test/fix cycles) without an external driver, until a human gate is reached.
224
- Human-actor prompts carry no tail. `--json` output never embeds the tail into
225
- `prompt` either β€” the structured `actor` field (see JSON schemas below) carries
226
- the same information: `"agent"` means another agent round, `"human"` means stop
227
- and hand off.
228
-
229
- ### `gtd status`
230
-
231
- Pure, read-only **dry-run prediction** β€” the same gather+resolve `gtd next`
232
- runs, but reporting a prediction of the next turn rather than the actual prompt.
233
- Performs no git mutation, no test run, no file write β€” guaranteed side-effect
234
- free, including on a dirty tree.
235
-
236
- Prints four fields:
237
-
238
- ```
239
- State: grilling
240
- Awaits: human
241
- Predicted commit: gtd(human): grilling
242
- Predicted state: grilling
243
- ```
244
-
245
- - **State** β€” the currently resolved state.
246
- - **Awaits** β€” the actor (`human` or `agent`) whose turn it is.
247
- - **Predicted commit** β€” the subject `step`/`step-agent` would author next, or
248
- `(none)` at a fixpoint (e.g. idle with nothing to do).
249
- - **Predicted state** β€” the state that commit would land in.
250
-
251
- `gtd status` takes no arguments β€” extra positional args are rejected.
252
-
253
- ### `gtd review <target>`
254
-
255
- A pure mutator that **anchors, then exits** β€” it never prints a prompt itself.
256
- Use it to start an ad-hoc human review against an explicit git ref or branch,
257
- independent of the automatic review base the workflow otherwise computes.
258
-
259
- 1. Refuses on a dirty tree.
260
- 2. Resolves `<target>` via merge-base semantics and computes the diff HEAD adds
261
- over `merge-base(<target>, HEAD)`.
262
- 3. Refuses if that diff is empty after filtering ("nothing to review").
263
- 4. Authors exactly one commit: `gtd: reviewing <full-hash-of-the-base>`.
264
- 5. Prints a short confirmation pointing at `gtd next` β€” it does **not** print
265
- the review prompt itself.
266
-
267
- ```bash
268
- gtd review main
269
- # anchored review at <hash> β€” run `gtd next` to get the review prompt
270
- gtd next --json
271
- # {"actor":"agent", ...} β€” the review-record prompt scoped to that anchor
272
- ```
273
-
274
- Errors (all exit 1, message on stderr):
275
-
276
- - Missing target: `gtd review: missing target argument`
277
- - Extra arguments:
278
- `gtd review: too many arguments β€” expected one target, got: …`
279
- - Unresolvable ref: `gtd review: cannot resolve ref '<target>': <error message>`
280
- - Empty diff:
281
- `gtd review: nothing to review (<target> diff is empty after filtering)`
282
-
283
- ### `gtd questions` / `gtd changesets`
284
-
285
- Pure, read-only reporters β€” no dirty-tree check, no mutation β€” that parse the
286
- structured content out of the active grilling/architecting and review documents,
287
- for a future UI:
288
-
289
- - **`gtd questions`** reads whichever of `.gtd/TODO.md` / `.gtd/ARCHITECTURE.md`
290
- is present and reports its `## Open Questions` list (see
291
- [Structured grilling/architecting and review files](#structured-grillingarchitecting-and-review-files)
292
- below). Reports an empty list when neither file exists.
293
- - **`gtd changesets`** reads `.gtd/REVIEW.md`, if present, and reports its
294
- chunks/file-pointer list. Reports an empty list when the file doesn't exist.
295
-
296
- Both take no arguments and always exit 0 β€” a malformed file is reported via the
297
- `errors` field/lines rather than failing the command (the same diagnosis
298
- `gtd step-agent` would refuse the agent's next turn capture with).
299
-
300
- ```bash
301
- gtd questions --json
302
- # {"file":".gtd/TODO.md","questions":[{"question":"Which operations?","status":"suggested","text":"add and subtract."}],"errors":[]}
303
- gtd changesets --json
304
- # {"file":".gtd/REVIEW.md","shortHash":"abc1234","fullHash":"abc1234...","changesets":[...],"errors":[]}
305
- ```
306
-
307
- ### `gtd format <file>`
308
-
309
- Unchanged from v1: formats a markdown file in place with a bundled prettier
310
- (`parser: "markdown"`, `printWidth: 80`, `proseWrap: "always"`), ignoring the
311
- host repo's own `.prettierrc` so `.gtd/TODO.md`/`.gtd/REVIEW.md` stay
312
- consistently formatted regardless of the host project's toolchain. Rejects
313
- `--json` (exit 1, `gtd format does not accept --json`) β€” it is a plain file
314
- operation, not a v2 state command.
315
-
316
- Errors (all exit 1, message on stderr):
317
-
318
- - Missing path: `gtd format: missing file path argument`
319
- - Extra arguments: `gtd format: too many arguments β€” expected one path, got: …`
320
- - Non-markdown file:
321
- `gtd format: <file> is not a markdown file (expected .md or .markdown)`
322
- - File not found: `gtd: skipped formatting <file>: not found`
323
-
324
- ## JSON schemas
325
-
326
- Pass `--json` to `step`, `step-agent`, `next`, `status`, `review`, `questions`,
327
- or `changesets` for machine-readable single-line JSON output instead of plain
328
- text.
329
-
330
- **`step` / `step-agent`** β€” `{state, actions, commits}`:
331
-
332
- ```json
333
- {
334
- "state": "architecting",
335
- "actions": ["capture the human turn as \"gtd(human): grilling\""],
336
- "commits": ["gtd(human): grilling", "gtd: architecting"]
337
- }
338
- ```
339
-
340
- - `state` β€” the final resolved state after the fixpoint loop settled.
341
- - `actions` β€” human-readable descriptions of every edge action this invocation
342
- performed, oldest→newest.
343
- - `commits` — every commit subject this invocation authored, oldest→newest.
344
-
345
- **`next`** β€” `{state, actor, pending, prompt}`:
346
-
347
- ```json
348
- {
349
- "state": "building",
350
- "actor": "agent",
351
- "pending": false,
352
- "prompt": "..."
353
- }
354
- ```
355
-
356
- - `state` β€” the resolved state.
357
- - `actor` β€” `"human"` or `"agent"`: who owns the next move. This is the single
358
- loop-driver signal: `"agent"` means proceed with another round β€” act on
359
- `prompt` when present, then run `gtd step-agent`; at an agent-driven pending
360
- checkpoint (`prompt` is `null`, nothing to act on) just run `gtd step-agent`.
361
- `"human"` means halt and hand off (a human rest, whose prompt body already
362
- tells the human what to do, or a human-driven pending checkpoint resumed by
363
- `gtd step`).
364
- - `pending` β€” `true` at a mid-chain HEAD (no prompt yet β€” resume with a mutator
365
- first); `false` at a genuine rest.
366
- - `prompt` β€” the full prompt markdown when `pending` is `false`, else `null`.
367
-
368
- **`status`** β€” `{state, actor, predictedCommit, predictedState}`:
369
-
370
- ```json
371
- {
372
- "state": "grilling",
373
- "actor": "human",
374
- "predictedCommit": "gtd(human): grilling",
375
- "predictedState": "grilling"
376
- }
377
- ```
378
-
379
- `predictedCommit` is `null` when the next invocation would author nothing (e.g.
380
- idle with a green health check).
381
-
382
- **`questions`** β€” `{file, questions, errors}`:
383
-
384
- ```json
385
- {
386
- "file": ".gtd/TODO.md",
387
- "questions": [
388
- {
389
- "question": "Which operations?",
390
- "status": "suggested",
391
- "text": "add and subtract."
392
- }
393
- ],
394
- "errors": []
395
- }
396
- ```
397
-
398
- `file` is `null` when neither `.gtd/TODO.md` nor `.gtd/ARCHITECTURE.md` is
399
- present. `errors` lists any structural problems in the file β€” the same diagnosis
400
- that would make `gtd step-agent` refuse the agent's next turn capture.
401
-
402
- **`changesets`** β€” `{file, shortHash, fullHash, changesets, errors}`:
403
-
404
- ```json
405
- {
406
- "file": ".gtd/REVIEW.md",
407
- "shortHash": "abc1234",
408
- "fullHash": "abc1234def5678901234567890123456789abcd",
409
- "changesets": [
410
- {
411
- "title": "Add calculator",
412
- "description": "New add function for the calculator.",
413
- "files": [{ "path": "./src/calc.ts", "line": 1, "checked": false }]
414
- }
415
- ],
416
- "errors": []
417
- }
418
- ```
419
-
420
- `file` is `null` when `.gtd/REVIEW.md` doesn't exist. `errors` mirrors
421
- `questions`' field above.
422
-
423
- **Error envelope** β€” every command, in `--json` mode, reports failures inside
424
- the JSON object rather than as unstructured text, and still exits 1:
425
-
426
- ```json
427
- { "state": "error", "prompt": "<message>" }
428
- ```
429
-
430
- There is no auto-advance flag anywhere in the wire format β€” `actor` replaces it.
431
- The caller decides whether to keep looping based on `actor` (halt on `"human"`)
432
- and `pending` (re-run `step`/`step-agent` first when `true`), not on a boolean
433
- auto-advance flag.
434
-
435
- ## The reference loop driver
436
-
437
- A minimal bash implementation of the pinned two-beat protocol, driving an agent
438
- CLI (e.g. `claude -p`) against `gtd --json` output. This is the authoritative
439
- reference for what a loop driver must do; keep any other implementation
440
- (including `skills/loop/SKILL.md`) consistent with it rather than editing both
441
- independently.
442
-
443
- ```bash
444
- #!/usr/bin/env bash
445
- set -euo pipefail
446
-
447
- while true; do
448
- # 1. Advance the machine's own agent-owned bookkeeping to a fixpoint.
449
- gtd step-agent --json >/dev/null || true
450
-
451
- # 2. Ask who's up next. `actor` is the single "proceed" signal.
452
- next="$(gtd next --json)"
453
- actor="$(jq -r .actor <<<"$next")"
454
- prompt="$(jq -r .prompt <<<"$next")"
455
-
456
- if [[ "$actor" != "agent" ]]; then
457
- echo "Halting β€” the human owns the next move."
458
- break
459
- fi
460
-
461
- if [[ "$prompt" == "null" ]]; then
462
- # Agent-driven pending checkpoint: nothing to act on β€” loop back to
463
- # step 1, whose `gtd step-agent` resumes the mid-chain bookkeeping.
464
- continue
465
- fi
466
-
467
- # Agent's turn: feed the prompt to the agent, then let it finish with
468
- # `gtd step-agent` itself (the prompt's tail instructs it to).
469
- claude -p "$prompt" --dangerously-skip-permissions
470
- done
471
- ```
472
-
473
- The agent is expected to run `gtd step-agent` itself once it finishes acting on
474
- the prompt (the plain-mode tail says exactly this) β€” the driver's own
475
- `step-agent` calls exist to advance any bookkeeping the agent doesn't own
476
- (routing commits, test runs) between agent turns.
477
-
478
- The loop halts on `actor: "human"` alone: a human rest (`pending: false`, the
479
- prompt body addresses the human) or a human-driven pending checkpoint
480
- (`pending: true`, resumed by the human's own `gtd step`). Everything the agent
481
- side can drive β€” agent rests and agent-driven checkpoints β€” reports
482
- `actor: "agent"`, so multiple agent turns and commits (e.g. successive test/fix
483
- cycles, a force-approved package close) chain without human involvement until an
484
- actual human gate is hit.
485
-
486
- `bin/gtd-loop`, installed as the `gtd-loop` binary, is the packaged
487
- implementation of this exact script β€” kept in sync with it the same way
488
- `skills/loop/SKILL.md` is. It additionally attempts `gtd step` (not just
489
- `gtd step-agent`) every iteration, so a plain rerun after you've edited a file
490
- at a human gate (no commit needed) picks up your edit and keeps going, and it
491
- halts with a diagnostic if the same state and prompt repeat with no progress
492
- (see `skills/loop/SKILL.md`'s "Stall detection").
493
-
494
- ### Using a different agent
495
-
496
- `gtd-loop` defaults to
497
- `claude -p "$GTD_LOOP_PROMPT" --dangerously-skip-permissions`, but the agent
498
- invocation is swappable: set `GTD_LOOP_AGENT_CMD` to any shell command, and it
499
- runs with the prompt available as `$GTD_LOOP_PROMPT` in its environment. For
500
- example, to drive a different agent CLI:
501
-
502
- ```bash
503
- GTD_LOOP_AGENT_CMD='my-agent-cli --prompt "$GTD_LOOP_PROMPT"' gtd-loop
504
- ```
505
-
506
- ## States & subjects overview
507
-
508
- `resolve()` lands on exactly one of **21 states**: `grilling`, `architecting`,
509
- `grilled`, `planning`, `building`, `testing`, `fixing`, `escalate`,
510
- `agentic-review`, `close-package`, `review`, `await-review`, `done`, `learning`,
511
- `await-learning-review`, `learning-apply`, `learning-applied`, `squashing`,
512
- `idle`, `health-check`, `health-fixing`. Each state has a fixed awaited actor
513
- (see `awaitedActor` in `src/Machine.ts`): `idle`, `escalate`, `await-review`,
514
- and `await-learning-review` await the **human**; every other state awaits the
515
- **agent**.
516
-
517
- For the full precedence ladder, illegal combinations, and the counter folds that
518
- drive the fix loops, see [STATES.md](STATES.md) β€” this section is a summary.
519
-
520
- ### Turn commits β€” `gtd(<actor>): <gate>`
521
-
522
- Authored by `gtd step`/`gtd step-agent` as the first commit of a fresh chain.
523
- The closed set of gates:
524
-
525
- | Gate | Authored by |
526
- | ---------------- | ------------------------------------------------------------------ |
527
- | `grilling` | human (answers) / agent (product-plan iteration) |
528
- | `architecting` | human (answers) / agent (architecture iteration) |
529
- | `grilled` | agent (converged, ready to decompose) |
530
- | `building` | agent (package work, or human feedback while agent is out of turn) |
531
- | `fixing` | agent (test-fix or review-fix round) |
532
- | `agentic-review` | agent (writes .gtd/FEEDBACK.md verdict) |
533
- | `review` | agent (writes .gtd/REVIEW.md) / human (approves or gives feedback) |
534
- | `squashing` | agent (overwrites .gtd/SQUASH_MSG.md) |
535
- | `learning` | agent (overwrites .gtd/LEARNINGS.md) / human (accepts or edits) |
536
- | `learning-apply` | agent (integrates .gtd/LEARNINGS.md into CLAUDE.md/AGENTS.md/docs) |
537
- | `health-fixing` | agent (idle health-check repair) |
538
- | `escalate` | human (deletes .gtd/ERRORS.md to resume) |
539
-
540
- ### Routing commits β€” `gtd: <phase>`
541
-
542
- Bookkeeping the machine authors itself between turns, never a turn a human or
543
- agent "wins": `gtd: architecting`, `gtd: grilled`, `gtd: planning`,
544
- `gtd: tests green`, `gtd: errors`, `gtd: package done`, `gtd: awaiting review`,
545
- `gtd: review feedback`, `gtd: done`, `gtd: squash template`,
546
- `gtd: reviewing <hash>` (parameterized, from `gtd review`), `gtd: health-check`,
547
- `gtd: health-fix`, `gtd: learning template`, `gtd: learning drafted`,
548
- `gtd: learning approved`, `gtd: learning applied`.
549
-
550
- Everything else β€” any non-`gtd` subject, and any `gtd: *` subject outside this
551
- closed set β€” is a **boundary commit**: inert as far as the machine's grammar is
552
- concerned. See [Upgrading from v1](#upgrading-from-v1-breaking-change) for why
553
- this matters on upgrade.
554
-
555
- ## Workflow walkthroughs
556
-
557
- ### Grilling: two phases, product then architecture
558
-
559
- A dirty tree at a boundary HEAD (a fresh idea, sketched in a file or just left
560
- as pending code) is captured in **one** human turn: `gtd step` commits
561
- everything pending as `gtd(human): grilling` β€” nothing is reverted or seeded,
562
- the captured files stay in history. `gtd next` hands the agent that turn's diff;
563
- the agent develops `.gtd/TODO.md` into a concrete **product-level** plan **in
564
- one turn** β€” user-facing decisions only, no architecture β€” proposing a
565
- **suggested default** for every open question under an enforced
566
- `## Open Questions` structure (see
567
- [Structured grilling/architecting and review files](#structured-grillingarchitecting-and-review-files)),
568
- and leaves `.gtd/TODO.md` uncommitted for `gtd(agent): grilling`.
569
-
570
- There are no markers to answer β€” the human either:
571
-
572
- - **Accepts the suggested defaults**: runs a clean `gtd step` at the answer
573
- gate. An empty `gtd(human): grilling` turn plus routing `gtd: architecting`
574
- lands automatically β€” `.gtd/ARCHITECTURE.md` is seeded from the converged
575
- `.gtd/TODO.md` content and `.gtd/TODO.md` is deleted, in that one commit.
576
- - **Edits `.gtd/TODO.md`** with real answers, then runs `gtd step`, which
577
- captures the edit as a fresh `gtd(human): grilling` turn and hands it back to
578
- the agent for another round.
579
-
580
- Technical architecting works exactly the same way, one file later: the agent
581
- develops `.gtd/ARCHITECTURE.md` into a concrete **technical** plan β€” file/module
582
- structure, data model, tech-stack choices β€” and the human answers or accepts
583
- defaults at the `architecting` gate. Accepting converges to `gtd: grilled` and
584
- `gtd next` emits the decompose prompt (which now reads `.gtd/ARCHITECTURE.md`).
585
-
586
- **Escape hatch for already-technical input:** if the human's initial dirty tree
587
- already contains `.gtd/ARCHITECTURE.md` (their own technical sketch), `gtd step`
588
- captures the entry turn as `gtd(human): architecting` directly, skipping product
589
- grilling for that cycle entirely β€” no CLI flag needed, it's driven purely by
590
- which steering file is present.
591
-
592
- ### Structured grilling/architecting and review files
593
-
594
- `.gtd/TODO.md`, `.gtd/ARCHITECTURE.md`, and `.gtd/REVIEW.md` stay plain,
595
- human-readable markdown, but each follows an enforced structure so the data can
596
- be parsed out programmatically (`gtd questions` / `gtd changesets`, both
597
- `--json`-able, for a future UI) instead of staying opaque prose.
598
-
599
- **Grilling/architecting** (identical contract, one file and phase apart): an
600
- OPTIONAL `## Open Questions` section β€” omitted entirely means zero open
601
- questions, not an error. Every `###` sub-heading directly under it is one open
602
- question; its first body line must be `Suggested default: <text>` (the agent's
603
- proposal) or `Answer: <text>` (a human's answer):
604
-
605
- ```markdown
606
- # Plan
607
-
608
- Build a calculator that can add and subtract.
609
-
610
- ## Open Questions
611
-
612
- ### Which operations?
613
-
614
- Suggested default: add and subtract.
615
- ```
616
-
617
- **Review**: a `# Review: <short-hash>` header as the first line, an
618
- `<!-- base: <full-hash> -->` comment, and at least one `##` chunk with a
619
- non-empty title and at least one `- [ ]` / `- [x]` file-pointer line β€” the same
620
- format `@review` already instructs the agent to write (see
621
- [Human review gate](#human-review-gate) below).
622
-
623
- Validation applies ONLY to the **agent's own authored draft** at the gate that
624
- writes the file β€” never to a human's free-form edits (their answer at the
625
- grilling/architecting gate, their feedback/approval at the review gate). When
626
- the active file is malformed, `gtd step-agent` refuses (zero commits, a stderr
627
- message listing every structural problem) instead of capturing the turn; the
628
- agent fixes the file and reruns `gtd step-agent`. `gtd questions --json` /
629
- `gtd changesets --json` surface the same `errors` without blocking anything, so
630
- an agent (or a UI) can self-check before committing to a turn.
631
-
632
- ### Build lifecycle: budgets
633
-
634
- Once decomposed, `.gtd/` holds ordered work packages. `gtd next` at
635
- `gtd: planning`/`gtd: package done` selects the lowest-numbered remaining
636
- package and inlines only its task files. The agent builds it and leaves the work
637
- **uncommitted**; the next invocation's edge action commits it (the
638
- `gtd(agent): building` turn commit) and runs `testCommand`.
639
-
640
- - **Green** β†’ Agentic Review.
641
- - **Red, below `fixAttemptCap`** (default 3) β†’ write findings, commit
642
- `gtd: errors`, rest at **Fixing** for the agent.
643
- - **Red, at/over the cap** β†’ write `.gtd/ERRORS.md` instead, commit
644
- `gtd: errors`, rest at **Escalate** β€” a human gate. Deleting `.gtd/ERRORS.md`
645
- and landing that deletion as `gtd(human): escalate` resets the budget and
646
- re-tests from zero in the same invocation.
647
-
648
- ### Agentic review
649
-
650
- A green test run always rests at **Agentic Review**: the agent reviews the
651
- package's accumulated diff against its task specs and writes `.gtd/FEEDBACK.md`.
652
- An **empty** `.gtd/FEEDBACK.md` is the approval signal β€” the same
653
- `gtd(agent): agentic-review` turn closes the package (`gtd: package done`,
654
- removing `.gtd/FEEDBACK.md` and the finished package directory) in one
655
- invocation. Non-empty findings rest for the fixing prompt; fixing loops back
656
- through the test gate and re-reviews. Once `reviewFixCount >= reviewThreshold`
657
- (default 3) within a package, Agentic Review **force-approves** without ever
658
- writing `.gtd/FEEDBACK.md` β€” so a package can never review-loop forever. The
659
- findings round that crosses the threshold still gets its fixing round; the
660
- force-approve close then fires at the next green re-test instead of another
661
- review. (Any agentic-review turn that touches `.gtd/FEEDBACK.md` counts toward
662
- the threshold β€” including the approval write itself; an approval that crosses
663
- the threshold simply closes the package as usual.) Setting
664
- `agenticReview: false` force-approves every package immediately.
665
-
666
- A **do-nothing agent invocation** β€” `gtd step-agent` on a clean tree at ANY
667
- agent-awaited rest whose move is a file artifact (`grilling`, `architecting`,
668
- `grilled`, `building`, `fixing`, `agentic-review`, `review`, `squashing` while
669
- `.gtd/SQUASH_MSG.md` still holds the unmodified template, `learning` while
670
- `.gtd/LEARNINGS.md` still holds the unmodified template, and `learning-apply`
671
- unconditionally) β€” is inert: zero commits, no state consumed; `gtd next`
672
- re-emits the same prompt. This is load-bearing for the loop protocol, whose
673
- every iteration opens with `gtd step-agent` before the agent has acted: without
674
- the guard that opening beat would author junk empty turns β€” and worse, consume
675
- workflow state (an empty decompose turn would delete `.gtd/ARCHITECTURE.md` with
676
- no packages written; an empty squashing turn would squash the cycle under the
677
- placeholder template). The same guards hold at the classification layer for
678
- histories that already carry such turns: a `gtd(agent): grilled` HEAD only
679
- routes to `gtd: planning` when packages exist, a `gtd(agent): review` HEAD only
680
- routes to `gtd: awaiting review` when `.gtd/REVIEW.md` exists, and a squashing
681
- (or learning) turn only proceeds once its template has been overwritten. The one
682
- deliberate exception is `health-fixing`, whose empty turn is meaningful (the
683
- failure may have been environmental β€” the machine removes `.gtd/HEALTH.md` and
684
- re-tests). Human gates are unaffected: an empty **human** turn stays a signal
685
- (accept-defaults at grilling/architecting, clean approval at review,
686
- accept-the-draft-as-is at the learning review gate).
687
-
688
- ### Human review gate
689
-
690
- Once `.gtd/` is fully closed, the machine writes `.gtd/REVIEW.md` and rests at
691
- **await-review**, awaiting the human. Approval is any of:
692
-
693
- - A **clean** `gtd step` (nothing edited) β€” an empty `gtd(human): review` turn
694
- plus routing `gtd: done`.
695
- - Flipping only `- [ ]` β†’ `- [x]` checkboxes in `.gtd/REVIEW.md` β€” checkbox-only
696
- edits are also treated as clean approval.
697
- - Deleting `.gtd/REVIEW.md` outright.
698
-
699
- Any **substantive** edit β€” to `.gtd/REVIEW.md` prose, or to the reviewed code
700
- itself β€” is feedback: `gtd(human): review` plus routing `gtd: review feedback`,
701
- `.gtd/REVIEW.md` removed, and `gtd next` re-emits a grilling prompt to the agent
702
- that inlines the human's finding.
703
-
704
- **The review diff lives in your editor.** While the gate is pending, gtd holds
705
- open a _review checkout window_: it saves the real head to
706
- `refs/gtd/review-head`, then rewinds HEAD and the index to the review base with
707
- `git reset --mixed`, leaving the working tree untouched. Every editor's standard
708
- git integration now shows the entire reviewable diff as ordinary uncommitted
709
- changes β€” SCM panel, gutter marks, per-file diffs. Review it there:
710
-
711
- - **Edit** anything (code or `.gtd/REVIEW.md` prose) β†’ feedback.
712
- - **Discard a hunk** in the editor β†’ that reversion IS the feedback: the agent
713
- is re-grilled with it.
714
- - **Delete a surfaced file** β†’ reject-this-file feedback.
715
- - Touch nothing (or tick checkboxes / delete `.gtd/REVIEW.md`) β†’ approval.
716
-
717
- Any gtd invocation closes the window first (restoring HEAD/index exactly, so
718
- only your own edits remain dirty β€” they land as their own separate
719
- `gtd(human): review` commit, never mixed into the reviewed work), and
720
- `gtd next`/`gtd status` re-arm it on their way out. The mechanics are
721
- crash-safe; details and invariants in STATES.md ("The review checkout window").
722
-
723
- Caveats while a review is pending: don't push (the branch tip rests at the
724
- review base β€” the real head is safe under `refs/gtd/review-head`); commits you
725
- make manually survive as working-tree content and become review feedback, but
726
- their commit message is discarded; linked `git worktree` checkouts are
727
- unsupported. If you switch branches mid-review, gtd refuses to touch the foreign
728
- branch and prints the manual recovery command.
729
-
730
- ### Learning
731
-
732
- With `learning: true` (the default), `gtd: done` (or the health-fix path's green
733
- re-test) is **not** a rest β€” the chain continues straight to
734
- `gtd: learning template`, writing and committing a `.gtd/LEARNINGS.md` template,
735
- running _before_ the squash decision so it still sees the pre-squash history.
736
- `gtd next` then emits the learning prompt: the agent walks the cycle's test
737
- failures, review feedback, and health-check rounds, keeps only
738
- durable/generalizable lessons, and overwrites `.gtd/LEARNINGS.md` with them.
739
- Once `gtd step-agent` captures that draft (`gtd(agent): learning`), it rests at
740
- **await-learning-review** for a human β€” who either accepts the draft as-is (an
741
- empty turn) or edits it; there is no reject path, so the very next `gtd step`
742
- always proceeds (`gtd(human): learning` β†’ `gtd: learning approved`), resting at
743
- **learning-apply** for the agent. The agent integrates the approved learnings
744
- into the project's own docs (`CLAUDE.md`/`AGENTS.md`/wherever fits, its
745
- judgment); its turn (`gtd(agent): learning-apply`) removes `.gtd/LEARNINGS.md`
746
- and lands at `gtd: learning applied`, which then runs the same squash decision
747
- `gtd: done` runs today. With `learning: false`, `gtd: done` behaves exactly as
748
- it does without this section: no `.gtd/LEARNINGS.md` is ever written. Learning
749
- and squash are independent flags β€” either can be on without the other.
750
-
751
- ### Squash
752
-
753
- With `squash: true` (the default), `gtd: done` (or, once learning has run,
754
- `gtd: learning applied`) is **not** a rest β€” the same chain continues straight
755
- to `gtd: squash template`, writing and committing a `.gtd/SQUASH_MSG.md`
756
- template. `gtd next` then emits the squashing prompt: the agent overwrites
757
- `.gtd/SQUASH_MSG.md` with a real conventional-commits message (drawing on
758
- grilling- and architecting-round decisions from history, and, when this cycle
759
- resolved any open questions, a `## Decisions` section recording them) and
760
- finishes its turn. `gtd step-agent` then performs the squash itself:
761
- `git reset --soft <base>` + `git commit`, collapsing every intermediate `gtd: *`
762
- commit of the cycle into one β€” including any review-feedback detours, and the
763
- learning phase's own commits if learning ran: the squash base is the cycle's
764
- ORIGINAL start (the first grilling or, via the escape hatch, architecting turn
765
- since the previous `gtd: done` boundary, or the `gtd: reviewing <hash>` anchor
766
- for an ad-hoc review cycle), not the most recent re-grilling round β€” the
767
- collapse folds the whole cycle into one, using the overwritten message's content
768
- verbatim (turn position, not message content, triggers the squash). Doc edits
769
- made during `learning-apply` survive in the squashed tree, not as their own
770
- commit. With `squash: false`, `gtd: done` (or `gtd: learning applied`) is the
771
- resting boundary and no template is ever written.
772
-
773
- ### Health check
774
-
775
- Outside any process (idle, nothing to review, no steering files), `gtd step`
776
- runs `testCommand` as a health check rather than settling immediately. Green
777
- settles idle with zero commits. Red below `fixAttemptCap` writes
778
- `.gtd/HEALTH.md` and rests at **Health Fixing** for the agent; the fixer's own
779
- turn (`gtd(agent): health-fixing`) removes `.gtd/HEALTH.md` and re-tests in the
780
- same chain β€” a green re-test continues to learning (if enabled), then squash (if
781
- enabled), or idle; red repeats the health-fix loop; red at the cap writes
782
- `.gtd/ERRORS.md` and escalates.
783
-
784
- ### Escalate / budget reset
785
-
786
- `.gtd/ERRORS.md` present is always a human gate, regardless of which loop wrote
787
- it (test-fix or health-fix). Deleting `.gtd/ERRORS.md` and running `gtd step`
788
- records the deletion as the human's `gtd(human): escalate` turn, which
789
- **immediately re-tests in the same invocation** β€” this resets the relevant
790
- fix-attempt budget to zero.
791
-
792
- ## States & subjects: overview table
793
-
794
- | State | Awaits | Turn/routing subject at rest |
795
- | ----------------------- | -------------- | ---------------------------------------------------------------- |
796
- | `grilling` | human or agent | `gtd(human): grilling` / `gtd(agent): grilling` |
797
- | `architecting` | human or agent | `gtd: architecting` / `gtd(agent): architecting` |
798
- | `grilled` | agent | `gtd: grilled` |
799
- | `planning` | agent | `.gtd/` modified |
800
- | `building` | agent | `gtd: planning` / `gtd: package done` |
801
- | `testing` | β€” (edge-only) | mid-chain only |
802
- | `fixing` | agent | `gtd: errors` |
803
- | `escalate` | human | `.gtd/ERRORS.md` present |
804
- | `agentic-review` | agent | `gtd: tests green` |
805
- | `close-package` | β€” (edge-only) | mid-chain only |
806
- | `review` | agent | `gtd: package done` (no more packages) / `gtd: reviewing <hash>` |
807
- | `await-review` | human | `gtd: awaiting review` |
808
- | `done` | β€” (edge-only) | `gtd: done` |
809
- | `learning` | agent | `gtd: learning template` |
810
- | `await-learning-review` | human | `gtd: learning drafted` |
811
- | `learning-apply` | agent | `gtd: learning approved` |
812
- | `learning-applied` | β€” (edge-only) | `gtd: learning applied` |
813
- | `squashing` | agent | `gtd: squash template` |
814
- | `idle` | human | no steering files, green health check |
815
- | `health-check` | β€” (edge-only) | mid-chain only |
816
- | `health-fixing` | agent | `.gtd/HEALTH.md` present |
817
-
818
- See [STATES.md](STATES.md) for the full precedence ladder, the counter folds,
819
- and every illegal steering-file combination.
820
-
821
- ## Configuration
822
-
823
- gtd reads an optional `.gtdrc` config file via
824
- [cosmiconfig](https://github.com/cosmiconfig/cosmiconfig). With no config, the
825
- built-in defaults apply. Supported filenames (searched in this order):
826
-
827
- - `.gtdrc`
828
- - `.gtdrc.json`
829
- - `.gtdrc.yaml`
830
- - `.gtdrc.yml`
831
- - `gtd.config.json`
832
- - `gtd.config.yaml`
833
-
834
- ### Schema
835
-
836
- - **`testCommand`** (string, default `npm run test`) β€” the command the edge runs
837
- after a build turn, and on the idle health-check path.
838
- - **`fixAttemptCap`** (non-negative integer, default `3`) β€” the test-fix budget:
839
- how many `gtd: errors` attempts are allowed per sub-loop before the failure is
840
- escalated to `.gtd/ERRORS.md` (Escalate). `0` disables the cap (escalates
841
- immediately on the first red run). Also reused as the health-fix budget β€” no
842
- separate config key.
843
- - **`reviewThreshold`** (integer β‰₯ 1, default `3`) β€” the review-fix budget: how
844
- many agentic-review findings rounds are allowed per package before Agentic
845
- Review force-approves.
846
- - **`agenticReview`** (boolean, default `true`) β€” kill-switch for the
847
- per-package Agentic Review gate. Set `false` to force-approve every package
848
- and proceed directly to human review.
849
- - **`squash`** (boolean, default `true`) β€” after `gtd: done` (or, once learning
850
- has run, `gtd: learning applied`), collapse the cycle's `gtd: *` commits into
851
- a single conventional-commits commit. Set `false` to keep the granular
852
- history.
853
- - **`learning`** (boolean, default `true`) β€” after `gtd: done` (or the
854
- health-fix path's green re-test), distill durable lessons from the cycle into
855
- `.gtd/LEARNINGS.md`, have a human review them, then integrate them into the
856
- project's own docs before the squash decision runs. Set `false` to skip the
857
- phase entirely β€” independent of `squash`.
858
- - **`decisionLog`** (boolean, default `true`) β€” squashing records this cycle's
859
- resolved open questions as a `## Decisions` section in the squash commit
860
- message; grilling/architecting inline every past squash commit's section,
861
- oldest to newest, as prior-decision context. Set `false` to skip both.
862
- - **`models`** β€” model selection for the subagent-spawning states:
863
- - `planning` β€” high-reasoning tier (default `claude-opus-4-8`), used by
864
- `decompose` (the `grilled`/`planning` states), `grilling`, `architecting`,
865
- `agentic-review`, and `clean` (the `review`/`squashing`/`learning`/
866
- `learning-apply` states).
867
- - `execution` β€” everyday tier (default `claude-sonnet-4-8`), used by
868
- `building` and `fixing`.
869
- - `states.*` β€” per-state overrides keyed by `decompose`, `grilling`,
870
- `architecting`, `building`, `fixing`, `agentic-review`, `clean`. Unknown
871
- `states` keys are **rejected**.
872
- - **`$schema`** (string, optional) β€” stripped before validation, so it never
873
- counts as an unknown key. Point it at the published schema for editor-backed
874
- autocompletion. A `schema.json` is generated from the config schema at build
875
- time and ships with the package.
876
-
877
- ### Validation and errors
878
-
879
- If a config file fails to load or is invalid, gtd **exits with code 1** and
880
- writes a human-readable error to **stderr** (never stdout):
881
-
882
- - **Parse errors** (malformed YAML/JSON) β€” message includes the offending
883
- filename.
884
- - **Non-object top-level** β€” a YAML list or `null` at the root is rejected with
885
- the filename in the message.
886
- - **Schema violations** β€” unknown keys or out-of-range values emit
887
- `Invalid gtd config: <field>: <reason>`.
888
- - **Missing test binary** β€” if `testCommand` names an executable that cannot be
889
- found (`ENOENT`), gtd exits 1 with `gtd: test command not found: <command>` on
890
- stderr. A non-zero test _exit code_ is not an error β€” it drives the normal red
891
- path.
892
-
893
- ### Lookup and precedence
894
-
895
- gtd walks from the current working directory **up to your home directory** (or
896
- to the filesystem root when cwd is outside home), collecting every `.gtdrc` it
897
- finds along the way. All found levels are **deep-merged**, with the **innermost
898
- (cwd) config winning** on conflicts β€” so a shared `.gtdrc` in a worktree-parent
899
- directory cascades to every checkout beneath it, while any individual checkout
900
- can still override settings with its own `.gtdrc`.
901
-
902
- ### Auto-init
903
-
904
- On every **state command** (`step`, `step-agent`, `next`, `status`, `review`)
905
- that has passed the repo-root guard, if the cwd→root walk finds **no** config
906
- anywhere, gtd creates and commits a starter `.gtdrc.json` at the repository root
907
- containing only a `$schema` link. Auto-init never runs for `--version`/`--help`,
908
- `format`, bare/unknown commands, or an invocation refused by the repo-root guard
909
- β€” those perform no repository mutation of any kind. On a repo with no commits
910
- yet, or whose HEAD is a plain (non-`gtd:`) commit, the stub is committed as its
911
- own `chore: add .gtdrc.json`. If HEAD is already a `gtd:`-owned commit
912
- (mid-workflow), the stub is instead **amended into HEAD** β€” stacking a fresh
913
- boundary commit there would produce an unrecognized HEAD most workflow states
914
- can't resolve past.
915
-
916
- ### Example
917
-
918
- ```yaml
919
- # .gtdrc.yaml
920
- testCommand: pnpm test
921
- fixAttemptCap: 3
922
- reviewThreshold: 3
923
- agenticReview: true
924
- squash: true
925
- learning: true
926
- decisionLog: true
927
- models:
928
- planning: claude-opus-4-8
929
- execution: claude-sonnet-4-8
930
- states:
931
- decompose: claude-opus-4-8
932
- building: claude-sonnet-4-8
933
- ```
934
-
935
- ## Repository requirements
936
-
937
- - **Single writer, linear branch.** State is folded from **first-parent**
938
- history only. A merge commit at HEAD is unsupported (documented, not handled)
939
- β€” it degrades gracefully on the default branch rather than crashing, but do
940
- not rely on merge commits mid-cycle.
941
- - **Test/build artifacts must be gitignored.** This is **load-bearing**, not a
942
- style preference: every fixpoint hop in `gtd step`/`gtd step-agent` detects
943
- "clean" via `git status --porcelain`, which silently omits anything matched by
944
- `.gitignore`. If your `testCommand` (or the build it triggers) writes
945
- tracked-but-untracked output β€” a `dist/`, a coverage report, a log file β€” into
946
- the working tree, the tree never goes clean after a green test run, and the
947
- fixpoint loop cannot converge: it will either loop forever re-detecting a
948
- "dirty" boundary or misclassify build output as the human's next feature
949
- capture. Gitignore every path your test/build toolchain writes before wiring
950
- gtd into a repo.
951
- - **Repository root invocation.** Every subcommand except `--help`/`--version`
952
- must run from the git repository root β€” steering files and diffs are resolved
953
- against the process cwd.
954
-
955
- ## Build orchestration
956
-
957
- ### Decompose
958
-
959
- The Grilled/Planning states spawn a planning-model subagent that breaks
960
- `.gtd/ARCHITECTURE.md` into executable work packages under `.gtd/`:
961
-
962
- ```
963
- .gtd/
964
- 01-auth-module/
965
- 01-define-types.md
966
- 02-implement-login.md
967
- 02-api-endpoints/
968
- 01-create-routes.md
969
- 02-add-middleware.md
970
- ```
971
-
972
- Rules:
973
-
974
- - **Packages are sequential, in ordinal dependency order** β€” `01-`, `02-`, …;
975
- the set is frozen once written. Package 02 cannot start until 01 is complete.
976
- - **Each package is green on its own** β€” the test suite runs after every
977
- package, so none may leave the tree red for a later package to fix.
978
- - **Tasks within a package are parallel and file-disjoint** β€” one subagent per
979
- task, no isolation; tasks that would touch the same file are merged into one.
980
- - **Vertical slices, not horizontal** β€” each package is a thin, end-to-end
981
- slice; prefer many thin packages over a "set up infrastructure" package.
982
- - **Task files are self-contained** β€” description, acceptance-criteria
983
- checkboxes, relevant file paths, constraints, and edge cases.
984
-
985
- ### Execute
986
-
987
- Execution is **one package per cycle**. `gtd next` selects the single next
988
- package itself, names it in the prompt, and inlines its task files' full
989
- contents β€” the agent never browses `.gtd/` or picks a package itself. A single
990
- cycle:
991
-
992
- 1. Spawn parallel execution-model workers for all tasks in the selected package.
993
- 2. Leave all changes **uncommitted**. Do not commit, do not delete the package
994
- directory, do not run tests.
995
- 3. Finish the turn with `gtd step-agent` β€” the next hop's edge action commits
996
- the work (`gtd(agent): building`) and runs `testCommand` to verify it.
997
-
998
- ## Upgrading from v1 (BREAKING CHANGE)
999
-
1000
- v2 ships as a **major** semantic-release bump (`2.0.0`) so the binary and the
1001
- loop-driving text (this README, `skills/loop/SKILL.md`) can never skew against
1002
- each other. There is **no backward compatibility with the v1 command surface**:
1003
- the single mutating `gtd` command, marker/sentinel files, the `autoAdvance` JSON
1004
- field, and the `gtd: transport` handoff commit are all gone. `gtd` bare now
1005
- errors rather than driving a loop; use `gtd step-agent` / `gtd next` /
1006
- `gtd step` instead.
1007
-
1008
- **Commit-history compatibility is one-way.** Any repo with v1-taxonomy history
1009
- in it (`gtd: new task`, `gtd: grilling`, `gtd: transport`, a bare
1010
- `gtd: reviewing` with no hash, …) upgrades cleanly: those subjects fall outside
1011
- v2's closed turn/routing grammar and parse as inert **boundary commits** β€” they
1012
- are never mistaken for v2 workflow state and never error.
1013
-
1014
- **Finish or clean up any in-flight v1 cycle first.** If a repo has an
1015
- **in-progress** v1 cycle β€” steering files present (root-level `TODO.md`,
1016
- `REVIEW.md`, `FEEDBACK.md`, `ERRORS.md`, or `.gtd/`) whose HEAD carries v1-only
1017
- commit subjects β€” the v2 binary does not know how to resume it: v1 steering
1018
- files have no v2 turn commit backing them, so a cold v2 invocation on that tree
1019
- can land in an unrecognized state. Either finish the v1 cycle to a clean
1020
- boundary with your existing v1 binary before upgrading, or manually clean up
1021
- (remove the steering files / `.gtd/`, commit the result) so the upgrade starts
1022
- from a plain boundary HEAD.
1023
-
1024
- **Steering files moved into `.gtd/`.** Earlier v2 builds kept `TODO.md`,
1025
- `REVIEW.md`, `FEEDBACK.md`, `ERRORS.md`, `HEALTH.md`, and `SQUASH_MSG.md` at the
1026
- repository root; they now live under `.gtd/`. Upgrade at a clean boundary (idle,
1027
- post-squash): a repo at rest needs nothing. Mid-cycle repos should either finish
1028
- the cycle on the old build first or move the root-level steering files into
1029
- `.gtd/` by hand and commit. History classification is backward-compatible β€” the
1030
- counter folds recognize both the old root paths and the new `.gtd/` paths in
1031
- existing commits.
1032
-
1033
- **Re-copy the loop skill.** If you vendor `skills/loop/` into a consuming repo
1034
- or agent harness, upgrading the `gtd` binary also means re-copying that skill
1035
- from this release β€” the v1 skill text still describes the old single-command
1036
- loop and will drive the new binary incorrectly.
1037
-
1038
- For maintainers: this repo releases via `semantic-release` reading Conventional
1039
- Commits, and needs **no config change** for a major bump β€” but the release
1040
- commit/PR **must carry a `BREAKING CHANGE:` footer** (or a `!` after the type)
1041
- for `@semantic-release/commit-analyzer` to compute `2.0.0` rather than a
1042
- minor/patch bump.
1043
-
1044
- ## Development
1045
-
1046
- ```bash
1047
- npm install
1048
- npm run dev # run from source, no build (node dev/run.mjs)
1049
- npm run build # tsdown β†’ dist/gtd.bundle.mjs
1050
- npm test # format:check, typecheck, lint, unit + e2e tests, fallow
1051
- npm run test:unit # vitest unit tests (the pure resolver) β€” --project unit
1052
- npm run test:e2e # gherkin e2e via vitest + quickpickle β€” --project e2e
1053
- npm run test:mutation # StrykerJS mutation testing (manual only, ~2 min)
1054
- npm run typecheck
1055
- npm run lint
1056
- ```
1057
-
1058
- ### Pre-commit hook
1059
-
1060
- A pre-commit hook is installed automatically via the `prepare` script when you
1061
- run `npm install` on a fresh clone β€” no manual setup needed. The hook runs
1062
- [lint-staged](https://github.com/lint-staged/lint-staged) with
1063
- [oxfmt](https://oxc.rs/docs/guide/usage/formatter.html), formatting every staged
1064
- file before each commit (`oxfmt --no-error-on-unmatched-pattern --write`),
1065
- mirroring the `format:check` step enforced in CI (`oxfmt --check .`).
1066
-
1067
- ### Prompt templates
1068
-
1069
- Each prompt-bearing state has a self-contained Eta template in
1070
- `src/prompts/*.md` that owns its full prompt β€” header, context, and body. Shared
1071
- fragments live as partials in `src/prompts/partials/`: `header`, the context
1072
- renderers (`diff`, `feedback`, `package`), and the single `agent-turn` tail
1073
- partial (the pinned "Finish your turn by running `gtd step-agent`. Then run
1074
- `gtd next` …" loop-closing instructions).
1075
-
1076
- At module load, `src/Prompt.ts` registers every template on a single `new Eta()`
1077
- instance via `loadTemplate`. `readFile` and `resolvePath` are nulled afterward
1078
- so rendering resolves exclusively from the in-memory cache β€” the compiled ESM
1079
- bundle carries no runtime `fs` dependency.
1080
-
1081
- `buildPrompt(result, resolveModel?, output?)` selects the state's template,
1082
- builds a view-model (model string, tail partial name, context), renders it,
1083
- collapses runs of three or more blank lines to two, and ensures exactly one
1084
- trailing newline. It throws for the five states that render no prompt at all
1085
- (`testing`, `planning`, `close-package`, `done`, `health-check`) β€” those are
1086
- performed entirely by the edge.
1087
-
1088
- `npm run dev` runs `src/main.ts` directly via Node's native TypeScript
1089
- type-stripping (requires Node 22.6+). It registers `dev/hooks.mjs`, which fills
1090
- the two gaps the tsdown build otherwise covers: resolving `./Foo.js` specifiers
1091
- to the on-disk `./Foo.ts`, and importing `*.md` prompt files as text. Pass CLI
1092
- args after `--`, e.g. `npm run dev -- format <file>`.
1093
-
1094
- The decision core (`src/Machine.ts`) is pure and IO-free, so the whole 16-state
1095
- ladder and both counter folds are trivially unit-testable in isolation; all
1096
- git/filesystem IO is confined to the edge (`src/Events.ts`).
1097
-
1098
- `npm run build` produces `dist/gtd.bundle.mjs`, which npm exposes as the `gtd`
1099
- binary via the `bin` field in `package.json`.
1100
-
1101
- ### Mutation testing
1102
-
1103
- Run mutation testing on-demand with `npm run test:mutation` (StrykerJS, ~2 min)
1104
- β€” never run it as part of routine development; it is a deliberate,
1105
- manually-triggered check. The single `stryker.config.json` mutates six core
1106
- files:
1107
-
1108
- ```
1109
- src/Machine.ts src/Prompt.ts src/Config.ts
1110
- src/Format.ts src/State.ts src/Events.ts
1111
- ```
1112
-
1113
- `src/Git.ts` is excluded: the Cucumber harness stubs git at the Effect boundary,
1114
- so `Git.ts` mutants have zero in-memory coverage.
1115
-
1116
- The HTML report lands in `reports/mutation/mutation.html` (git-ignored).
1117
-
1118
- ## Releasing
1119
-
1120
- Releases are automatic. Push releasable Conventional Commits (`fix:`, `feat:`,
1121
- or breaking changes) to `main` and the Release workflow runs the tests, then
1122
- `npx semantic-release`. Semantic-release computes the next version, writes it
1123
- into `package.json`, builds the bundle, commits the bump back as
1124
- `chore(release): X.Y.Z [skip ci]`, tags `vX.Y.Z`, and creates the GitHub release
1125
- with `gtd.bundle.mjs` attached.
52
+ schema stub on first run (see [Configuration](docs/configuration.md#auto-init)).
53
+
54
+ ## How it works
55
+
56
+ gtd is a small **pattern machine**: named states, each awaiting one actor and
57
+ carrying one piece of content (a script, a prompt, a message, or a squash commit
58
+ template), with an ordered set of change-patterns routing to the next state.
59
+ Four commands drive it:
60
+
61
+ - **`gtd step <actor>`** β€” authenticate as `<actor>` and perform the one
62
+ transition the pending changes match.
63
+ - **`gtd next [--json]`** β€” print whichever actor is awaited and what they
64
+ should do, without mutating anything.
65
+ - **`gtd run`** β€” execute the awaited script (the only place gtd itself spawns a
66
+ subprocess), then step its actor.
67
+ - **`gtd status`** β€” a dry-run report of the resolved state and which pattern
68
+ each pending change matches.
69
+
70
+ The loop is one beat, repeated: run `gtd next --json` and dispatch on `kind` β€”
71
+ `"message"` means it's a human's move (stop and hand off); `"script"` means
72
+ `gtd run` it; `"prompt"` means feed `content` to your agent, then run
73
+ `gtd step <actor>` once it's done. See [STATES.md](STATES.md) for the model and
74
+ [Driving the loop](docs/loop.md) for the full protocol.
75
+
76
+ Along the way, the bundled default workflow develops your sketch into an
77
+ implementation plan β€” asking any open question it can't settle itself via a
78
+ deterministic `.gtd/TODO.md` format, validated before it ever reaches you β€”
79
+ builds it, runs your tests (looping on failures), and hands you a
80
+ `.gtd/REVIEW.md` checkbox review of the cycle's diff: tick a box to approve that
81
+ item, or edit/untick for feedback. Approving rests the cycle back at idle, with
82
+ every turn commit still sitting in history for you to squash however you like
83
+ (or not at all; gtd makes no assumption) β€” see
84
+ [STATES.md](STATES.md#10-the-bundled-default-workflow) for the full shape. A
85
+ heavier machine β€” two-phase Q&A planning, an architecture phase, task
86
+ decomposition, a per-task build loop, and a squash finale β€” is preserved as a
87
+ copy-paste `.gtdrc` example at
88
+ [docs/examples/advanced-workflow.md](docs/examples/advanced-workflow.md). The
89
+ workflow itself is just `.gtdrc` config β€” swap it for your own (see
90
+ [Configuration](docs/configuration.md)).
91
+
92
+ `gtd-loop`, installed alongside `gtd`, is a ready-to-run driver for the whole
93
+ protocol β€” point it at a repo and it runs the loop until it's your turn. See
94
+ [Driving the loop](docs/loop.md).
95
+
96
+ Before wiring gtd into a repo, note the
97
+ [repository requirements](docs/cli.md#repository-requirements) β€” most
98
+ importantly: gitignore everything your scripts write.
99
+
100
+ Editor integration: `gtd lsp` starts an LSP server over stdio for `.gtd/`
101
+ steering files β€” symbols and check/uncheck actions over a `review`-mode file's
102
+ chunks, symbols over a `qa`-mode file's open questions, diagnostics for both
103
+ (live as you edit), and a `gtd.openSteeringFile` command that jumps to the
104
+ current state's steering file. Config-driven via each state's `file:`/`mode:`
105
+ (see [CLI reference](docs/cli.md#gtd-lsp)) β€” falls back to basename dispatch
106
+ (`TODO.md`/`REVIEW.md`) with no config in sight.
107
+
108
+ ## Documentation
109
+
110
+ - [STATES.md](STATES.md) β€” the full pattern-machine specification: the model,
111
+ the pattern grammar, resolution, retry, the squash lifecycle, and the bundled
112
+ default workflow
113
+ - [CLI reference](docs/cli.md) β€” every command, exit codes, JSON schemas,
114
+ repository requirements
115
+ - [Driving the loop](docs/loop.md) β€” the reference loop driver, `gtd-loop`,
116
+ custom agents
117
+ - [Configuration](docs/configuration.md) β€” `.gtdrc` `workflow:` schema, lookup,
118
+ auto-init
119
+ - [Upgrading](docs/upgrading.md) β€” breaking changes and migration
120
+ - [Development](docs/development.md) β€” building, testing, releasing
1126
121
 
1127
122
  ## License
1128
123