@ckanner/flywheel 0.28.4 → 0.29.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.
@@ -21,7 +21,7 @@ An unreadable higher-priority file, invalid JSON, or broken symlink is an error,
21
21
  flywheel config inspect --cwd /absolute/path/to/repo --task-dir /absolute/path/to/repo/docs/my-feature --json
22
22
  ```
23
23
 
24
- The result includes `source`, `scope`, resolved physical paths, and stage `bindings`. Without `--task-dir`, discovery starts at the selected project and lower levels. Inspection does not create global configuration or task state, read account tokens, or invoke a model.
24
+ The result includes `source`, `scope`, resolved physical paths, `sessions`, and stage `bindings`. Each binding's `session` reports selected mode, adapter support, a reason, and `historyRecoveryTested:false`. Without `--task-dir`, discovery starts at the selected project and lower levels. Inspection does not create global configuration or task state, read account tokens, or invoke a model.
25
25
 
26
26
  ## Apply the subscription preset to existing configuration
27
27
 
@@ -37,7 +37,7 @@ flywheel config migrate --preset subscriptions --cwd /repo --apply --json
37
37
  flywheel config inspect --cwd /repo --json
38
38
  ```
39
39
 
40
- The first command only previews. `--apply` backs up the original bytes and updates the effective task/project/global file; with no file, it creates global configuration. Optional `--expect-sha256` binds application to a preview. Changed source files, invalid input, unsupported file identities, and extra custom routes/stages are rejected. Budgets, verification, worktrees, retries, pricing, notes, and an explicit Plan `resident-session:false` are preserved.
40
+ The first command only previews. `--apply` backs up the original bytes and updates the effective task/project/global file; with no file, it creates global configuration. Optional `--expect-sha256` binds application to a preview. Changed source files, invalid input, unsupported file identities, and extra custom routes/stages are rejected. Budgets, verification, worktrees, retries, pricing, notes, an explicit Plan `resident-session:false`, and the existing `sessions` policy or its omission are preserved. Model migration does not opt an existing file into scoped history.
41
41
 
42
42
  The preset replaces the model bindings, removes their old profile references, and clears fallback/model mappings on the selected channels so that old paid routes are no longer automatically reachable. Unreferenced custom profiles and channels remain intact, including the old 0.28.2 API channel; it is not an automatic fallback for the account route. The preset disables the optional second opinion and reports removal of the old unverified multimodal route. Kimi K3.1 Pro/high handles Plan, frontend execution, and Garden; DeepSeek Flash/high handles ordinary execution and Flash/low handles Intake; GPT-6.1 Sol/high handles hard execution and Review; GPT-6 Astra/high handles Judge. Hard execution uses Codex Pro; Review/Judge use the DSH ChatGPT provider. Kimi's omitted-model default is `kimi-code/k3.1-pro`, without overriding an explicitly selected model. See [Reasoning effort and account selection](model-policy.md) for the rationale and the project comparison that remains unperformed.
43
43
 
@@ -57,11 +57,117 @@ Existing files without this setting retain `role-based`: Plan/Execute request wo
57
57
 
58
58
  Full access preserves task boundaries, frozen acceptance, verification, and candidate identity checks. A reviewer still cannot change the candidate or acceptance criteria and obtain a valid verdict. Select `role-based` explicitly when confinement is intended; a worktree is not an OS sandbox.
59
59
 
