@jagreehal/shepherd 0.0.0-stage → 0.2.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.
Files changed (57) hide show
  1. package/AGENTS.md +158 -0
  2. package/LICENSE +21 -0
  3. package/README.md +445 -2
  4. package/THIRD_PARTY_NOTICES.md +41 -0
  5. package/commands/shepherd.md +18 -0
  6. package/examples/local-demo/baseline/src/config.ts +2 -0
  7. package/examples/local-demo/baseline/src/db.ts +5 -0
  8. package/examples/local-demo/baseline/src/notes.ts +15 -0
  9. package/examples/local-demo/baseline/src/users.ts +8 -0
  10. package/examples/local-demo/expected.json +12 -0
  11. package/examples/local-demo/planted/src/config.ts +2 -0
  12. package/examples/local-demo/planted/src/notes.ts +15 -0
  13. package/examples/local-demo/planted/src/search.ts +8 -0
  14. package/examples/local-demo/planted/src/users.ts +8 -0
  15. package/lenses/observability/SKILL.md +26 -0
  16. package/package.json +46 -4
  17. package/skills/ci-repair/SKILL.md +178 -0
  18. package/skills/code-review/SKILL.md +89 -0
  19. package/skills/code-review/agents/openai.yaml +3 -0
  20. package/skills/diagnosing-bugs/SKILL.md +138 -0
  21. package/skills/diagnosing-bugs/agents/openai.yaml +3 -0
  22. package/skills/diagnosing-bugs/scripts/hitl-loop.template.sh +44 -0
  23. package/skills/garden/SKILL.md +144 -0
  24. package/skills/incident/SKILL.md +261 -0
  25. package/skills/pair/SKILL.md +111 -0
  26. package/skills/pr/CREDITS.md +3 -0
  27. package/skills/pr/SKILL.md +170 -0
  28. package/skills/pr/agents/openai.yaml +3 -0
  29. package/skills/retro/SKILL.md +44 -0
  30. package/skills/retro/agents/openai.yaml +5 -0
  31. package/skills/review-correctness/SKILL.md +80 -0
  32. package/skills/review-maintainability/SKILL.md +86 -0
  33. package/skills/review-security/SKILL.md +75 -0
  34. package/skills/review-simplicity/SKILL.md +87 -0
  35. package/skills/review-slop/SKILL.md +94 -0
  36. package/skills/review-spec/SKILL.md +57 -0
  37. package/skills/shepherd/SKILL.md +407 -0
  38. package/skills/shepherd/references/degradation.md +21 -0
  39. package/skills/shepherd/references/dispatch.md +117 -0
  40. package/skills/shepherd/references/formats.md +46 -0
  41. package/skills/shepherd/references/models.md +88 -0
  42. package/skills/shepherd/references/policy.md +110 -0
  43. package/skills/swarm/SKILL.md +521 -0
  44. package/skills/swarm/references/custom-lenses.md +129 -0
  45. package/skills/swarm/references/formats.md +91 -0
  46. package/skills/triage/SKILL.md +388 -0
  47. package/skills/writing-for-agents/SKILL-MECHANICS.md +22 -0
  48. package/skills/writing-for-agents/SKILL.md +81 -0
  49. package/skills/writing-for-agents/agents/openai.yaml +3 -0
  50. package/src/acceptance.ts +111 -0
  51. package/src/cli.ts +379 -0
  52. package/src/config.ts +439 -0
  53. package/src/doctor.ts +153 -0
  54. package/src/garden.ts +198 -0
  55. package/src/install.ts +86 -0
  56. package/src/lens.ts +178 -0
  57. package/src/local.ts +393 -0
