opencode-herdr-orchestration 0.1.5 → 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.
package/README.md CHANGED
@@ -1,11 +1,227 @@
1
1
  # opencode-herdr-orchestration
2
2
 
3
- Capability-separated OpenCode agents for planning, implementation, independent review, and delivery through Herdr.
3
+ Capability-separated OpenCode agents for planning, implementation, independent review, and delivery through Herdr, organized as **Developer → Shepherd → Flock**.
4
4
 
5
5
  This package registers the agents, provides complete structured worker-response retrieval, injects session-specific orchestration mode into shell environments, and ships a reproducible Git `pre-push` policy for new and existing repositories.
6
6
 
7
7
  Requires Node.js 20 or newer when running the package CLI or tests.
8
8
 
9
+ ## Philosophy
10
+
11
+ There is exactly **one Developer: the human operator**, and the Developer sits above the Shepherd. The Developer owns intent, product judgment, risk tolerance, and every final approval. No agent replaces the Developer; the Shepherd and every agent below it only prepare decisions for the Developer.
12
+
13
+ The Developer works through the Shepherd's two **technical phases**, each a registered agent:
14
+
15
+ - `shepherd` — the **planning** phase. Researches the repository through read-only workers and presents implementation-ready plans. It never implements.
16
+ - `shepherd-governor` — the **governance** phase. Approves plans by taking over the session, contracts bounded work, judges semantics — integrated results, review verdicts, and escalations — and owns everything remote: pushes, merges, PRs, and delivery.
17
+
18
+ The **Flock** is the bounded workforce herded under those phases:
19
+
20
+ - `sheepdog` — herds the working flock: prepares worker branches and worktrees, drives worker delegation, watches progress, retries and re-contracts leaves, runs deterministic validation, selects the shearer review tier, recovers conflicts by re-scoping ownership, and performs local integration of worker output under the governor's contracts.
21
+ - `grazer` — read-only research workers that graze the repository for evidence.
22
+ - `sheep` — bounded implementation workers that produce verified local commits.
23
+ - `shearer-low` / `shearer-medium` — independent read-only reviewers.
24
+
25
+ Three invariants govern the whole system:
26
+
27
+ 1. **Authority flows down, never sideways or up.** Each role may mutate only what its authority permits. A worker cannot delegate beyond its assignment; a reviewer cannot mutate; the flock cannot deliver.
28
+ 2. **Results flow up through structured channels.** Shepherd-phase agents act on settled, paginated responses and committed artifacts — never on terminal scrollback, partial state, or a worker's reasoning transcript.
29
+ 3. **Approval never flows down implicitly.** Reaching a milestone never grants authority, and the Developer's acknowledgement of a plan is a separate, explicit control.
30
+
31
+ ## Topology
32
+
33
+ ```text
34
+ Developer (the human operator, one per flock)
35
+
36
+ ├── Planning phase: shepherd
37
+ │ └── grazer read-only research
38
+
39
+ └── Governance phase: shepherd-governor
40
+ ├── grazer read-only research
41
+ └── sheepdog herds the working flock
42
+ ├── sheep bounded implementation
43
+ ├── shearer-low independent review, low reasoning
44
+ └── shearer-medium independent review, medium reasoning
45
+ ```
46
+
47
+ ## Roles and authorities
48
+
49
+ | Agent | Tier | Direct mutation | Spawns | Git authority |
50
+ | --- | --- | --- | --- | --- |
51
+ | `shepherd` | Strong (inherits active model) | Markdown plans, research notes, task briefs, handoffs | `grazer` only | Local Markdown commits only; no push |
52
+ | `shepherd-governor` | Strong (inherits active model) | Markdown briefs, handoffs, review notes | `grazer`, `sheepdog` | Integration, push, PR, merge, delivery |
53
+ | `sheepdog` | Fast worker (`litellm/glm-5.3-flash`) | None | `grazer`, `sheep`, `shearer-low`, `shearer-medium` | Local integration of worker output; no push |
54
+ | `grazer` | Fast worker (`litellm/glm-5.3-flash`) | None | None | Read-only inspection |
55
+ | `sheep` | Fast worker (`litellm/glm-5.3-flash`) | Assigned implementation | None | Local task commit only |
56
+ | `shearer-low` | Reviewer (`litellm-responses/gpt-5.6-terra`, low) | None | None | Read-only inspection |
57
+ | `shearer-medium` | Reviewer (`litellm-responses/gpt-5.6-terra`, medium) | None | None | Read-only inspection |
58
+
59
+ Model tiers are deliberate. The two shepherd-phase agents run on the active strong model and inherit its reasoning behavior, because planning and governance are the judgment-heavy work. Flock workers run on a fast, cheap model because their tasks are bounded and their outputs are validated. Shearers run a dedicated independent model at fixed `low` and `medium` reasoning so review is never the same model grading its own family's homework.
60
+
61
+ Sheepdog chooses `shearer-low` for localized mechanical changes with strong deterministic coverage. It chooses `shearer-medium` for security, architecture, migrations, public APIs, deployment, concurrency, cross-component work, weak coverage, or material uncertainty.
62
+
63
+ ## Governing controls
64
+
65
+ ### Separate acknowledgement and milestone controls
66
+
67
+ Acknowledgement and progress are intentionally different mechanisms:
68
+
69
+ - **Acknowledgement** is the act of selecting `shepherd-governor` in the session. Switching from the planning phase to the governance phase approves the latest presented plan. Nothing else — not a worker finishing, not a check passing, not time passing — approves a plan.
70
+ - **Milestones** track progress: the plan header (`Plan-ID`, `Base-Commit`, `Status`), each `task_id` contract, each verified local task commit, and each review verdict.
71
+
72
+ Milestones never imply acknowledgement, and acknowledgement never auto-advances a milestone. Governance-phase startup reports the plan ID, approved base, and current HEAD, then inspects divergence from the approved base before delegating.
73
+
74
+ Before acknowledging any task contract, the sheepdog reads the authoritative plan artifact itself with `herdr_plan_read` using the contract's plan ID — never a secondhand summary — and replans when the contract contradicts what the plan artifact says.
75
+
76
+ Final plans carry:
77
+
78
+ ```text
79
+ Plan-ID: <short-project-topic>-<YYYYMMDD>-<sequence>
80
+ Base-Commit: <full commit hash>
81
+ Status: PROPOSED
82
+ ```
83
+
84
+ ### Worker reply protocol
85
+
86
+ Worker replies are keyword-prefixed structured messages with two distinct channels:
87
+
88
+ - **Acknowledgement replies** open a coordinator's first response to a task contract: `ACK` (contract accepted, work starting), `CORRECT` (contract must be corrected first), `REPLAN` (contract conflicts with the approved plan or repository evidence), or `STOP` (blocked outright). Only the sheepdog — a squad lead, not a leaf — sends an acknowledgement turn, and only to the governor.
89
+ - **Leaf workers work directly.** Grazer, sheep, and shearers start their assignments without an acknowledgement turn. If a leaf cannot start, its first reply begins with `CORRECT`, `REPLAN`, or `STOP`.
90
+ - **Milestone replies** report completed milestones: `CONTINUE` (ready for the next milestone), `CORRECT` (defects need correction within the current task), `REPLAN` (evidence invalidates the plan; escalation for re-planning), `STOP` (blocked after a milestone), or `FINALIZE` (all milestones complete, final report follows).
91
+
92
+ `FINALIZE` closes a task and is never an acknowledgement. `CORRECT`, `REPLAN`, and `STOP` are legal on either channel.
93
+
94
+ ### No chain of thought
95
+
96
+ Shepherd-phase agents govern by contracts and results, not by reading worker reasoning. The `herdr_agent_response` tool returns only the latest completed final assistant message: intermediate tool-call steps, errors, ignored text, reasoning, and terminal rendering are excluded at the source. Shearers likewise receive fresh bounded context — user goal, approved plan, task contract, base and implementation commits, diff, and verification results — never the worker conversation.
97
+
98
+ This keeps delegation bounded, keeps review independent, and keeps a shepherd-phase agent's context small enough to govern many workers.
99
+
100
+ ### Deterministic validation
101
+
102
+ Before requesting semantic review, sheepdog runs or delegates deterministic repository-native checks (the repository's own check and test commands) and owns retrying deterministic failures back to the responsible sheep. Shearers judge semantics and defects; deterministic coverage is confirmed first so review cycles are never spent discovering what a test would have caught.
103
+
104
+ ### Review
105
+
106
+ Shearer verdicts are:
107
+
108
+ - `PASS`: integrate after governor checks.
109
+ - `REWORK`: return actionable findings to the responsible sheep and review the correction.
110
+ - `ESCALATE`: research, re-plan, or request Shepherd judgment.
111
+
112
+ Two failed semantic review cycles for the same task escalate instead of looping indefinitely.
113
+
114
+ ### Escalation
115
+
116
+ Task contracts carry explicit `escalate_if` conditions. Flock workers must escalate rather than guess when evidence contradicts the assignment, ownership must expand, a public API or migration changes unexpectedly, a product or architecture decision is needed, permissions block required work, or repeated attempts fail. Shepherd-phase agents resolve what repository evidence permits and surface unresolved product choices to the Developer — the human — for judgment. `unknown` is treated as inconclusive, never complete.
117
+
118
+ ### Local integration and conflict delegation
119
+
120
+ Sheepdog owns the execution mechanics end to end: it prepares each parallel `sheep` worker a dedicated branch and worktree with non-overlapping ownership and an explicit integration order, performs local integration of worker output under the governor's contracts using a narrow merge and cherry-pick lifecycle (`git merge --ff-only`, `git merge --no-ff --no-edit`, `git cherry-pick`, and their continue/abort/quit forms), and owns conflict recovery: on any conflict it aborts immediately, re-inspects, recovers by re-scoping ownership or issuing bounded recovery tasks to the responsible sheep, and escalates when conflicts invalidate the plan, repeat, or exceed its authority. Sheepdog never hand-edits a conflicted file. The governor judges the result semantically — mechanical drift is reported as deviations, and it returns defects to sheepdog rather than editing implementation itself. No flock role pushes, opens PRs, or delivers; all integration stays local until the delivery authority pushes.
121
+
122
+ ## State storage
123
+
124
+ All durable orchestration state lives outside agent memory and plugin process state, in two places:
125
+
126
+ - **The constrained orchestration state API.** Four plugin tools store and retrieve Markdown artifacts with JSON frontmatter under the repository's shared Git common directory: `herdr_plan_write` for plan artifacts (the planning shepherd only), `herdr_plan_read` for plan artifacts (shepherd, shepherd-governor, and sheepdog), and `herdr_execution_write` and `herdr_execution_read` for execution artifacts (sheepdog). Sheepdog and the governor may read the authoritative plan but never write one; plan authorship stays with the planning shepherd. Artifacts live at `<git-common-dir>/herdr/plans/<planId>.md` and `<git-common-dir>/herdr/executions/<planId>.md`. Writes are atomic; the service invokes only read-only `git rev-parse`; Markdown bodies are capped at 1 MiB; plan IDs are 1–64 characters of letters, digits, dot, underscore, or hyphen.
127
+ - **Git history.** Shepherd-phase agents may commit intended Markdown planning artifacts locally, and worker output is a verified local commit; progress is Git history, reviewable and revertable.
128
+
129
+ Every worker worktree sheepdog creates — including worktrees created from other worktrees — is a **peer that shares the same Git common repository**, never a nested checkout. Because the state API stores artifacts under the common directory, a plan written in one worktree governs workers in all of them, and orchestration state survives session ends, process restarts, and machine reboots. Separate clones never share this state.
130
+
131
+ Everything not stored this way is explicitly ephemeral: `SHEPHERD_MODE` is injected per OpenCode session and dies with the session; response cursors are HMAC-signed with a per-plugin-process secret, expire after six hours, and do not survive a restart of the shepherd's OpenCode plugin process.
132
+
133
+ ## Git authority
134
+
135
+ | Mode | Hook behavior |
136
+ | --- | --- |
137
+ | Planning phase (`shepherd`) | Denies every push; delivery belongs to the governance phase |
138
+ | Governance phase (`governor`) | Allows only the current attached branch pushed to the same remote branch |
139
+ | Flock workers (sheepdog, grazer, sheep) | Denies every push |
140
+ | Shearers (shearer-low, shearer-medium) | Denies every push |
141
+ | Missing/unknown | Does not interfere with normal human Git use |
142
+
143
+ The hook rejects pushes from detached HEAD in governance mode, protected branches, ref renames, unrelated refs, and remote ref deletions. In governance mode `main` and `master` are always protected; add repository-specific branches:
144
+
145
+ ```bash
146
+ git config --add orchestration.protectedBranch production
147
+ git config --add orchestration.protectedBranch release
148
+ ```
149
+
150
+ ### Security boundary
151
+
152
+ The hook and OpenCode Bash matchers are defense in depth, not a security sandbox. A process with arbitrary local command execution may be able to alter environment variables, Git configuration, hooks, or invoke remote protocols outside ordinary `git push`. Keep server-side protected branches and repository permissions as the authoritative control. A future integration can strengthen mode provenance with signed, session-scoped policy data, but cannot replace remote authorization.
153
+
154
+ ## Response topology
155
+
156
+ The `herdr_agent_response` OpenCode tool retrieves completed responses from Herdr-managed OpenCode workers without reading terminal scrollback or creating response files. Only `shepherd`, `shepherd-governor`, and `sheepdog` may call it, with a second role allowlist check inside the tool, and only for settled Herdr targets with a trusted `herdr:opencode` session mapping and an approved role. Each caller may retrieve only from its own workers: `shepherd` from `grazer`; `shepherd-governor` from `grazer` and `sheepdog`; `sheepdog` from `grazer`, `sheep`, `shearer-low`, and `shearer-medium`.
157
+
158
+ Initial call:
159
+
160
+ ```json
161
+ {
162
+ "target": "frontend_worker",
163
+ "maxBytes": 8192
164
+ }
165
+ ```
166
+
167
+ Continuation call:
168
+
169
+ ```json
170
+ {
171
+ "cursor": "<opaque-signed-cursor>",
172
+ "maxBytes": 8192
173
+ }
174
+ ```
175
+
176
+ Successful page:
177
+
178
+ ```json
179
+ {
180
+ "ok": true,
181
+ "target": "frontend_worker",
182
+ "sessionID": "ses_...",
183
+ "messageID": "msg_...",
184
+ "role": "sheep",
185
+ "finish": "stop",
186
+ "offset": 0,
187
+ "nextOffset": 8192,
188
+ "totalBytes": 24500,
189
+ "complete": false,
190
+ "cursor": "<opaque-signed-cursor>",
191
+ "text": "..."
192
+ }
193
+ ```
194
+
195
+ Shepherd-phase agents must continue until `complete` is true before acting on the response. Pages use UTF-8 byte offsets and never split a multibyte character.
196
+
197
+ The tool:
198
+
199
+ - resolves Herdr's tracked OpenCode session ID;
200
+ - runs `opencode export <sessionID>` with an argv API rather than shell interpolation;
201
+ - selects the latest completed final assistant message after the latest user prompt;
202
+ - excludes intermediate tool-call steps, errors, ignored text, reasoning, and terminal rendering;
203
+ - pins continuation reads to the original session, message, response digest, and offset;
204
+ - HMAC-signs opaque cursors with a random per-plugin-process secret;
205
+ - paginates on UTF-8-safe boundaries with a bounded tool-output budget;
206
+ - supports concurrent shepherds without response files or shared mutable retrieval state.
207
+
208
+ The export backend is intentional. Herdr starts each worker as a separate OpenCode process, so the shepherd plugin's SDK client may be tied to a different OpenCode server. `opencode export` reads the shared OpenCode session store across those process boundaries.
209
+
210
+ Normal lifecycle failures return structured errors such as:
211
+
212
+ ```json
213
+ {
214
+ "ok": false,
215
+ "error": {
216
+ "code": "AGENT_NOT_SETTLED",
217
+ "message": "Herdr agent frontend_worker is working; wait for idle or done.",
218
+ "retryable": true
219
+ }
220
+ }
221
+ ```
222
+
223
+ Cursor continuations do not query Herdr again, so a worker may begin another turn or leave the live agent list after the initial page. The response remains pinned as long as the OpenCode session and message still exist and are unchanged. Cursors expire after six hours by default and do not survive a restart of the shepherd's OpenCode plugin process.
224
+
9
225
  ## Installation
10
226
 
11
227
  Install or update the plugin with the cross-platform npm CLI:
@@ -19,11 +235,11 @@ The installer:
19
235
 
20
236
  - locates the global OpenCode config directory;
21
237
  - installs an exact package version there;
22
- - interactively asks which models the shepherd, sheep worker, and shearer reviewer roles should use when run in a terminal;
238
+ - interactively asks which models the shepherd, sheepdog, flock worker, and shearer reviewer roles should use when run in a terminal;
23
239
  - preserves existing JSONC comments, trailing commas, plugins, and tuple options;
24
240
  - adds the stable file URL required by current OpenCode npm plugin loading;
25
241
  - creates timestamped backups of changed config and npm manifest files;
26
- - validates `shepherd-build` through a short-lived OpenCode debug process;
242
+ - validates every agent role through a short-lived OpenCode debug process;
27
243
  - never restarts or signals a running OpenCode process.
28
244
 
29
245
  The shared Git push policy remains opt-in:
@@ -43,7 +259,7 @@ npx -y opencode-herdr-orchestration@latest uninstall --with-hooks
43
259
 
44
260
  After installation or update, quit and restart OpenCode intentionally when ready. Existing processes keep their already-loaded configuration.
45
261
 
46
- `configure-agents` updates the same model choices after installation. Press Enter to keep the displayed value, or enter `-` to restore that role's package default. Model names must include their provider prefix, such as `anthropic/claude-sonnet-4-6`.
262
+ `configure-agents` updates the same model choices after installation. Press Enter to keep the displayed value, or enter `-` to restore that role's package default. Model names must include their provider prefix, such as `anthropic/claude-sonnet-4-6`. The sheepdog and flock worker reasoning efforts accept the provider's variant names, such as `low`, `medium`, or `high`; leaving either unset uses the model's default reasoning behavior. Shepherd-phase agents always inherit the active model and its reasoning behavior, and shearer reasoning stays fixed at `low` and `medium`.
47
263
 
48
264
  ## Manual Installation
49
265
 
@@ -89,39 +305,25 @@ Confirm the installed agents:
89
305
  opencode agent list
90
306
  ```
91
307
 
92
- The expected package agents are `shepherd-plan`, `shepherd-build`, `sheep-plan`, `sheep-build`, `shearer-review-low`, and `shearer-review-medium`.
93
-
94
- ### Migrating from standalone agent files
95
-
96
- Agent definitions are merged by agent name. A local file with the same name as a package agent overrides the corresponding package fields, including its prompt and permissions.
308
+ The expected package agents are `shepherd`, `shepherd-governor`, `sheepdog`, `grazer`, `sheep`, `shearer-low`, and `shearer-medium`.
97
309
 
98
- Before switching completely, archive or remove standalone files named `sheep-plan.md`, `sheep-build.md`, `shepherd-plan.md`, or `shepherd-build.md` after any existing OpenCode processes that depend on them have ended. Older misspelled files such as `sheperd-plan.md` and `sheperd-build.md` do not override the correctly named package agents; they load as additional legacy agents until removed.
310
+ ## Breaking migration: remove stale agent files
99
311
 
100
- Do not remove agent files merely to affect an already-running process. Complete or stop that process first, update the files, then start a new OpenCode process and verify the effective agent list.
312
+ **Before updating to the current package, remove stale standalone agent files from the previous architecture.** Agent definitions are merged by agent name, so a leftover local file with a colliding name silently overrides the corresponding package fields, including its prompt and permissions.
101
313
 
102
- ## Architecture
314
+ Archive or remove these standalone files after any existing OpenCode processes that depend on them have ended:
103
315
 
104
- ```text
105
- shepherd-plan
106
- └── sheep-plan
107
-
108
- shepherd-build
109
- ├── sheep-plan
110
- ├── sheep-build
111
- ├── shearer-review-low
112
- └── shearer-review-medium
113
- ```
316
+ - `shepherd-plan.md`
317
+ - `shepherd-build.md`
318
+ - `sheep-plan.md`
319
+ - `sheep-build.md`
320
+ - `shearer-review-low.md`
321
+ - `shearer-review-medium.md`
322
+ - Older misspelled files such as `sheperd-plan.md` and `sheperd-build.md`, which load as additional legacy agents until removed.
114
323
 
115
- | Agent | Direct mutation | Delegation | Git authority | Model |
116
- | --- | --- | --- | --- | --- |
117
- | `shepherd-plan` | Markdown planning artifacts | `sheep-plan` only | Markdown commits; current non-protected branch push | Active strong model |
118
- | `shepherd-build` | Markdown handoffs/review notes | All four leaf roles | Integration, push, PR, merge, delivery | Active strong model |
119
- | `sheep-plan` | None | None | Read-only inspection | `litellm/glm-5.3-flash` |
120
- | `sheep-build` | Assigned implementation | None | Local task commit only | `litellm/glm-5.3-flash` |
121
- | `shearer-review-low` | None | None | Read-only inspection | GPT-5.6 Terra, low |
122
- | `shearer-review-medium` | None | None | Read-only inspection | GPT-5.6 Terra, medium |
324
+ Do not remove agent files merely to affect an already-running process. Complete or stop that process first, update the files, then start a new OpenCode process and verify the effective agent list with `opencode agent list`.
123
325
 
124
- The build shepherd chooses low review for localized mechanical changes with strong deterministic coverage. It chooses medium review for security, architecture, migrations, public APIs, deployment, concurrency, cross-component work, weak coverage, or material uncertainty.
326
+ Local agent definitions with the same names are merged over plugin defaults. This permits deliberate user customization without losing unspecified plugin permissions or prompts but only if the local file is intentionally maintained, not a stale leftover.
125
327
 
126
328
  ## Plugin configuration
127
329
 
@@ -140,6 +342,7 @@ For the published package, use:
140
342
 
141
343
  ```jsonc
142
344
  {
345
+ "$schema": "https://opencode.ai/config.json",
143
346
  "plugin": ["opencode-herdr-orchestration"]
144
347
  }
145
348
  ```
@@ -153,7 +356,10 @@ Plugin tuple options can override model defaults:
153
356
  "opencode-herdr-orchestration",
154
357
  {
155
358
  "shepherdModel": "anthropic/claude-sonnet-4-6",
359
+ "sheepdogModel": "litellm/glm-5.3-flash",
360
+ "sheepdogVariant": "medium",
156
361
  "workerModel": "litellm/glm-5.3-flash",
362
+ "workerVariant": "medium",
157
363
  "reviewerModel": "litellm-responses/gpt-5.6-terra"
158
364
  }
159
365
  ]
@@ -161,7 +367,9 @@ Plugin tuple options can override model defaults:
161
367
  }
162
368
  ```
163
369
 
164
- Machine-specific `shepherd-build` permissions and instructions can also be added declaratively without a local JavaScript wrapper:
370
+ The sheepdog has its own model and reasoning effort options, separate from the sheep workers it supervises.
371
+
372
+ Machine-specific governance permissions and instructions can also be added declaratively without a local JavaScript wrapper:
165
373
 
166
374
  ```jsonc
167
375
  {
@@ -169,21 +377,19 @@ Machine-specific `shepherd-build` permissions and instructions can also be added
169
377
  [
170
378
  "opencode-herdr-orchestration",
171
379
  {
172
- "shepherdBuildPermissions": {
380
+ "shepherdPermissions": {
173
381
  "private_deployment_status": "allow"
174
382
  },
175
- "shepherdBuildPromptAppend": "Use private deployment tools according to local policy."
383
+ "shepherdPromptAppend": "Use private deployment tools according to local policy."
176
384
  }
177
385
  ]
178
386
  ]
179
387
  }
180
388
  ```
181
389
 
182
- `shepherdBuildPermissions` is merged over the package's `shepherd-build` permissions. `shepherdBuildPromptAppend` is appended as a separate final paragraph. Keep secrets out of plugin options because configuration may be displayed by diagnostics.
183
-
184
- Local agent definitions with the same names are merged over plugin defaults. This permits deliberate user customization without losing unspecified plugin permissions or prompts.
390
+ `shepherdPermissions` is merged over the planning `shepherd` agent's permissions. `shepherdPromptAppend` is appended as a separate final paragraph to the `shepherd` agent's prompt. Keep secrets out of plugin options because configuration may be displayed by diagnostics.
185
391
 
186
- Machine- or organization-specific MCP tools, deployment rules, and private service instructions should stay in a local `shepherd-build` override rather than this public package. Add only the private permissions and prompt additions required by your environment; unspecified package defaults remain intact through deep merging.
392
+ Machine- or organization-specific MCP tools, deployment rules, and private service instructions should stay in a local governance-agent override rather than this public package. Add only the private permissions and prompt additions required by your environment; unspecified package defaults remain intact through deep merging.
187
393
 
188
394
  OpenCode loads plugins and agent definitions at startup. Restart OpenCode when intentionally enabling or updating the plugin. The installer never stops or restarts an OpenCode process.
189
395
 
@@ -225,137 +431,12 @@ node .\bin\orchestration.js status
225
431
  node .\bin\orchestration.js uninstall-hooks
226
432
  ```
227
433
 
228
- Add repository-specific protected branches:
229
-
230
- ```bash
231
- git config --add orchestration.protectedBranch production
232
- git config --add orchestration.protectedBranch release
233
- ```
234
-
235
- `main` and `master` are always protected in planning mode.
236
-
237
- ## Push policy
238
-
239
- The plugin tracks the selected agent per OpenCode session and injects `SHEPHERD_MODE` into that session's shell environment.
240
-
241
- | Mode | Hook behavior |
242
- | --- | --- |
243
- | `plan` | Allows only the attached current branch to the same non-protected remote branch |
244
- | `build` | Does not add planning restrictions; shepherd-build owns delivery |
245
- | `sheep-plan` | Denies every push |
246
- | `sheep-build` | Denies every push |
247
- | `review` | Denies every push |
248
- | Missing/unknown | Does not interfere with normal human Git use |
249
-
250
- The hook rejects detached-HEAD planning pushes, protected branches, ref renames, unrelated refs, and deletions.
251
-
252
- ### Security boundary
253
-
254
- The hook and OpenCode Bash matchers are defense in depth, not a security sandbox. A process with arbitrary local command execution may be able to alter environment variables, Git configuration, hooks, or invoke remote protocols outside ordinary `git push`. Keep server-side protected branches and repository permissions as the authoritative control. A future integration can strengthen mode provenance with signed, session-scoped policy data, but cannot replace remote authorization.
255
-
256
- ## Planning handoff
257
-
258
- Final plans include:
259
-
260
- ```text
261
- Plan-ID: <topic>-<YYYYMMDD>-<sequence>
262
- Base-Commit: <full commit hash>
263
- Status: PROPOSED
264
- ```
265
-
266
- Switching the session to `shepherd-build` approves that plan. Build startup reports the plan ID, approved base, and current HEAD, then inspects divergence before delegation.
267
-
268
- Implementation contracts include the objective, ownership and forbidden paths, dependencies, acceptance criteria, verification, escalation conditions, and required deliverables. `sheep-build` hands a verified local commit upward. `shepherd-build` runs deterministic checks before requesting semantic review.
269
-
270
- Reviewer verdicts are:
271
-
272
- - `PASS`: integrate after shepherd checks.
273
- - `REWORK`: return actionable findings to the responsible sheep and review the correction.
274
- - `ESCALATE`: research, re-plan, or request user judgment.
275
-
276
- Two failed semantic review cycles escalate instead of looping indefinitely.
277
-
278
434
  ## Worker interruption
279
435
 
280
- Herdr currently exposes `send-keys`, not a narrower agent interrupt command. Shepherds retain it to send Ctrl+C only after confirming that a worker is genuinely stuck. Prompts prohibit using worker terminals to type implementation commands or bypass shepherd permissions.
436
+ Herdr currently exposes `send-keys`, not a narrower agent interrupt command. Shepherd-phase agents retain it to send Ctrl+C only after confirming that a worker is genuinely stuck. Prompts prohibit using worker terminals to type implementation commands or bypass shepherd permissions.
281
437
 
282
438
  This restriction is not hard-enforced by Herdr. A native `herdr agent interrupt <target>` command would close that capability gap.
283
439
 
284
- ## Worker response retrieval
285
-
286
- The `herdr_agent_response` OpenCode tool retrieves completed responses from Herdr-managed OpenCode workers without reading terminal scrollback or creating response files.
287
-
288
- Initial call:
289
-
290
- ```json
291
- {
292
- "target": "frontend_worker",
293
- "maxBytes": 8192
294
- }
295
- ```
296
-
297
- Continuation call:
298
-
299
- ```json
300
- {
301
- "cursor": "<opaque-signed-cursor>",
302
- "maxBytes": 8192
303
- }
304
- ```
305
-
306
- Successful page:
307
-
308
- ```json
309
- {
310
- "ok": true,
311
- "target": "frontend_worker",
312
- "sessionID": "ses_...",
313
- "messageID": "msg_...",
314
- "role": "sheep-build",
315
- "finish": "stop",
316
- "offset": 0,
317
- "nextOffset": 8192,
318
- "totalBytes": 24500,
319
- "complete": false,
320
- "cursor": "<opaque-signed-cursor>",
321
- "text": "..."
322
- }
323
- ```
324
-
325
- Shepherds must continue until `complete` is true before acting on the response. Pages use UTF-8 byte offsets and never split a multibyte character.
326
-
327
- The tool:
328
-
329
- - resolves Herdr's tracked OpenCode session ID;
330
- - runs `opencode export <sessionID>` with an argv API rather than shell interpolation;
331
- - selects the latest completed final assistant message after the latest user prompt;
332
- - excludes intermediate tool-call steps, errors, ignored text, reasoning, and terminal rendering;
333
- - pins continuation reads to the original session, message, response digest, and offset;
334
- - HMAC-signs opaque cursors with a random per-plugin-process secret;
335
- - paginates on UTF-8-safe boundaries with a bounded tool-output budget;
336
- - supports concurrent shepherds without response files or shared mutable retrieval state;
337
- - allows only `shepherd-plan` and `shepherd-build`, with a second authorization check inside the tool;
338
- - accepts only settled Herdr targets with a trusted `herdr:opencode` session mapping and an approved leaf role.
339
-
340
- The export backend is intentional. Herdr starts each worker as a separate OpenCode process, so the shepherd plugin's SDK client may be tied to a different OpenCode server. `opencode export` reads the shared OpenCode session store across those process boundaries.
341
-
342
- Normal lifecycle failures return structured errors such as:
343
-
344
- ```json
345
- {
346
- "ok": false,
347
- "error": {
348
- "code": "AGENT_NOT_SETTLED",
349
- "message": "Herdr agent frontend_worker is working; wait for idle or done.",
350
- "retryable": true
351
- }
352
- }
353
- ```
354
-
355
- Cursor continuations do not query Herdr again, so a worker may begin another turn or leave the live agent list after the initial page. The response remains pinned as long as the OpenCode session and message still exist and are unchanged. Cursors expire after six hours by default and do not survive a restart of the shepherd's OpenCode plugin process.
356
-
357
- The previous file helper may remain for already-running OpenCode sessions. Once those processes end and this plugin is active, it is no longer needed by new sessions.
358
-
359
440
  ## Development
360
441
 
361
442
  ```bash
@@ -363,7 +444,7 @@ npm run check
363
444
  npm test
364
445
  ```
365
446
 
366
- Tests cover topology, model variants, permissions, override merging, session mode isolation, response selection, signed cursors, UTF-8 pagination, concurrent response reads, tool authorization, and Git hook behavior on protected, worker, review, build, and planning pushes.
447
+ Tests cover topology, model variants, permissions, override merging, session mode isolation, response selection, signed cursors, UTF-8 pagination, concurrent response reads, tool authorization, orchestration state storage and access, and Git hook behavior on protected, worker, review, governance, and planning pushes.
367
448
 
368
449
  ## Releases
369
450
 
@@ -393,6 +474,6 @@ For stronger release control, configure required reviewers on the `npm` environm
393
474
  - OpenCode command patterns cannot prove semantic Git intent; the hook adds checks but server-side protection is still required.
394
475
  - `herdr agent send-keys` is broader than interrupt-only authority.
395
476
  - Global `core.hooksPath` is singular. Existing hook frameworks must be composed rather than overwritten.
396
- - PR commands are narrowly available to `shepherd-build`, but work only in GitHub repositories with an authenticated `gh` installation.
477
+ - PR commands are narrowly available to the governance phase, but work only in GitHub repositories with an authenticated `gh` installation.
397
478
  - Agent registration and environment hooks take effect only in newly started OpenCode processes.
398
479
  - Worker session exports are capped at 64 MiB by default to bound host memory use. The response tool returns `SESSION_EXPORT_TOO_LARGE` rather than loading a larger session.
@@ -14,10 +14,13 @@ import {
14
14
  PACKAGE_NAME,
15
15
  packageVersion,
16
16
  orchestrationOptions,
17
+ reconcileAgentFiles,
18
+ removeAgentFilesManifest,
17
19
  restoreBackup,
18
20
  status as installationStatus,
19
21
  uninstallPackage,
20
22
  validateOpenCode,
23
+ writeAgentFilesManifest,
21
24
  writePluginConfig,
22
25
  } from "../src/installer.js";
23
26
 
@@ -28,9 +31,12 @@ const installedHook = join(hooksPath, "pre-push");
28
31
  const [command, ...flags] = process.argv.slice(2);
29
32
 
30
33
  const MODEL_ROLES = [
31
- ["shepherdModel", "Shepherd agents", "OpenCode active model"],
32
- ["workerModel", "Sheep worker agents", "litellm/glm-5.3-flash"],
33
- ["reviewerModel", "Shearer review agents", "litellm-responses/gpt-5.6-terra"],
34
+ ["shepherdModel", "Shepherd agents", "OpenCode active model", "model"],
35
+ ["sheepdogModel", "Sheepdog agents", "litellm/glm-5.3-flash", "model"],
36
+ ["sheepdogVariant", "Sheepdog reasoning effort", "model default", "variant"],
37
+ ["workerModel", "Sheep worker agents", "litellm/glm-5.3-flash", "model"],
38
+ ["workerVariant", "Sheep worker reasoning effort", "model default", "variant"],
39
+ ["reviewerModel", "Shearer review agents", "litellm-responses/gpt-5.6-terra", "model"],
34
40
  ];
35
41
 
36
42
  function git(args, options = {}) {
@@ -82,11 +88,13 @@ async function promptForModels(configDir) {
82
88
  const prompt = createInterface({ input: process.stdin, output: process.stdout });
83
89
  process.stdout.write("Configure agent models. Press Enter to keep the shown value; enter - to restore the package default.\n");
84
90
  try {
85
- for (const [key, label, packageDefault] of MODEL_ROLES) {
91
+ for (const [key, label, packageDefault, kind] of MODEL_ROLES) {
86
92
  const shown = existing[key] || packageDefault;
87
93
  const answer = (await prompt.question(`${label} [${shown}]: `)).trim();
88
94
  const value = answer === "-" ? "" : (answer || existing[key] || "");
89
- if (value && !value.includes("/")) throw new Error(`${label} model must include a provider prefix, for example provider/model.`);
95
+ if (value && kind === "model" && !value.includes("/")) {
96
+ throw new Error(`${label} model must include a provider prefix, for example provider/model.`);
97
+ }
90
98
  answers[key] = value;
91
99
  }
92
100
  } finally {
@@ -95,6 +103,15 @@ async function promptForModels(configDir) {
95
103
  return answers;
96
104
  }
97
105
 
106
+ function reportReconciliation(reconciliation) {
107
+ for (const relPath of reconciliation.deleted) {
108
+ process.stdout.write(`Removed obsolete package-owned agent file: ${relPath}\n`);
109
+ }
110
+ for (const item of reconciliation.remediation) {
111
+ process.stdout.write(`Action required (${item.reason}): ${item.remediation}\n`);
112
+ }
113
+ }
114
+
98
115
  async function installOrUpdate(useLatest) {
99
116
  const configDir = configDirectory();
100
117
  const models = command === "install" && process.stdin.isTTY && process.stdout.isTTY
@@ -109,8 +126,11 @@ async function installOrUpdate(useLatest) {
109
126
  restoreBackup(result.file, result.backup, result.existed);
110
127
  throw new Error(`OpenCode validation failed; restored the previous config. ${error.message}`);
111
128
  }
129
+ const reconciliation = reconcileAgentFiles(configDir, { remove: false });
130
+ writeAgentFilesManifest(configDir, reconciliation.manifestEntries, version);
112
131
  if (flags.includes("--with-hooks")) installHooks();
113
132
  process.stdout.write(`Configured ${PACKAGE_NAME}@${version} in ${result.file}\n`);
133
+ reportReconciliation(reconciliation);
114
134
  if (result.backup) process.stdout.write(`Backup: ${result.backup}\n`);
115
135
  for (const backup of packageBackups) process.stdout.write(`Backup: ${backup}\n`);
116
136
  process.stdout.write("Restart OpenCode intentionally to load the new configuration.\n");
@@ -138,8 +158,14 @@ function uninstallOrchestration() {
138
158
  const configDir = configDirectory();
139
159
  const result = writePluginConfig(configDir, true);
140
160
  const packageBackups = uninstallPackage(configDir);
161
+ const reconciliation = reconcileAgentFiles(configDir, { remove: true });
162
+ removeAgentFilesManifest(configDir);
141
163
  if (flags.includes("--with-hooks")) uninstallHooks();
142
164
  process.stdout.write(`Removed orchestration plugin configuration from ${result.file}\n`);
165
+ for (const relPath of reconciliation.deleted) {
166
+ process.stdout.write(`Removed package-owned agent file: ${relPath}\n`);
167
+ }
168
+ reportReconciliation(reconciliation);
143
169
  if (result.backup) process.stdout.write(`Backup: ${result.backup}\n`);
144
170
  for (const backup of packageBackups) process.stdout.write(`Backup: ${backup}\n`);
145
171
  }