sortie-dogs 0.10.23 → 0.11.1

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,301 +1,221 @@
1
1
  # Sortie-dogs
2
2
 
3
- **A goal-preserving, adaptive execution harness for OpenCode that optimizes cost,
4
- time, and proof without taking your setup over.**
3
+ **A user-facing operator protects your intent and quality; a cheaper implementer does the work.**
5
4
 
6
- Use OpenCode normally. Invoke Sortie only when you want scoped investigation,
7
- implementation, validation, review, and model routing.
5
+ Sortie-dogs v0.11 is a native OpenCode V2 plugin. Use OpenCode normally, then select
6
+ Sortie to delegate investigation, implementation, testing and corrections while
7
+ keeping the complete original request.
8
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.
9
+ **v0.11 qualification:** native execution and the common suite pass. After fixing
10
+ validation and failure-coverage defects, all three selected dev23 cases passed on
11
+ the same candidate, with no unmet outcomes or timeouts. PVlib used a predeclared
12
+ NumPy-compatible scoring environment. The [qualification record](docs/v011-qualification.md)
13
+ retains the earlier failures and exact conditions. Published package hashes and
14
+ final-main verification are recorded in the [releases](https://github.com/zufall-upon/Sortie-dogs/releases).
17
15
 
18
16
  [![GitHub Release](https://img.shields.io/github/v/release/zufall-upon/Sortie-dogs)](https://github.com/zufall-upon/Sortie-dogs/releases/latest)
19
17
  [![npm](https://img.shields.io/npm/v/sortie-dogs?label=npm)](https://www.npmjs.com/package/sortie-dogs)
20
18
  [![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)
21
- [![OpenCode Plugin](https://img.shields.io/badge/OpenCode-Plugin-5C5CFF)](https://opencode.ai/)
22
- [![TypeScript](https://img.shields.io/badge/TypeScript-5.9-3178C6?logo=typescript&logoColor=white)](https://www.typescriptlang.org/)
23
- [![Node.js](https://img.shields.io/node/v/sortie-dogs)](https://www.npmjs.com/package/sortie-dogs)
24
19
  [![MIT License](https://img.shields.io/npm/l/sortie-dogs)](LICENSE)
25
20
 
26
- ![Sortie-dogs coordinating a bounded implementation workflow](https://raw.githubusercontent.com/zufall-upon/Sortie-dogs/main/docs/assets/sortie-workflow.gif)
27
-
28
21
  Guides: [日本語](docs/guide-ja.md) · [简体中文](docs/guide-zh-CN.md) ·
29
22
  [Testing](docs/testing.md) · [CLI testing](docs/cli-testing.md)
30
23
 
31
- > **Beta:** v0.10.x is under active stabilization. Runtime behavior,
32
- > configuration, and generated assets may still change before 1.0.
24
+ > Pre-1.0: runtime behavior, configuration and generated assets may change between minor versions.
33
25
 
34
26
  ## Quick start
35
27
 
36
- Requirements: Node.js 22.6 or newer, npm, and OpenCode.
37
-
38
- Run these commands in the target project:
28
+ Requirements: Node.js 22.6+, npm, OpenCode V2 (qualified with 2.0.14), and access to
29
+ `openai/gpt-6-sol` and `openai/gpt-6-luna-fast`.
39
30
 
40
31
  ```sh
41
32
  npm install --save-dev sortie-dogs
42
33
  npx sortie-dogs init .
43
34
  ```
44
35
 
45
- The beta package defaults to the v0.10 profile. Add the OpenCode V2 plugin and the required
46
- two-level subagent depth to `.opencode/opencode.json`, preserving existing values:
36
+ `init` defaults to the **v011** runtime assets. Add the plugin to
37
+ `.opencode/opencode.json(c)`, preserving existing settings:
47
38
 
48
- ```json
39
+ ```jsonc
49
40
  {
41
+ "$schema": "https://opencode.ai/config.json",
50
42
  "plugins": ["sortie-dogs"],
51
- "experimental": { "subagent_depth": 2 }
43
+ "agents": {
44
+ "compaction": { "model": "openai/gpt-6-luna-fast#high" },
45
+ "title": { "model": "openai/gpt-6-luna-fast#high" }
46
+ }
52
47
  }
53
48
  ```
54
49
 
55
- Restart OpenCode, then run:
50
+ The auxiliary settings select Luna6 Fast for summaries and titles. Keep any
51
+ additional settings on those agents. Sortie permits SOL6 and Luna6 for its
52
+ execution requests; reviewer/advisor model selections are independent.
53
+
54
+ Restart the OpenCode host after installing or updating the plugin, then run:
56
55
 
57
56
  ```text
58
- /sortie-v010 <task>
57
+ /sortie-v011 <your task>
59
58
  ```
60
59
 
61
- Selecting `dog-operator` directly starts the same workflow. `dog-operator` is the
62
- only user-facing v0.10 authority. `dogs-coordinator` and every `*-v010` role are
63
- internal children and must not be selected as task entry points.
64
-
65
- `init` installs runtime assets; the `plugins` entry loads runtime enforcement and
66
- model routing. Both are required. A new session alone does not reload an updated
67
- plugin process, so restart OpenCode after installation or upgrade.
68
-
69
- ## v0.10.x direction
70
-
71
- v0.10.x separates strategic authority from bounded operations:
72
-
73
- - `dog-operator` preserves the original request, acceptance criteria, scope,
74
- review decision, and final acceptance.
75
- - Hidden `dogs-coordinator` investigates or advances an approved serial queue,
76
- but cannot edit source, change acceptance, review, or publish.
77
- - `dog-worker-v010` implements one host-generated unit inside exact read, write,
78
- and validation boundaries.
79
- - Scout, advisor, and reviewer roles are optional and bounded by an explicit
80
- evidence gap, strategy trigger, or risk decision.
81
-
82
- The v0.10 profile is serial by design. The stable profile's Luna fabric and
83
- parallel integration path are not exposed in this profile. More agents are not a
84
- goal; preserving quality while reducing unnecessary expensive work is.
85
-
86
- ### SWE-bench evaluation
87
-
88
- A frozen Sortie-dogs v0.10.14 build was evaluated on 23 fixed tasks.
89
-
90
- - Official verifier PASS: 6 / 23
91
- - Scored FAIL: 17 / 23
92
- - Infrastructure blocked: 0 / 23
93
- - Total estimated model cost: $15.75
94
- - Median agent runtime: 15.2 min
95
-
96
- The same Sortie-dogs candidate, model routes, budgets, tools, and verification
97
- procedure were held fixed for all tasks. This is one frozen evaluation, not a
98
- general success-rate claim.
99
-
100
- Full methodology and per-task results: [benchmark details](docs/benchmark-v0.10.14-dev23.md)
101
-
102
- Historical qualification references remain in [benchmark reference](docs/benchmark-reference.md).
103
-
104
- ## How v0.10.6 works
105
-
106
- 1. **Freeze intent**: `dog-operator` preserves the complete request as ordered
107
- requirements, negative constraints, quality thresholds, references, and finite
108
- proposal/execution budgets.
109
- 2. **Investigate only when needed**: a nontrivial task can send one bounded,
110
- read-only proposal investigation to `dogs-coordinator`. It cannot edit, run
111
- shell commands, dispatch workers, or widen its approved read prefixes.
112
- 3. **Approve an exact plan**: the root compares the proposal with the original
113
- request and approves its exact revision and hash. Uncovered requirements or
114
- widened scope fail closed. A simple task with a complete known contract can
115
- use the direct worker fast path.
116
- 4. **Generate controls**: the host creates and schema-validates the handoff,
117
- operation manifest, acceptance ledger, and short task reference. Models do not
118
- hand-authorize their own write scope.
119
- 5. **Execute serial units**: one unit goes directly to `dog-worker-v010`; a
120
- multi-unit plan is advanced serially by hidden `dogs-coordinator`. A worker
121
- binds once and can modify only declared paths and run only declared validation.
122
- 6. **Collect host evidence**: validation identity binds source snapshot,
123
- candidate, command, environment, scope, and owner. Claims in prose do not
124
- become proof.
125
- 7. **Review by risk**: high-risk candidates receive independent SourceReview;
126
- low-risk review may be explicitly skipped. The reviewer is tool-free and does
127
- not implement fixes.
128
- 8. **Remediate without weakening the goal**: acceptance failures and blocking
129
- review findings create a same-goal replacement from the committed candidate,
130
- retaining acceptance and cumulative budget. Scope growth still requires a
131
- later explicit user decision.
132
- 9. **Accept explicitly**: only the root's successful completion operation closes
133
- the run. Terminal states remain `DONE`, `INTERRUPTED`, `BLOCKED`, and
134
- `NEED_DECISION`; the host-generated return report uses observed evidence.
135
-
136
- Durable profile state and hash-bound task references support restart and
137
- compaction recovery without reconstructing criteria from summary prose. Stale,
138
- foreign-root, or changed references are rejected. An optional Git lifecycle can
139
- create one non-overwriting branch and one explicit-path commit; it never grants
140
- arbitrary Git, force push, release, or publication authority.
141
-
142
- ## Configuration
143
-
144
- ### Profile files and precedence
145
-
146
- The default package entry is the v0.10 profile:
147
-
148
- - Command: `/sortie-v010`
149
- - Primary agent: `dog-operator`
150
- - Project settings: `.opencode/sortie-dogs-v010.json`
151
- - Global settings: `~/.config/opencode/sortie-dogs-v010.json`
152
- - JSON environment override: `SORTIE_DOGS_V010_CONFIG`
153
- - Runtime state: `.sortie-dogs-v010/`
154
- - Installed asset marker: `.opencode/sortie-dogs-v010.version`
155
-
156
- Precedence is built-in defaults, global file, project file, environment JSON,
157
- then plugin factory options. Unknown properties or invalid types are rejected.
158
- Use external v0.10 role names such as `dog-operator`, `dogs-coordinator`, and
159
- `dog-reviewer-v010` in `modelRouting`; do not also declare their stable aliases.
160
-
161
- Example `.opencode/sortie-dogs-v010.json`:
162
-
163
- ```json
60
+ Selecting **`dog-operator`** directly uses the same workflow. `dogs-coordinator`
61
+ is an internal implementation child. The default V2 package export and
62
+ `sortie-dogs/server` both load v0.11. This workflow uses one child level.
63
+
64
+ ## How v0.11 works
65
+
66
+ 1. **Keep the original request.** The host retains the user's words, attachments,
67
+ selected skills and subsequent instructions in durable plugin storage.
68
+ 2. **Delegate practical work.** The operator adds short guidance and dispatches
69
+ one host-generated native task. The implementer searches, reads, edits, builds,
70
+ tests and fixes ordinary problems within that invocation.
71
+ 3. **Collect real checks.** `sortie_v011_check` calls OpenCode's native shell
72
+ executor, retaining its permission checks, process ownership and cancellation.
73
+ It records actual exit status and source identity before and after execution.
74
+ 4. **Compare intent with results.** The operator inspects actual changes and
75
+ current check evidence against every original requirement, including negative
76
+ constraints. Relevant successful tests support this judgment; they do not replace it.
77
+ 5. **Correct or accept.** A revision returns feedback to the **same child session**.
78
+ Only the operator can accept. Acceptance rejects missing, failed, superseded or
79
+ stale selected checks and an outdated operator view of the request/source/evidence.
80
+
81
+ Every formal `check` remains a verification obligation: editing source or selecting an
82
+ unrelated success cannot hide a failed check. Rerun it successfully on the final source.
83
+ For a corrected/combined command, the operator can record an equivalent passing
84
+ `check_replacements` link with a coverage explanation. `work_status(check_ids=[...])`
85
+ exposes stored output for inspection. Exploratory diagnostics use ordinary shell tools.
86
+ Unavailable required tests produce **blocked**, not succeeded, completion; `start_work`
87
+ resumes that same job and child when the blocker can be resolved.
88
+
89
+ The default workflow requires no proposal investigation, immutable whole-task
90
+ execution plan, exact-file manifest, or model-authored proof mapping.
91
+ Technical scope and useful verification commands are discovered while working.
92
+ Project `AGENTS.md`, user instructions and native OpenCode permissions remain authoritative.
93
+
94
+ ### Execution progress and bounded discovery
95
+
96
+ The native child call publishes host-observed progress every five seconds: elapsed
97
+ time, current inspection/command, last exit, command starts and edits. The same
98
+ information is available through `sortie_v011_work_status`. Activity is never
99
+ treated as completed work or an inferred benchmark score. Long jobs should reuse
100
+ their existing controller and ledger, rather than rebuilding one before launch.
101
+
102
+ By default, 12 inspection calls or three minutes without an executable step stop
103
+ the child with a **blocked** reason. A running native shell/check keeps its own
104
+ timeout. Resuming a discovery stall requires concrete next-step guidance; the same
105
+ child, user instructions, failed checks and attempt budget are retained. Plugin
106
+ options `maxDiscoveryCalls`, `maxPlanningMs` and `progressIntervalMs` configure these
107
+ bounds. Interrupted outgoing tool calls receive an explicitly unverified error
108
+ result when native history omitted one; stored history and check evidence are preserved.
109
+
110
+ ### Roles and models
111
+
112
+ | Role | Model | Responsibility |
113
+ | --- | --- | --- |
114
+ | `dog-operator` | `openai/gpt-6-sol#xhigh` | User proxy, intent/quality comparison, feedback, final acceptance |
115
+ | `dogs-coordinator` | `openai/gpt-6-luna-fast#max` | Investigation, implementation, tests, corrections and routine work |
116
+ | `dog-reviewer-v010` / `dog-advisor-v010` | Existing configuration | Optional independent review or focused advice |
117
+
118
+ **`gpt-6-luna-fast` is a real OpenCode catalog selector.** It sends API model
119
+ `gpt-6-luna` with `body.service_tier: "priority"`, the documented Fast setting.
120
+ Selecting it is sufficient; a second custom alias or manual tier setting is unnecessary.
121
+ Fast is separate from the reasoning variant. Older auxiliary configurations selecting
122
+ base Luna6 also receive a Fast tier overlay while used by Sortie.
123
+
124
+ The cost report estimates completed requests using published per-request rates,
125
+ including Fast's 2x multiplier and long-context/cache pricing. Provider-reported
126
+ tiers are shown separately. The acceptance call's in-flight model response and
127
+ later final answer are not yet included, so this is an estimate rather than a bill.
128
+ Historical Terra-compatible pricing remains available for older reports.
129
+
130
+ ### Continuation, cancellation and budgets
131
+
132
+ - Native OpenCode owns normal continuation and compaction. Original instructions,
133
+ feedback, attempts and validation receipts are durable; `work_status` restores them.
134
+ - `start_work` resumes interrupted work with the same child and cumulative attempt
135
+ count. `cancel_work` stops the owned child and preserves existing files/evidence.
136
+ - A completed/cancelled job is archived when a subsequent request starts. It does
137
+ not authorize or spend the next job's attempts.
138
+ - The default is **six child invocations per job**, including revisions/resumptions.
139
+ This is not a six-tool-call limit. The implementer can investigate and correct
140
+ failures continuously inside one invocation. OpenCode controls context/turn budgets.
141
+ - Configure `maxAttempts` (1–32) through native plugin options:
142
+
143
+ ```jsonc
164
144
  {
165
- "validationProfile": "balanced",
166
- "readOnlyTools": ["my_mcp_search"],
167
- "freeTierFallbackModels": ["opencode/deepseek-v4-flash-free"],
168
- "modelRouting": {
169
- "dog-operator": {
170
- "preferred": { "model": "provider/model", "variant": "high" }
171
- },
172
- "dogs-coordinator": {
173
- "preferred": { "model": "provider/model", "variant": "deep" }
174
- }
175
- },
176
- "modelCatalog": {
177
- "project": [
178
- { "model": "provider/model", "variants": ["high", "deep"] }
179
- ]
180
- },
181
- "continuation": {
182
- "enabled": true,
183
- "taskWatchdogMilliseconds": 300000
184
- }
145
+ "plugins": [{ "package": "sortie-dogs", "options": { "maxAttempts": 6 } }]
185
146
  }
186
147
  ```
187
148
 
188
- Declare only models and named variants the host actually provides. Sortie does
189
- not invent, probe, or translate variant names.
190
-
191
- ### Settings reference
192
-
193
- - `readOnlyTools`: additional host-specific tools known not to mutate project
194
- files. Values accumulate across configuration layers. Unknown tools are denied
195
- in a bound worker session.
196
- - `modelRouting`: preferred and ordered fallback targets by external profile role.
197
- - `modelCatalog`: available `project` and `global` model/variant declarations.
198
- - `freeTierFallbackModels`: ordered global last-resort model IDs. Default:
199
- `opencode/deepseek-v4-flash-free`; `[]` disables this fallback.
200
- - `dedicatedWorkerModel`: canonical stable serial target, default
201
- `openai/gpt-6-sol` / `medium`. The v0.10 profile also supplies its explicit
202
- role routes below; do not infer the v0.10 worker route from this stable setting.
203
- - `consultation.strategy`: fixed advisor identity, optional `required`, and
204
- positive `maxCallsPerCandidate`; default one call and not required.
205
- - `consultation.sourceReview`: risk-based review with `maxCallsPerCandidate`
206
- default `1` and `maxArtifactBytes` default/maximum `30720`. Unavailable review
207
- blocks only when review is required.
208
- - `continuation.enabled`: default `true`.
209
- - Automatic continuation has no turn-count ceiling. The legacy positive-integer
210
- `continuation.maxAutoContinues` setting is accepted but ignored.
211
- - `continuation.taskWatchdogMilliseconds`: root inactivity while an implementation
212
- Task is outstanding; default `300000`, valid range `10..1800000`.
213
- - `continuation.summarizeModel`: optional explicit compaction model; omission
214
- reuses the latest observed root model.
215
- - `validationProfile`: `fast`, `balanced`, or `assurance`; default `balanced`.
216
- - `reflection`: accepted by the shared schema, but reflection writes are not
217
- exposed by the serial v0.10 profile. Stable reflection remains opt-in and off by
218
- default.
219
-
220
- The v0.10 host owns handoff and manifest controls under
221
- `.sortie-dogs-v010/contracts/`. Do not create a legacy root
222
- `operation-manifest.json` for this profile and do not edit generated controls.
223
- Delete `.sortie-dogs-v010/` only when no Sortie run is active.
224
-
225
- ### Validation policy
226
-
227
- `validationProfile` chooses non-canonical depth:
228
-
229
- - `fast`: static checks
230
- - `balanced`: targeted checks
231
- - `assurance`: related checks
232
-
233
- Canonical proof remains canonical. Full-suite execution requires release context
234
- or explicit risk. Workers own static, targeted, and related checks; the root owns
235
- canonical and full-suite checks. An unchanged candidate, command, and environment
236
- reuse the same evidence instead of spending the validation budget again.
237
-
238
- ### Default v0.10 routes
239
-
240
- - `dog-operator`: `openai/gpt-6-luna` / `max`
241
- - `dogs-coordinator`: `openai/gpt-6-sol` / `xhigh`
242
- - `dog-worker-v010`: `openai/gpt-6-luna` / `max`
243
- - `dog-scout-v010`: `openai/gpt-6-luna` / `xhigh`
244
- - `dog-reviewer-v010`: `openai/gpt-6-sol` / `xhigh`
245
- - `dog-advisor-v010`: preferred declared `anthropic/claude-opus-5`, otherwise
246
- `openai/gpt-6-sol` / `xhigh`
247
-
248
- An explicit model and variant selected in OpenCode remains authoritative for that
249
- session. Child role defaults fill absent native settings and may be overridden by
250
- valid profile routing. Review never silently inherits the implementation model.
251
-
252
- ## Stable compatibility profile
253
-
254
- The earlier parallel-capable runtime remains available explicitly:
149
+ These are v0.11 options; `.opencode/sortie-dogs-v010.json` configures only the
150
+ compatibility runtime. The v0.11 source identity covers tracked and nonignored
151
+ working files (or regular workspace files outside Git), rather than dependency
152
+ caches or external services. The operator selects meaningful checks for the task.
255
153
 
256
- ```sh
257
- npx sortie-dogs init . --profile stable
258
- ```
154
+ ## Upgrading from v0.10
259
155
 
260
- Load it through a project bridge instead of the default package plugin entry:
156
+ After replacing the dependency, run `npx sortie-dogs init .` or
157
+ `sortie-dogs init --global` and restart OpenCode.
261
158
 
262
- ```ts
263
- export { SortieDogsPlugin } from "sortie-dogs/plugin/stable";
264
- ```
159
+ - The v0.11 marker is `.opencode/sortie-dogs-v011.version` (without `.opencode/`
160
+ for global installation).
161
+ - Existing v0.10 `dog-operator` and `dogs-coordinator` files are backed up under
162
+ `sortie-dogs-v011-backup/agent/` before their role definitions are replaced.
163
+ - Existing reviewer/advisor definitions and user JSON/JSONC configuration are
164
+ preserved. Their settings can still be customized normally.
165
+ - The plugin enforces the new SOL6 operator / Luna6 Fast implementer routes,
166
+ including sessions that retained an inverted v0.10 model selection.
167
+ - A wrapper exporting the default from `sortie-dogs/server` uses v0.11.
168
+ Explicit `createSortieDogsV2Plugin()` wrappers select the older runtime;
169
+ change them to `export { default } from "sortie-dogs/server"` for v0.11.
170
+ - Finish or cancel an active v0.10 job before switching runtimes. Its immutable
171
+ plans are not converted into v0.11 jobs. A fresh request starts the new workflow.
265
172
 
266
- The stable profile uses `/sortie`, `dog-coordinator`,
267
- `.opencode/sortie-dogs.json`, `SORTIE_DOGS_CONFIG`, and `.sortie-dogs/`. Do not
268
- register stable and v0.10 from the same package installation path in one host.
173
+ `init` installs assets and is idempotent. Plugin registration is a separate config
174
+ step. Unknown ownership or conflicting backup files stop initialization with rollback.
269
175
 
270
- ## Global availability
176
+ ## Compatibility runtimes
271
177
 
272
- Project-local installation is recommended. To expose v0.10 assets globally:
178
+ The v0.10 serial runtime remains explicit:
273
179
 
274
180
  ```sh
275
- npm install --global sortie-dogs
276
- sortie-dogs init --global --profile v010
181
+ npx sortie-dogs init . --profile v010
277
182
  ```
278
183
 
279
- Then add `sortie-dogs` and `experimental.subagent_depth: 2` to the global OpenCode config.
280
- Global initialization installs assets only; it does not silently change the
281
- default agent or merge user settings.
184
+ ```js
185
+ // .opencode/plugins/sortie-compat/index.js
186
+ export { default } from "sortie-dogs/server/v010";
187
+ ```
188
+
189
+ The earlier stable parallel runtime uses `init --profile stable` and a V2 wrapper:
190
+
191
+ ```js
192
+ import { createSortieDogsV2Plugin } from "sortie-dogs/server";
193
+ import { SortieDogsPlugin } from "sortie-dogs/plugin/stable";
194
+ export default createSortieDogsV2Plugin(SortieDogsPlugin);
195
+ ```
282
196
 
283
- ## Updates and removal
197
+ Register one runtime per installation. v0.10 and v0.11 share primary/implementation
198
+ agent filenames. Legacy V1 entrypoints remain at `sortie-dogs/plugin` (v0.10) and
199
+ `sortie-dogs/plugin/stable`; they are separate from the V2 default.
284
200
 
285
- After replacing the dependency, rerun initialization and restart OpenCode:
201
+ ## Verification and historical benchmarks
202
+
203
+ The native qualification runs a frozen installed tarball with SOL6/Luna6 Fast, an
204
+ initial failing oracle, native compaction, correction, explicit operator acceptance,
205
+ and a second task in the same root session. It records outbound model/tier choices,
206
+ protected-file hashes, actual exits and receipts. Run it with:
286
207
 
287
208
  ```sh
288
- npx sortie-dogs init .
209
+ node scripts/user-proxy-smoke.mjs <candidate.tgz> <evidence-directory>
289
210
  ```
290
211
 
291
- `init` is idempotent. It updates recognized Sortie-owned assets, records the asset
292
- version, preserves user configuration, and stops safely on unknown ownership or
293
- conflicting files.
294
-
295
- There is no supported uninstall command. Remove the npm dependency separately,
296
- then follow the [safe manual removal guide](docs/uninstall.md). Delete only known
297
- Sortie-owned paths; never remove the whole `.opencode` directory or use broad
298
- wildcards.
212
+ This is functional qualification, not a representative cost or success-rate benchmark.
213
+ SWE-bench is a separate optional evaluation. The earlier **v0.10.14** 23-task run
214
+ scored 6 PASS / 17 FAIL at $15.75 estimated cost and 15.2 minutes median runtime;
215
+ those are historical results, not v0.11 scores.
216
+ [Historical methodology](docs/benchmark-v0.10.14-dev23.md).
217
+ [v0.10 limitations and v0.11 direction](docs/v010-retrospective.md).
299
218
 
300
- Maintainers: the [release batch guide](docs/release-batch.md) covers fixed-tarball
301
- validation, global application, GitHub publication, and manual npm publication.
219
+ For global assets, use `npm install --global sortie-dogs` and
220
+ `sortie-dogs init --global`, then register the package in the global OpenCode config.
221
+ [Manual removal](docs/uninstall.md) · [Release batch guide](docs/release-batch.md).
@@ -4,4 +4,5 @@
4
4
  */
5
5
  export declare const RUNTIME_ASSET_VERSION = "0.3.89-completion-proof-v1";
6
6
  export declare const V010_RUNTIME_ASSET_VERSION = "0.10.0-v0912-language4-cost-rpt10-compaction-ref2-proposal1-review-remediation1-surface4-proposal-recovery2-quality1-terminal2-route1-path1-permission2-prerequisite1-v2-bridge1-intent1-reflection1-cancel1-proposal-budget1-goal-recovery1-delegate-execute1-v2-depth1-process-replacement1-unstarted-v2-1-cold-turn1-return-report-v2-2-root-revision1";
7
- export type RuntimeAssetVersion = typeof RUNTIME_ASSET_VERSION | typeof V010_RUNTIME_ASSET_VERSION;
7
+ export declare const V011_RUNTIME_ASSET_VERSION = "0.11.1-user-proxy-native-v4-progress-recovery";
8
+ export type RuntimeAssetVersion = typeof RUNTIME_ASSET_VERSION | typeof V010_RUNTIME_ASSET_VERSION | typeof V011_RUNTIME_ASSET_VERSION;
@@ -4,3 +4,4 @@
4
4
  */
5
5
  export const RUNTIME_ASSET_VERSION = "0.3.89-completion-proof-v1";
6
6
  export const V010_RUNTIME_ASSET_VERSION = "0.10.0-v0912-language4-cost-rpt10-compaction-ref2-proposal1-review-remediation1-surface4-proposal-recovery2-quality1-terminal2-route1-path1-permission2-prerequisite1-v2-bridge1-intent1-reflection1-cancel1-proposal-budget1-goal-recovery1-delegate-execute1-v2-depth1-process-replacement1-unstarted-v2-1-cold-turn1-return-report-v2-2-root-revision1";
7
+ export const V011_RUNTIME_ASSET_VERSION = "0.11.1-user-proxy-native-v4-progress-recovery";
package/dist/cli/main.js CHANGED
@@ -29,9 +29,9 @@ const USAGE = `Usage: sortie-dogs lint <handoff.json> [<handoff.json> ...]
29
29
  [--changed-paths-from <file|->]
30
30
  [--changed-path <path> ...]
31
31
  [--format text|json] [--quiet] [--strict]`;
32
- const INIT_USAGE = `Usage: sortie-dogs init [project-root] [--profile stable|v010]
33
- sortie-dogs init --global [--profile stable|v010]
34
- This beta package defaults to the v010 profile.`;
32
+ const INIT_USAGE = `Usage: sortie-dogs init [project-root] [--profile stable|v010|v011]
33
+ sortie-dogs init --global [--profile stable|v010|v011]
34
+ This package defaults to the V2-native v011 user-proxy profile.`;
35
35
  class InputFailure extends Error {
36
36
  safeMessage;
37
37
  constructor(safeMessage) {
@@ -232,11 +232,11 @@ export async function run(argv) {
232
232
  }
233
233
  const initArgs = [...argv.slice(1)];
234
234
  const profileIndex = initArgs.indexOf("--profile");
235
- const profile = profileIndex < 0 ? "v010" : initArgs[profileIndex + 1];
235
+ const profile = profileIndex < 0 ? "v011" : initArgs[profileIndex + 1];
236
236
  if (profileIndex >= 0)
237
237
  initArgs.splice(profileIndex, 2);
238
238
  const global = initArgs[0] === "--global";
239
- if ((profile !== "stable" && profile !== "v010") || initArgs.length > 1 || (initArgs[0]?.startsWith("-") === true && !global)) {
239
+ if ((profile !== "stable" && profile !== "v010" && profile !== "v011") || initArgs.length > 1 || (initArgs[0]?.startsWith("-") === true && !global)) {
240
240
  process.stderr.write(`${INIT_USAGE}\n`);
241
241
  return 2;
242
242
  }
@@ -371,8 +371,11 @@ async function initializeRoot(requestedRoot, layout, installAssets = runtimeAsse
371
371
  return present ? await readFile(resolve(root, entry.relativePath)) : undefined;
372
372
  }));
373
373
  const markerIndex = entries.length - 1;
374
- const markerText = existing[markerIndex];
375
- const matches = (entry, index) => existing[index]?.equals(Buffer.from(entry.content)) ?? false;
374
+ const migrating = existing[markerIndex] === undefined && layout.previousMarkerPath !== undefined &&
375
+ await assertSafeExistingPath(root, layout.previousMarkerPath, true);
376
+ const markerText = existing[markerIndex] ?? (migrating ? await readFile(resolve(root, layout.previousMarkerPath)) : undefined);
377
+ const matches = (entry, index) => existing[index] !== undefined && (existing[index].equals(Buffer.from(entry.content)) ||
378
+ (layout.preserveExistingPaths ?? []).some(path => entry.relativePath === safeAssetPath(path, layout.assetPrefix)));
376
379
  const assetsMatch = assetEntries.every(matches);
377
380
  if (markerText !== undefined && parseMarker(markerText.toString("utf8")) === version && assetsMatch) {
378
381
  if (layout.controlIgnore ?? !layout.preserveAllLegacy)
@@ -422,6 +425,21 @@ async function initializeRoot(requestedRoot, layout, installAssets = runtimeAsse
422
425
  const removedFiles = [];
423
426
  const createdDirectories = [];
424
427
  try {
428
+ if (migrating) {
429
+ for (const [index, entry] of assetEntries.entries()) {
430
+ if (!existing[index] || matches(entry, index))
431
+ continue;
432
+ const backup = safeAssetPath(`sortie-dogs-v011-backup/${installAssets[index].installPath}.bak`, layout.assetPrefix);
433
+ await ensureDirectory(root, dirname(backup).replaceAll("\\", "/"), createdDirectories);
434
+ if (await assertSafeExistingPath(root, backup, true)) {
435
+ if (!(await readFile(resolve(root, backup))).equals(existing[index]))
436
+ throw new ProjectInitializationError("conflict", "Existing v0.11 migration backup differs.");
437
+ }
438
+ else
439
+ await createFile(resolve(root, backup), existing[index].toString("utf8"), createdFiles);
440
+ preservedLegacyPaths.push(backup);
441
+ }
442
+ }
425
443
  if (layout.controlIgnore ?? !layout.preserveAllLegacy) {
426
444
  await ensureProjectLunaControlIgnore(root, createdFiles, modifiedFiles, createdDirectories);
427
445
  }
@@ -504,6 +522,14 @@ async function profileInstallation(id, global) {
504
522
  throw new ProjectInitializationError("invalid-project", "Unknown runtime profile.");
505
523
  if (id === "stable")
506
524
  return { layout: global ? GLOBAL_LAYOUT : PROJECT_LAYOUT, assets: runtimeAssets };
525
+ if (id === "v011") {
526
+ const module = await import(__rewriteRelativeImportExtension(`../runtime-assets-v011.${import.meta.url.endsWith(".ts") ? "ts" : "js"}`));
527
+ return { layout: { ...(global ? GLOBAL_LAYOUT : PROJECT_LAYOUT),
528
+ markerPath: global ? profile.markerFile : `${OPEN_CODE_DIRECTORY}/${profile.markerFile}`,
529
+ previousMarkerPath: global ? "sortie-dogs-v010.version" : `${OPEN_CODE_DIRECTORY}/sortie-dogs-v010.version`,
530
+ preserveExistingPaths: ["agent/dog-reviewer-v010.md", "agent/dog-advisor-v010.md"],
531
+ preserveAllLegacy: false, controlIgnore: false, legacyAssets: [] }, assets: module.runtimeAssets };
532
+ }
507
533
  const module = await import(__rewriteRelativeImportExtension(`../runtime-assets-v010.${import.meta.url.endsWith(".ts") ? "ts" : "js"}`));
508
534
  return { layout: { ...(global ? GLOBAL_LAYOUT : PROJECT_LAYOUT),
509
535
  markerPath: global ? profile.markerFile : `${OPEN_CODE_DIRECTORY}/${profile.markerFile}`,
@@ -1,6 +1,6 @@
1
1
  /** Runtime identity is independent of the model route and the release's npm dist-tag. */
2
2
  export interface RuntimeProfile {
3
- readonly id: "stable" | "v010";
3
+ readonly id: "stable" | "v010" | "v011";
4
4
  readonly agentSuffix: string;
5
5
  readonly toolPrefix: string;
6
6
  readonly stateDirectory: string;
@@ -17,9 +17,11 @@ export declare const CANONICAL_AGENT_ROLES: readonly ["dog-coordinator", "dog-wo
17
17
  export type CanonicalAgentRole = (typeof CANONICAL_AGENT_ROLES)[number];
18
18
  export declare const STABLE_RUNTIME_PROFILE: RuntimeProfile;
19
19
  export declare const V010_RUNTIME_PROFILE: RuntimeProfile;
20
+ export declare const V011_RUNTIME_PROFILE: RuntimeProfile;
20
21
  export declare const RUNTIME_PROFILES: Readonly<{
21
22
  stable: RuntimeProfile;
22
23
  v010: RuntimeProfile;
24
+ v011: RuntimeProfile;
23
25
  }>;
24
26
  export type RuntimeProfileId = keyof typeof RUNTIME_PROFILES;
25
27
  export declare function profileAgent(profile: RuntimeProfile, role: CanonicalAgentRole): string;
@@ -20,7 +20,14 @@ export const V010_RUNTIME_PROFILE = Object.freeze({
20
20
  "dog-operator": "dogs-coordinator",
21
21
  }),
22
22
  });
23
- export const RUNTIME_PROFILES = Object.freeze({ stable: STABLE_RUNTIME_PROFILE, v010: V010_RUNTIME_PROFILE });
23
+ export const V011_RUNTIME_PROFILE = Object.freeze({
24
+ id: "v011", agentSuffix: "-v011", toolPrefix: "sortie_v011_", stateDirectory: ".sortie-dogs-v011", flightDirectory: "run-flight-v011",
25
+ configFile: "sortie-dogs-v011.json", configEnvironment: "SORTIE_DOGS_V011_CONFIG",
26
+ markerFile: "sortie-dogs-v011.version", commandName: "sortie-v011", parallel: false,
27
+ agentNames: Object.freeze({ ...suffixedAgentNames("-v011"), "dog-operator": "dog-operator", "dog-coordinator": "dog-operator", "dog-worker": "dogs-coordinator",
28
+ "dog-reviewer": "dog-reviewer-v010", "dog-advisor": "dog-advisor-v010" }),
29
+ });
30
+ export const RUNTIME_PROFILES = Object.freeze({ stable: STABLE_RUNTIME_PROFILE, v010: V010_RUNTIME_PROFILE, v011: V011_RUNTIME_PROFILE });
24
31
  export function profileAgent(profile, role) {
25
32
  return profile.agentNames[role];
26
33
  }