60
+ ## Session policy, history reuse, and invocation safety
61
+
62
+ ```json
63
+ {"sessions":{"mode":"scoped","policy-version":1}}
64
+ ```
65
+
66
+ Both new-installation templates explicitly select `scoped`. An existing file without `sessions` normalizes to `fresh`, policy version 1; upgrades do not rewrite it. An explicit policy must contain both fields. Unknown modes, future versions, nulls, typos, and incomplete objects fail before a model starts. The [session policy schema](../../templates/session-policy.schema.json) is the field contract.
67
+
68
+ `sessions.mode` controls history reuse; it does not disable invocation safety records. Main-task Plan, Execute, Review, and Judge calls to Codex Pro, Claude Code Pro, DSH, and Kimi journal intent and trusted terminal receipts in both modes. `fresh` disables general role history reuse, retains each backend's native new-call behavior, and preserves existing Kimi Plan `resident-session` behavior. `scoped` can continue compatible history after a trusted normal terminal outcome. Other adapters and mock retain their existing invocation path. Intake and Garden are outside this first-phase role session policy.
69
+
70
+ | Role | History scope and responsibility |
71
+ |---|---|
72
+ | Plan | Same task and milestone; only permitted task-contract revisions |
73
+ | Execute | Same task and packet; ordinary repairs may continue executor history |
74
+ | Review | Same task, packet, and review responsibility; isolated from the executor and still inspecting the complete current candidate |
75
+ | Judge / second opinion | Same task and milestone, with separate histories for primary and panel judgments |
76
+
77
+ Quick final Review and Full packet Review have different completion requirements and cannot exchange old histories or verdicts. Quick's first-success path still has two stage-agent calls, Execute and final Review. Go owns all session selection, continuation, rebuilding, and accounting. Skills, models, and desktop controls do not scan backend history to guess a session.
78
+
79
+ An explicit Plan `resident-session:false` still disables that role's history reuse under scoped mode; omission is different from an explicit opt-out. `resident-session:true` remains the legacy Kimi Plan option, not a cross-harness switch. Codex Pro still rejects it; select scoped Codex Pro history through `sessions`.
80
+
81
+ Reuse identity includes the actual task and working directories, role and scope, harness, provider, channel, model, thinking, permissions, and backend runtime references. Backend home/profile, worker, and command references reflect the child configuration actually used; only the names of injected credentials are included, never their values. Renaming a profile without changing its resolved binding does not invalidate history. A changed backend, account channel, model, permission, or working directory selects a new history. Changes to the Spec goal, non-goals, requirement identity, or packet goal, body, boundaries, and requirement mapping also invalidate the previous task semantics. Milestone-scoped Plan, Judge, and second opinions also check the milestone title and the identities and goal fields of its constituent packets. Compatible acceptance revisions can retain already-consumed history, with the current contract and evidence supplied again.
82
+
83
+ These non-secret references do not attest an account's identity or the contents of the referenced files. Replacing configuration, account authorization, or an executable in place under the same path is not guaranteed to change this policy's binding. Credential values are not read to compare accounts. Accepted configuration and effective permissions remain limited to what the current adapter receipt can establish.
84
+
85
+ Completed but unconsumed receipts have stricter rules: Review and Judge must match the original contract, candidate, and verification evidence. Running verification again cannot replace that evidence. Plan may update its permitted contract files, but replay remains bound to the complete post-call candidate and durable original before/after guards. A forbidden reviewer or planner mutation cannot become an accepted result after restart.
86
+
87
+ `state.sessions` records each scope's generation, action/reason, and latest invocation facts. One atomically replaced `.sessions` receipt slot per scope bounds recovery storage; raw receipts are excluded from Git. Recovery verifies the saved intent, receipt digest, and identity before consuming the same result, without another model request or duplicate billing. Budgets constrain new dispatches; consuming an already completed trusted receipt is not a new call. Metrics retain earlier audit facts.
88
+
89
+ The single-slot limit applies only to Flywheel's recovery receipt. Native thread and Session histories follow the backend's retention rules. Rebuilding a role history or shutting down its worker does not automatically delete earlier backend histories.
90
+
91
+ An unknown dispatch, outcome, or cleanup state blocks further execution. Changing to fresh mode, changing adapters, or restarting cannot bypass it. Process exit alone does not establish a known model outcome. `resume-candidate` only permits an adapter to attempt normal continuation; it does not prove recovery after an arbitrary crash. Main-task calls through Codex Pro 0.9.0 and Claude Code Pro 0.4.0 use outer worker v3: public typed lifecycle events, ACKs that wait for Go's durable checkpoint, and a read-only recovery entry that never sends a new turn. Codex can gate dispatch after verified `thread-ready`; Claude's native init follows prompt dispatch and cannot provide equivalent pre-dispatch configuration evidence. Both retain uncertainty when evidence is insufficient. See [interrupted invocation reconciliation](session-recovery.md).
92
+
93
+ `status` and `control status` expose role, scope, generation, action/reason, latest status, dispatch/outcome/cleanup, history-reuse selection, and usage status. The compact projection does not read receipt contents or conversation history and never changes the ledger. Legacy tasks without session records are not assumed to have recovery eligibility.
94
+
95
+ ### Role overrides and context quality
96
+
97
+ Optional `sessions.roles` selects `fresh` or `scoped` separately for `plan`, `execute`, `review`, `judge`, and `judge-panel`. Omitted roles inherit `mode`. An explicit `roles.plan:"fresh"` also disables the legacy Kimi Plan reuse shortcut; an explicit `resident-session:false` still prevents Plan reuse. Intake and Garden do not accept these overrides. This example changes history policy without changing model or account allocation:
98
+
99
+ ```json
100
+ {
101
+ "sessions": {
102
+ "mode": "scoped",
103
+ "policy-version": 1,
104
+ "roles": {"review": "fresh"},
105
+ "quality": {
106
+ "max-confirmed-turns": 0,
107
+ "max-unproductive-turns": 0,
108
+ "max-run-input-tokens": 0
109
+ }
110
+ }
111
+ }
112
+ ```
113
+
114
+ All quality thresholds default to `0`, meaning disabled. Deployment defaults are not tuned from unmeasured benefits. A positive value selects these mechanically checked limits:
115
+
116
+ | Field | Observation that can trigger rebuilding |
117
+ |---|---|
118
+ | `max-confirmed-turns` | Safely ended, dispatched invocations in this role history generation reach the limit |
119
+ | `max-unproductive-turns` | Consecutive Execute calls leave the authoritative before/after candidate fingerprint unchanged; this is a candidate observation, not semantic judgement |
120
+ | `max-run-input-tokens` | The latest complete per-run input usage reaches the limit; aggregate run input is a workload measure, not native context-window occupancy |
121
+
122
+ A quality rebuild requires the previous result to be consumed, accounted, and known safe in dispatch, outcome, and cleanup, with history otherwise eligible for continuation. Proven non-dispatch does not increment confirmed turns. Recovery deduplicates observations by invocation ID. Partial/unknown usage is not filled with zero and cannot trigger the input threshold by itself. Original budgets, attempts, stagnation limits, work, and independent acceptance remain intact. A rebuild hands over this role's generation/invocation references, reason, and current authoritative materials; it does not copy another role's private transcript or start an additional model compression call.
123
+
124
+ `state.sessions.records[*].quality` and corresponding metrics expose confirmed turns, unchanged-candidate observations, latest input measurement and completeness, generation rebuild count, and reason. The same schema bounds values and rejects unknown fields before dispatch. See [paired session evaluation](session-evaluation.md) for executable real-task comparisons, threshold selection, and unresolved-result handling.
125
+
126
+ ## Workflow policy and recovery
127
+
128
+ Workflow policy chooses stages. Model profiles, loops, routes, and `permissions.mode` independently choose each stage's backend and permissions. **Put workflow in the Spec's YAML frontmatter, not in `flywheel.config.json`.** The unified `flywheel-task` entry defaults to Auto and records researched facts before Go validates them. This example shows the fields; replace the content with evidence from the actual task:
129
+
130
+ ```yaml
131
+ workflow:
132
+ version: 1
133
+ mode: auto
134
+ reason: "The failure is located and follows an existing implementation and regression pattern"
135
+ scope-clear: true
136
+ implementation-known: true
137
+ verification-complete: true
138
+ review-sufficient: true
139
+ evidence:
140
+ - "Inspected the implementation, callers, and a regression test reproducing this failure"
141
+ risks: []
142
+ not-applicable:
143
+ L2: "No cross-module protocol changes; L1 covers the calling boundary"
144
+ L3: "No separate UI or external-service path; the local function contract directly verifies behavior"
145
+ ```
146
+
147
+ Only `version` and `mode` are required fields; missing assessment data does not qualify a task for Quick. Quick needs one milestone and packet, all four fact flags true, nonempty reason/evidence, no risks, every Spec requirement referenced by the packet with a nonempty verification description, at least one L1 command, and reasons for absent L2/L3. Go validates structure and declarations; a model's low-risk label is not proof of semantic safety. Insufficient evidence or declared risks selects Full, and execution/review can still discover new risks.
148
+
149
+ ```sh
150
+ flywheel control launch --task-dir /repo/docs/task --cwd /repo --mode auto
151
+ flywheel control start --task-dir /repo/docs/task --cwd /repo --mode full
152
+ flywheel run /repo/docs/task --mode full
153
+ flywheel control status --task-dir /repo/docs/task --cwd /repo
154
+ ```
155
+
156
+ `launch` defaults to Auto. `start` and `run` preserve the contract or persisted choice when `--mode` is omitted. Status/stop do not switch modes. Legacy contracts and existing state without workflow remain Full. Recovery retains the selected policy: Auto does not reclassify, and Full never downgrades to Quick. A new risk, verification gap, or explicit Full request upgrades Quick through a persisted checkpoint before the full loop continues. Unknown workflow versions fail explicitly. Never edit state or create a replacement task to reset budget or evidence.
157
+
158
+ `state.workflow` stores requested/effective policy, reason, evidence, risks, version, selection time, Plan/Judge applicability, and upgrades. A stage marked not applicable is not a passing check. Effective policy and completion requirements participate in evidence identity, so a Quick final Review cannot stand in for Full's Judge after upgrade. New packets can declare `workflow-risks: []` in `done-report-format`; the executor reports facts through that string array rather than editing policy or state.
159
+
160
+ Quick reuses existing Execute and Review bindings without changing effort, accounts, fallbacks, or full-access settings. All required checks remain, and applicable L2/L3 run in the actual candidate before final Review. The reviewer checks every requirement; the first-success path uses two stage-agent calls, Execute and final Review. See the [Spec schema](../../templates/spec.schema.json), [state schema](../../templates/state.schema.json), and [workflow guide](workflow.md).
161
+
162
+ ## Optional Claude Code Pro
163
+
164
+ The `claude-code-pro` harness and unreferenced `claude-sonnet` profile can be selected for any configured loop or Execute route. See the [Claude Code Pro guide](claude-code-pro.md) for model/effort choices, optional-peer installation, full-access-only permissions, continuation, and durable receipt recovery. The provider field remains specific to DSH native adapters; default stage allocation is unchanged.
165
+
60
166
  ## Fields and identities
61
167
 
62
168
  | Field | Meaning | Example |
63
169
  |---|---|---|
64
- | `harness` | Process and tool-loop backend | `dsh`, `kimi`, `codex-pro`; `codex` is the explicit older CLI path |
170
+ | `harness` | Process and tool-loop backend | `dsh`, `kimi`, `codex-pro`, `claude-code-pro`; `codex` is the explicit older CLI path |
65
171
  | `provider` | Registered DSH SDK LLM adapter ID; applies to DSH bindings | `deepseek-account`, `chatgpt` |
66
172
  | `channel` | A configuration label used for credentials, fallback, and accounting | `deepseek-account-sdk`, `chatgpt-sdk`, `kimi-subscription` |
