sortie-dogs 0.10.5 → 0.10.6

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 (34) hide show
  1. package/README.md +320 -644
  2. package/dist/asset-version.d.ts +1 -1
  3. package/dist/asset-version.js +1 -1
  4. package/dist/core/goal-bound.d.ts +12 -3
  5. package/dist/core/goal-bound.js +30 -6
  6. package/dist/core/observed-goal-evidence.d.ts +2 -0
  7. package/dist/core/observed-goal-evidence.js +4 -1
  8. package/dist/core/operator-proposal.js +1 -1
  9. package/dist/core/operator-runtime.d.ts +39 -2
  10. package/dist/core/operator-runtime.js +132 -22
  11. package/dist/core/run-flight-ledger.d.ts +22 -7
  12. package/dist/core/run-flight-ledger.js +90 -25
  13. package/dist/core/types.d.ts +3 -1
  14. package/dist/core/validation-budget.d.ts +42 -3
  15. package/dist/core/validation-budget.js +104 -11
  16. package/dist/core/worktree-commit-artifact.d.ts +3 -2
  17. package/dist/core/worktree-commit-artifact.js +358 -344
  18. package/dist/core/worktree-integration-queue.js +18 -5
  19. package/dist/core/worktree-parallel-dispatch.d.ts +24 -0
  20. package/dist/core/worktree-parallel-dispatch.js +68 -21
  21. package/dist/plugin/config.d.ts +4 -0
  22. package/dist/plugin/config.js +10 -1
  23. package/dist/plugin/continuation.js +9 -1
  24. package/dist/plugin/index.js +173 -31
  25. package/dist/plugin/model-cost.d.ts +1 -1
  26. package/dist/plugin/model-cost.js +2 -0
  27. package/dist/plugin/profiled.d.ts +11 -0
  28. package/dist/plugin/profiled.js +115 -15
  29. package/dist/plugin/runtime-bridge.d.ts +4 -0
  30. package/dist/plugin/sortie-debrief.d.ts +8 -0
  31. package/dist/plugin/sortie-debrief.js +27 -2
  32. package/dist/runtime-assets-v010.d.ts +1 -1
  33. package/dist/runtime-assets-v010.js +70 -34
  34. package/package.json +2 -2
