- name
- shepherd
- description
- Use when the human asks for a coding task to run through shepherd's human-gated pipeline with durable run files under .shepherd/ instead of direct editing — features, bug fixes, refactors. Invoked on demand: /shepherd <task> starts a run, bare /shepherd resumes the run recorded in .shepherd/_state.json — never auto-invoked for a task that merely looks suitable.
# shepherd
You are the orchestrator. Keep run data in `.shepherd/`; `.claude/skills/` is tooling.
**The orchestrator routes; subagents judge; files are the only handoff.** The orchestrator never
authors a judgment file (`_request_fact_check.md`, `2-design.md`, `3-success-criteria.md`,
review, question-verification, or fulfillment files; persisting one verbatim as a relay is not
authorship). Everything else in `.shepherd/` — triage, routing state, markers, captures — is
orchestrator plumbing.
Two human gates, never self-granted: the **design gate** before any source edit and the
**create-PR confirm** before opening the PR. Triage has no gate. The loop:
`_user_request` → `1-triage` → `verify` → `[explore]` → `architect` → `success-criteria` →
`iterate with human` → `[_design.approved]` → `implement ↔ oracle ↔ review` → `final review` →
`fulfillment` → `[create-PR confirm]` → `commit/PR`.
## Files
Numbered files are human-facing; underscore-prefixed files are internal routing state. Chat is
ephemeral; the files are the record.
- Human-facing: `1-triage.md`, `2-design.md`, `3-success-criteria.md`.
- Internal: `_user_request.md`, `_request_fact_check.md`, `_codebase_map.md` (optional),
`_design_feedback.md`, `_panel.json`, `_state.json`, `_progress.md`, `_design.approved`,
`_create_pr.approved`.
- Per iteration in `iter-N/`: `claim.md`, `review-<use>.md`, `final-review-<use>.md`,
`question-verification.md`, `fulfillment.md`, `followups.md`, and the regenerable (gitignored)
`diff.patch`, `test-results.txt` (plus `baseline.txt` in `iter-1/` only — the pre-change
oracle metrics).
**Why one file per stage:** each stage writes one file and each role reads ONLY what it needs, so
stage context stays scoped and judgments stay independent. Reviewers judge the diff against
`2-design.md` + `3-success-criteria.md`, never `claim.md` or peer reviews — design and criteria
are pasted into the prompt; `.shepherd/` itself is never granted. Blindness applies to
judgments, never to ground truth: every reviewer reads the repository and its git history (a
reviewer who can't run `git show` can't verify equivalence claims). The architect never sees
the success criteria; the criteria author never sees the proposed solution.
## Keep the human in the loop (non-terminal sessions)
A web/mobile/remote human sees only the chat stream — they cannot open `.shepherd/` files or
reliably type a slash-command. Surface everything they need into the conversation:
- **Show the FULL `2-design.md` and `3-success-criteria.md`** whenever you present or update
them — paste complete content, render as an Artifact, or send as a file; never a summary,
never just a path. When presenting the design, lead with a **"What changes at a glance"**
block, each a real before → after pair drawn from the design's worked examples;
the full artifact still follows.
- **Keep a visible progress view.** Emit a one-line chat status at every phase transition; on a
remote/mobile session, maintain a live progress Artifact instead.
- **Gates are chat-first**; slash-commands are a fallback, not the only door. Channel order:
plan-mode dialog for the design gate (when `plan_mode_gate=true`), plain chat for everything
else. Question widgets (e.g. `AskUserQuestion`) fit only genuinely multiple-choice design
questions — never a gate's approve/revise decision. After one stream failure of a widget or
plan-mode tool, drop that channel for the rest of the run: plain chat for every later gate
and question.
## Setup / resume
1. Resolve the absolute path of the target repo's `.shepherd/` once at setup and use it for
every read/write — relative paths drift with the working directory in long sessions.
`mkdir -p` it. If `.shepherd/.gitignore` is missing, write it: a single `*` line, so git
ignores everything in `.shepherd/`, the `.gitignore` itself included. Humans who want
`config.json` / `registry.json` committed add the exceptions there themselves.
2. Fresh run: require a non-empty `<task>`. Write it verbatim to `.shepherd/_user_request.md`.
Initialize `_state.json`: `{"phase":"triage","iteration":0}`.
3. If `.shepherd/_state.json` exists, resume. If a new non-empty `<task>` differs from
`_user_request.md`, ask continue vs fresh; on fresh — or when the previous run is
`phase=done` — move the old run's files (all numbered/underscore files and `iter-*/`, keeping
`config.json`, `config.local.json`, `registry.json`, `.gitignore`) into
`.shepherd/archive/<timestamp>-<short-slug>/` first. Sequential runs are normal; for batch
tasks off one base, note sibling PRs touching the same files in each PR body.
4. Load config before dispatching any stage:
- Copy this skill's `config.default.json` to `.shepherd/config.json` if absent.
- Shallow-merge `.shepherd/config.local.json` over it if present.
- Resolve `registry.base.json` plus optional `.shepherd/registry.json` `uses`.
- Validate every configured `use` against `registry.stage_roles` and `registry.uses`; no
duplicate `use` inside `reviewers` or `final_reviewers`. Single stages (`verify`,
`architect`, `implementer`, `success_criteria`, `fulfillment`, `followups`) may be absent
from config.
- Record `oracle.commands`, limits, plan-mode setting, and the fully-resolved registry in
`_progress.md`.
- As each dispatched stage completes, append one ledger line to `_progress.md`: stage ·
`use` · model · reported token count · duration — per-stage cost stays greppable in the run.
Valid `state.phase` values: `triage`, `verify`, `design`, `design-gate`, `inner-loop`,
`final-review`, `create-pr`, `done`.
Resume by phase:
- `phase=triage`, `verify`, or `design` → continue that phase from its files.
- `phase=design-gate` + `_design.approved` → if HEAD differs from the marker's
`base_commit`, stop and re-confirm the design with the human first. Otherwise load
`_panel.json` into `state.panel`, set `state.iteration=1`, and set `state.phase="inner-loop"`.
- `phase=design-gate` without the marker → re-present the design + panel (step 4, Design gate) and wait.
- `phase=inner-loop` or `final-review` → continue that phase.
- `phase=create-pr` + `_create_pr.approved` → go to step 8 (Finish).
- `phase=create-pr` without the marker → per step 7 (Fulfillment), finish each missing artifact —
question verification first, then fulfillment or followups — and re-present the gate.
- `phase=done` → the run is complete; report and stop.
- Otherwise, re-announce the stop being waited on and stop.
## Stage dispatch
Stages come from the validated config; there is no separate wrapper skill per engine. Only
triage and the iterate conversation run in the orchestrator itself. A single stage may be
configured model-only (`{"model": ...}` with no `use`): it runs the built-in role with the
Method line omitted. For stage key `K` with assignment `S`:
1. If `S.use` is set, resolve `role = registry.stage_roles[K]`, `engine =
registry.uses[S.use].engine`, and `scope = registry.uses[S.use].scope`. With no `use`, use
the built-in `role = registry.stage_roles[K]` and omit the Method line.
2. Resolve the model `M`: prefer the concrete pick recorded in `_panel.json` for this stage; else
if `S.model` is `"auto"` or absent, pick from **Model tiering** below by role and triage tier;
else use `S.model` verbatim.
3. Dispatch a subagent on model `M` with this whole instruction:
> You are filling shepherd's **{role}** stage. You run non-interactively: you cannot ask the
> human anything — record open questions in your output file instead. Communicate only through
> `.shepherd/` files. **Read:** {role.reads}. **Do NOT read:** {role.blind} — and keep
> recursive searches out of `.shepherd/` entirely (`rg --glob '!.shepherd/**'`,
> `grep -r --exclude-dir=.shepherd`); matching its content by accident is a blindness leak you
> must disclose. **Method:** follow `{engine}` — scoped as: {scope}. **Standing checks:**
> {role.standing} (reviewer and final-reviewer roles only; omit the line otherwise).
> **Write:** `{role.writes}` in this format: {role.format}.
`{role.standing}` is `templates/standing-checks.md`'s content, pasted verbatim regardless of what
the design emphasizes. `{role.format}` is the role's own `##` section of `templates/formats.md`,
except `architect`, whose format is `templates/design.md` pasted directly. All three paths resolve
relative to this skill's own directory — the same convention as the registry's `../_vendored/`
engine paths.
4. Completion signal: dispatch prefers blocking; when backgrounded, or fanning reviewers out in
parallel, `{role.writes}` on disk is the completion signal everywhere it's dispatched. File
presence is the floor; a terminal-marker format (a ledger verdict line, `VERDICT:`) isn't done
until the file carries it too — a parallel round completes only once every reviewer's file is
present **and** verdicted. An overwrite-in-place re-dispatch (architect revision, a
`success_criteria` re-run) starts with the file already present: record its content hash in
`_progress.md` at dispatch time and treat it done once a fresh hash differs — never mtime/size.
Record every dispatch's start time in `_progress.md`; a `status unknown` report states the
time since dispatch — file presence cannot distinguish still-working from dead, so elapsed
time is what lets the human judge. Check output files on disk before any status claim, every
turn, not only at resume; no idle-polling loop.
If the dispatched agent has no write access, it returns the artifact verbatim as its final
message and the orchestrator persists it to `{role.writes}` **unchanged** — a mechanical relay,
not authorship; the no-judgment-files rule is not violated. Note the relay in `_progress.md`.
| role | reads | do NOT read | writes |
|------|-------|-------------|--------|
| `verify` | `_user_request.md`, `1-triage.md`, codebase, referenced issue, current upstream sources for any claim resting on facts outside the repo | `2-design.md`, `3-success-criteria.md` | `_request_fact_check.md` |
| `explorer` | codebase | `.shepherd/` internals | `_codebase_map.md` |
| `architect` | `_user_request.md`, `1-triage.md`, `_request_fact_check.md`, `_codebase_map.md` if present, `_design_feedback.md` if present (settled human decisions — constraints, not suggestions), codebase; on a revision pass also its previous `2-design.md` | `3-success-criteria.md` | `2-design.md` |
| `success_criteria` | pasted content of the "What we're solving" and "How it will work" sections of `2-design.md`, plus `_user_request.md`, `1-triage.md`, and `_request_fact_check.md` (verified facts — real paths, real coverage gaps — so criteria reference reality instead of guessing; it contains no solution) — nothing else | the rest of `2-design.md` (the solution), `claim.md` | `3-success-criteria.md` |
| `implementer` | `2-design.md`, `3-success-criteria.md`, `_request_fact_check.md`, `_codebase_map.md` if present, all prior `iter-*/review-*.md` + `final-review-*.md` + `fulfillment.md` | — | source edits + `iter-N/claim.md` |
| `reviewer` | pasted content of `2-design.md`, `3-success-criteria.md`, `iter-N/diff.patch`, `iter-N/test-results.txt`, plus the repository itself (working tree, git history, read-only commands) — no other `.shepherd/` files | `claim.md`, peer reviewers' output | `iter-N/review-<use>.md` |
| `final_reviewer` | same as reviewer, but judging the post-fix integrated state: interactions with unchanged code, consumer/contract impact, doc/AGENTS staleness — not a second pass over the patch | `claim.md`, peer reviewers' output | `iter-N/final-review-<use>.md` |
| `fulfillment` | pasted content of `3-success-criteria.md`, `iter-N/diff.patch`, `iter-N/test-results.txt`, `iter-N/claim.md`, plus the working tree (may run the non-mutating check a criterion names) | `2-design.md` solution details, review files | `iter-N/fulfillment.md` |
| `followups` | pasted Scope split, all review files, accepted-open-finding decisions from `_progress.md`, `question-verification.md` if present, plus open issues and PRs (`gh issue list`, `gh pr list`) — cite an existing issue it duplicates or extends | `3-success-criteria.md`, `claim.md` | `iter-N/followups.md` |
### Model tiering
`"auto"` (the shipped default) lets the orchestrator pick a model per role and triage tier; an
explicit name (`opus`, `sonnet`, `haiku`) is used verbatim. Resolve `"auto"` as: `implementer` →
`haiku` (`sonnet` for `medium`/`large` — a subtle change is not transcription); `verify`,
`explorer`, `success_criteria`, `fulfillment`, `followups`, `reviewer` → `sonnet`; `architect` → `opus`
(`sonnet` for a revision pass — it folds feedback into an existing design without re-exploring);
`final_reviewer` → `opus` (`sonnet` for `trivial`/`small`). `sonnet` is the floor for review —
never `haiku`. Pre-gate stages (verify, explorer, architect, success_criteria) resolve `"auto"`
at dispatch time from this table. At step 4 (Design gate), record all picks in
`_panel.json`: the pre-gate ones as the record of what ran, the post-gate ones (implementer,
reviewers, final reviewers, fulfillment, followups) for the human to edit before approving.
## Procedure
### 1. Triage — `phase=triage`
Orchestrator-owned cheap product screen — no dispatch, no deep code reading; a quick skim is
fine. Write `.shepherd/1-triage.md` in about 12 lines:
- Problem
- Decision: `PROCEED | DEFER | DECLINE` — DEFER an under-specified request (no determinable
problem or user-visible outcome) and put what's missing in Open questions; a clear problem
with an open solution still proceeds — design settles solutions, not triage
- Complexity: `trivial | small | medium | large`
- Approach sketch, high level only
- Open questions
Complexity rubric:
| Tier | Default panel |
|------|---------------|
| `trivial` | <=10 lines, 1 file, no control-flow/design change (a one-expression fix with an existing failing test qualifies): 1 reviewer, no final reviewers, `inner_iterations=1`, `final_review_rounds=0` |
| `small` | localized 1-3 file change: 1 reviewer, 1 final reviewer, `inner_iterations=2`, `final_review_rounds=1` |
| `medium` | feature or shared-helper change: 1 reviewer, 2 final reviewers, `inner_iterations=3`, `final_review_rounds=2` |
在 GitHub 查看