67
173
  | `model` | Exact model identifier passed to the selected backend | `deepseek-flash`, `kimi-code/k3.1-pro`, `gpt-6.1-sol` |
@@ -140,14 +246,14 @@ Do not create a task file containing only a few profiles and expect it to inheri
140
246
  | Stage omits a profile field | Inherit that field from the referenced profile |
141
247
  | Stage explicitly supplies `model`, `thinking`, `channel`, etc. | Override only that stage |
142
248
  | `thinking: ""` | Use the harness's default effort instead of re-inheriting the profile |
143
- | `resident-session: false` | Explicitly disable the stage's resume request |
249
+ | Plan `resident-session: false` | Explicitly disable Plan history reuse; loading, profile expansion, and effective config export preserve its presence |
144
250
  | `judge-panel: null` | Disable the optional second opinion |
145
251
  | Missing/empty profile `harness`, `model`, or `channel` | Configuration error |
146
252
  | Unknown profile, field, stage name, or harness | Configuration error |
147
253
  | A profile references another profile | Unsupported; configuration error |
148
254
  | `_note` or `_note_*` | Permitted explanatory metadata, excluded from execution bindings |
149
255
 
150
- `resident-session` belongs on a stage, not in a profile. Currently only Kimi Plan can resume, and only when harness, model, channel, working directory, thinking, and permission mode match. This restores session history, not a permanently running process. Execution and review calls start fresh sessions.
256
+ `resident-session` is a legacy stage option, not a profile field. It continues to control the existing Kimi Plan behavior, and an explicit false also opts Plan out of scoped history. Other roles use the top-level `sessions` policy. Restoring history does not require a permanently running model process.
151
257
 
152
258
  Legal existing zero values, including `env-key: null`, `retry.jitter: 0`, and `worktree.enabled: false`, remain meaningful. When changing a harness or channel, also inspect any inherited provider. Use `provider: ""` when necessary to clear an explicit value before resolving the newly selected DSH channel.
153
259
 
@@ -168,13 +274,15 @@ The 0.28.0 embedded hard route uses this binding. This is a **fragment**, not a
168
274
  }
169
275
  ```
170
276
 
171
- The complete profile template uses `profiles.codex-pro` and references it from `routes.hard`. The npm dependency is exactly `dsh-subagent-codex-pro@0.8.0`. The worker imports its public `dsh-subagent-codex-pro/machine` entry and calls `runMachine` using protocol 1. The plugin itself runs Codex app-server and uses the existing Codex login.
277
+ The complete profile template uses `profiles.codex-pro` and references it from `routes.hard`. The worker consumes the exact public `dsh-subagent-codex-pro@0.9.0` package and its `dsh-subagent-codex-pro/machine` entry. The current candidate bundles the real package built from reviewed upstream source; this does not claim that 0.9.0 has been published to the registry. The plugin runs Codex app-server and uses the existing Codex login. Claude remains a separate exact `0.4.0` optional peer and is unnecessary when that backend is not selected.
172
278
 
173
279
  The external tool name `subagent_codex_pro` is not a DSH provider. This route does not create a parent DSH model to make a second delegation. Missing dependencies or invalid receipts fail; they do not trigger an implicit fallback to the older CLI driver.
174
280
 
175
281
  To migrate an existing configuration, use `config inspect` to locate the effective file. Change the hard route's inline harness or referenced profile from `codex` to `codex-pro`, retain the intended model/channel/thinking, inspect the result, and restart. Keeping `harness: "codex"` explicitly retains the older `codex exec` behavior.
176
282
 
177
- `codex-pro` requires nonempty model and channel values. It does not inherit the old Codex driver's implicit model. Omitted thinking defaults to `high`; `resident-session: true` is rejected. Each execute/review call uses a new ephemeral session.
283
+ `codex-pro` requires nonempty model and channel values. It does not inherit the old Codex driver's implicit model. Omitted thinking defaults to `high`; `resident-session: true` is rejected.
284
+
285
+ Main-task fresh and scoped calls both use outer worker protocol 3. Fresh selects ephemeral history; scoped selects persistent history and an exact thread ID for continuation. Dispatch waits for the relevant lifecycle checkpoints and Go's durable ACK. Public machine requests/terminal receipts remain protocol 1, with separately versioned lifecycle contracts. The legacy outer v1/v2 entries remain for low-level compatibility and do not acquire the main-task durable recovery guarantees. Resume must accept the same thread; busy, missing-history, and generic failures cannot be classified as safe cold-start opportunities from error text. See [interrupted invocation reconciliation](session-recovery.md).
178
286
 
179
287
  ### Worker environment
180
288
 
@@ -193,9 +301,9 @@ These settings must be visible to the process starting the engine. The installer
193
301
 
194
302
  ### Permissions, receipts, and cleanup
195
303
 
196
- The plugin checks the requested model, working directory, approval policy, and sandbox mode before a turn. Flywheel examines the complete returned policy afterward. In role-based mode, workspace-write permits the workspace and standard Codex temporary directories; extra external write roots, enabled network, or unconfirmed policy make the result ineligible for successful delivery. Explicit full access verifies the matching `danger-full-access` sandbox and `dangerFullAccess` policy without claiming confinement.
304
+ The Codex plugin checks the requested model, working directory, approval policy, and sandbox mode before a turn. Its public `thread-ready` checkpoint exposes the full effective policy; Flywheel checks it before durably acknowledging permission to continue toward dispatch. In role-based mode, workspace-write permits the workspace and standard Codex temporary directories; extra external write roots, enabled network, or unconfirmed policy are rejected before the new turn. The terminal receipt is checked again. Explicit full access verifies the matching `danger-full-access` sandbox and `dangerFullAccess` policy without claiming confinement.
197
305
 
198
- **The complete policy check happens after execution. It cannot prevent access already allowed by custom Codex configuration.** An environment requiring a full policy rejection before any turn needs an upstream public pre-turn guard. Kimi's current CLI integration also provides no OS-level sandbox guarantee; a configured permission requirement should not be read as proof of its enforcement.
306
+ Claude's native initialization follows prompt submission, so its adapter does not claim a pre-dispatch `thread-ready` guarantee. Claude requires explicitly configured full access; native approval modes cannot stand in for an OS sandbox. Kimi's current CLI integration also provides no OS-level sandbox guarantee. Adapter capabilities and actual lifecycle evidence must be evaluated separately.
199
307
 
200
308
  The `codex-pro-receipt` metric preserves the complete machine receipt, including requested and actual configuration, thread/turn IDs, process outcomes, cleanup, usage, and failures. An accepted effort request is not proof of effective server reasoning effort; `effectiveEffort` remains null.
201
309
 
@@ -221,13 +329,15 @@ flywheel doctor --cwd /absolute/path/to/repo --task-dir /absolute/path/to/repo/d
221
329
  flywheel doctor --cwd /absolute/path/to/repo --task-dir /absolute/path/to/repo/docs/my-feature --probe --json
222
330
  ```
223
331
 
224
- Without a task, doctor checks all configured bindings. With a task, it validates the Spec/packets and requires Plan, Review, Judge, enabled second opinions, and routes used by the packets; other bindings can be skipped. With no packets yet, it checks the default execution route and reports that preparation must finish. A real run still needs at least one reviewed legal packet.
332
+ Without a task, doctor checks all configured bindings. With a task, it validates the Spec/packets and uses the engine's policy resolver: fresh tasks follow the Spec, existing tasks retain their saved policy, and legacy state remains Full. Full requires Plan, Review, Judge, enabled second opinions, and the used execution routes. Qualified Quick requires Review and the actual routes, marking Plan/Judge/second opinion skipped. Malformed workflow state blocks SDK probes without mutating or reclassifying the task. With no packets yet, it checks the default route and reports incomplete preparation. A real run still needs at least one valid packet for an authorized scope.
333
+
334
+ Doctor does not accept the runtime `--mode` override; it reports the Spec/saved state. An explicit launch override is resolved and persisted by the engine when starting. Configuration inspection lists bindings without claiming every configured stage will be called.
225
335
 
