Tutorial

One small PRD, from an empty repo to every task passed.

zurdo v1.36.0

You'll build greet.sh, a two-task feature, and take its PRD from nothing to passed. The terminals show real zurdo v1.30.1 output, trimmed. A scripted stand-in played the agent, so it ran in milliseconds and reported no token counts.

  1. Set up. zurdo init and zurdo doctor, once per repo.
  2. Write the PRD. Two tasks, each criterion with a hint.
  3. Check it. validate and analyze, before any tokens.
  4. Run it. zurdo drives the agent and checks every criterion itself.
  5. Sign off. zurdo review settles the [manual] criterion.
  6. Ship it. You commit. zurdo never touches git.

Step 1: Set up the repo

You need zurdo on your PATH (Installation), a signed-in agent CLI (claude, codex or copilot) and a git repository. From its root:

acme/hello
$ zurdo init
init: wrote .zurdo/config.toml
$ echo .zurdo/ >> .gitignore
$ zurdo doctor
providers:
  ok    executor → anthropic: cli `claude` found on PATH
git:
  ok    git work tree: /src/acme/hello is a git work tree
…
doctor: all checks passed
init also installs the bundled skills. Run state stays out of git.

Step 2: Write the PRD

Each criterion carries a hint that zurdo runs itself, so the agent can't grade its own work. Save this as docs/greeter/prds/prd-01-hello.md:

# PRD: Hello CLI

## Task: task-greet — Print a greeting
**Effort**: low
**Depends-on**: []

### Description
Create `greet.sh` at the repo root. With no arguments it prints `Hello, world`.

### Acceptance Criteria
- [ ] the script exists [file-exists: greet.sh]
- [ ] it greets the world [shell: sh greet.sh | grep -qx "Hello, world"]

## Task: task-name — Greet by name
**Effort**: low
**Depends-on**: [task-greet]

### Description
When `greet.sh` gets a name, it prints `Hello, <name>` instead.

### Acceptance Criteria
- [ ] it greets by name [shell: sh greet.sh Ada | grep -qx "Hello, Ada"]
- [ ] the usage line reads well [manual]

— em-dash Between task id and title. A hyphen fails validation.

Depends-on task-name waits for task-greet.

[manual] A human signs this one off in step 5.

On a real project, the zurdo-prd-author skill writes this with you. See Your first PRD.

Step 3: Check it

docs/greeter/prds/prd-01-hello.md
$ zurdo validate docs/greeter/prds/prd-01-hello.md
OK
$ zurdo analyze --static-only docs/greeter/prds/prd-01-hello.md
…
[info] Execution order: task-greet → task-name

═══ Verdict ═══ ✓ READY TO RUN — 0 errors, 0 warnings, 1 info

Both are free. Drop --static-only to add an LLM critique.

Step 4: Run it

zurdo run docs/greeter/prds/prd-01-hello.md
─── task-greet: Print a greeting ─── effort=low, deps=[]
  → iteration 1 of 3 (max-attempts=3, agent-timeout=30m 00s)
  ✓ agent completed: exit=0, 425ms
    ✓ file-exists: greet.sh
    ✓ shell: sh greet.sh | grep -qx "Hello, world"
  ✓ task-greet: passed in 1 iterations
─── task-name: Greet by name ─── effort=low, deps=[task-greet]
  → iteration 1 of 3
  ✓ agent completed: exit=0, 55ms
    ✗ shell: sh greet.sh Ada | grep -qx "Hello, Ada"
    ✓ [manual]
  → iteration 2 of 3
  ✓ agent completed: exit=0, 51ms
    ✓ shell: sh greet.sh Ada | grep -qx "Hello, Ada"
    ✓ [manual]
  ✓ task-name: passed-pending-review in 2 iterations
═══ Run Summary ═══
  task-greet           passed                   1/3   425ms   2/2
  task-name            passed-pending-review    2/3   152ms   2/2
  totals               1 passed, 1 pending-review, 0 failed, 0 blocked
The agent said "Done!" both times. zurdo's own check caught the first try.

The failing hint went into the retry prompt. Ctrl-C is safe at any point: zurdo run again resumes. More in Running a PRD.

Step 5: Sign off

task-name waits on its [manual] criterion. zurdo review <prd> opens a terminal UI over the evidence. Without a terminal, list what's pending as JSON and sign by address:

zurdo review, headless
$ zurdo review docs/greeter/prds/prd-01-hello.md --no-prompt
{"prd":"docs/greeter/prds/prd-01-hello.md", … "log_valid":true,
 "pending":[{"address":"task-name:2","criterion":"the usage line reads well", …}]}
$ zurdo review docs/greeter/prds/prd-01-hello.md --sign-off task-name:2 --by ada
{"address":"task-name:2", … "by":"ada","via":"headless","task_status":"passed"}
Read greet.sh first. Sign-offs are logged and can't be undone.

Step 6: Ship it

Every task is passed. Read .zurdo/<slug>/run-diff.patch, then commit greet.sh and the PRD together yourself. To mirror the PRD and its run onto GitHub issues, add Carol.

StepCommand
1 · Set upzurdo init · zurdo doctor
2 · PRDwrite it, or scaffold one
3 · Checkzurdo validate · zurdo analyze
4 · Runzurdo run
5 · Sign offzurdo review
6 · Shipgit commit

Next: Your first PRD