package/README.md CHANGED
@@ -1,64 +1,20 @@
1
- # Sortie-dogs
2
-
3
- **A goal-preserving, adaptive execution harness for OpenCode
4
- that optimizes cost, time, and proof without taking your setup over.**
5
-
6
- Use OpenCode normally. Invoke Sortie only when you want
7
- scoped implementation, validation, review, and model routing.
8
-
9
- ### Four design pillars
10
-
11
- - **Goal invariance** — Accepted outcomes and proof requirements survive delegation, continuation, and remediation. A child agent cannot silently weaken the job to make it easier to finish.
12
- - **Adaptive execution** — Small work stays small. Parallel workers, stronger models, and independent review are added only when task shape and risk justify them.
13
- - **Coexistence and portability** — Sortie activates only when invited, preserves normal OpenCode agents and settings, and keeps project-local setup as the default.
14
- - **Cost, time, and proof** — The objective is not maximum agent count. It is the lowest practical cost and effort for a verified outcome, with explicit evidence when work does or does not pass.
15
-
16
- ### Direction for v0.10.x
17
-
18
- The v0.10.x line is being developed around an **Astra operator / Terra dogs** split. Astra is the
19
- top-level decision authority that protects the accepted goal, quality bar, escalation decisions,
20
- and final acceptance. Because Astra is expensive, it should do only the small amount of work that
21
- requires that level of judgment. Terra-based dogs handle most bounded planning, coordination, and
22
- execution. The intended result is Astra-level judgment with Terra-level operating cost.
23
-
24
- This is an architectural direction under active validation, not a demonstrated benchmark result.
25
- Goal and quality authority remain centralized; implementation volume does not.
26
-
27
- ## Try it
28
-
29
- Requirements: Node.js 22.6 or newer, npm, and OpenCode.
30
- Start in your project directory. This block covers all four steps;
31
- the JSON belongs in the configuration file, and `/sortie` runs inside OpenCode.
32
- If the configuration already exists, add `sortie-dogs` to its `plugin` array
33
- while keeping existing entries and settings.
34
-
35
- ```text
36
- 1. Install — run in your terminal
37
- npm install --save-dev sortie-dogs
38
- npx sortie-dogs init .
39
-
40
- 2. Add plugin — save or merge into .opencode/opencode.json
41
- {
42
- "plugin": ["sortie-dogs"]
43
- }
44
-
45
- 3. Restart OpenCode
46
-
47
- 4. Start a task — enter in OpenCode
48
- /sortie <task>
49
- ```
50
-
51
- Project-local setup is recommended. `init` installs runtime assets;
52
- the plugin entry enables the plugin, including model routing.
53
- See [configuration details](#configuration) for model selection and other setup options.
54
-
55
- > **v0.10.x migration:** Give workflow instructions to **`dog-operator`**, not
56
- > `dog-coordinator`. `dog-operator` is the user-facing authority in v0.10.x;
57
- > coordinator roles are internal delegates and are not the task entry point.
58
-
59
- > **Project status: Beta.** v0.10.x is under active stabilization. Runtime
60
- > behavior, configuration, and runtime assets may still change before 1.0.
61
-
1
+ # Sortie-dogs
2
+
3
+ **A goal-preserving, adaptive execution harness for OpenCode that optimizes cost,
4
+ time, and proof without taking your setup over.**
5
+
6
+ Use OpenCode normally. Invoke Sortie only when you want scoped investigation,
7
+ implementation, validation, review, and model routing.
8
+
9
+ - **Goal invariance**: accepted outcomes and proof requirements survive delegation,
10
+ continuation, remediation, and restart.
11
+ - **Adaptive execution**: small work stays small; additional agents and stronger
12
+ models are used only when task shape or risk justifies them.
13
+ - **Coexistence**: Sortie activates only when selected and preserves normal
14
+ OpenCode agents, settings, and user-owned files.
15
+ - **Cost, time, and proof**: the objective is a verified result at the lowest
16
+ practical cost and wall time, not the largest agent count.
17
+
62
18
  [![GitHub Release](https://img.shields.io/github/v/release/zufall-upon/Sortie-dogs)](https://github.com/zufall-upon/Sortie-dogs/releases/latest)
63
19
  [![npm](https://img.shields.io/npm/v/sortie-dogs?label=npm)](https://www.npmjs.com/package/sortie-dogs)
64
20
  [![Tests](https://github.com/zufall-upon/Sortie-dogs/actions/workflows/test.yml/badge.svg)](https://github.com/zufall-upon/Sortie-dogs/actions/workflows/test.yml)
@@ -66,586 +22,306 @@ See [configuration details](#configuration) for model selection and other setup
66
22
  [![TypeScript](https://img.shields.io/badge/TypeScript-5.9-3178C6?logo=typescript&logoColor=white)](https://www.typescriptlang.org/)
67
23
  [![Node.js](https://img.shields.io/node/v/sortie-dogs)](https://www.npmjs.com/package/sortie-dogs)
68
24
  [![MIT License](https://img.shields.io/npm/l/sortie-dogs)](LICENSE)
69
-
70
- ![Sortie-dogs coordinating a bounded implementation workflow](https://raw.githubusercontent.com/zufall-upon/Sortie-dogs/main/docs/assets/sortie-workflow.gif)
71
-
72
- Sortie-dogs turns selected work into a scoped plan, optional evidence gathering,
73
- bounded implementation, canonical validation, and evidence-backed completion.
74
-
75
- Guides: [日本語](docs/guide-ja.md) · [简体中文](docs/guide-zh-CN.md) · [テスト実行](docs/testing.md) · [CLI testing](docs/cli-testing.md)
76
-
77
- Release: [v0.10.5](https://github.com/zufall-upon/Sortie-dogs/releases/tag/v0.10.5)
78
-
79
- ## Latest local benchmark case study
80
-
81
- **Completion-filtered reference values, not a successful benchmark or leaderboard claim.**
82
- On 2026-09-14, Bare OpenCode and Sortie-dogs v0.9.12 each collected three completed runs of the
83
- same frozen task, `datacurve/anko-typed-variable-bindings`. Bare needed three attempts; Sortie
84
- needed five because two attempts returned `INTERRUPTED`. These were separate local trial batches,
85
- not three matched pairs. Docker and Runta were intentionally unused.
86
-
87
- Run configuration was fixed per product configuration:
88
-
89
- - **Bare OpenCode:** standard `build` agent, `openai/gpt-5.6-sol` / `high`, with no Sortie plugin
90
- or Sortie runtime assets in the effective configuration.
91
- - **Sortie v0.9.12:** `dog-coordinator` on `openai/gpt-5.6-terra` / `high`; observed implementation
92
- children on `openai/gpt-5.6-sol` / `medium`, with the pinned Sortie package and runtime assets.
93
- No Luna, Astra, or Opus messages were observed in these trials.
94
-
95
- | Metric · one frozen task | Bare OpenCode | Sortie v0.9.12 | Sortie v0.10.1 RC qualification | Sortie v0.10.3 qualification · Terra/xhigh | Sortie v0.10.4 qualification · Terra/xhigh | Sortie v0.10.5 candidate qualification · Terra/xhigh + Luna/max |
96
- | --- | ---: | ---: | ---: | ---: | ---: | ---: |
97
- | Attempts needed | 3 | 5 | 1 | 1 | 2 | 1 recorded success |
98
- | Completed runs compared | 3 | 3 | 1 | 1 | 2 | 1 recorded success |
99
- | Verified PASS | 0/3 | 0/3 | 0/1 | 0/1 | 0/2 | **1/1** |
100
- | Task checks · F2P | 11.1% · 3/27 | 85.2% · 23/27 | 88.9% · 8/9 | 77.8% · 7/9 | 72.2% · 5/9 and 8/9 | **100% · 9/9** |
101
- | Retained checks · P2P | 282/282 | 282/282 | 94/94 | 94/94 | 94/94 | **94/94** |
102
- | Median agent wall | 24.5 min | 25.7 min | 23.2 min · n=1 | 22.7 min · n=1 | 31.1 min · n=2 | 43.1 min · n=1 |
103
- | Median model steps | 43 | 39 | 41 · CLI stream only | 36 · CLI stream only | 44 · CLI stream only | 25 · CLI stream only |
104
- | Implementation child sessions · total | 0 | 13 | 3 | 5 | 10 | 3 |
105
- | Estimated API-equivalent cost · median completed run | $3.53 | $2.85 | **$4.48** · n=1 | **$3.79** · n=1 | **$3.82** · n=2 | **$1.72** · n=1 |
106
- | Estimated cost · completed runs | $10.69 | $9.74 | **$4.48** | **$3.79** | **$7.64** | **$1.72** |
107
- | Additional interrupted-attempt cost · same fixed snapshot | $0 | $6.20 | $0 | $0 | $0 | Not reported |
108
- | Total cost to acquire completed runs · same fixed snapshot | $10.69 | $15.94 | **$4.48** | **$3.79** | **$7.64** | Not reported |
109
-
110
- All three Bare runs passed 1/9 task checks. The three completed Sortie runs passed 7/9, 8/9,
111
- and 8/9. Every compared candidate retained 94/94 prior checks, but every official verifier still
112
- returned reward 0. The two interrupted Sortie attempts are excluded from completed-run quality,
113
- time, and cost aggregates; their attempt count and estimated cost remain visible above.
114
-
115
- The v0.10.1 RC value is a standalone qualification-only reference, not a fourth matched run or a
116
- FrontierHarness leaderboard result. It used no fresh Bare control and a localized Docker-free
117
- verifier. The RC label identifies an unreleased working-tree snapshot; the benchmark tarball's
118
- package metadata remained `0.10.0`, fixed by package SHA-256
119
- `67582ee023c3bd57813262e292c067a3f90f30d61c01d8caf6f91f09ae78f61d`.
120
-
121
- Its estimated API-equivalent cost is **$4.478613**: $3.23 Sol and $1.25 Terra when rounded to cents.
122
- The audit prices all root and descendant assistant messages: 84 priced requests, 4,215,698 tokens,
123
- 100% pricing coverage, and no unpriced requests. It uses the product's 2026-09-14 Standard schedule
124
- per request, including cached input, reasoning as output, and the long-context rate band. The earlier
125
- delivery-incomplete package was a different source snapshot (`32dea0a3…`): it spent **$4.276578**
126
- across 90 priced requests and 3,704,649 tokens, with no terminal outcome or verifier. It is not folded
127
- into this RC's same-snapshot acquisition cost. Observed spend across both distinct snapshots was
128
- **$8.755191**, which is development spend rather than this RC's acquisition cost. Historical Bare and
129
- v0.9.12 costs retain their 2026-07-30 schedule; their cost cells are not same-rate comparisons with
130
- this RC estimate.
131
-
132
- The released **v0.10.3** Terra/xhigh treatment is a separate one-shot qualification, not a matched
133
- comparison or leaderboard result. It reached `DONE` and the localized Docker-free official verifier,
134
- which returned reward **0**, F2P **7/9**, and P2P **94/94**. Its full root-plus-eight-descendant audit
135
- prices 93 assistant requests and 4,809,706 tokens at **$3.789190** API-equivalent cost: **$2.186540**
136
- for Terra/xhigh and **$1.602650** for Sol/low. Pricing coverage is 100%, with no unpriced or pending
137
- requests. This uses the same 2026-09-14 per-request schedule; the observed host cost of $0 is not used
138
- as cost evidence, and the estimate is not an invoice or subscription charge.
139
-
140
- The released **v0.10.4** Terra/xhigh treatment repeats that qualification twice on the same frozen
141
- task, pins, and verifier. Both runs reached `DONE` with confirmed cleanup, and the localized
142
- Docker-free official verifier returned reward **0** with P2P **94/94** each time. F2P was **5/9** and
143
- **8/9**, so the single v0.10.3 observation of 7/9 sits inside this spread: neither release solves the
144
- task, and the per-run difference is run-to-run variance at n=1 and n=2, not a measured quality change.
145
-
146
- The **v0.10.5 candidate** switches the v0.10 implementation worker default from Sol/low to
147
- Luna/max. One separate qualification on the same frozen task, pins, and localized Docker-free
148
- official verifier reached `DONE` and returned reward **1**, F2P **9/9**, and P2P **94/94**. Agent
149
- wall was **2,583,374 ms** (43.1 min), the CLI stream recorded 25 model steps, and the operation
150
- created three implementation child sessions. Its full root-plus-five-descendant audit prices 106
151
- assistant requests and 8,830,131 tokens at **$1.719999** API-equivalent cost: **$1.436725** for
152
- Terra/xhigh and **$0.283274** for Luna/max. Pricing coverage was 100%, with no unpriced or pending
153
- requests. The candidate package was built before the release version bump and reported package
154
- metadata `0.10.4`; this is a source-snapshot reference, not a released-package measurement.
155
-
156
- The v0.10.5 column deliberately reports this one verified success only. It is not a success-rate or
157
- acquisition-cost aggregate, and its `Not reported` cells do not imply zero cost or zero failed
158
- attempts outside this recorded success.
159
-
160
- The release payload this qualification exists to check is a prompt-cache correctness fix, and that
161
- effect is separable from task quality. Before the fix the proposal investigation child re-sent its
162
- whole prompt uncached on every request, because a consumed-read counter sat in the system block and a
163
- system element is an absolute prompt prefix. The audit now reports per-session prefix reuse, which
164
- isolates exactly that failure: the v0.10.3 proposal child reused a median **0.065** of the previous
165
- prompt and was the only flagged session in its run, while both v0.10.4 runs reuse **0.957** and
166
- **0.986** and flag none. Its uncached input fell from **406,202** tokens to **213,115** and
167
- **285,060**, and its estimated cost fell from **$0.943508** to **$0.574788** and **$0.802139**. Whole-run
168
- cost is not a clean measure of the same fix, because each run performed a different amount of work:
169
- the two v0.10.4 runs priced 97 requests at **$3.268415** and 119 requests at **$4.368122**, both at
170
- 100% pricing coverage on the 2026-09-14 per-request schedule.
171
-
172
- ![Historical local case study: Bare completed 11.1 percent of task checks at a median estimated API-equivalent cost of $3.53; Sortie v0.9.12 completed 85.2 percent at $2.85. The one-shot v0.10.3 Terra/xhigh qualification completed 77.8 percent at $3.79. Neither configuration achieved a Verified PASS.](docs/assets/quality-cost-reference.svg)
173
-
174
- Cost audits use deduplicated root and descendant session tokens, grouped by the model that produced
175
- each message. Historical values retain their frozen 2026-07-30 short-context schedule; the v0.10
176
- qualifications use the product's 2026-09-14 per-request schedule described above. Completed-run cost shows execution
177
- efficiency; same-snapshot acquisition cost adds interrupted attempts. These are API-equivalent
178
- estimates, not invoices.
179
-
180
- The product objective is **more verified outcomes per unit of cost and time without weakening the
181
- accepted goal**. This small, single-task local case study does not establish that claim, isolate
182
- orchestration from model quality, or establish a cost advantage. Codex, Pi, and Oh My OpenCode use
183
- separate methodologies and are not assigned quantitative positions from these observations.
184
-
185
- [Definitions, frozen inputs, current failure status, and limitations](docs/benchmark-reference.md)
186
- · [Machine-readable reference values](docs/benchmarks/provisional-reference.json)
187
-
188
- ## How the design is enforced
189
-
190
- The four pillars above become operational constraints rather than a second set
191
- of product promises:
192
-
193
- ### 1. Keep the goal invariant
194
-
195
- Sortie turns the requested outcome into explicit acceptance criteria and carries
196
- them through planning, delegation, continuation, validation, and remediation.
197
- Workers receive bounded units, but unit boundaries do not redefine success. A
198
- child result, local process limit, or convenient partial implementation cannot
199
- silently remove an unmet criterion. Only an explicit user-authorized revision
200
- changes the accepted goal.
201
-
202
- ### 2. Adapt execution to the work
203
-
204
- Small changes can use one worker and targeted validation without paying for Scout,
205
- parallel coordination, independent review, or a full-suite run. Larger work can be
206
- split into bounded units; safely independent units may use a Luna fabric DAG.
207
- Higher-risk candidates add stronger implementation or independent review. The
208
- harness expands because the task requires it, not because more agents look better.
209
-
210
- ### 3. Coexist with OpenCode
211
-
212
- Use normal OpenCode normally. Sortie activates only for `/sortie` or
213
- `dog-coordinator`; it does not disable or replace standard agents. Project-local
214
- installation is the default, existing settings remain authoritative, and unknown
215
- user-owned runtime files are preserved. The same package can move with a project
216
- without requiring users to surrender their global OpenCode environment.
217
-
218
- ### 4. Optimize cost, time, and proof together
219
-
220
- Lower-cost models handle bounded retrieval and parallel volume work; stronger
221
- models are reserved for implementation, escalation, and independent review where
222
- their capability can change the outcome. Writes remain scoped, and completion
223
- requires validation evidence rather than agent confidence. The returned Speed /
224
- Cost / Proof debrief makes incomplete and failed outcomes visible too. Agent count
225
- is an implementation detail, not the optimization target.
226
-
227
- ## Designed to coexist with OpenCode
228
-
229
- Sortie-dogs adds a workflow to your existing setup rather than replacing it.
230
-
231
- - It does not disable OpenCode's native agents or replace standard roles such as
232
- `build`, `plan`, `explore`, or `general`.
233
- - Ordinary sessions are not automatically converted into Sortie workflows.
234
- - Project-local initialization is the recommended setup and does not change
235
- user settings.
236
- - Global runtime availability and cross-project reflection require separate,
237
- explicit opt-in. Reflection is disabled by default.
238
- - Unknown or user-owned runtime files are preserved rather than overwritten.
239
- - Manual removal targets only known Sortie-owned runtime assets.
240
-
241
- Use OpenCode normally. Invoke the pack only when you want it.
242
-
243
- ## Configuration
244
-
245
- The [Try it](#try-it) steps above are the recommended project-local installation.
246
- Runtime assets stay with the project. This section covers plugin behavior, model
247
- selection, and alternative loading after installation.
248
-
249
- Installing the runtime assets does not load the plugin, and without the plugin
250
- every role runs on whichever model the caller happened to use. Add the package
251
- to the `plugin` array in the project's `.opencode/opencode.json`:
252
-
253
- ```json
254
- {
255
- "plugin": ["sortie-dogs"]
256
- }
257
- ```
258
-
259
- Restart OpenCode afterwards. A `plugin` entry must name the package, not a
260
- subpath: `sortie-dogs/plugin` is an import specifier, not a plugin specifier.
261
-
262
- `dog-coordinator` defaults to `openai/gpt-5.6-terra` with the `high` variant; `dog-scout` defaults to
263
- `openai/gpt-5.6-luna`. To pin either role to another model, save this
264
- as `.opencode/sortie-dogs.json`:
265
-
266
- ```json
267
- {
268
- "dedicatedWorkerModel": {
269
- "model": "openai/gpt-5.6-sol",
270
- "variant": "medium"
271
- },
272
- "modelRouting": {
273
- "dog-coordinator": {
274
- "preferred": { "model": "provider/model" }
275
- },
276
- "dog-scout": {
277
- "preferred": { "model": "provider/model" }
278
- }
279
- },
280
- "modelCatalog": {
281
- "project": [{ "model": "provider/model" }]
282
- }
283
- }
284
- ```
285
-
286
- Replace `provider/model` with a model available to you.
287
-
288
- A project that depends on the package can load it from
289
- `.opencode/plugins/sortie-dogs.ts` instead of the `plugin` array:
290
-
291
- ```ts
292
- export { SortieDogsPlugin } from "sortie-dogs/plugin";
293
- ```
294
-
295
- OpenCode discovers that file automatically. Export the plugin and nothing else:
296
- OpenCode calls every runtime export of a plugin module as a plugin factory, so
297
- one extra export disables the whole module. Restart OpenCode, then start a task:
298
-
299
- ```text
300
- /sortie <task>
301
- ```
302
-
303
- Selecting `dog-coordinator` directly also activates the workflow.
304
-
305
- ## The write gate
306
-
307
- The write gate is opt-in per project. Without `operation-manifest.json` in the
308
- project root, the plugin stays passive and never denies a tool call. Creating
309
- that file is how a project opts in, so the coordinator can always create it.
310
-
311
- ```json
312
- {
313
- "version": "0.1.0",
314
- "task_id": "add-requested-behavior",
315
- "read": ["src/feature.ts", "test/feature.test.ts"],
316
- "write": ["src/feature.ts", "test/feature.test.ts"],
317
- "validation": ["npm test"]
318
- }
319
- ```
320
-
321
- - `write` lists the only paths a bound worker may change. A listed directory
322
- covers the files under it; every other entry is an exact path.
323
- - `validation` lists the exact commands a bound worker may run. Build and test
324
- commands cannot be classified by path, so a command is allowed only when it
325
- matches a declared entry exactly. Anything else is denied as unclassified.
326
- - `read` documents the intended reading scope; reads are never blocked.
327
-
328
- `dog-coordinator` owns this file. A worker binds to it once per candidate with
329
- `sortie_bind_write_gate`, and only after the coordinator's handoff has been
330
- inspected. Coordinator sessions are never gated.
331
-
332
- Both documents are schema-checked before inspection and binding, and every object
333
- rejects unknown properties. A rejection always names the failing document, the
334
- exact JSON pointer, and the failing rule, for example
335
- `Defects: handoff /state/blocked/0 schema_type`, so the coordinator repairs that
336
- pointer instead of resending an unchanged document. Check a handoff before
337
- dispatch with the read-only `sortie_check_contract` tool, which reports the same
338
- defects without inspecting or binding, or with `sortie-dogs lint <handoff.json>
339
- --manifest <operation-manifest.json>`. The two most common defects are a
340
- `state.blocked` list of strings instead of `{ reason, needed }` objects, and an
341
- operation manifest that declares anything other than `version`, `task_id`,
342
- `read`, `write`, and `validation`.
343
-
344
- Optional settings in `.opencode/sortie-dogs.json`:
345
-
346
- ```json
347
- {
348
- "operationManifestPath": "operation-manifest.json",
349
- "handoffPaths": ["handoff.json"],
350
- "readOnlyTools": ["my_mcp_search"],
351
- "dedicatedWorkerModel": { "model": "provider/model", "variant": "deep" },
352
- "continuation": { "enabled": true, "maxAutoContinues": 10 },
353
- "reflection": {
354
- "enabled": false,
355
- "layers": { "run": true, "project": true, "global": false },
356
- "maxInjectedTokens": 500
357
- }
358
- }
359
- ```
360
-
361
- The same schema may be saved globally as
362
- `~/.config/opencode/sortie-dogs.json` (on Windows,
363
- `%USERPROFILE%\.config\opencode\sortie-dogs.json`). Precedence is built-in
364
- defaults, global file, project file, `SORTIE_DOGS_CONFIG`, then plugin factory
365
- options. OpenCode plugin normalization may omit factory options, so use the
366
- global file for durable global settings.
367
-
368
- - `operationManifestPath` moves the manifest; the path is project-relative.
369
- - `handoffPaths` lists the handoff files the plugin inspects. A worker can only
370
- bind after one of these files passes inspection, so an empty list disables
371
- binding entirely. Relative entries are also candidate-relative in a nested
372
- repository: a child candidate may use its own `handoff.json` while OpenCode is
373
- opened at the parent workspace. For operational work the coordinator creates
374
- that valid handoff before dispatch and sends its exact absolute path; the
375
- binding child must use the built-in Read tool on it immediately before bind.
376
- New coordinator contracts are emitted under the candidate-relative
377
- `.sortie-dogs/contracts/` directory as `handoff.<id>.json` and
378
- `<id>.operation-manifest.json`. The directory is ignored by this repository's
379
- `.gitignore`; legacy root/scoped paths and configured custom paths remain
380
- readable and preflight-compatible, but are never moved or deleted.
381
- Remove the directory only when no Sortie run is active.
382
- - `readOnlyTools` adds host-specific tool names that never change files, such as
383
- MCP tools. Unknown tools are denied for a bound session by default.
384
- - `dedicatedWorkerModel` selects the serial implementation target used by
385
- `implementation`, `remediation`, `blocker-resolution`, `sol-worker-mk2a2`, and
386
- `dog-worker`. It defaults to `openai/gpt-5.6-sol` with variant `medium`.
387
- The installed `dog-luna-worker` fabric route remains fixed to
388
- `openai/gpt-5.6-luna` with variant `max`; pointing the serial target at that
389
- Luna model is invalid because it would collapse the two route identities. The
390
- coordinator dispatches this role only for a ready descriptor of a prepared
391
- `luna-fabric` run; a `sol-serial` run keeps `dog-worker`.
392
- - `continuation` bounds the batch loop. After a terminal unit and its checkpoint,
393
- `dog-coordinator` calls `sortie_compact_and_continue`, which compacts the run
394
- and resumes the same root session on the next independent unit. Only a root
395
- `dog-coordinator` session is ever resumed: a child session is never promoted and
396
- another coordinator is never adopted. Set `enabled` to `false` to keep every
397
- batch manual, lower `maxAutoContinues` (default and maximum `10`) to change the
398
- ceiling, and set `summarizeModel` to override the latest coordinator
399
- model used for compaction. Normal OpenCode auto-compaction keeps the
400
- host's auto-continue behavior; Sortie suppresses it only while its own
401
- explicitly queued rollover owns the resume.
402
- Every terminal root-coordinator response that does not resume another unit
403
- compacts without auto-continuing, so completed tool output is not carried into
404
- the next user request.
405
- - `reflection` is an opt-in process-prevention companion for an activated root
406
- `dog-coordinator`. It is disabled by default. Run and project layers default
407
- to enabled after opt-in; the cross-project global storage layer remains
408
- disabled unless explicitly enabled. Child and non-coordinator sessions fail
409
- closed, and `SORTIE_REFLECTION=0` is an immediate kill switch. The coordinator
410
- injects the governing `REFLECTION_POLICY` only while reflection is enabled.
411
- `maxInjectedTokens` budgets the dynamic `SORTIE_PROCESS_REFLECTIONS` heading
412
- and persisted entry lines; the policy is outside that entry budget.
413
- The coordinator
414
- evaluates it only after a resolved blocker/review defect and at a terminal
415
- unit, with a maximum of three records per run; routine bugs and external
416
- failures are never journaled.
417
-
418
- ## Example run
419
-
420
- An illustrative low-risk run stays bounded and reports its gates:
421
-
422
- ```text
423
- You: /sortie Add the requested behavior
424
- dog-coordinator: manifest confirmed
425
- dog-scout: skipped — no concrete evidence gap
426
- dog-worker: implementation complete
427
- validation: npm test — PASS
428
- review: skipped — low risk
429
- dog-coordinator: completion evidence accepted
430
- ```
431
-
432
- ## The workflow
433
-
434
- 1. **Freeze the goal and plan** — `dog-coordinator` turns the request into invariant
435
- acceptance criteria, a write manifest, and validation requirements.
436
- 2. **Optional scout** — one bounded, read-only investigation runs only for a
437
- concrete pre-worker evidence gap.
438
- 3. **Adaptive execution** — the coordinator selects one worker or bounded parallel
439
- units according to task shape; workers implement only their approved manifests.
440
- 4. **Canonical validation** — the declared test or build command must produce
441
- acceptable evidence.
442
- 5. **Risk-based review** — high-risk candidates receive independent review;
443
- low-risk candidates can skip that extra pass after validation.
444
- 6. **Goal-level completion** — only the coordinator closes the loop after every
445
- accepted criterion has manifest, validation, review, and evidence coverage.
446
- 7. **Bounded continuation** — restart recovery and compaction handoffs preserve
447
- progress; repeated batches remain bounded rather than becoming endless
448
- delegation.
449
-
450
- ## Built to work on itself
451
-
452
- Self-improvement keeps the same scoped manifests, worker ownership, validation,
453
- and review gates as other work. A loaded plugin is not treated as hot-reloadable:
454
- source changes are validated first, then packaged into an isolated `_testenv`
455
- fixture and exercised through the real OpenCode CLI. Continuation and compaction
456
- changes must demonstrate same-session recovery and terminal completion there.
457
-
458
- `npm run test:full` is reserved for explicit release validation; ordinary
459
- changes run targeted tests and `npm test`. The control plane coordinating a run
460
- is not replaced while that run is in flight.
461
-
462
- ## A visual walkthrough
463
-
464
- ### Control complexity
465
-
466
- ![Bounded roles and gates containing orchestration complexity](https://raw.githubusercontent.com/zufall-upon/Sortie-dogs/main/docs/assets/sortie-complexity.png)
467
-
468
- The coordinator keeps investigation, implementation, validation, and review in
469
- separate roles. Manifest gates keep their writes bounded even as the project
470
- gets more complex.
471
-
472
- ### Finish with evidence
473
-
474
- ![Validated work reaching coordinator-owned completion](https://raw.githubusercontent.com/zufall-upon/Sortie-dogs/main/docs/assets/sortie-complete.png)
475
-
476
- Validation and risk-based review happen before coordinator-owned completion, so
477
- the result returns with a concise record of what changed and how it was checked.
478
-
479
- ## Scope and session guarantees
480
-
481
- The plugin is passive by default. It activates a session only when a message
482
- uses `/sortie` or the selected agent is `dog-coordinator`. It validates exact
483
- write scope through source or operation manifests and rejects invalid worker
484
- handoffs. Standard OpenCode agents, roles, settings, and unrelated sessions are
485
- preserved.
486
-
487
- On `session.idle`, the final handoff is checked and the session is released. A
488
- `session.deleted` event also releases it. A later request must activate the
489
- workflow again.
490
-
491
- One host defect is repaired in place. A subagent result is built from the last
492
- text part of the child's final message, so a reasoning model that closes its
493
- turn with an empty text part returns an empty result and the coordinator
494
- re-dispatches work the worker already finished. When a completed `task` result
495
- is empty, Sortie-dogs restores the last real assistant text from that child
496
- session. Non-empty results, other tools, and unreadable child sessions are left
497
- untouched.
498
-
499
- ## Model routing
500
-
501
- Default routes split work by required capability and repeated-context cost.
502
- Sortie-dogs keeps retrieval on Luna, coordinator routing on Terra, and independent
503
- review on Sol unless the host declares another target.
504
-
505
- `dog-coordinator` defaults to `openai/gpt-5.6-terra` with the `high` variant. Coordinator quality controls
506
- planning and forward progress, so Terra High is the default balance between capability and cost.
507
- Project or global `modelRouting` can override
508
- this default. If the host proves Terra unavailable,
509
- the existing availability policy uses a configured free-tier fallback when present
510
- and otherwise preserves the session model.
511
-
512
- `dog-scout` defaults to `openai/gpt-5.6-luna` with the `high` variant, since
513
- gathering bounded evidence is retrieval rather than reasoning and that tier is
514
- where the curve gives the most per unit of cost. Nobody selects a model for a
515
- session the loop spawns, which is why delegated roles carry defaults and the
516
- coordinator does not. Project-local routing can override this default.
517
-
518
- The `implementation`, `remediation`, `blocker-resolution`, `sol-worker-mk2a2`,
519
- and `dog-worker` roles always use the stable serial target,
520
- `openai/gpt-5.6-sol` with the `medium` variant. `dedicatedWorkerModel` may move
521
- that serial target when a host cannot serve it. The installed `dog-luna-worker`
522
- route is separately fixed to `openai/gpt-5.6-luna` with the `max` variant. Its
523
- shared worker contract requires one validated fabric descriptor: the coordinator
524
- admits a v0.8 DAG contract with `sortie_admit_luna_fabric`, prepares it with
525
- `sortie_prepare_luna_fabric`, and materializes only the current ready wave, with
526
- at most five distinct Luna units. The complete DAG may contain up to 64 units.
527
- After every active artifact is verified, `sortie_advance_luna_fabric_wave`
528
- integrates them into a runtime-owned hidden candidate, cleans those worktrees,
529
- and creates fresh worktrees from that exact snapshot. After the final wave,
530
- `sortie_validate_luna_fabric_candidate` runs canonical validation once and
531
- `sortie_accept_luna_fabric_candidate` records review before one target CAS.
532
- Declared shared-path ownership serializes overlapping units
533
- across waves; unowned overlap or any admission defect routes the whole job back
534
- to one `dog-worker`. The fabric never duplicates one unit across lanes.
535
- `modelRouting` cannot replace either fixed
536
- route, and a serial override naming the Luna fabric model is invalid rather than
537
- silently collapsing both identities. Version 0.7.0 routed `dog-worker` to Luna
538
- Max; v0.8 intentionally preserves that history while splitting stable Sol and
539
- fabric Luna roles. Other explicit routes try the preferred target, then ordered
540
- fallbacks. Roles without a built-in default or explicit route keep OpenCode's
541
- already selected model.
542
-
543
- `dog-reviewer` and `dog-advisor` must never inherit the caller's model, because
544
- review and strategy lose their value when they run on the model that produced
545
- the candidate. Both default to `anthropic/claude-opus-5` when the catalog
546
- declares it, and otherwise fall back to `openai/gpt-5.6-sol` with the `xhigh`
547
- variant. That fallback uses higher effort than the Sol Medium worker because
548
- review has to be able to reject work the worker just produced. Moving
549
- `dedicatedWorkerModel` does not change consultation policy. Nothing here requires
550
- a particular vendor: both roles stay fully configurable, so declare whichever
551
- model you can actually serve.
552
-
553
- ```json
554
- {
555
- "dedicatedWorkerModel": {
556
- "model": "openai/gpt-5.6-sol",
557
- "variant": "medium"
558
- },
559
- "modelRouting": {
560
- "dog-coordinator": {
561
- "preferred": { "model": "openai/gpt-5.6-luna", "variant": "max" }
562
- },
563
- "dog-scout": {
564
- "preferred": { "model": "openai/gpt-5.6-luna", "variant": "high" }
565
- },
566
- "dog-reviewer": {
567
- "preferred": { "model": "anthropic/claude-opus-5" },
568
- "fallback": [{ "model": "openai/gpt-5.6-sol", "variant": "xhigh" }]
569
- },
570
- "dog-advisor": {
571
- "preferred": { "model": "openai/gpt-5.6-sol", "variant": "xhigh" }
572
- }
573
- },
574
- "modelCatalog": {
575
- "project": [
576
- { "model": "openai/gpt-5.6-sol", "variants": ["medium", "xhigh"] },
577
- { "model": "openai/gpt-5.6-luna", "variants": ["max", "high"] },
578
- { "model": "anthropic/claude-opus-5" }
579
- ]
580
- }
581
- }
582
- ```
583
-
584
- `dog-worker` intentionally has no `modelRouting` entry. It uses
585
- `dedicatedWorkerModel`, shared with the other stable serial implementation roles.
586
- `dog-luna-worker` remains a separate fixed fabric route.
587
-
588
- Save project configuration as `.opencode/sortie-dogs.json`. `modelCatalog`
589
- declares provider models and named variants that are actually available;
590
- Sortie-dogs does not invent, probe, or translate variants. The built-in catalog
591
- intentionally omits `anthropic/claude-opus-5`, so the preferred consultation
592
- model applies only after you declare it. Resolution tries the preferred target
593
- and then its fallbacks, rejecting an explicitly routed role when no candidate
594
- appears in the catalog.
595
-
596
- `dog-advisor` accepts bounded Strategy or SourceReview consultation from the
597
- coordinator. `dog-reviewer` independently checks high-risk candidates after
598
- canonical validation. Neither role implements, stages, commits, or acts as a
599
- user-facing worker.
600
-
601
- ## Optional global availability
602
-
603
- If you intentionally want the Sortie roles available across projects, install
604
- the CLI and runtime assets globally:
605
-
606
- ```sh
607
- npm install --global sortie-dogs
608
- sortie-dogs init --global
609
- ```
610
-
611
- This writes canonical Sortie runtime assets to OpenCode's global configuration;
612
- it does not make project-local initialization global. Load the plugin from the
613
- global `~/.config/opencode/opencode.json` when using these assets:
614
-
615
- ```json
616
- {
617
- "plugin": ["sortie-dogs"]
618
- }
619
- ```
620
-
621
- Project-local configuration and plugin loading remain available when a project
622
- needs its own settings or dependency.
623
-
624
- ## Updates and migration
625
-
626
- After replacing the dependency with a newer release asset, run:
627
-
628
- ```sh
629
- npx sortie-dogs init .
630
- ```
631
-
632
- After initialization, fully restart the OpenCode host before resuming a coordinator or opening a
633
- fresh session. Plugin modules are process-scoped, so a new session alone cannot load the update.
634
-
635
- `init` is idempotent. It updates files owned by Sortie-dogs, migrates recognized
636
- older runtime files, and records the installed version in
637
- `.opencode/sortie-dogs.version`. Conflicting or unrecognized files remain
638
- untouched and initialization stops safely. User-owned configuration—including
639
- `.opencode/sortie-dogs.json`—and standard OpenCode files are preserved.
640
-
641
- ## Maintainer releases
642
-
643
- The [release batch guide](docs/release-batch.md) covers fixed-tarball CLI verification,
644
- global application, resumable GitHub publication, and manual npm publication checks.
645
-
646
- ## Safe manual removal
647
-
648
- There is no supported Sortie-dogs uninstall command. Remove the npm dependency
649
- separately, then follow the [safe manual removal guide](docs/uninstall.md) to
650
- delete only Sortie-dogs-owned runtime files without affecting user files or
651
- standard OpenCode agents.
25
+
26
+ ![Sortie-dogs coordinating a bounded implementation workflow](https://raw.githubusercontent.com/zufall-upon/Sortie-dogs/main/docs/assets/sortie-workflow.gif)
27
+
28
+ Guides: [日本語](docs/guide-ja.md) · [简体中文](docs/guide-zh-CN.md) ·
29
+ [Testing](docs/testing.md) · [CLI testing](docs/cli-testing.md)
30
+
31
+ Release: [v0.10.6](https://github.com/zufall-upon/Sortie-dogs/releases/tag/v0.10.6)
32
+
33
+ > **Beta:** v0.10.x is under active stabilization. Runtime behavior,
34
+ > configuration, and generated assets may still change before 1.0.
35
+
36
+ ## Quick start
37
+
38
+ Requirements: Node.js 22.6 or newer, npm, and OpenCode.
39
+
40
+ Run these commands in the target project:
41
+
42
+ ```sh
43
+ npm install --save-dev sortie-dogs
44
+ npx sortie-dogs init .
45
+ ```
46
+
47
+ The beta package defaults to the v0.10 profile. Add the plugin and the required
48
+ two-level subagent depth to `.opencode/opencode.json`, preserving existing values:
49
+
50
+ ```json
51
+ {
52
+ "plugin": ["sortie-dogs"],
53
+ "subagent_depth": 2
54
+ }
55
+ ```
56
+
57
+ Restart OpenCode, then run:
58
+
59
+ ```text
60
+ /sortie-v010 <task>
61
+ ```
62
+
63
+ Selecting `dog-operator` directly starts the same workflow. `dog-operator` is the
64
+ only user-facing v0.10 authority. `dogs-coordinator` and every `*-v010` role are
65
+ internal children and must not be selected as task entry points.
66
+
67
+ `init` installs runtime assets; the `plugin` entry loads runtime enforcement and
68
+ model routing. Both are required. A new session alone does not reload an updated
69
+ plugin process, so restart OpenCode after installation or upgrade.
70
+
71
+ ## v0.10.x direction
72
+
73
+ v0.10.x separates strategic authority from bounded operations:
74
+
75
+ - `dog-operator` preserves the original request, acceptance criteria, scope,
76
+ review decision, and final acceptance.
77
+ - Hidden `dogs-coordinator` investigates or advances an approved serial queue,
78
+ but cannot edit source, change acceptance, review, or publish.
79
+ - `dog-worker-v010` implements one host-generated unit inside exact read, write,
80
+ and validation boundaries.
81
+ - Scout, advisor, and reviewer roles are optional and bounded by an explicit
82
+ evidence gap, strategy trigger, or risk decision.
83
+
84
+ The v0.10 profile is serial by design. The stable profile's Luna fabric and
85
+ parallel integration path are not exposed in this profile. More agents are not a
86
+ goal; preserving quality while reducing unnecessary expensive work is.
87
+
88
+ ### SWE-bench policy from v0.10.6
89
+
90
+ Starting with v0.10.6, development proceeds alongside recurring SWE-bench
91
+ measurement. This is a measurement policy, not a claim that an unrun suite passed.
92
+
93
+ - Freeze the task input, package/source snapshot, model routes, budgets, tools,
94
+ and stop endpoint before comparing runs.
95
+ - Freeze the candidate only after all writers stop, then grade a separate copy
96
+ with one pinned official verifier execution.
97
+ - Record benchmark completion, official task correctness, and harness terminal
98
+ state independently. A Sortie `DONE` or review `PASS` is not an official
99
+ verifier reward.
100
+ - Record agent-to-freeze and verifier time separately, plus root and descendant
101
+ tokens, model steps, children, cache behavior, estimated cost, and coverage.
102
+ - Keep infrastructure failure distinct from scored failure. Small or unmatched
103
+ samples remain case studies, not leaderboard or general success-rate claims.
104
+
105
+ The pre-v0.10.6 local benchmark condition is closed historical evidence. New
106
+ development decisions use SWE-bench measurements collected under the frozen
107
+ contract in [Coding benchmark completion and correctness](docs/benchmark-completion-contract.md).
108
+
109
+ ## Historical local case study
110
+
111
+ These are completion-filtered local references on one frozen DeepSWE task,
112
+ `datacurve/anko-typed-variable-bindings`, collected from 2026-09-14 through
113
+ 2026-09-18. They are not matched pairs or a leaderboard result.
114
+
115
+ - Bare OpenCode: Verified PASS `0/3`, F2P `3/27`, median agent wall `24.5 min`,
116
+ median completed-run API-equivalent cost `$3.53`.
117
+ - Sortie v0.9.12: Verified PASS `0/3`, F2P `23/27`, median wall `25.7 min`,
118
+ median completed-run cost `$2.85`; two additional interrupted attempts cost
119
+ an estimated `$6.20`.
120
+ - Sortie v0.10.3 one-shot: Verified PASS `0/1`, F2P `7/9`, wall `22.7 min`,
121
+ estimated cost `$3.79`.
122
+ - Sortie v0.10.5 one-shot: Verified PASS `1/1`, F2P `9/9`, P2P `94/94`, wall
123
+ `43.8 min`, estimated cost `$2.58`.
124
+
125
+ The v0.10.5 result is one verified success, not a success rate. Historical rate
126
+ schedules and endpoints differ, and the host-reported zero cost is not treated as
127
+ a bill. See [definitions, frozen inputs, and limitations](docs/benchmark-reference.md)
128
+ and [machine-readable values](docs/benchmarks/provisional-reference.json).
129
+
130
+ ## How v0.10.6 works
131
+
132
+ 1. **Freeze intent**: `dog-operator` preserves the complete request as ordered
133
+ requirements, negative constraints, quality thresholds, references, and finite
134
+ proposal/execution budgets.
135
+ 2. **Investigate only when needed**: a nontrivial task can send one bounded,
136
+ read-only proposal investigation to `dogs-coordinator`. It cannot edit, run
137
+ shell commands, dispatch workers, or widen its approved read prefixes.
138
+ 3. **Approve an exact plan**: the root compares the proposal with the original
139
+ request and approves its exact revision and hash. Uncovered requirements or
140
+ widened scope fail closed. A simple task with a complete known contract can
141
+ use the direct worker fast path.
142
+ 4. **Generate controls**: the host creates and schema-validates the handoff,
143
+ operation manifest, acceptance ledger, and short task reference. Models do not
144
+ hand-authorize their own write scope.
145
+ 5. **Execute serial units**: one unit goes directly to `dog-worker-v010`; a
146
+ multi-unit plan is advanced serially by hidden `dogs-coordinator`. A worker
147
+ binds once and can modify only declared paths and run only declared validation.
148
+ 6. **Collect host evidence**: validation identity binds source snapshot,
149
+ candidate, command, environment, scope, and owner. Claims in prose do not
150
+ become proof.
151
+ 7. **Review by risk**: high-risk candidates receive independent SourceReview;
152
+ low-risk review may be explicitly skipped. The reviewer is tool-free and does
153
+ not implement fixes.
154
+ 8. **Remediate without weakening the goal**: acceptance failures and blocking
155
+ review findings create a same-goal replacement from the committed candidate,
156
+ retaining acceptance and cumulative budget. Scope growth still requires a
157
+ later explicit user decision.
158
+ 9. **Accept explicitly**: only the root's successful completion operation closes
159
+ the run. Terminal states remain `DONE`, `INTERRUPTED`, `BLOCKED`, and
160
+ `NEED_DECISION`; the host-generated return report uses observed evidence.
161
+
162
+ Durable profile state and hash-bound task references support restart and
163
+ compaction recovery without reconstructing criteria from summary prose. Stale,
164
+ foreign-root, or changed references are rejected. An optional Git lifecycle can
165
+ create one non-overwriting branch and one explicit-path commit; it never grants
166
+ arbitrary Git, force push, release, or publication authority.
167
+
168
+ ## Configuration
169
+
170
+ ### Profile files and precedence
171
+
172
+ The default package entry is the v0.10 profile:
173
+
174
+ - Command: `/sortie-v010`
175
+ - Primary agent: `dog-operator`
176
+ - Project settings: `.opencode/sortie-dogs-v010.json`
177
+ - Global settings: `~/.config/opencode/sortie-dogs-v010.json`
178
+ - JSON environment override: `SORTIE_DOGS_V010_CONFIG`
179
+ - Runtime state: `.sortie-dogs-v010/`
180
+ - Installed asset marker: `.opencode/sortie-dogs-v010.version`
181
+
182
+ Precedence is built-in defaults, global file, project file, environment JSON,
183
+ then plugin factory options. Unknown properties or invalid types are rejected.
184
+ Use external v0.10 role names such as `dog-operator`, `dogs-coordinator`, and
185
+ `dog-reviewer-v010` in `modelRouting`; do not also declare their stable aliases.
186
+
187
+ Example `.opencode/sortie-dogs-v010.json`:
188
+
189
+ ```json
190
+ {
191
+ "validationProfile": "balanced",
192
+ "readOnlyTools": ["my_mcp_search"],
193
+ "freeTierFallbackModels": ["opencode/deepseek-v4-flash-free"],
194
+ "modelRouting": {
195
+ "dog-operator": {
196
+ "preferred": { "model": "provider/model", "variant": "high" }
197
+ },
198
+ "dogs-coordinator": {
199
+ "preferred": { "model": "provider/model", "variant": "deep" }
200
+ }
201
+ },
202
+ "modelCatalog": {
203
+ "project": [
204
+ { "model": "provider/model", "variants": ["high", "deep"] }
205
+ ]
206
+ },
207
+ "continuation": {
208
+ "enabled": true,
209
+ "maxAutoContinues": 10,
210
+ "taskWatchdogMilliseconds": 300000
211
+ }
212
+ }
213
+ ```
214
+
215
+ Declare only models and named variants the host actually provides. Sortie does
216
+ not invent, probe, or translate variant names.
217
+
218
+ ### Settings reference
219
+
220
+ - `readOnlyTools`: additional host-specific tools known not to mutate project
221
+ files. Values accumulate across configuration layers. Unknown tools are denied
222
+ in a bound worker session.
223
+ - `modelRouting`: preferred and ordered fallback targets by external profile role.
224
+ - `modelCatalog`: available `project` and `global` model/variant declarations.
225
+ - `freeTierFallbackModels`: ordered global last-resort model IDs. Default:
226
+ `opencode/deepseek-v4-flash-free`; `[]` disables this fallback.
227
+ - `dedicatedWorkerModel`: canonical stable serial target, default
228
+ `openai/gpt-5.6-sol` / `medium`. The v0.10 profile also supplies its explicit
229
+ role routes below; do not infer the v0.10 worker route from this stable setting.
230
+ - `consultation.strategy`: fixed advisor identity, optional `required`, and
231
+ positive `maxCallsPerCandidate`; default one call and not required.
232
+ - `consultation.sourceReview`: risk-based review with `maxCallsPerCandidate`
233
+ default `1` and `maxArtifactBytes` default/maximum `30720`. Unavailable review
234
+ blocks only when review is required.
235
+ - `continuation.enabled`: default `true`.
236
+ - `continuation.maxAutoContinues`: positive integer, default and maximum `10`.
237
+ - `continuation.taskWatchdogMilliseconds`: root inactivity while an implementation
238
+ Task is outstanding; default `300000`, valid range `10..1800000`.
239
+ - `continuation.summarizeModel`: optional explicit compaction model; omission
240
+ reuses the latest observed root model.
241
+ - `validationProfile`: `fast`, `balanced`, or `assurance`; default `balanced`.
242
+ - `reflection`: accepted by the shared schema, but reflection writes are not
243
+ exposed by the serial v0.10 profile. Stable reflection remains opt-in and off by
244
+ default.
245
+
246
+ The v0.10 host owns handoff and manifest controls under
247
+ `.sortie-dogs-v010/contracts/`. Do not create a legacy root
248
+ `operation-manifest.json` for this profile and do not edit generated controls.
249
+ Delete `.sortie-dogs-v010/` only when no Sortie run is active.
250
+
251
+ ### Validation policy
252
+
253
+ `validationProfile` chooses non-canonical depth:
254
+
255
+ - `fast`: static checks
256
+ - `balanced`: targeted checks
257
+ - `assurance`: related checks
258
+
259
+ Canonical proof remains canonical. Full-suite execution requires release context
260
+ or explicit risk. Workers own static, targeted, and related checks; the root owns
261
+ canonical and full-suite checks. An unchanged candidate, command, and environment
262
+ reuse the same evidence instead of spending the validation budget again.
263
+
264
+ ### Default v0.10 routes
265
+
266
+ - `dog-operator`: `openai/gpt-5.6-luna-fast` / `max`
267
+ - `dogs-coordinator`: `openai/gpt-5.6-terra` / `xhigh`
268
+ - `dog-worker-v010`: `openai/gpt-5.6-luna-fast` / `max`
269
+ - `dog-scout-v010`: `openai/gpt-5.6-luna-fast` / `xhigh`
270
+ - `dog-reviewer-v010`: `openai/gpt-5.6-terra` / `xhigh`
271
+ - `dog-advisor-v010`: preferred declared `anthropic/claude-opus-5`, otherwise
272
+ `openai/gpt-5.6-sol` / `xhigh`
273
+
274
+ An explicit model and variant selected in OpenCode remains authoritative for that
275
+ session. Child role defaults fill absent native settings and may be overridden by
276
+ valid profile routing. Review never silently inherits the implementation model.
277
+
278
+ ## Stable compatibility profile
279
+
280
+ The earlier parallel-capable runtime remains available explicitly:
281
+
282
+ ```sh
283
+ npx sortie-dogs init . --profile stable
284
+ ```
285
+
286
+ Load it through a project bridge instead of the default package plugin entry:
287
+
288
+ ```ts
289
+ export { SortieDogsPlugin } from "sortie-dogs/plugin/stable";
290
+ ```
291
+
292
+ The stable profile uses `/sortie`, `dog-coordinator`,
293
+ `.opencode/sortie-dogs.json`, `SORTIE_DOGS_CONFIG`, and `.sortie-dogs/`. Do not
294
+ register stable and v0.10 from the same package installation path in one host.
295
+
296
+ ## Global availability
297
+
298
+ Project-local installation is recommended. To expose v0.10 assets globally:
299
+
300
+ ```sh
301
+ npm install --global sortie-dogs
302
+ sortie-dogs init --global --profile v010
303
+ ```
304
+
305
+ Then add `sortie-dogs` and `subagent_depth: 2` to the global OpenCode config.
306
+ Global initialization installs assets only; it does not silently change the
307
+ default agent or merge user settings.
308
+
309
+ ## Updates and removal
310
+
311
+ After replacing the dependency, rerun initialization and restart OpenCode:
312
+
313
+ ```sh
314
+ npx sortie-dogs init .
315
+ ```
316
+
317
+ `init` is idempotent. It updates recognized Sortie-owned assets, records the asset
318
+ version, preserves user configuration, and stops safely on unknown ownership or
319
+ conflicting files.
320
+
321
+ There is no supported uninstall command. Remove the npm dependency separately,
322
+ then follow the [safe manual removal guide](docs/uninstall.md). Delete only known
323
+ Sortie-owned paths; never remove the whole `.opencode` directory or use broad
324
+ wildcards.
325
+
326
+ Maintainers: the [release batch guide](docs/release-batch.md) covers fixed-tarball
327
+ validation, global application, GitHub publication, and manual npm publication.