226
336
  Local checks cover commands, versions, directories, configuration, and declared nonempty environment variables, without showing their values. `--probe` additionally initializes DSH SDK sessions, verifies accepted configuration, working directory, permissions, and normal shutdown. Identical probes are deduplicated only when their relevant identity and permissions match. The probe budget is 40 seconds plus bounded process cleanup time.
227
337
 
228
338
  DSH's `ready.reasoningEffort` echoes the requested value after SDK configuration acceptance; it is not an independent server attestation of effective reasoning effort. A no-inference probe cannot demonstrate quality gains from a higher effort. GPT, Kimi, and Flash also have different native effort enums; see [Reasoning effort](model-policy.md).
229
339
 
230
- Codex Pro checks actually import the public API and verify exact version 0.8.0/protocol 1, Node compatibility, and the Codex executable. `--probe` does not send a task through this path: account/model/effort and full runtime policy remain unverified. A successful import is not a successful model call.
340
+ Codex Pro checks actually import the public API and verify exact version 0.9.0/protocol 1, typed lifecycle/recovery exports, Node compatibility, and the Codex executable. Binding fields `durableJournal`, `readOnlyRecovery`, and `threadReadyBeforeDispatch` describe pinned adapter capabilities; Claude's last field is false. `historyRecoveryTested` remains false. `--probe` sends no model task and does not turn a successful import into evidence of account access, effective permissions, or recovery of a particular saved history.
231
341
 
232
342
  | Status | Meaning |
233
343
  |---|---|
@@ -237,6 +347,8 @@ Codex Pro checks actually import the public API and verify exact version 0.8.0/p
237
347
  | `unknown` | Not verified, such as entitlement, quota, or real inference |
238
348
  | `skipped` | Not required, mock mode, duplicate probe, or an unmet prerequisite |
239
349
 
350
+ `sessions.policy` confirms only the configured mode and version. Each applicable real binding's `.session` check reports selection, reason, and adapter support, while history recovery remains unknown. Doctor does not restore user histories, send a test turn, or treat a successful worker import as proof of durability.
351
+
240
352
  No probe sends an inference prompt, runs L1/L2/L3, creates a worktree, or writes Flywheel task state. SDK initialization may contact a provider's catalog and write its own cache/session files; read-only here is scoped to Flywheel state and configuration. Recheck in the desktop panel because its PATH/profile/environment may differ from the terminal.
241
353
 