@@ -0,0 +1,88 @@
1
+ # Model ladder
2
+
3
+ Every runner starts as low on the ladder as its job allows. A stronger model
4
+ validates a result; it never replaces a test.
5
+
6
+ ## Resolve the ladder before pinning anything
7
+
8
+ **The operator's choice comes first.** Take `ladder` and `models` from the
9
+ team policy (`policy.md`): `.shepherd/config.yml` or `.shepherd/lenses.yml`
10
+ and its packs, on the **default branch**, never the PR head; then from
11
+ `~/.config/shepherd/lenses.yml`. The repository's ladder wins; a personal
12
+ ladder applies only when the repository sets none. `models:` pins merge per
13
+ name, the repository winning. `shepherd models` prints the result.
14
+
15
+ ```yaml
16
+ ladder: [opencode-go/deepseek-v4-flash, opencode-go/glm-5.3, opencode-go/kimi-k3, opencode-go/qwen3.8-max]
17
+ models: # a name runs on exactly this model, whatever its rung
18
+ security: opencode-go/qwen3.8-max
19
+ router: opencode-go/deepseek-v4-flash
20
+ ```
21
+
22
+ Pin names: `router`, `verifier`, `validator`, `triage`, `simplify`,
23
+ `ci-repair`, and any lens, built-in (`correctness`, `security`, `simplicity`,
24
+ `maintainability`, `slop`) or custom. A model id passes to the agent tool's
25
+ model parameter exactly as written: `haiku` on Claude Code, `provider/model`
26
+ on OpenCode. Never translate one id into another provider's. A pin replaces
27
+ the rung for that runner only; climbing for validation starts from the pin's
28
+ position on the ladder, or the top rung when the pin is not on it. A pin that
29
+ the agent tool rejects falls back to the runner's rung, and the summary says
30
+ so.
31
+
32
+ **When the subagent tool has no model parameter** (OpenCode 1.x), pick the
33
+ model by agent instead: `shepherd opencode-agents` generates one agent per rung
34
+ (`shepherd-r0` is the bottom rung, `shepherd-r1` the next) and one per pin
35
+ (`shepherd-pin-<name>`), each fixed to its model. Dispatch the runner with that
36
+ agent as its type. If those agents are not listed, say so in the summary: every
37
+ runner then runs on the session model.
38
+
39
+ With nothing configured, use the harness's ladder:
40
+
41
+ | Harness | Ladder, cheapest first |
42
+ |---|---|
43
+ | Claude Code | `haiku` -> `sonnet` -> `opus` -> `fable` |
44
+ | OpenCode | none built in: list `opencode models` and take the operator's ladder; with none set, the session model is one rung |
45
+ | Codex | the harness's own subagent models, cheapest first; with no per-agent model choice, one rung |
46
+ | Anything else | whatever the agent tool accepts, cheapest first |
47
+
48
+ If you cannot tell which models the agent tool accepts, assume the Claude Code
49
+ ladder and fall back one rung at a time on rejection. Never let a rejected pin
50
+ silently land every runner on the session model: that is the costliest outcome
51
+ and the one this ladder exists to prevent. When a caller passes a ladder, use it
52
+ exactly and ignore this table.
53
+
54
+ ## Roles
55
+
56
+ - **Bottom rung:** work that only reads and that a later step checks: the swarm
57
+ router, whose findings a verifier or lens confirms.
58
+ - **Second rung:** runners that edit code, push commits, or resolve threads:
59
+ triage, simplify, and ci-repair. In trials the bottom rung fixed code and forgot to resolve the
60
+ thread, committed without pushing, invented domain rules, edited code to
61
+ get past a gate, and a simplify pass reverted a review fix. Each slip cost a redo one rung up, so starting there is the
62
+ cheaper path.
63
+ - **One rung up:** swarm's default delegation target; the validator for a risky
64
+ change; swarm's verifier for a bottom-rung finding.
65
+ - **Two rungs up:** fallback when the rung below is unavailable.
66
+ - **Top rung:** a delegation the rungs below could not settle, or reviewers who
67
+ disagree and need a stronger read.
68
+
69
+ ## Validation
70
+
71
+ 1. Prefer deterministic proof: tests, typecheck, lint, the final diff, evidence
72
+ from GitHub or CI.
73
+ 2. For a risky or uncertain decision, ask the next rung up with only the
74
+ evidence and the narrow question.
75
+ 3. Climb one rung at a time; stop when the evidence is clear.
76
+ 4. Record which model ran each step.
77
+
78
+ A second-model validation is **required** before an autonomous change that
79
+ touches authentication, permissions, billing, data deletion, migrations,
80
+ concurrency, a public API, or a broad shared abstraction, and whenever reviewers
81
+ disagree or the checks cannot prove the change safe. Mechanical work the checks
82
+ prove needs no stronger model.
83
+
84
+ ## When nothing cheaper exists
85
+
86
+ If no rung below the session model can be dispatched, every runner costs
87
+ session rates. Say so in the narration and the summary, and cut the quality
88
+ loop's round cap to 2.
@@ -0,0 +1,110 @@
1
+ # Team policy
2
+
3
+ A team sets shepherd's policy in `.shepherd/config.yml` (an older repository
4
+ may have only `.shepherd/lenses.yml`; it reads the same way). It can extend
5
+ packs, which apply first, and the repository file wins over them. Every
6
+ runner reads the policy the same way and holds to it.
7
+
8
+ ## Load it once per run
9
+
10
+ ```bash
11
+ git fetch -q origin <default>
12
+ shepherd config explain --json # or: bunx @jagreehal/shepherd config explain --json
13
+ ```
14
+
15
+ It reads the **default branch**, never the PR head, so a PR cannot change the
16
+ policy it is reviewed under. It resolves the packs, and each value carries its
17
+ `source`. Done when you hold the JSON.
18
+
19
+ Without the CLI, read the file yourself:
20
+ `git show origin/<default>:.shepherd/config.yml`, else
21
+ `git show origin/<default>:.shepherd/lenses.yml`. If that file has `extends`,
22
+ the packs are unresolved: run as `fixes.mode: suggest` (nothing edits code)
23
+ and say `policy packs unresolved` in the summary. Never guess a pack's
24
+ contents.
25
+
26
+ Personal settings (`~/.config/shepherd/lenses.yml`) are a preview: their
27
+ lenses print locally and never post, and their ladder and pins fill in only
28
+ where the team set none. They never change checks, fixes, escalation or
29
+ recipes.
30
+
31
+ ## What each setting means
32
+
33
+ - **`checks`**: named commands. When set, swarm runs exactly these as its
34
+ machine checks; ci-repair looks here first for the local command behind a
35
+ failing job; incident runs them before calling a fix done. When empty, each
36
+ runner finds the commands as its own skill says.
37
+ - **`fixes.mode`**: how far fixing goes.
38
+ - `push` (default): fix, commit, push, as each skill says.
39
+ - `local`: fix in the working tree; never commit, push, or resolve a
40
+ thread. The review after a fix is `swarm --local` on the working tree,
41
+ which leaves the receipt `shepherd local status` checks. Report "fixes
42
+ left in the working tree".
43
+ - `suggest`: change no code. Triage, simplify, ci-repair and incident report
44
+ what they would fix and stop; review threads stay open for the author.
45
+ - **`escalate.paths`**: globs a person must decide. No runner changes a
46
+ matching file. A finding whose fix needs one is deferred to the author with
47
+ `escalate.reason` (or "team policy: a person changes <path>"); ci-repair
48
+ classifies it `needs-decision`; incident stops with
49
+ `outcome=needs_decision`. A gate or deny-list elsewhere still applies.
50
+ - **`lenses`**, **`ladder`**, **`models`**: as in `../../swarm/references/custom-lenses.md`
51
+ and `models.md`.
52
+ - **`recipes`**: named step lists for `/shepherd <pr> --recipe <name>`. See
53
+ below.
54
+
55
+ ## Recipes
56
+
57
+ A recipe is an ordered list of shepherd's own steps: `swarm`, `triage`,
58
+ `simplify`, `ci-repair`, `stamp`, `incident`. `shepherd config validate`
59
+ rejects an order that cannot work (triage before any swarm, stamp anywhere
60
+ but last, a code change nothing reviews afterwards, a fixing step under
61
+ `fixes.mode: suggest`, and under `local` a fix that only stamp reviews, since
62
+ stamp sees the pushed head and local fixes never reach it). A built-in recipe
63
+ the fix mode rules out is unavailable rather than an error; `shepherd preview
64
+ --recipe <name>` says why. The built-in ones:
65
+
66
+ | Recipe | Steps | Runs under |
67
+ |---|---|---|
68
+ | `review` | swarm | every mode |
69
+ | `fix` | swarm, triage, simplify, swarm | local, push |
70
+ | `pr` | swarm, triage, simplify, swarm, ci-repair, stamp | push |
71
+ | `incident` | incident, swarm, triage, simplify, swarm, ci-repair, stamp | push |
72
+
73
+ Without `--recipe`, `/shepherd` runs the recipe its fix mode selects:
74
+ `review` under `suggest`, `fix` under `local`, `pr` under `push`. `pr` is
75
+ shepherd's own loop (`../SKILL.md`, Steps 1 to 5).
76
+
77
+ Running one:
78
+
79
+ 1. Run the steps in the order listed, one at a time. Code-changing steps
80
+ never overlap: they share one working tree and one branch.
81
+ 2. Each step keeps every rule of its own skill and of `AGENTS.md`.
82
+ 3. A review step (a swarm round that finds nothing new, or a stamp approval)
83
+ must run **after the last change** this iteration made. Otherwise the
84
+ result is `pending`, naming the step that still needs to review.
85
+
86
+ ## How a recipe finishes
87
+
88
+ Finishing a recipe is not the same as a PR being ready. Report exactly one of:
89
+
90
+ - **`reviewed`**: a recipe with no fixing step (`review`) finished. Findings
91
+ are posted for the author. It says nothing about merge readiness; never
92
+ call the PR ready or approved.
93
+ - **`fixes_uncommitted`**: under `fixes.mode: local`, the fixes sit in the
94
+ working tree and the last swarm reviewed the tree, not the PR head. The PR
95
+ is unchanged; the person commits, pushes and runs again.
96
+ - **`ready`**: only when all three hold on the current head: stamp approved
97
+ it, CI is green, and no review thread is open. A recipe without stamp can
98
+ reach `reviewed`, never `ready`.
99
+ - **`pending`**: anything short of those, naming what is missing.
100
+
101
+ ## Packs and lens files
102
+
103
+ A lens in a pack pinned to a commit (`github:owner/repo/pack.yml@<sha>`) can
104
+ name a path in the pack's own repository (`skill: lenses/payments`). It
105
+ resolves at the same commit, which must be on that repository's default branch: shepherd fetches that directory once into
106
+ `~/.cache/shepherd/packs/`, keyed by the commit, and `config explain --json`
107
+ gives the lens's `path` there. A bare name (`skill: payments-rules`) is an
108
+ installed skill. A lens path in a pack inside this repository resolves in
109
+ this repository. `shepherd config validate` reports a lens skill it cannot
110
+ find.