@ckanner/flywheel 0.31.0 → 0.32.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (153) hide show
  1. package/CHANGELOG.md +122 -5
  2. package/CONTRIBUTING.md +19 -0
  3. package/LICENSE +21 -0
  4. package/README.en.md +4 -171
  5. package/README.md +152 -269
  6. package/README.zh-CN.md +116 -0
  7. package/bin/flywheel-claude-code-pro-worker.js +1 -1
  8. package/bin/flywheel-codex-pro-worker.js +1 -1
  9. package/bin/flywheel-dsh-worker.js +1 -1
  10. package/bin/flywheel.js +1 -1
  11. package/bin/runtime.js +1 -1
  12. package/docs/README.md +86 -0
  13. package/docs/README.zh-CN.md +64 -0
  14. package/docs/archive/README.md +13 -0
  15. package/docs/archive/codex-pro-adapter-handoff.md +197 -0
  16. package/docs/archive/design-v0.24.md +540 -0
  17. package/docs/design.md +812 -0
  18. package/docs/en/claude-code-pro.md +25 -16
  19. package/docs/en/configuration.md +405 -145
  20. package/docs/en/contributing.md +303 -0
  21. package/docs/en/flow-console.md +142 -24
  22. package/docs/en/getting-started.md +232 -126
  23. package/docs/en/investigation.md +263 -0
  24. package/docs/en/jev-shadow.md +5 -0
  25. package/docs/en/jev.md +240 -0
  26. package/docs/en/model-policy.md +154 -62
  27. package/docs/en/releasing.md +207 -0
  28. package/docs/en/session-evaluation.md +4 -2
  29. package/docs/en/session-recovery.md +88 -6
  30. package/docs/en/workflow.md +241 -114
  31. package/docs/evaluation/README.md +12 -0
  32. package/docs/evaluation/jev-historical-provisional.json +138 -0
  33. package/docs/evaluation/jev-historical-result-2026-11-10.json +174 -0
  34. package/docs/plans/2026-11-01-dsh-integration.md +67 -0
  35. package/docs/plans/2026-11-01-model-profiles-preflight.md +29 -0
  36. package/docs/plans/2026-11-01-npm-installation.md +19 -0
  37. package/docs/plans/2026-11-03-codex-pro-default.md +28 -0
  38. package/docs/plans/2026-11-06-adaptive-workflow.md +365 -0
  39. package/docs/plans/2026-11-07-session-lifecycle.en.md +424 -0
  40. package/docs/plans/2026-11-07-session-lifecycle.md +337 -0
  41. package/docs/plans/2026-11-08-flow-console.md +271 -0
  42. package/docs/plans/2026-11-10-jev-shadow.md +32 -0
  43. package/docs/plans/2026-11-10-task-discovery.md +17 -0
  44. package/docs/plans/2026-11-10-workbench-redesign.md +19 -0
  45. package/docs/plans/2026-11-12-feedback-driven-workflows.md +739 -0
  46. package/docs/plans/2026-11-12-unified-jev-decisions.md +89 -0
  47. package/docs/plans/2026-11-13-jev-execution-decisions.md +110 -0
  48. package/docs/plans/2026-11-13-p5-ready-queue-prewarm.md +178 -0
  49. package/docs/plans/README.md +25 -0
  50. package/docs/reviews/2026-08-24-v0.18-review-fixplan.md +265 -0
  51. package/docs/reviews/2026-09-12-pr4-pr5-review.md +70 -0
  52. package/docs/reviews/README.md +12 -0
  53. package/docs/validation/2026-11-01-npm-installation.md +105 -0
  54. package/docs/validation/2026-11-01-profiles-preflight.md +67 -0
  55. package/docs/validation/2026-11-01-results.md +114 -0
  56. package/docs/validation/2026-11-03-codex-pro-default.md +90 -0
  57. package/docs/validation/2026-11-04-dsh-native-view.md +85 -0
  58. package/docs/validation/2026-11-04-release-0.28.1.md +33 -0
  59. package/docs/validation/2026-11-04-release-0.28.2.md +35 -0
  60. package/docs/validation/2026-11-05-dsh-0.2.2-compatibility.md +26 -0
  61. package/docs/validation/2026-11-05-registry-smoke-recovery.md +26 -0
  62. package/docs/validation/2026-11-05-release-0.28.3.md +32 -0
  63. package/docs/validation/2026-11-05-subscription-model-access.md +60 -0
  64. package/docs/validation/2026-11-05-view-order.md +14 -0
  65. package/docs/validation/2026-11-07-adaptive-workflow.md +79 -0
  66. package/docs/validation/2026-11-07-claude-code-pro.md +144 -0
  67. package/docs/validation/2026-11-07-session-lifecycle.md +136 -0
  68. package/docs/validation/2026-11-08-session-p3-p4.md +99 -0
  69. package/docs/validation/2026-11-09-flow-console.md +81 -0
  70. package/docs/validation/2026-11-10-jev-shadow.md +50 -0
  71. package/docs/validation/2026-11-10-task-discovery.md +45 -0
  72. package/docs/validation/2026-11-10-workbench-redesign.md +54 -0
  73. package/docs/validation/2026-11-11-release-0.30.2.md +65 -0
  74. package/docs/validation/2026-11-11-release-0.31.0.md +46 -0
  75. package/docs/validation/2026-11-12-dsh-0.2.2-rc.2.md +58 -0
  76. package/docs/validation/2026-11-12-feedback-driven-workflows.md +187 -0
  77. package/docs/validation/2026-11-12-release-0.31.1.md +58 -0
  78. package/docs/validation/2026-11-12-session-console-ux.md +46 -0
  79. package/docs/validation/2026-11-12-unified-jev-decisions.md +93 -0
  80. package/docs/validation/2026-11-13-dsh-settings-controls.md +104 -0
  81. package/docs/validation/2026-11-13-jev-execution-decisions.md +140 -0
  82. package/docs/validation/2026-11-13-p5-ready-queue-prewarm.md +138 -0
  83. package/docs/validation/2026-11-13-p5-review-closure.md +114 -0
  84. package/docs/validation/2026-11-13-p5-tracked-runtime-fixes.md +108 -0
  85. package/docs/validation/2026-11-13-prewarm-receipts-and-expiry-tests.md +92 -0
  86. package/docs/validation/2026-11-13-workspace-redesign.md +66 -0
  87. package/docs/validation/README.md +51 -0
  88. package/docs/validation/evidence/2026-11-08-session-p3-p4.json +5430 -0
  89. package/docs/validation/evidence/2026-11-13-p5-npm-candidate.json +54 -0
  90. package/docs/validation/evidence/claude-node-bridges.txt +118 -0
  91. package/docs/validation/evidence/claude-npm-build.txt +15 -0
  92. package/docs/validation/evidence/claude-npm-candidate.json +54 -0
  93. package/docs/validation/evidence/claude-npm-install.txt +21 -0
  94. package/docs/validation/evidence/claude-npm-tests.txt +145 -0
  95. package/docs/validation/evidence/claude-plugin-tests.txt +205 -0
  96. package/docs/validation/evidence/claude-quality-gate.txt +29 -0
  97. package/docs/validation/evidence/claude-race.txt +7 -0
  98. package/docs/validation/evidence/codex-pro-070-probes.txt +4 -0
  99. package/docs/validation/evidence/dsh-bridge.txt +4 -0
  100. package/docs/validation/evidence/dsh-native-view-bridge-tests.txt +1 -0
  101. package/docs/validation/evidence/dsh-native-view-build.txt +15 -0
  102. package/docs/validation/evidence/dsh-native-view-candidate.json +54 -0
  103. package/docs/validation/evidence/dsh-native-view-inspect.txt +27 -0
  104. package/docs/validation/evidence/dsh-native-view-install-tests.txt +19 -0
  105. package/docs/validation/evidence/dsh-native-view-npm-tests.txt +143 -0
  106. package/docs/validation/evidence/dsh-native-view-plugin-tests.txt +99 -0
  107. package/docs/validation/evidence/dsh-native-view-quality-gate.txt +29 -0
  108. package/docs/validation/evidence/dsh-plugin-tests.txt +48 -0
  109. package/docs/validation/evidence/function-coverage.txt +378 -0
  110. package/docs/validation/evidence/npm-build.txt +13 -0
  111. package/docs/validation/evidence/npm-contract-tests.txt +65 -0
  112. package/docs/validation/evidence/npm-dsh-bridge.txt +18 -0
  113. package/docs/validation/evidence/npm-dsh-plugin-tests.txt +62 -0
  114. package/docs/validation/evidence/npm-function-coverage.txt +420 -0
  115. package/docs/validation/evidence/npm-install-tests.txt +20 -0
  116. package/docs/validation/evidence/npm-quality-gate.txt +29 -0
  117. package/docs/validation/evidence/npm-race.txt +7 -0
  118. package/docs/validation/evidence/pr-dsh-bridge.txt +4 -0
  119. package/docs/validation/evidence/pr-dsh-plugin-tests.txt +48 -0
  120. package/docs/validation/evidence/pr-function-coverage.txt +379 -0
  121. package/docs/validation/evidence/pr-quality-gate.txt +28 -0
  122. package/docs/validation/evidence/pr-race.txt +6 -0
  123. package/docs/validation/evidence/profiles-control-smoke.json +1 -0
  124. package/docs/validation/evidence/profiles-dsh-bridge.txt +18 -0
  125. package/docs/validation/evidence/profiles-dsh-plugin-tests.txt +59 -0
  126. package/docs/validation/evidence/profiles-function-coverage.txt +411 -0
  127. package/docs/validation/evidence/profiles-quality-gate.txt +29 -0
  128. package/docs/validation/evidence/profiles-race.txt +7 -0
  129. package/docs/validation/evidence/quality-gate.txt +28 -0
  130. package/docs/validation/evidence/race.txt +6 -0
  131. package/docs/validation/evidence/watchdog-startup-after.txt +2 -0
  132. package/docs/validation/evidence/watchdog-startup-before.txt +6 -0
  133. package/docs/validation/evidence/watchdog-startup-quality-gate.txt +29 -0
  134. package/docs/validation/evidence/watchdog-startup-race.txt +7 -0
  135. package/docs/{claude-code-pro.md → zh-CN/claude-code-pro.md} +23 -17
  136. package/docs/{configuration.md → zh-CN/configuration.md} +397 -142
  137. package/docs/zh-CN/contributing.md +240 -0
  138. package/docs/zh-CN/flow-console.md +216 -0
  139. package/docs/zh-CN/getting-started.md +352 -0
  140. package/docs/zh-CN/investigation.md +213 -0
  141. package/docs/zh-CN/jev-shadow.md +5 -0
  142. package/docs/zh-CN/jev.md +192 -0
  143. package/docs/zh-CN/model-policy.md +128 -0
  144. package/docs/zh-CN/releasing.md +120 -0
  145. package/docs/{session-evaluation.md → zh-CN/session-evaluation.md} +4 -2
  146. package/docs/{session-recovery.md → zh-CN/session-recovery.md} +75 -12
  147. package/docs/zh-CN/workflow.md +284 -0
  148. package/npm/install.js +1 -1
  149. package/package.json +12 -25
  150. package/docs/flow-console.md +0 -122
  151. package/docs/getting-started.md +0 -418
  152. package/docs/model-policy.md +0 -65
  153. package/docs/workflow.md +0 -314