242
354
  Repository references: [inline defaults](https://github.com/ckanner/flywheel/blob/main/templates/flywheel.config.example.json), [complete profiles](https://github.com/ckanner/flywheel/blob/main/templates/flywheel.profiles.example.json), [design](https://github.com/ckanner/flywheel/blob/main/docs/design.md), and [worker protocol](https://github.com/ckanner/flywheel/blob/main/plugins/dsh/PROTOCOL.md).
@@ -2,16 +2,24 @@
2
2
 
3
3
  [English README](../../README.en.md) · [中文](../getting-started.md) · [Workflow](workflow.md) · [Configuration](configuration.md)
4
4
 
5
- This guide covers **Flywheel 0.28.4**: npm installation, the DSH desktop and workers, configuration, preflight, a small task, and recovery. The checked desktop interfaces are **DSH Mac 0.2.1-rc.5 and 0.2.2-rc.1**, both declared from Flywheel 0.28.4. DSH 0.2.2 itself requires Node 24.9 or later; use its official desktop-supplied CLI. Real desktop UI, macOS permissions, authentication, and model inference still need testing on the intended machine.
5
+ This guide covers **Flywheel 0.28.5**: npm installation, the DSH desktop and workers, configuration, preflight, a small task, and recovery. The checked desktop interfaces are **DSH Mac 0.2.1-rc.5 and 0.2.2-rc.1**, both declared from Flywheel 0.28.4. DSH 0.2.2 itself requires Node 24.9 or later; use its official desktop-supplied CLI. Real desktop UI, macOS permissions, authentication, and model inference still need testing on the intended machine.
6
6
 
7
7
  Before installing, check `npm view @ckanner/flywheel version`. Continue with these instructions once the registry has the version you intend to use. A merged source change or GitHub Release does not establish npm publication, and an older installed release may not include these interfaces.
8
8
 
9
+ **Adaptive workflow in current source:** `/flywheel-task`, `control launch`, Auto/Quick/Full, and automatic DSH task association require a CLI, plugin, and skills containing this implementation. Check `flywheel control launch --help`; the earlier 0.28.5 version label alone does not establish that these additions are installed.
10
+
9
11
  The top-level **Flywheel conversation view** below is available from `0.28.1`. Version `0.28.0` uses the composer popup; upgrade the CLI and desktop plugin to the same new version. Merging source or reloading the old version does not change that layout. CLI and task-directory interfaces remain the same.
10
12
 
11
13
  Subscription preset migration and `permissions.mode` are available from **0.28.2**. Upgrades preserve existing configuration; preview `flywheel config migrate --preset subscriptions`, review the model bindings and full-access policy, then explicitly apply it with `--apply` and a backup.
12
14
 
15
+ **Ordering from 0.28.5:** the external Flywheel conversation view follows the built-in Statistics view. DSH still owns view selection and overflow navigation.
16
+
13
17
  **Fixes in 0.28.3:** the `deepseek-account` default and the current session directory when the project path is omitted. Version 0.28.2 still uses `deepseek-official` and the original directory. Check the registry version before installing. Upgrades preserve configuration; adopting the account preset requires explicit migration.
14
18
 
19
+ **Optional Claude backend:** the default installation does not require Claude. Selecting `claude-code-pro` requires the companion 0.4.0 plugin in the worker's dependency tree and an installed/authenticated Claude CLI. See [Claude Code Pro](claude-code-pro.md) for configuration and source-candidate boundaries.
20
+
21
+ The reviewed Codex Pro 0.9.0 source package is bundled with this Flywheel candidate; installation does not assume an unpublished registry version exists. See [provenance](../../plugins/dsh/vendor/README.md), [recovery](session-recovery.md), and [paired evaluation](session-evaluation.md).
22
+
15
23
  ## 1. Prepare the environment
16
24
 
17
25
  | Requirement | Why it is needed |
@@ -26,7 +34,7 @@ Subscription preset migration and `permissions.mode` are available from **0.28.2
26
34
 
27
35
  Check command locations and versions with `git --version`, `node --version`, `npm --version`, `command -v dsh`, `dsh --version`, `kimi --version`, and `codex --version`. Check the desktop version in About as well. Use the respective tools' documented installation and login flows.
28
36
 
29
- The defaults reuse the Kimi subscription, ChatGPT subscription, and existing signed-in, funded DeepSeek account. DeepSeek API access is an explicitly configured alternative. Flywheel does not log in, copy credentials, or replace the desktop application. A task using only the default execution route can skip the hard route at runtime, but it still needs its configured Plan, Execute, Review, and Judge backends.
37
+ The defaults reuse the Kimi subscription, ChatGPT subscription, and existing signed-in, funded DeepSeek account. DeepSeek API access is an explicitly configured alternative. Flywheel does not log in, copy credentials, or replace the desktop application. Full needs its configured Plan, Execute, Review, and Judge backends. A qualified Quick task needs its actual execution route and independent Review; Plan and Judge are recorded as inapplicable. Unused execution routes do not become runtime requirements.
30
38
 
31
39
  ## 2. Install
32
40
 
@@ -36,7 +44,7 @@ From a terminal that can find the desktop's `dsh` command:
36
44
  npx -y @ckanner/flywheel@latest install
37
45
  ```
38
46
 
39
- For an agent consuming a single JSON result, use the same command with `--json`. The installer installs its exact version globally, resolves the platform binary and workers, installs the ten bundled skills, creates global configuration only if absent, records a GUI launcher, registers the matching DSH plugin, and runs local diagnostics.
47
+ For an agent consuming a single JSON result, use the same command with `--json`. The installer installs its exact version globally, resolves the platform binary and workers, installs that version's bundled skills (eleven in current source), creates global configuration only if absent, records a GUI launcher, registers the matching DSH plugin, and runs local diagnostics.
40
48
 
41
49
  `ok:true` means the installation steps completed. `ready:true` means that local doctor found no blocker. For example, missing Kimi can produce `ok:true, ready:false` with the reason in `diagnostic.checks`. Neither result proves real authentication or inference. A failed step retains its partial results so the actual cause can be corrected before retrying.
42
50
 
@@ -81,7 +89,7 @@ dsh plugin --profile desktop add --save-exact --ignore-scripts @ckanner/dsh-plug
81
89
 
82
90
  This is the command shape used internally, not a placeholder to paste literally. An independent npm DSH CLI cannot manage the reserved `desktop` profile. Reload according to the host's instructions and select **Flywheel** in the native view bar alongside Chat and Trajectory. Check that bar's More menu if the entry is not directly visible.
83
91
 
84
- This view controls and observes an already prepared task: progress, intervention, effective models, environment checks, and explicit start/refresh/stop. DSH keeps its chat, trajectory, composer, model selector, and right sidebar. Discuss requirements and prepare contracts through the original chat and skills. The view does not discover tasks started elsewhere; select the same task directory to observe one.
92
+ This view controls and observes an already prepared task: progress, intervention, effective models, environment checks, and explicit start/refresh/stop. DSH keeps its chat, trajectory, composer, model selector, and right sidebar. Discuss requirements and prepare contracts through the original chat and skills. A launch or start through the DSH tools associates the exact task with that conversation. The view does not scan for tasks started elsewhere; select the same task directory to observe one.
85
93
 
86
94
  The worker defaults to a separate **`sdk` profile**. The standard SDK layers on `base`, which already includes DeepSeek's account and API adapters. Current source explicitly selects `provider: "deepseek-account"` and `model: "deepseek-flash"` to reuse the signed-in, funded account. `deepseek-official` is only for an explicitly chosen API-key configuration; there is no automatic paid-channel fallback.
87
95
 
@@ -95,7 +103,7 @@ That is a checked compatibility version, not a claim about the latest adapter. F
95
103
 
96
104
  The SDK worker's temporary permission and tool policy applies only to its child process. It does not edit the desktop profile or remove desktop capabilities. Worker-owned delegation, auxiliary model compaction, and currently the entire web tool are disabled. A native view does not make the worker inherit desktop plugins or merge its history. See the [plugin's lifecycle boundaries](https://github.com/ckanner/flywheel/blob/main/plugins/dsh/README.en.md#permissions-and-lifecycle-boundaries) for the capability limits and separate work needed to restore retrieval safely.
97
105
 
98
- The hard route uses the installed `dsh-subagent-codex-pro@0.8.0` dependency's public machine API directly. It does not use `subagent_codex_pro` as a native LLM provider or require a parent model to delegate. Its underlying Codex app-server still needs the local Codex command and login.
106
+ The hard route uses the installed `dsh-subagent-codex-pro@0.9.0` dependency's public machine API directly. It does not use `subagent_codex_pro` as a native LLM provider or require a parent model to delegate. Its underlying Codex app-server still needs the local Codex command and login.
99
107
 
100
108
  ### Desktop launcher
101
109
 
@@ -115,19 +123,19 @@ flywheel template flywheel.config.example.json
115
123
  flywheel template flywheel.profiles.example.json
116
124
  ```
117
125
 
118
- Use either complete template as a starting point and review it before writing a configuration file. The [configuration guide](configuration.md) covers safe export, fields, profile overrides, channel identity, and migration to `codex-pro`. `loops.plan` controls engine planning; the host's selected conversation model controls initial `flywheel-new` preparation.
126
+ Use either complete template as a starting point and review it before writing a configuration file. The [configuration guide](configuration.md) covers safe export, fields, profile overrides, channel identity, and migration to `codex-pro`. `loops.plan` controls Full engine planning; the host's selected conversation model controls initial preparation through `flywheel-task` or `flywheel-new`.
119
127
 
120
- The installer includes ten skills. Skills are optional host entry points; the desktop panel and CLI also work independently. To inspect or install them for an existing project:
128
+ Current source includes eleven skills. Skills are optional host entry points; the desktop panel and CLI also work independently. To inspect or install them for an existing project:
121
129
 
122
130
  ```sh
123
131
  flywheel skills list
124
- flywheel skills read flywheel-run
132
+ flywheel skills read flywheel-task
125
133
  flywheel install-skills --project /absolute/path/to/repo --json
126
134
  ```
127
135
 
128
136
  Follow the host's skill-discovery rules. Copying files does not prove the host loaded them. Installer-owned unchanged snapshots can update; modified files, unowned directories, and invalid manifests are preserved and reported as conflicts.
129
137
 
130
- In DSH Chat, use `/flywheel-new`, `/flywheel-run`, and `/flywheel-status`, or select them from the `/` menu. Kimi instead uses `/skill:flywheel-new` and corresponding prefixed names. Preparation, start, and status can all happen in the conversation: **no initial Flywheel-view form is required.** The view is an alternative way to open an already prepared task. See the [copyable workflow](workflow.md#3-prepare-and-review-the-contracts).
138
+ In DSH Chat, use `/flywheel-task <goal>` for research, preparation, and validated launch; Auto is the default. Use `/flywheel-new` for a proposal without launching, `/flywheel-run` for an existing task, and `/flywheel-status` for its state. Kimi uses `/skill:flywheel-task` and corresponding prefixed names. **No initial Flywheel-view form is required.** The view is an alternative way to open an already prepared task. See the [copyable workflow](workflow.md#0-normal-entry-describe-a-goal-and-launch).
131
139
 
132
140
  ## 5. Run preflight without inference
133
141
 
@@ -150,7 +158,9 @@ After contracts exist, narrow the checks to the selected task:
150
158
  flywheel doctor --cwd "$PWD" --task-dir "$PWD/docs/my-feature" --probe --json
151
159
  ```
152
160
 
153
- A task without packets can be inspected during preparation, but a real start still needs at least one reviewed legal packet. Fix schema, directory, provider, or permission failures at their source.
161
+ Task preflight uses a fresh Spec's qualification or the saved workflow policy. For qualified Quick it skips Plan, Judge, and the Judge panel; legacy tasks remain Full. It does not consume a later launch/run `--mode` override. A malformed saved policy blocks probes rather than being silently reclassified. Configuration inspection still lists all configured bindings.
162
+
163
+ A task without packets can be inspected during preparation, but a real launch still needs at least one legal packet within the authorized scope. Fix schema, directory, provider, or permission failures at their source.
154
164
 
155
165
  The view's optional configuration and troubleshooting section offers “Inspect model configuration,” “Check installation and configuration,” and “Check DSH integration.” Use these for setup, configuration changes, or troubleshooting; they are not buttons that must be pressed for every task. Neither diagnostic performs model inference.
156
166
 
@@ -158,16 +168,18 @@ The view's optional configuration and troubleshooting section offers “Inspect
158
168
 
159
169
  ### Existing repository
160
170
 
161
- Create or deliberately reuse a task integration branch and independent worktree **before** running `flywheel-new`. Prepare contracts and launch the engine from that same root, using a task path inside it. The [workflow guide](workflow.md) gives the branch commands, model recommendations, draft-PR timing, and exact working directory for each loop.
171
+ The normal DSH entry is `/flywheel-task` followed by the actual requirement. The assistant researches the repository, creates or deliberately reuses a task integration branch and independent worktree, prepares compact contracts and real verification evidence, then launches within the existing authorization. Auto chooses Quick only when the contracts qualify; uncertain or complex tasks use Full. The [workflow guide](workflow.md) gives the branch commands, model bindings, delivery boundaries, and working directory for each stage.
162
172
 
163
- The normal DSH entry is `/flywheel-new` followed by the actual requirement. The assistant creates or reuses the task worktree, prepares `docs/<slug>/spec.md` and task packets, and reports two actual absolute paths: the **project directory** is the code worktree; the **task files directory** is its `docs/<slug>` holding this task's contracts and later state/reports. You do not need to invent an empty directory or fill in the UI first. Review the contracts, then reuse the supplied task path.
173
+ Use `/flywheel-new` when you want to review a proposal before execution. Both preparation entries report two actual absolute paths: the **project directory** is the code worktree; the **task files directory** is its `docs/<slug>` holding this task's contracts and later state/reports. You do not need to invent an empty directory or fill in the UI first. Keep both paths for observation and recovery.
164
174
 
165
- Use the bundled templates to prepare a real Spec and packets with actual acceptance commands, protected oracles, and recorded dry-run results. Commit the reviewed contracts before starting so packet worktrees can read them from Git. Do not create `state.json` manually.
175
+ Use the bundled templates to prepare a real Spec and packets with actual acceptance commands, protected oracles, and recorded dry-run results. Persist authorized contracts before starting so packet worktrees can read them from Git. Preparation and loop scheduling are separate: skills never write `state.json` or orchestrate stage retries themselves.
166
176
 
167
177
  ### Disposable first-run example
168
178
 
169
179
  For a first installation check, the packaged scaffold creates a separate Go addition task. The initial implementation is intentionally wrong; the executor must fix it and add ordinary tests without changing the frozen acceptance test. This example needs Go 1.27 or later and an unused destination directory.
170
180
 
181
+ The scaffold intentionally has no `workflow` assessment and therefore follows legacy Full behavior. To try Quick, ask `flywheel-task` to inspect and qualify an actual small task; changing a mode flag alone does not supply the missing evidence.
182
+
171
183
  ```sh
172
184
  FLYWHEEL_PACKAGE="$(npm root --global)/@ckanner/flywheel"
173
185
  bash "$FLYWHEEL_PACKAGE/docs/examples/create-first-task.sh" "$HOME/flywheel-demo"
@@ -211,11 +223,11 @@ flywheel control status --cwd "$PWD" --task-dir "$PWD/docs/add"
211
223
 
212
224
  In DSH Chat, the equivalent entries are `/flywheel-run <absolute-task-path>` and `/flywheel-status <same-path>`, with `/flywheel-stop <same-path>` when stopping is needed. Replace the placeholders with the real path returned during preparation. These skills resolve the project root without requiring an initial view selection.
213
225
 
214
- To use the top **Flywheel** view instead, enter that same `task_dir` in “Task files directory.” Leave “Project directory” blank only when the DSH session's current working directory is already the task's `repo_dir`; otherwise enter the project path supplied by the assistant. A shell `cd` alone does not change the DSH session directory, and skill calls do not automatically select the view's task. Expand configuration and troubleshooting when needed, then use start, refresh, or stop. A control response's `ok` means the operation succeeded; task completion is determined by `state.status`. The view displays the last refresh time and does not poll automatically.
226
+ Launch/start through `flywheel_launch` or `flywheel_control` associates the exact task with the current DSH conversation. The top **Flywheel** view then requests fresh status once. For a task started from a terminal, enter that same `task_dir` in “Task files directory.” Leave “Project directory” blank only when the DSH session's current working directory is already the task's `repo_dir`; otherwise enter the project path supplied by the assistant. A shell `cd` alone does not change the DSH session directory. Expand configuration and troubleshooting when needed. A control response's `ok` means the operation succeeded; task completion is determined by `state.status`. The view displays the last refresh time and does not poll automatically.
215
227
 
216
- Draft paths and fetched snapshots are retained separately for each session across view switches while the host retains that session binding; a plugin reload or desktop restart may require selecting the paths again. Path edits discard old results and reject late replies without stopping the old task. Only one control request is pending per session, and a start or stop locks directory inputs while waiting.
228
+ Explicit task association is reconstructed from the host's public session projection and retained command/tool records across reload; a fork does not inherit the parent task. Manually entered draft paths and fetched snapshots are separate view caches with a shorter lifetime. Path edits discard old results and reject late replies without stopping the old task. Only one control request is pending per session, and launch/start/stop locks directory inputs while waiting. Opening the view never starts a task or scans directories.
217
229
 
218
- After a start/stop timeout or disconnect, the background task's outcome may be unconfirmed. Keep the same task directory, refresh status, and inspect logs before deciding how to recover. The view disables further starts/stops until that task is successfully reconciled and never retries mutations automatically. A prior snapshot, closing a page, or switching sessions cannot prove the engine stopped. The native trajectory retains its parent-session records; full worker histories are not merged into it.
230
+ After a launch/start/stop timeout or disconnect, the background task's outcome may be unconfirmed. Keep the original task and project paths, refresh that task's status, and inspect logs before deciding how to recover. The view disables further mutations until that task is successfully reconciled and never retries them automatically. A prior snapshot, closing a page, or switching sessions cannot prove the engine stopped. The native trajectory retains its parent-session records; full worker histories are not merged into it.
219
231
 
220
232
  If the host explicitly confirms rejection before the control process started, such as a missing directory, correct the path or environment and submit again. This requires structured host evidence; error-message text alone cannot establish that a lost request was never executed.
221
233
 
@@ -225,7 +237,7 @@ For a foreground run that pauses before Review, use this instead of background s
225
237
  flywheel run docs/add --pause-before review
226
238
  ```
227
239
 
228
- `control start` does not accept `--pause-before`, and pause mode cannot be combined with `--only`. `--only execute` runs the bounded execution/L1 loop; it is not a single model call. `--only review` returns a review result without continuing into Plan or local merge. `--only verify` runs deterministic acceptance without Review/Judge or worktree creation.
240
+ `control launch` and `control start` do not accept `--pause-before`, and pause mode cannot be combined with `--only`. `--only execute` runs the bounded execution/L1 loop; it is neither Quick nor a single model call. For Quick, `--only review` uses the task-final review contract and saves any required one-way Full upgrade without continuing into Plan or local merge; `--only verify` includes applicable candidate L2/L3, even with a selected packet. Running Plan on Quick requires an explicit `--mode full` upgrade. See the individual skills for partial-loop recovery.
229
241
 
230
242
  Inspect progress:
231
243
 
@@ -14,7 +14,7 @@ High provides an initial comparison baseline without starting every loop at maxi
14
14
 
15
15
  | Current path | Checked capability | Flywheel request |
16
16
  |---|---|---|
17
- | GPT-6.1 Sol / Codex Pro 0.8.0 | Model supports `low/medium/high/xhigh/max`; machine API forwards effort | hard: high |
17
+ | GPT-6.1 Sol / Codex Pro 0.9.0 | Model supports `low/medium/high/xhigh/max`; machine API forwards effort | hard: high |
18
18
  | Sol and Astra / DSH ChatGPT provider | Models and checked provider catalog support `low/medium/high/xhigh/max`; serialized as `reasoning.effort` | Review and Judge: high |
19
19
  | Kimi K3.1 Pro / Kimi CLI | Native `low/high/max`, default high; thinking cannot be disabled | Plan, frontend, Garden: high |
20
20
  | DeepSeek Flash / DSH rc.5 | DSH accepts `off/low/high/max`, default high | ordinary execution: high; Intake: low |
@@ -48,7 +48,7 @@ For an actual comparison, hold the model, backend, context, task, and acceptance
48
48
 
49
49
  Source and offline protocol tests establish field transmission and error behavior. SDK configuration acceptance or a successful machine-API request establishes acceptance at that interface. Independent effective-effort evidence and improved delivery quality require server evidence or actual task measurements.
50
50
 
51
- DSH `initialize` validates configuration but returns only serverInfo. Flywheel's `ready.reasoningEffort` echoes the request after initialization; it is not independent model-server attestation. Codex Pro separates `requestedEffort`, `accepted`, and unknown `effectiveEffort:null`. See the [DSH SDK server](https://github.com/deepseek-ai/deepseek-harness/blob/b830ec950faba0a46dda564be3e2d854afed94f1/packages/sdk/server/src/server.ts) and [Codex Pro 0.8.0 protocol](https://github.com/ckanner/dsh-subagent-codex-pro/blob/04ecdb677735d84f3a0f5dba01a9d9b28c324c0e/docs/machine.md). A no-inference doctor cannot establish account balance, real inference, or higher-effort benefits.
51
+ DSH `initialize` validates configuration but returns only serverInfo. Flywheel's `ready.reasoningEffort` echoes the request after initialization; it is not independent model-server attestation. Codex Pro separates `requestedEffort`, `accepted`, and unknown `effectiveEffort:null`. See the [DSH SDK server](https://github.com/deepseek-ai/deepseek-harness/blob/b830ec950faba0a46dda564be3e2d854afed94f1/packages/sdk/server/src/server.ts) and [Codex Pro 0.9.0 protocol](https://github.com/ckanner/dsh-subagent-codex-pro/blob/37da3d75de32b809c4fb1a631ccc15191f3d87f9/docs/machine.md). A no-inference doctor cannot establish account balance, real inference, or higher-effort benefits.
52
52
 
53
53
  ## The funded DeepSeek account is the intended default
54
54
 
@@ -57,3 +57,7 @@ Current source selects `deepseek-account` for Flash in defaults and the subscrip
57
57
  Desktop login can initialize an account-model default, but independent SDK calls still need explicit provider/model values. Flywheel requests `deepseek-account` and `deepseek-flash`, preserving both the selected access method and the Flash-only choice. Authentication or quota failures are reported. The default preset has no cross-channel fallback; explicit user-defined fallback chains retain their existing policy.
58
58
 
59
59
  **Release and migration are separate:** 0.28.3 changes the embedded default to account access; 0.28.2 still embeds the API default. Upgrades preserve user configuration, so adoption requires 0.28.3 or later followed by explicit migration. See [Configuration](configuration.md#deepseek-account-and-api-key-providers) for credential-sharing conditions and the preview/apply workflow. No user credentials or running tasks were modified by this source change.
60
+
61
+ ## Optional Claude Code Pro
62
+
63
+ Claude remains unassigned in the default model policy. The optional `claude-code-pro` harness accepts an explicit native model and low/medium/high/xhigh/max request; an installed CLI or account can reject a choice. No new model ranking or effort benchmark is implied. See [the adapter guide](claude-code-pro.md) for the companion 0.4.0 public API, full-access boundary, and usage semantics.
@@ -0,0 +1,120 @@
1
+ # Session quality policy and paired evaluation
2
+
3
+ P4 provides two executable capabilities: bounded rebuilding based on confirmed facts, and paired experiments using three history policies on the same tasks. Rebuild thresholds default to disabled. The evaluator preserves original conditions and results, keeps missing usage unknown, and assumes no quality, cache, or speed benefit.
4
+
5
+ See [configuration](configuration.md) for the policy and [recovery](session-recovery.md) for lifecycle and ledger semantics. Implementation entry points are the [quality policy](../../internal/machine/session_quality.go), [evaluator](../../scripts/evaluate-sessions.js), and [corpus preparer](../../scripts/prepare-session-evaluation.js).
6
+
7
+ ## Bounded rebuilding
8
+
9
+ `sessions.roles` accepts `fresh` or `scoped` for `plan`, `execute`, `review`, `judge`, and `judge-panel`. Unspecified roles inherit `sessions.mode`. Plan's explicit `resident-session:false` still prevents history reuse; explicit `sessions.roles.plan:"fresh"` also disables the legacy Kimi Plan continuation path.
10
+
11
+ All `sessions.quality` thresholds default to `0`, meaning disabled. Existing default behavior is unchanged.
12
+
13
+ | Setting | Trigger | What it establishes |
14
+ |---|---|---|
15
+ | `max-confirmed-turns` | Confirmed, safely attributed turns in the current generation reach the threshold | Reuse count, not demonstrated quality loss |
16
+ | `max-unproductive-turns` | Consecutive Execute completions leave the candidate fingerprint unchanged | No candidate progress on disk, not an inference about private reasoning |
17
+ | `max-run-input-tokens` | The last complete, attributable per-run input reaches the threshold | That run's measured input, not native history size or remaining context capacity |
18
+
19
+ These thresholds permit rebuilding only after the previous invocation is consumed and its accounting state persisted, dispatch and outcome are known, cleanup is confirmed, and the candidate is identifiable. Unknown dispatch/outcome, unfinished lifecycle checkpoints, and unconfirmed cleanup first use P3 reconciliation or the existing escalation path. Partial/unknown usage cannot trigger the input threshold; confirmed-turn and unchanged-candidate thresholds remain independently usable. Usage uncertainty is preserved, and the existing hard budget can separately block another invocation. Consuming an invocation again cannot increment its counters again.
20
+
21
+ Rebuilding records the reason, generation, and replaced invocation reference. The handoff uses the current Spec, packet, disk candidate, valid reports, verification evidence, and structured feedback. It does not transfer Executor private history to Reviewer. The new generation resets its quality counters while task attempts, failures, elapsed work, and budget accounting remain. This policy uses verifiable rebuilding, without an extra unmetered model call to compress history.
22
+
23
+ ## Three fixed policies
24
+
25
+ Experiments hold the Git commit, contracts, models, effort, permissions, acceptance, and quality thresholds constant. Only Execute and Review history policies differ.
26
+
27
+ | Report variant | Execute | Review | Plan / Judge / judge-panel |
28
+ |---|---|---|---|
29
+ | `fresh` | Fresh each time | Fresh each time | Explicitly fresh |
30
+ | `executor-scoped` | Scoped to the same packet | Fresh each time | Explicitly fresh |
31
+ | `role-scoped` | Scoped to the same packet | Scoped to the Reviewer's own review scope | Explicitly fresh |
32
+
33
+ `role-scoped` implements the design's separate Executor and Reviewer histories; it does not share one thread across roles. Each case has at least two paired repetitions, each containing all three policies. Order rotates by case and repetition. Every trial uses a new isolated Git clone. The original repository is unchanged, and one trial's candidate or history is not given to another trial.
34
+
35
+ ## Prepare an executable corpus
36
+
37
+ Prepare a complete Flywheel configuration with explicit `routes.default`, `loops.review`, and their channels. Use a backend and account configuration that can already execute tasks. The preparer reads this file without running a model or reading/copying account credentials.
38
+
39
+ ```sh
40
+ node scripts/prepare-session-evaluation.js \
41
+ --config /absolute/path/flywheel.config.json \
42
+ --output /absolute/path/new-session-corpus \
43
+ --repetitions 2
44
+ ```
45
+
46
+ The preparer creates a new local Git repository, exact commit, and `manifest.json`. It disables additional worktree creation equally for every trial because the evaluator already isolates each clone, and protects the frozen `eval/` checks. It does not overwrite the supplied configuration file.
47
+
48
+ The generated configuration-change case uses `medium` / `high`. The selected model must accept both. For a backend with different effort values, edit the manifest's `configure` step before running to use another explicitly supported value. All three policies use that same edited manifest; no trial guesses or substitutes its own value.
49
+
50
+ The built-in task is an independently testable code change: implement pure `compactRanges`, converting safe integer arrays into sorted maximal inclusive intervals, removing duplicates, handling negatives and empty input, and preserving the caller's array. Frozen L1 checks output. Final Review independently checks input preservation. A separate pinned oracle checks both. The model's done-report does not supply the evaluation score.
51
+
52
+ | Scenario | Experiment | Required observation |
53
+ |---|---|---|
54
+ | `first-pass` | Run normally from an unimplemented function | Completed task with one Execute and one Review |
55
+ | `l1-repair` | After the first execution, a fixed injector breaks output; real L1 rejects it and the engine repairs it | Failed L1 evidence and more than one Execute |
56
+ | `review-return` | Inject an in-place input sort that preserves all output checks; L1 passes and Review should return it | Review return evidence and more than one Execute |
57
+ | `long-context` | Put stable reference material in the actual Execute prompt's `cache-scope` | Measured per-run input reaches the manifest threshold; absent usage is unknown |
58
+ | `stop-resume` | Pause normally before Review, then explicitly run again | Saved paused state followed by continuation; this is a stage-boundary pause |
59
+ | `configuration-change` | Change the same binding's thinking after the first Execute, then execute again | A different effective binding fingerprint is observed |
60
+
61
+ Controlled injectors modify candidate code only. The evaluator verifies that Go state, contracts, and configuration remain unchanged across injection. It does not fabricate L1, Review, receipts, metrics, or state. The stage-boundary pause complements the separate P3 tests for active-turn termination, ACK failure windows, and read-only recovery.
62
+
63
+ Effective configuration lives outside the trial candidate and is selected with `FLYWHEEL_CONFIG`. Before the engine establishes its BaseRef, the evaluator removes overriding root/task configuration files in the disposable clone and commits this setup. Configuration changes therefore do not impersonate model edits to protected contracts. The source configuration and before/after bindings remain recorded.
64
+
65
+ ## Run real backend evaluation
66
+
67
+ Build the current Go CLI and verify that the selected public adapter, native CLI, and account can execute tasks, then run:
68
+
69
+ ```sh
70
+ node scripts/evaluate-sessions.js \
71
+ --manifest /absolute/path/new-session-corpus/manifest.json \
72
+ --flywheel /absolute/path/flywheel \
73
+ --output /absolute/path/new-session-results \
74
+ --live
75
+ ```
76
+
77
+ `execution:"live"` requires `--live` and rejects mock driver bindings. The evaluator uses the supplied models and permissions without automatically choosing another model, channel, or broader permission mode. The output directory must not exist; saved experiments are never overwritten.
78
+
79
+ Every invocation retains the engine's normal budget, stopping, and recovery rules. The manifest's `maxCalls` is an additional observed-call limit: every 50 ms, the runner checks persisted metrics and requests cancellation when the threshold is reached. In-flight calls and delayed metric writes can exceed it; it is not a transactional reservation before model dispatch. `runTimeoutMs` bounds each step, with up to 30 seconds allowed for cancellation cleanup. Forced termination, unknown dispatch/outcome, or unconfirmed cleanup stops the entire experiment and preserves available evidence without replay.
80
+
81
+ ## Interpret the report
82
+
83
+ `report.json` records source commit/tree, manifest/configuration/engine/oracle SHA-256 hashes, timestamps, trial conditions, order, policy, step outcomes, and paired comparisons. Each trial also retains stdout/stderr, state snapshots, and original metrics. The independent oracle is copied from the fixed source commit outside the candidate and checked by hash before and after execution. Candidate tampering with that oracle stops the experiment.
84
+
85
+ | Field | Meaning and limits |
86
+ |---|---|
87
+ | `quality.pass`, `omissions`, `regressions` | Independent oracle results; unfinished checks remain null. Engine completion is separate from quality. |
88
+ | `repairRounds` | Total packet attempts beyond the first, from actual Go state |
89
+ | `repeatedFindings` | Exactly repeated Review return reasons after whitespace normalization, not semantic equivalence |
90
+ | `elapsedMs` | Engine run time; excludes clone, oracle, and injection overhead |
91
+ | `usage.*.known` | Known complete per-run input/output/cacheRead/cacheWrite/totalTokens totals |
92
+ | `observedCalls` / `missingCalls` | Calls with and without each metric; known totals are lower bounds when anything is missing |
93
+ | `cost.knownUSD` | Known monetary cost, with missing costs counted separately; subscription billing is not assumed zero |
94
+ | `actions`, `rebuildReasons` | Actual create/resume/rebuild counts and attributable reasons |
95
+ | `recovery` | Resumes, failed or unknown resumes, unknown outcomes, unresolved invocations, and reconciliation count |
96
+ | `scenarioCoverage` | Planned, observed, unobserved, and unknown separately; a scenario label alone is not evidence |
97
+
98
+ P3 `record-kind:"reconciliation"` rows replace the original invocation's later-known facts using `reconciles-invocation`. They are audit corrections, not new model calls, and do not add the same usage or cost twice. Original audit rows remain preserved.
99
+
100
+ Deltas require all three paired policies, matching fixed conditions, and equal observed role/harness/provider/channel/model sets. Missing usage makes that metric's delta null. The report does not automatically produce savings percentages. Establish quality and actual scenario coverage before interpreting performance changes.
101
+
102
+ ## Separate offline gates from live evidence
103
+
104
+ The repository provides three distinct evidence paths:
105
+
106
+ 1. `node --test npm/test/session-evaluation.test.js` tests manifest validation, isolation, unknown usage, pairing, and stopping through an explicitly labeled runner protocol fixture.
107
+ 2. The command below runs the real Go CLI → worker 3 → actual public Codex 0.9 package → native CLI fixture for 36 trials. The fixture implements native protocol and controlled code work, never Go state/metrics/receipts. The real engine evaluates L1, Review, Git boundaries, and history decisions.
108
+ 3. `--live` performs actual backend inference and supplies model quality, cache, time, and cost evidence.
109
+
110
+ ```sh
111
+ FLYWHEEL_EVAL_BINARY=/absolute/path/freshly-built-flywheel \
112
+ FLYWHEEL_EVAL_OUTPUT=/absolute/path/new-native-evaluation \
113
+ node scripts/test-session-evaluation.js
114
+ ```
115
+
116
+ From the repository root, `npm run test:sessions` invokes the same gate with the same environment variables.
117
+
118
+ The second path requires built `plugins/dsh/dist` files and the installed exact public Codex package. Missing binaries or dependencies fail rather than skip. It freezes worker and public package bytes in a separate directory. The native fixture requires an explicitly marked experimental CODEX_HOME and corpus, without actual account access. Its usage is synthetic protocol evidence, not measured model savings.
119
+
120
+ Passing offline gates does not establish real-account or macOS lifecycle acceptance. If a live environment rejects permissions or times out during thread/start, retain that blocker as evidence. Keep default thresholds disabled until paired real results justify a specific change.