@@ -1,8 +1,20 @@
1
- # Model profiles, stage bindings, and diagnostics
1
+ # Configuration
2
2
 
3
- [English README](../../README.en.md) · [中文](../configuration.md) · [Workflow](workflow.md)
3
+ [Documentation](../README.md) · English · [简体中文](../zh-CN/configuration.md)
4
4
 
5
- Flywheel loads one complete configuration, expands its model profiles, and resolves each stage's binding before starting. Model selection is explicit configuration. Restart the engine after changing it. This guide follows the current source; existing user configuration is not automatically migrated during installation. The account-provider correction below is separate from the published 0.28.2 release.
5
+ Flywheel loads one complete configuration, expands model profiles, and resolves
6
+ stage bindings before starting. Model allocation, workflow selection, permissions,
7
+ scheduling, and session history are separate policies. Restart the engine after
8
+ changing configuration; installation preserves existing files.
9
+
10
+ Use `config inspect` to find the effective file before editing. The examples below
11
+ that show selected fields are **fragments** to place in a complete configuration.
12
+
13
+ - [Configuration sources](#configuration-precedence) and [templates](#start-from-a-complete-template)
14
+ - [Model fields](#fields-and-identities) and [subscription migration](#apply-the-subscription-preset-to-existing-configuration)
15
+ - [Permissions](#full-access-without-per-action-approval) and [scheduling](#scheduling-and-worktrees)
16
+ - [Session history](#session-policy-history-reuse-and-invocation-safety) and [workflow policy](#workflow-policy-and-recovery)
17
+ - [Backend integration](#codex-pro-and-migration), [budgets](#fallback-and-budgets), and [diagnostics](#diagnose-without-inference)
6
18
 
7
19
  ## Configuration precedence
8
20
 
@@ -23,11 +35,111 @@ flywheel config inspect --cwd /absolute/path/to/repo --task-dir /absolute/path/t
23
35
 
24
36
  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
37
 
38
+ ### Editing configuration in the workflow console
39
+
40
+ The Global / project configuration view first reads an explicit scope and file revision. Edit model bindings, role history policies, budget, timeouts, retries or the global permission policy, then review changes and save beside the form. Concurrent edits reject replacement; reread an unconfirmed save before proceeding. New project files use the current version's complete default template. A higher-priority task file can still hide the project/global file being edited. Files do not merge.
41
+
42
+ Advanced callers send JSON on stdin to `flywheel control config-edit --cwd /absolute/repo`, with `{"scope":"project"}`. Save through `control config-save` using scope, the returned revision and values containing changed sections only. With reset=true, replacement starts from the full embedded default template. Saving creates a backup and publishes atomically; the next engine start loads the file.
43
+
44
+ ## Fields and identities
45
+
46
+ | Field | Meaning | Example |
47
+ |---|---|---|
48
+ | `harness` | Process and tool-loop backend | `dsh`, `kimi`, `codex-pro`, `claude-code-pro`; `codex` is the explicit older CLI path |
49
+ | `provider` | Registered DSH SDK LLM adapter ID; applies to DSH bindings | `deepseek-account`, `chatgpt` |
50
+ | `channel` | A configuration label used for credentials, fallback, and accounting | `deepseek-account-sdk`, `chatgpt-sdk`, `kimi-subscription` |
51
+ | `model` | Exact model identifier passed to the selected backend | `deepseek-flash`, `kimi-code/k3.1-pro`, `gpt-6.1-sol` |
52
+ | `thinking` | Requested reasoning effort | `high` |
53
+ | `profile` | Reusable model fields inside this Flywheel configuration | `flash`, `gpt-review`, `codex-pro` |
54
+
55
+ A Flywheel model profile is different from a DSH `sdk` or `desktop` profile. The latter chooses the host's plugins and authorization configuration. A channel alias alone does not switch DSH accounts or create a separate subscription or quota pool.
56
+
57
+ For DSH, the provider resolves from `binding.provider`, then `channels[channel].provider`, then the legacy channel name. Explicit binding and channel provider values must agree. Kimi and Codex use their own login state; a DSH provider cannot be attached to those harnesses and silently ignored.
58
+
59
+ Only supported effort values should be used. The checked DSH Flash adapter accepts `off/low/high/max`; it has no `medium`. A configuration value names an intended binding, not evidence of account entitlement or measured model performance.
60
+
61
+ ### DeepSeek account and API-key providers
62
+
63
+ | Access method | Provider | Credentials | Selection |
64
+ |---|---|---|---|
65
+ | Signed-in, funded DeepSeek account in DSH | `deepseek-account` | DSH's `deepseekAccount` service | Current source default; no `DEEPSEEK_API_KEY` required |
66
+ | DeepSeek API key | `deepseek-official` | DSH credentials or launch environment; default reference `DEEPSEEK_API_KEY` | An explicitly selected alternative |
67
+
68
+ The standard SDK profile layers over a [base](https://github.com/deepseek-ai/deepseek-harness/blob/b830ec950faba0a46dda564be3e2d854afed94f1/packages/bundle/base/cordis.patch.yml) that includes the account service and both adapters. The standard desktop and SDK share the [account credential store](https://github.com/deepseek-ai/deepseek-harness/blob/b830ec950faba0a46dda564be3e2d854afed94f1/packages/credentials/credentials-local/src/index.ts) when they use the same `DSH_HOME`. Profiles isolate plugin configuration; no token copy or switch to the reserved `desktop` profile is needed. Custom homes, credential stores, or SDK plugin sets must resolve the intended authorization source.
69
+
70
+ After login, the desktop can choose the first account model when no provider API key exists. That host selection neither controls an independent SDK session nor guarantees Flash is the first model. Flywheel explicitly sends `deepseek-account` and `deepseek-flash`; the default preset has no API-key fallback for sign-in failures, invalid tokens, or insufficient quota. Explicit user-defined fallback chains retain their existing policy. The checked sources are the [account adapter](https://github.com/deepseek-ai/deepseek-harness/blob/b830ec950faba0a46dda564be3e2d854afed94f1/packages/llm/llm-deepseek-account/src/index.ts), [API adapter](https://github.com/deepseek-ai/deepseek-harness/blob/b830ec950faba0a46dda564be3e2d854afed94f1/packages/llm/llm-deepseek-api-key/src/index.ts), and [host default selection](https://github.com/deepseek-ai/deepseek-harness/blob/b830ec950faba0a46dda564be3e2d854afed94f1/packages/api/session-controller/src/index.ts).
71
+
72
+ Explicit API-key configurations remain supported. Select `deepseek-official` consistently in the relevant binding and its channel, and configure credentials through DSH's API-provider flow. Renaming a channel does not override a conflicting explicit provider. Account access does not need an additional API key.
73
+
74
+ ## Start from a complete template
75
+
76
+ Inspect either bundled example:
77
+
78
+ ```sh
79
+ flywheel template flywheel.config.example.json
80
+ flywheel template flywheel.profiles.example.json
81
+ ```
82
+
83
+ The first uses inline bindings. The second is a complete configuration with reusable profiles. If you choose to create a project configuration, first confirm that no file needs preserving; then export one template from the target Git root. For example, Bash's noclobber option prevents replacing an existing regular file:
84
+
85
+ ```sh
86
+ (set -C; flywheel template flywheel.profiles.example.json > flywheel.config.json)
87
+ ```
88
+
89
+ Do not create a task file containing only a few profiles and expect it to inherit the rest from the project file. An illustrative **fragment**, to incorporate into a complete file, is:
90
+
91
+ ```json
92
+ {
93
+ "profiles": {
94
+ "flash": {
95
+ "harness": "dsh",
96
+ "provider": "deepseek-account",
97
+ "channel": "deepseek-account-sdk",
98
+ "model": "deepseek-flash",
99
+ "thinking": "high"
100
+ }
101
+ },
102
+ "routes": {
103
+ "default": { "profile": "flash" }
104
+ },
105
+ "loops": {
106
+ "intake": { "profile": "flash", "thinking": "low" }
107
+ },
108
+ "channels": {
109
+ "deepseek-account-sdk": {
110
+ "harness": "dsh",
111
+ "provider": "deepseek-account",
112
+ "env-key": null
113
+ }
114
+ }
115
+ }
116
+ ```
117
+
118
+ `loops` binds Plan, Review, Judge, Intake, and Garden. `routes` selects the Execute backend for default/frontend/hard packets. `drivers` selects real or mock drivers; it is not a provider-name mapping. The full default routing table is in the [model policy](model-policy.md).
119
+
120
+ ### Profile override and validation rules
121
+
122
+ | Input | Effect |
123
+ |---|---|
124
+ | Stage omits a profile field | Inherit that field from the referenced profile |
125
+ | Stage explicitly supplies `model`, `thinking`, `channel`, etc. | Override only that stage |
126
+ | `thinking: ""` | Use the harness's default effort instead of re-inheriting the profile |
127
+ | Plan `resident-session: false` | Explicitly disable Plan history reuse; loading, profile expansion, and effective config export preserve its presence |
128
+ | `judge-panel: null` | Disable the optional second opinion |
129
+ | Missing/empty profile `harness`, `model`, or `channel` | Configuration error |
130
+ | Unknown profile, field, stage name, or harness | Configuration error |
131
+ | A profile references another profile | Unsupported; configuration error |
132
+ | `_note` or `_note_*` | Permitted explanatory metadata, excluded from execution bindings |
133
+
134
+ `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.
135
+
136
+ 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.
137
+
26
138
  ## Apply the subscription preset to existing configuration
27
139
 
28
- The current source-level `subscriptions` preset uses ChatGPT subscriptions, Kimi Code subscriptions, and the signed-in, funded DeepSeek account in DSH, with Flash and `provider:deepseek-account`. Normal installation and upgrades preserve existing configuration, including old Z.AI/GLM routes, Kimi K3 bindings, API providers, and effort choices.
140
+ The current `subscriptions` preset uses ChatGPT subscriptions, Kimi Code subscriptions, and the signed-in, funded DeepSeek account in DSH, with Flash and `provider:deepseek-account`. Normal installation and upgrades preserve existing configuration, including old Z.AI/GLM routes, Kimi K3 bindings, API providers, and effort choices.
29
141
 
30
- **Release boundary:** migration and `permissions.mode` shipped in 0.28.2, but that published preset still selects the `deepseek-official` API-key route. The account-default correction is available from 0.28.3. Check the registry version before installing. First check that `flywheel template flywheel.config.example.json` from your binary contains `deepseek-account`; rerunning migration with the published 0.28.2 binary does not select the new account default.
142
+ Inspect the preset shipped with your installed binary using `flywheel template flywheel.config.example.json`. The current preset selects `deepseek-account`; an old binary can still contain older defaults. Release history belongs to the [changelog](../../CHANGELOG.md).
31
143
 
32
144
  From the actual project, preview and apply the selected configuration. Add `--task-dir /repo/docs/my-task` when the task has its own configuration:
33
145
 
@@ -39,7 +151,7 @@ flywheel config inspect --cwd /repo --json
39
151
 
40
152
  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
153
 
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.
154
+ 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 an older 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
155
 
44
156
  Do not edit the target file while migrating. The lock coordinates Flywheel migration processes; the source is checked again before a complete file is atomically replaced. This is not an atomic compare-and-set against arbitrary external editors. Reports distinguish proposed configuration (`configurationStatus: proposed`), re-read effective configuration (`effective`), and an unconfirmed post-write result (`unconfirmed`). A failed backup or write must not present the proposed models as already effective.
45
157
 
@@ -51,21 +163,163 @@ Migration does not sign in or invoke models. Running tasks retain their startup
51
163
  {"permissions":{"mode":"full-access"}}
52
164
  ```
53
165
 
54
- New installation templates and the explicit subscription migration select this mode for every stage. DSH/Codex request `danger-full-access` and `approval=never`; Codex Pro maps through its public machine API; Kimi print retains native auto behavior. This grants worker access within the current operating-system user's permissions. It is independent of the desktop conversation's permission dropdown.
166
+ New installation templates and the explicit subscription migration set this global mode. Explicit per-binding overrides still take precedence. DSH/Codex request `danger-full-access` and `approval=never`; Codex Pro maps through its public machine API; Kimi print retains native auto behavior. This grants worker access within the current operating-system user's permissions. It is independent of the desktop conversation's permission dropdown.
55
167
 
56
168
  Existing files without this setting retain `role-based`: Plan/Execute request workspace-write, and Review/Judge request read-only. Neither policy waits for interactive approval. In restricted modes, `never` can reject an action; it does not itself grant full access. Invalid policy names and types fail before execution.
57
169
 
58
170
  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
171
 
172
+ ### Per-binding permission overrides
173
+
174
+ `permissions.bindings` overrides the global policy for `loops.<role>`,
175
+ `routes.<route>`, or `judge-panel`. Values are `read-only`, `workspace-write`, or
176
+ `danger-full-access`; omitted bindings retain the global policy. For example:
177
+
178
+ ```json
179
+ {
180
+ "permissions": {
181
+ "mode": "full-access",
182
+ "bindings": {"loops.review": "read-only"}
183
+ }
184
+ }
185
+ ```
186
+
187
+ The [permission schema](https://github.com/ckanner/flywheel/blob/main/templates/permission-policy.schema.json) defines the
188
+ accepted fields. Each backend must support the selected policy. Claude Code Pro
189
+ requires full access; native approval settings do not provide an OS read-only sandbox.
190
+ Changing effective permissions also changes session-reuse eligibility.
191
+
192
+ ## Scheduling and worktrees
193
+
194
+ The embedded installation default selects parallel scheduling with a maximum of two packets.
195
+ An existing complete file without `scheduler` normalizes to **serial**, and an
196
+ explicit serial choice remains unchanged. Installing a new release does not replace
197
+ that file. The [scheduler schema](https://github.com/ckanner/flywheel/blob/main/templates/scheduler-policy.schema.json)
198
+ bounds total and per-channel concurrency from 1 to 8.
199
+ Both new and existing configurations default to `dispatch: "batch"` and
200
+ `prewarm: false`. These settings do not change the Quick/Full workflow or enable JEV.
201
+
202
+ ```json
203
+ {
204
+ "scheduler": {
205
+ "mode": "parallel",
206
+ "max-parallel": 2,
207
+ "providers": {"deepseek-account": 1},
208
+ "dispatch": "batch",
209
+ "prewarm": false
210
+ },
211
+ "worktree": {"enabled": true}
212
+ }
213
+ ```
214
+
215
+ Despite the field name, `providers` keys are the **actual configuration channel
216
+ names**, not DSH provider IDs. The inline template uses `deepseek-account`; if your
217
+ binding uses `deepseek-account-sdk`, use that channel name instead.
218
+
219
+ Parallel eligibility comes from a packet's frozen declaration:
220
+
221
+ ```yaml
222
+ schedule:
223
+ after: [M01-T01]
224
+ writes: [src/search/, tests/search/]
225
+ ```
226
+
227
+ Dependencies must name earlier known packets. Write scopes are normalized relative
228
+ paths or directory prefixes, without globs or escapes. Only ready packets with
229
+ nonoverlapping scopes qualify; missing declarations, conflicting scopes, and
230
+ live-credential units remain serial. Hard budgets admit one model call at a time
231
+ until its accounting is durable. Review, integration, and final gates remain serial.
232
+
233
+ `worktree.enabled` defaults to true and controls automatic packet directory
234
+ management, independently of scheduling. Parallel automatic management requires
235
+ isolated worktrees and fails if creation fails. The legacy serial path can record
236
+ an in-place fallback. With automatic management off, executors can share the task
237
+ checkout or register a qualifying external worktree before implementation. Shared
238
+ batches verify the complete combined candidate after workers finish and deliver
239
+ only when every member passes; external worktrees are retained.
240
+
241
+ Project workspace identity and execution location are recorded separately. Native
242
+ backends that cannot separate a `workspace-write` sandbox root reject unsupported
243
+ split-directory requests before dispatch, without expanding permissions. See the
244
+ [console guide](flow-console.md#parallel-execution) for registration and batch rules.
245
+
246
+ ### Ready queues and runtime preparation
247
+
248
+ `scheduler.dispatch` accepts `batch` or `ready-queue`. Batch dispatch waits for the
249
+ current bounded group before selecting more work. Ready queues admit the next
250
+ already independent packet when an Execute/L1 slot becomes free. They apply to
251
+ Full with parallel scheduling, a maximum above one, and automatic Worktree
252
+ management. Quick, serial scheduling, a maximum of one, and automatic management
253
+ off retain their existing path. Shared-checkout execution retains its batch rules,
254
+ including when executors may register external Worktrees later.
255
+
256
+ The first ready-queue window must have every Worktree prepared and saved before
257
+ dispatch. Later packets prepare their directory before taking a freed slot. A
258
+ preparation failure stops admission and cancels and awaits started workers; queued
259
+ packets that have not been admitted create no directory or model invocation.
260
+ Dependencies become ready only after delivery. Review, replanning and integration
261
+ wait for all admitted workers to settle, and every combined candidate is rechecked.
262
+ Existing total/channel limits, hard budgets, attempts and unknown-result recovery
263
+ remain in force.
264
+
265
+ A replacement packet does not recover or cancel a sibling's still-running model
266
+ call. The coordinator retains those calls and their shared accounting. An unknown
267
+ result or failed receipt persistence stops new admission immediately and must be
268
+ reconciled before resuming.
269
+
270
+ `--pause-before review` also applies to independent parallel Worktrees. Once all
271
+ Execute/L1 work in the current group passes and its workers settle, the task pauses
272
+ before any Review or integration, retaining the verified candidates. Batch mode
273
+ finishes its admitted group; ready-queue mode may refill the fixed independent
274
+ queue before reaching that boundary. Resuming the same task reuses valid execution
275
+ evidence instead of repeating Execute. A candidate changed by later integration
276
+ still requires validation again.
277
+
278
+ `scheduler.prewarm: true` allows a serial packet to initialize one DSH Review
279
+ runtime while its post-Execute deterministic checks run. Initialization sends no
280
+ model prompt or Session request. Review inference still waits for its checks and
281
+ normal admission. Parallel Execute/L1 lanes do not prepare runtimes: after their
282
+ barrier, preparation can begin only in the serial Review path. Shared-candidate
283
+ batches do not prewarm. The main overlap opportunity is therefore a serial
284
+ Execute's L1 and applicable Quick checks, not every parallel lane's validation.
285
+
286
+ Unused or incompatible runtimes must finish bounded cleanup before further model
287
+ work. If an unused runtime reaches its 60-second lifetime before a formal start
288
+ is attempted, one cold invocation may use the same persisted request identity and
289
+ remaining time allowance. This requires an exact, durable no-dispatch receipt,
290
+ confirmed SDK and process-group cleanup, and no cancellation or expired invocation
291
+ deadline. It does not grant another attempt or reset a budget. Unknown cleanup
292
+ remains blocking. Other harnesses start normally. Session history reuse is separate
293
+ from runtime preparation and retains role isolation.
294
+
295
+ Confirmed initialization failures preserve their reported error classification and
296
+ the normal retry/fallback rules. An authentication or invalid-request failure does
297
+ not become a transport retry or qualify as a harmless prepared-runtime expiration.
298
+
299
+ In Settings → Execution, dispatch is a Batch/Ready queue selector and prewarm is
300
+ an independent switch. The form shows unmet Ready queue configuration conditions
301
+ without resetting the selected value; task eligibility is checked by the engine.
302
+ Both options also remain available in advanced JSON. Saving
303
+ applies to the next start; the current process retains its loaded policy. A resumed
304
+ run still reconciles existing invocations and shared batches before new dispatch.
305
+ An outstanding prepared worker also requires its original no-prompt cleanup
306
+ receipt, synchronized file and directory, and confirmed worker/process-group exit,
307
+ even after `prewarm` is disabled; see
308
+ [prewarm recovery](session-recovery.md#dsh-runtime-preparation-after-a-restart).
309
+ Both optimizations remain optional while live latency, resource use and adoption
310
+ defaults are evaluated separately. Offline checks establish behavior and recovery,
311
+ not a guaranteed speed or token improvement. See the
312
+ [P5 implementation plan](../plans/2026-11-13-p5-ready-queue-prewarm.md) (Chinese).
313
+
60
314
  ## Session policy, history reuse, and invocation safety
61
315
 
62
316
  ```json
63
317
  {"sessions":{"mode":"scoped","policy-version":1}}
64
318
  ```
65
319
 
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.
320
+ 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](https://github.com/ckanner/flywheel/blob/main/templates/session-policy.schema.json) is the field contract.
67
321
 
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.
322
+ `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 role session policy.
69
323
 
70
324
  | Role | History scope and responsibility |
71
325
  |---|---|
@@ -123,6 +377,104 @@ A quality rebuild requires the previous result to be consumed, accounted, and kn
123
377
 
124
378
  `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
379
 
380
+ ### Verified incremental executor context
381
+
382
+ `sessions.context` is optional: omission or `"full"` retains the complete prompt;
383
+ `"verified-incremental"` enables an Execute-only optimization. First calls and
384
+ rebuilds receive full authority. Later same-role resumes may omit the stable
385
+ contract only after Go rechecks the consumed terminal receipt, exact session
386
+ binding, prompt version, contract and all context/cache file content digests.
387
+ References must be readable regular files within the current execution directory,
388
+ bounded to 1 MiB per file. The update includes feedback, current/prior candidate
389
+ identities, attempt and authoritative references.
390
+
391
+ Missing or revised references, contract changes, absent legacy checkpoints and
392
+ invalid context receipts select full input. A changed model, effort, permission
393
+ or explicit session mode rebuilds history. Plan, Review and Judge keep full
394
+ inputs; Review always examines the complete current candidate and requirements.
395
+ `state.sessions.records[*].context` records mode, identity and reason. This is
396
+ protocol behavior, not measured evidence of token savings or equal quality.
397
+
398
+ ## Bounded execution policy (opt-in)
399
+
400
+ `execution-policy` version 1 is independent of Auto/Quick/Full. Omission preserves
401
+ fixed route bindings and channel fallback behavior. Its
402
+ [schema](https://github.com/ckanner/flywheel/blob/main/templates/execution-policy.schema.json)
403
+ requires complete bindings and an explicit allowed set. Add this section to the
404
+ effective **complete** configuration after checking channels and permissions;
405
+ do not install the fragment as a partial override file:
406
+
407
+ ```json
408
+ {
409
+ "execution-policy": {
410
+ "version": 1,
411
+ "bindings": {
412
+ "flash-low": {
413
+ "harness": "dsh", "provider": "deepseek-account",
414
+ "channel": "deepseek-account", "model": "deepseek-flash",
415
+ "thinking": "low", "permission": "danger-full-access",
416
+ "session-mode": "scoped"
417
+ },
418
+ "flash-high": {
419
+ "harness": "dsh", "provider": "deepseek-account",
420
+ "channel": "deepseek-account", "model": "deepseek-flash",
421
+ "thinking": "high", "permission": "danger-full-access",
422
+ "session-mode": "scoped"
423
+ }
424
+ },
425
+ "routes": {
426
+ "default": {
427
+ "initial": "flash-low", "allowed": ["flash-low", "flash-high"],
428
+ "quality-order": ["flash-low", "flash-high"],
429
+ "after-stalled-attempts": 1, "max-switches": 1
430
+ }
431
+ }
432
+ }
433
+ }
434
+ ```
435
+
436
+ Each binding explicitly declares harness/provider/channel/model/thinking,
437
+ permission and session mode; non-DSH bindings use `provider:""`. Version 1 supports
438
+ the durable DSH, Kimi, Codex Pro and Claude Code Pro adapters. Every binding's
439
+ permission must equal the route's existing authorized permission, so this example
440
+ assumes it already uses `danger-full-access`. Backend admission still validates
441
+ actual model availability and public configuration/permission capabilities.
442
+
443
+ `quality-order` is a user-declared experiment order, not a model ranking. Go may
444
+ advance one entry when complete repeated L1 observations show the same candidate,
445
+ check set, recorded environment and failures. Version 1 requires
446
+ `after-stalled-attempts:1`, before the existing spin stop. AUTH, QUOTA,
447
+ transport/protocol errors and unknown observations do not trigger quality
448
+ upgrades. Original packet `max-retries` and task token budgets remain in force;
449
+ switching never resets failures, adds attempts or weakens final gates/Review.
450
+
451
+ Optional `channel-fallbacks` maps one allowed binding ID to another. Its target
452
+ must match the configured channel fallback chain, target harness and route model
453
+ mapping. A channel chain alone cannot escape the allowed set. `max-switches`
454
+ bounds both kinds of switch per packet. Go freezes the policy identity before
455
+ dispatch; `state.packets[*].execution-policy.history` records separate
456
+ `quality-upgrade` and `channel-fallback` events with full before/after bindings,
457
+ attempt and reason. Parallel packets retain independent records.
458
+
459
+ With `jev.enabled`, confirmed failures can also select a legal binding through
460
+ JEV. These switches are recorded as `jev-model-selection`, use the same
461
+ `max-switches` and cold-start rules, and do not alter channel-error handling.
462
+ The allowed bindings remain an explicit resource/permission declaration; the
463
+ JEV switch does not add a provider, account or model to that set.
464
+
465
+ `config inspect --json` exposes the complete declaration under
466
+ `execution-policy`; the ordinary bindings table remains the configured baseline.
467
+ Current choices belong to packet/session state. Doctor's existing binding probes
468
+ do not establish admission of every allowed experimental binding; actual dispatch
469
+ still requires the adapter's configuration and permission checks.
470
+
471
+ Every switch cold-starts Execute, even an effort-only change; effort remains in
472
+ the session binding. Unknown or unconsumed invocations reconcile first. Removing
473
+ or changing a frozen policy is refused on resume: restore it, or use a new task
474
+ for a changed experiment. Requested settings and available admission facts remain
475
+ in session/adapter receipts; unavailable effective effort, usage and subscription
476
+ cost stay unknown. Workflow, Review/Judge and delivery authorization are separate.
477
+
126
478
  ## Workflow policy and recovery
127
479
 
128
480
  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:
@@ -157,109 +509,11 @@ flywheel control status --task-dir /repo/docs/task --cwd /repo
157
509
 
158
510
  `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
511
 
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
-
166
- ## Fields and identities
167
-
168
- | Field | Meaning | Example |
169
- |---|---|---|
170
- | `harness` | Process and tool-loop backend | `dsh`, `kimi`, `codex-pro`, `claude-code-pro`; `codex` is the explicit older CLI path |
171
- | `provider` | Registered DSH SDK LLM adapter ID; applies to DSH bindings | `deepseek-account`, `chatgpt` |
172
- | `channel` | A configuration label used for credentials, fallback, and accounting | `deepseek-account-sdk`, `chatgpt-sdk`, `kimi-subscription` |
173
- | `model` | Exact model identifier passed to the selected backend | `deepseek-flash`, `kimi-code/k3.1-pro`, `gpt-6.1-sol` |
174
- | `thinking` | Requested reasoning effort | `high` |
175
- | `profile` | Reusable model fields inside this Flywheel configuration | `flash`, `gpt-review`, `codex-pro` |
176
-
177
- A Flywheel model profile is different from a DSH `sdk` or `desktop` profile. The latter chooses the host's plugins and authorization configuration. A channel alias alone does not switch DSH accounts or create a separate subscription or quota pool.
178
-
179
- For DSH, the provider resolves from `binding.provider`, then `channels[channel].provider`, then the legacy channel name. Explicit binding and channel provider values must agree. Kimi and Codex use their own login state; a DSH provider cannot be attached to those harnesses and silently ignored.
180
-
181
- Only supported effort values should be used. The checked DSH Flash adapter accepts `off/low/high/max`; it has no `medium`. A configuration value names an intended binding, not evidence of account entitlement or measured model performance.
182
-
183
- ### DeepSeek account and API-key providers
184
-
185
- | Access method | Provider | Credentials | Selection |
186
- |---|---|---|---|
187
- | Signed-in, funded DeepSeek account in DSH | `deepseek-account` | DSH's `deepseekAccount` service | Current source default; no `DEEPSEEK_API_KEY` required |
188
- | DeepSeek API key | `deepseek-official` | DSH credentials or launch environment; default reference `DEEPSEEK_API_KEY` | An explicitly selected alternative |
189
-
190
- The standard SDK profile layers over a [base](https://github.com/deepseek-ai/deepseek-harness/blob/b830ec950faba0a46dda564be3e2d854afed94f1/packages/bundle/base/cordis.patch.yml) that includes the account service and both adapters. The standard desktop and SDK share the [account credential store](https://github.com/deepseek-ai/deepseek-harness/blob/b830ec950faba0a46dda564be3e2d854afed94f1/packages/credentials/credentials-local/src/index.ts) when they use the same `DSH_HOME`. Profiles isolate plugin configuration; no token copy or switch to the reserved `desktop` profile is needed. Custom homes, credential stores, or SDK plugin sets must resolve the intended authorization source.
191
-
192
- After login, the desktop can choose the first account model when no provider API key exists. That host selection neither controls an independent SDK session nor guarantees Flash is the first model. Flywheel explicitly sends `deepseek-account` and `deepseek-flash`; the default preset has no API-key fallback for sign-in failures, invalid tokens, or insufficient quota. Explicit user-defined fallback chains retain their existing policy. The checked sources are the [account adapter](https://github.com/deepseek-ai/deepseek-harness/blob/b830ec950faba0a46dda564be3e2d854afed94f1/packages/llm/llm-deepseek-account/src/index.ts), [API adapter](https://github.com/deepseek-ai/deepseek-harness/blob/b830ec950faba0a46dda564be3e2d854afed94f1/packages/llm/llm-deepseek-api-key/src/index.ts), and [host default selection](https://github.com/deepseek-ai/deepseek-harness/blob/b830ec950faba0a46dda564be3e2d854afed94f1/packages/api/session-controller/src/index.ts).
193
-
194
- Explicit API-key configurations remain supported. Select `deepseek-official` consistently in the relevant binding and its channel, and configure credentials through DSH's API-provider flow. Renaming a channel does not override a conflicting explicit provider. Account access does not need an additional API key.
195
-
196
- ## Start from a complete template
197
-
198
- Inspect either bundled example:
199
-
200
- ```sh
201
- flywheel template flywheel.config.example.json
202
- flywheel template flywheel.profiles.example.json
203
- ```
204
-
205
- The first uses inline bindings. The second is a complete configuration with reusable profiles. If you choose to create a project configuration, first confirm that no file needs preserving; then export one template from the target Git root. For example, Bash's noclobber option prevents replacing an existing regular file:
206
-
207
- ```sh
208
- (set -C; flywheel template flywheel.profiles.example.json > flywheel.config.json)
209
- ```
210
-
211
- Do not create a task file containing only a few profiles and expect it to inherit the rest from the project file. An illustrative **fragment**, to incorporate into a complete file, is:
212
-
213
- ```json
214
- {
215
- "profiles": {
216
- "flash": {
217
- "harness": "dsh",
218
- "provider": "deepseek-account",
219
- "channel": "deepseek-account-sdk",
220
- "model": "deepseek-flash",
221
- "thinking": "high"
222
- }
223
- },
224
- "routes": {
225
- "default": { "profile": "flash" }
226
- },
227
- "loops": {
228
- "intake": { "profile": "flash", "thinking": "low" }
229
- },
230
- "channels": {
231
- "deepseek-account-sdk": {
232
- "harness": "dsh",
233
- "provider": "deepseek-account",
234
- "env-key": null
235
- }
236
- }
237
- }
238
- ```
239
-
240
- `loops` binds Plan, Review, Judge, Intake, and Garden. `routes` selects the Execute backend for default/frontend/hard packets. `drivers` selects real or mock drivers; it is not a provider-name mapping. The full default routing table is in the [README](../../README.en.md#default-model-routes).
241
-
242
- ### Profile override and validation rules
243
-
244
- | Input | Effect |
245
- |---|---|
246
- | Stage omits a profile field | Inherit that field from the referenced profile |
247
- | Stage explicitly supplies `model`, `thinking`, `channel`, etc. | Override only that stage |
248
- | `thinking: ""` | Use the harness's default effort instead of re-inheriting the profile |
249
- | Plan `resident-session: false` | Explicitly disable Plan history reuse; loading, profile expansion, and effective config export preserve its presence |
250
- | `judge-panel: null` | Disable the optional second opinion |
251
- | Missing/empty profile `harness`, `model`, or `channel` | Configuration error |
252
- | Unknown profile, field, stage name, or harness | Configuration error |
253
- | A profile references another profile | Unsupported; configuration error |
254
- | `_note` or `_note_*` | Permitted explanatory metadata, excluded from execution bindings |
255
-
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.
257
-
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.
512
+ 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](https://github.com/ckanner/flywheel/blob/main/templates/spec.schema.json), [state schema](https://github.com/ckanner/flywheel/blob/main/templates/state.schema.json), and [workflow guide](workflow.md).
259
513
 
260
514
  ## Codex Pro and migration
261
515
 
262
- The 0.28.0 embedded hard route uses this binding. This is a **fragment**, not a complete replacement configuration:
516
+ The embedded hard route uses this binding. This is a **fragment**, not a complete replacement configuration:
263
517
 
264
518
  ```json
265
519
  {
@@ -274,7 +528,7 @@ The 0.28.0 embedded hard route uses this binding. This is a **fragment**, not a
274
528
  }
275
529
  ```
276
530
 
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.
531
+ 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 dependency is pinned by the plugin package and lockfile; [vendor provenance](https://github.com/ckanner/flywheel/blob/main/plugins/dsh/vendor/README.md) records the reviewed source package used during lifecycle development. 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.
278
532
 
279
533
  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.
280
534
 
@@ -309,6 +563,10 @@ The `codex-pro-receipt` metric preserves the complete machine receipt, including
309
563
 
310
564
  An abnormal worker exit does not prove the plugin's separately managed processes stopped. If cleanup cannot be confirmed after startup, the engine records the evidence, escalates, and ends the run instead of automatically retrying or falling back. Before resuming, confirm the owned app-server/guardian processes have terminated. See [recovery](workflow.md#7-stop-and-recover-without-losing-evidence).
311
565
 
566
+ ## Optional Claude Code Pro
567
+
568
+ 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.
569
+
312
570
  ## Fallback and budgets
313
571
 
314
572
  Default profiles do not enable automatic paid fallback across channels. An explicitly configured `channels[channel].fallback` is a bounded chain and is used only when error classification and retry policy permit it. A fallback resolves provider and model for the newly selected channel; an omitted harness inherits the current harness.
@@ -349,38 +607,40 @@ Codex Pro checks actually import the public API and verify exact version 0.9.0/p
349
607
 
350
608
  `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
609
 
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.
353
-
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).
355
-
356
- ### Editing configuration in the workflow console
357
-
358
- The Global / project configuration view first reads an explicit scope and file revision. Edit model bindings, role history policies, budget, timeouts, retries or the global permission policy, then review section changes before saving. Concurrent edits reject replacement; reread an unconfirmed save before proceeding. New project files use the current version's complete default template. Task files override project files, which override global configuration.
359
-
360
- Advanced callers send JSON on stdin to `flywheel control config-edit --cwd /absolute/repo`, with `{"scope":"project"}`. Save through `control config-save` using scope, the returned revision and values containing changed sections only. With reset=true, replacement starts from the full embedded default template. Saving creates a backup and publishes atomically; the next engine start loads the file.
361
-
362
- ### Console permissions and scheduling
363
-
364
- `permissions.bindings` overrides the global mode by `loops.<role>`, `routes.<route>` or `judge-panel`, using read-only, workspace-write or danger-full-access. Read `permission-policy.schema.json` for the contract. Adapters must still prove the requested capability; native Claude approval modes are not advertised as an OS read-only sandbox.
365
-
366
- `scheduler` is defined by `scheduler-policy.schema.json`. The new default permits parallel execution with a limit of two; existing explicit serial settings remain unchanged. Parallel only dispatches independent units declared by frozen schedule.after/writes; max-parallel limits units and providers limits actual account channels. Hard budgets admit one model call until its accounting is durable. Missing declarations and overlapping write scopes are not independence.
367
-
368
- For example:
369
-
370
- ```json
371
- {
372
- "permissions": {
373
- "mode": "full-access",
374
- "bindings": {"loops.review":"read-only"}
375
- },
376
- "scheduler": {"mode":"parallel","max-parallel":2,"providers":{"deepseek-account":1}}
377
- }
378
- ```
379
-
380
- This is a field excerpt, not a complete configuration replacement. The console reads and validates the complete selected file. See the [console guide](flow-console.md) for run indexing, controlled session interaction, observation completeness and remote-delivery authority.
381
-
382
- ## Optional JEV shadow evaluation
383
-
384
- `jev-shadow.enabled` defaults to false, including older configurations that omit it. The global/project editor exposes the switch. Enabling only observes new tasks; failures never block workflows or change Quick/Full. See the [JEV guide](jev-shadow.md) for endpoint, version pin, key variable and timeout. This feature requires the 0.30.1 CLI/plugin.
385
-
386
- Automatic Worktree management (`worktree.enabled`, default true) is independent from scheduling. Off neither prohibits parallel dispatch nor prevents callers from creating Worktrees. Project membership and execution directories are separate; see the [console guide](flow-console.md) for directory registration. Native backends without a separate `workspace-write` sandbox root reject unsupported split-directory requests before dispatch, without expanding permissions.
610
+ 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 files and temporary probe-session persistence; 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.
611
+
612
+
613
+ ## JEV decisions
614
+
615
+ `jev.enabled` is the only JEV activation setting and defaults to false. The desktop
616
+ editor exposes one switch; enabled investigation preparations automatically freeze
617
+ an adoption policy for action selection, evidence-backed deferral and early report
618
+ handoff. Confirmed implementation failures can also select bounded repair, an
619
+ approved feedback check, replanning or an allowed execution binding. Task/New/Run
620
+ share the same engine-owned policy. Disabling stops subsequent
621
+ requests and adoption, while existing receipts and budgets are retained.
622
+
623
+ There is no independent task shadow/advisory switch. Legacy `jev-shadow` is read
624
+ only to migrate connection hints into a disabled unified configuration; editor saves
625
+ remove the old key. Explicit new `jev` wins, and configuration still selects one
626
+ complete task/project/global/embedded file without merging. Endpoint, fixed model,
627
+ credential variable, limits, data categories and recovery are documented in the
628
+ [JEV guide](jev.md).
629
+
630
+ Packets may declare up to eight optional `feedback-checks`, using the same
631
+ `cmd`/`script` and `expect` shape as an acceptance command. They are short,
632
+ approved diagnostic candidates, not replacements for `acceptance.L1/L2/L3`.
633
+ Add a concise `purpose` (up to 160 characters) explaining what each check can
634
+ distinguish. JEV receives that approved purpose, not the command. A check without
635
+ `purpose` remains executor guidance and is excluded from JEV's targeted candidates.
636
+ Keep credentials, raw logs and command text out of the purpose. JEV may also use
637
+ an eligible previously failed L1 check. Execution uses the existing
638
+ verification timeout, environment allowlist and process cleanup rules. Changing
639
+ these checks changes the contract identity and invalidates stale decisions.
640
+
641
+ ## Reference files
642
+
643
+ - [Inline defaults](https://github.com/ckanner/flywheel/blob/main/templates/flywheel.config.example.json)
644
+ - [Complete profile example](https://github.com/ckanner/flywheel/blob/main/templates/flywheel.profiles.example.json)
645
+ - [System design](../design.md), in Chinese
646
+ - [Worker protocol](https://github.com/ckanner/flywheel/blob/main/plugins/dsh/PROTOCOL.md)