返回 CodeWhale
MODES.md
根目录 / docs / MODES.md
1 # Modes and Permission Postures
2
3 > 阅读简体中文版:[zh_hans/MODES.md](zh_hans/MODES.md)
4
5 Codewhale has three related concepts:
6
7 - **TUI mode**: what kind of visible interaction you're in (Plan/Work/Operate).
8 - **Permission posture**: how aggressively the UI asks before executing tools.
9 - **Workflow**: named steps that coordinate sub-agents, with dependencies and
10 results, available in any TUI mode.
11
12 Model selection is separate. `--model auto` and `/model auto` route each turn to
13 a concrete model and thinking level; they are not TUI modes and are not part of
14 the `Tab` cycle.
15
16 Workflow runs named steps through the same sub-agent runtime; Fleet manages
17 their saved roles and model assignments. A workflow adds ordering, result
18 handoffs, gates and a progress view. The active mode and permission posture
19 still control what each step may execute.
20
21 Before assigning steps, query `agent(action="roster")` for the saved Fleet
22 models and roles. A plan child can select a listed model with `model`, or use
23 the saved `role`/`profile` assignment. An Exact Fleet fixes each member's route.
24
25 ## TUI Modes
26
27 Press `Tab` to complete composer menus or cycle through the visible modes
28 when the composer is empty: **Plan → Work → Operate → Plan**. `Tab` never sends
29 or queues composer text; use `Enter` to send or queue it.
30 Press `Shift+Tab` to cycle permission posture (Ask → Auto-Review → Full Access).
31 Press `Ctrl+T` to cycle reasoning effort.
32 Run `/mode` to open the mode picker, or switch directly with `/mode work`,
33 `/mode plan`, or `/mode operate`.
34
35 - **Plan**: design-first prompting. The stable primitive names remain familiar, but the runtime centrally refuses file mutation and shell execution. Read-only inspection and policy-allowed research, including deferred Web search/fetch, remain available.
36 - **Work** (internally `agent`): ordinary multi-step execution. The first-turn toolbox includes `read`, `write`, `edit`, `bash`, `agent`, `workflow`, and `todo_write`, plus `create_goal`, `get_goal`, and `update_goal` so goal controls are available without discovery. Goals still require an explicit user request; approval, sandbox, repository law, and managed policy decide what may execute.
37 - **Operate**: manage a goal through planned steps and verified results. Fleet configures the same sub-agents and roles that execute those steps. It has the same primitive identities and execution authority as Work. Goals are model-decided: the agent calls `create_goal` when a request is a durable objective, and `/goal` always works as the direct user control — the host never infers a goal from wording. Once a goal exists, the transcript shows `◆ goal set · Operate keeps working until it is verified · /goal to edit`. An explicit `/goal` declaration always wins, `/goal` still edits it, and an existing goal is never replaced. The parent session is the **operator**: handle small or tightly coupled tasks directly. Before multi-step delegation, state a compact plan with named steps, dependencies, bounded file scopes and a completion check — or skip the ceremony when the delegation is a single bounded child — then run it through the existing Workflow tool. Parallelize independent steps; each phase receives the previous phase's results, and a dependent step cannot start when a required result is missing. A single bounded independent task can use a direct `agent` call. Reuse a worker with followup for corrections and report completed, blocked and next steps. **Dispatch is not completion** — write-capable children must return real verification evidence. The first Operate turn of a session appends this contract once as a user-role runtime message (append-only history, never the pinned system prompt), so Plan, Work, and Operate keep one shared prompt prefix.
38
39 `Act` and `/mode act` remain compatibility aliases for Work. Saved settings
40 still normalize to the internal value `agent`.
41
42 ### Tool availability by mode
43
44 | Tool family | Plan | Work | Operate |
45 |:---|:---:|:---:|:---:|
46 | `read` and policy-allowed deferred research tools | yes | yes | yes |
47 | `write` and `edit` | visible names; execution denied | approval- and policy-gated | same as Work |
48 | `bash` | visible name; execution denied | approval- and policy-gated | same as Work; delegation is preferred when parallelism or isolation helps |
49 | `agent` | yes, subject to child-depth authority | yes, subject to child-depth authority | yes, subject to child-depth authority |
50 | Deferred native, MCP, and plugin tools | discoverable through `tool_search` when policy permits | same | same |
51 | Paid or external-service tools | follows permission posture | follows permission posture | follows permission posture |
52 | Access outside the workspace root | explicit trusted paths only | only through trusted paths or trust mode | same trusted-path/trust policy as Work; fleet profiles never widen it |
53
54 Operate changes scheduling emphasis, not authority. It neither adds a
55 mode-specific tool denial nor bypasses the active approval, sandbox, shell,
56 ask-rule, repository-law, or managed-policy boundary. Plan remains the
57 mode-specific execution boundary for shell and write-capable tools; that
58 authority difference does not require a different primitive vocabulary.
59
60 ### Operate loop (one screen)
61
62 ```text
63 User message
64 → small / chat / one-file? → parent does it (Work-equivalent tools)
65 → multi-step work? → goal → named steps + dependencies + completion checks
66 → Workflow phases → independent sub-agents in parallel
67 → collect results → check evidence → hand off to the next phase
68 → missing required result? → stop dependent work and repair the step
69 → one independent task? → one direct sub-agent
70 → parent integrates results and reports completed, blocked and next steps
71 ```
72
73 Lifecycle claims stay exact: dispatched ≠ settled ≠ verified.
74
75 `allow_shell` controls whether `bash` can execute; it does not rename the tool
76 or make mode the approval authority. Durable tasks and automation keep
77 conservative omitted-field defaults and receive shell authority only when their
78 settings explicitly grant it. Stateful terminal/background controls are
79 specialized deferred tools rather than fields on the small foreground `bash`
80 schema. Full Access changes the permission posture while hard safety and
81 repository-policy holds remain authoritative.
82
83 Action-capable modes can discover the deferred `rlm` family through
84 `tool_search`; its `open`, `eval`, `configure`, and `close` actions own persistent
85 RLM sessions. The legacy split `rlm_*` spellings remain replay-only aliases.
86 Inside an RLM Python REPL, `sub_query_batch` fans out 1-16 cheap parallel child
87 calls pinned to `deepseek-v4-flash`.
88
89 The fast `deepseek-v4-flash` / thinking-off path is called Fin in the product
90 language. Fin is a seam for routing, summaries, cheap child calls, and
91 coordination work; it does not change approval behavior.
92
93 The orchestration controls remain available without taking over the starting
94 screen: `/auto` turns on Auto-Review so the agent just works, `/goal` keeps one
95 objective across turns, and `/workflow` prepares a repeatable ordered or
96 fan-out workflow. They are directly callable and searchable through the full
97 command palette, but are not pinned to the starter slash menu, idle welcome,
98 footer, or default Hotbar. A bare `/` instead opens the small task-oriented
99 starter set; use `/help` or the command palette for the complete inventory.
100
101 `/goal <objective>` sets a session objective with an optional token budget and
102 keeps active objectives visible as Work context. The agent may also create the
103 goal itself when a direct request describes a verifiable end state that will
104 take more than one turn ("until the tests pass", "make X work end to end"); it
105 then shows one receipt line and you can `/goal pause` or `/goal clear` it. Bare
106 `/goal` shows progress (state, elapsed, continuations, and how to continue when
107 no turn is running); with no goal and no conversation yet it prints usage.
108 `/goal pause` stops goal continuation without changing the objective, `/goal
109 resume` resumes and sends the objective back into the turn, `/goal complete`
110 marks it done, `/goal blocked` marks it blocked, and `/goal clear` removes it. Goal state does not change the active TUI mode,
111 permission posture, or model route. This remains distinct from `--model auto`, which
112 only controls model and thinking selection.
113
114 Workflow builds on the same separation: a goal can ask the agent to keep
115 working, while Workflow supplies the repeatable workflow/progress surface for
116 large fanout. In the UI, a Workflow run should be shown as an overlay on the
117 main screen, not as another mode beside Plan, Work, and Operate.
118
119 App-server clients can persist a thread-scoped goal with `thread/goal/set`, read
120 it with `thread/goal/get`, and clear it with `thread/goal/clear`. That persisted
121 record carries `active`, `paused`, `blocked`, `usage_limited`, `budget_limited`,
122 or `complete` status plus token/time accounting fields for clients that need
123 thread resume semantics.
124
125 ## Mode Persistence
126
127 Choosing a mode interactively also sets the mode a fresh session starts in.
128 Tab/Shift+Tab cycling, the `Alt+A` / `Alt+P` / `Alt+Y` shortcuts, the hotbar's
129 Plan/Work/Operate actions, and `/mode` all write `default_mode` to
130 `~/.codewhale/settings.toml`, so switching to Operate survives a restart. The
131 write happens off the event loop; if it fails, the TUI says so in a warning
132 toast rather than reverting silently on the next launch.
133
134 Mode, thinking level, and the model picker share one serialized writer, so the
135 selection you made last is the one on disk — a burst of Tab presses cannot end
136 up persisting whichever write happened to finish last — and a mode write never
137 rolls back an unrelated key such as `default_model`.
138
139 Two paths deliberately do **not** rewrite the startup default: restoring a saved
140 session (which re-installs the mode that session was in) and a mode change
141 refused because a turn is in flight. The legacy `yolo` entry point installs Work
142 plus Full Access, and `agent` is what it persists — `yolo` is a permission
143 alias, never a startup mode.
144
145 Re-selecting the mode you are already in is not a no-op. After a restored
146 session the live mode and `default_mode` routinely disagree, so choosing the
147 live mode again is how you make it durable; Codewhale confirms with a
148 "saved as startup default" receipt rather than reporting "already in that mode".
149
150 While a turn is running, every change to the live route is refused — mode,
151 model, thinking level, and provider — no matter which surface you use. That
152 now includes the slash surfaces (`/mode`, `/model`, `/config <key> <value>`,
153 `/config preset`), which are reachable mid-turn. Press
154 Esc to interrupt first. The restart-only `default_mode` key is exempt, because
155 it does not touch the running turn.
156
157 Codewhale writes `settings.toml` under a lock that spans processes, and replaces
158 the file atomically, so a second Codewhale instance on the same home directory
159 cannot lose your selection or read a half-written file. At exit, queued writes
160 are flushed before the terminal is restored; anything that failed is printed on
161 the way out instead of disappearing with the alternate screen.
162
163 ## Compatibility Notes
164
165 - Older settings files with `default_mode = "normal"` still load as `agent`; saving rewrites the normalized value.
166
167 ## Escape Key Behavior
168
169 `Esc` is a cancel stack, not a mode switch.
170
171 - Close slash menus or transient UI first.
172 - Cancel the active request if a turn is running.
173 - Discard a queued draft if the composer is empty.
174 - Clear the current input if text is present.
175 - Otherwise it is a no-op.
176
177 ## Permission Posture
178
179 Permission posture controls tool approval and whether a turn may pause for a
180 missing user decision. It is one layer of the full
181 [authorization order](AUTHORIZATION_ORDER.md), not a bypass for tool admission,
182 repository law, or sandbox enforcement. Cycle it with `Shift+Tab`, or edit it
183 at runtime:
184
185 ```text
186 /config
187 # edit the approval_mode row to: suggest | auto | never
188 ```
189
190 Legacy note: `/set approval_mode ...` was retired in favor of `/config`.
191
192 - `suggest` (**Ask**, default): tool approvals may interrupt, and Codewhale asks
193 when an unresolved user choice materially changes authority, cost, scope, or
194 outcome.
195 - `auto` (**Auto-Review**): reviews tool calls automatically. Deliberate user
196 questions remain available in interactive sessions through `request_user_input`;
197 a question parks the turn until answered, canceled, or its configured timeout
198 expires. Headless `exec` withholds that tool because it has no responder.
199 Tool safety holds remain separate from user questions. Two layers decide approvals. The
200 **deterministic floor** (configured block rules plus the built-in safety
201 floor) allows proven-safe calls and hard-blocks publish-like actions and
202 destructive background/headless work; it is never model-reviewed. Fallback
203 holds — calls the deterministic engine could not prove safe — escalate to a
204 one-shot **model guardian** (v0.9.8) that returns risk, allow/deny, and a
205 rationale. The guardian sees the exact held call and deterministic
206 observations in separate JSON fields; conversation history, skill
207 instructions, attachments, and expanded model context are excluded. It does
208 not infer user intent or compute a generic user-intent score.
209 High or critical risk cannot auto-run even if the model says allow. It has no
210 tools, remembers no rules, and denies rather than truncates an oversized
211 exact call. Exactly one reviewer request is made; incomplete or malformed
212 output, timeout, cancellation, or provider failure fails closed. Headless
213 adapters use the deterministic-only tier. Repo-law
214 holds that explicitly require a person block in Auto-Review rather than
215 opening a hidden approval modal.
216
217 The LLM reviewer is closest to OpenAI Codex's experimental Auto-Review at
218 commit [`6fc6b9d6d2580d62622fc9884b5f5707f6505a5e`](https://github.com/openai/codex/tree/6fc6b9d6d2580d62622fc9884b5f5707f6505a5e).
219 Codex's [guardian entry point](https://github.com/openai/codex/blob/6fc6b9d6d2580d62622fc9884b5f5707f6505a5e/codex-rs/core/src/guardian/mod.rs)
220 reconstructs conversation context and runs a dedicated review session.
221 Codewhale deliberately adopts only the exact-action structured decision,
222 90-second deadline, and fail-closed result. It does not copy Codex's transcript
223 reconstruction, user-authorization score, reviewer tools, retries, persistent
224 review session, or denial ledger.
225
226 Kimi Code at commit
227 [`1414d4602898f406e540b23342cb18db23ff9efc`](https://github.com/MoonshotAI/kimi-code/tree/1414d4602898f406e540b23342cb18db23ff9efc)
228 also has no LLM reviewer. Its ordered
229 [permission policy](https://github.com/MoonshotAI/kimi-code/blob/1414d4602898f406e540b23342cb18db23ff9efc/packages/agent-core-v2/src/agent/permissionPolicy/permissionPolicyService.ts)
230 applies explicit deny rules and then its
231 [Auto policy](https://github.com/MoonshotAI/kimi-code/blob/1414d4602898f406e540b23342cb18db23ff9efc/packages/agent-core-v2/src/agent/permissionPolicy/policies/auto-mode-approve.ts)
232 returns `approve` directly. Codewhale uses the deterministic floor and guardian
233 described above, while keeping deliberate user questions available.
234
235 The sandbox and escalation baseline is grounded in DeepSeek Harness
236 `0.1.0-rc.5` at
237 commit [`47f943859bef60e4160492346772ded9b24f765a`](https://github.com/deepseek-ai/deepseek-harness/tree/47f943859bef60e4160492346772ded9b24f765a):
238 its [sandbox contract](https://github.com/deepseek-ai/deepseek-harness/blob/47f943859bef60e4160492346772ded9b24f765a/docs/subsystems/sandbox.md)
239 defines per-call `read-only`, `workspace-write`, and `danger-full-access`
240 boundaries and forbids silent unconfined fallback; its
241 [approval contract](https://github.com/deepseek-ai/deepseek-harness/blob/47f943859bef60e4160492346772ded9b24f765a/docs/subsystems/approval.md)
242 grants only `allowed-once` and fails closed on rejection, cancellation, or an
243 unavailable answerer; and its
244 [sandbox result contract](https://github.com/deepseek-ai/deepseek-harness/blob/47f943859bef60e4160492346772ded9b24f765a/packages/shell/bash-sandbox/README.md)
245 tells the model to retry a denied command exactly once with the narrowest wider
246 mode plus a justification. DeepSeek Harness does not add an LLM reviewer to
247 that path. Codewhale's autonomous posture adds only the single stateless
248 guardian request described above; deterministic hard blocks remain
249 non-bypassable.
250 - `bypass` (**Full Access**): ordinary tool calls do not show approval prompts,
251 while deliberate user questions remain available. Non-bypassable registered
252 holds auto-approve instead of opening a contradictory modal. Repository-law
253 and managed-policy holds fail closed as hard blocks instead of contradicting
254 Full Access with an approval modal.
255 - `never`: blocks any tool that is not considered safe/read-only; deliberate
256 user questions remain available.
257
258 The effective posture and its question discipline are projected into every
259 turn from the same runtime authority that gates tools. A mode/posture change is
260 therefore visible to the next turn. Untrusted runtime-generated input is
261 narrowed before metadata is built and cannot invent approval authority. An
262 explicit Full Access sub-agent handoff preserves the parent's standing posture
263 so ordinary child work does not begin prompting again.
264
265 ### Children (sub-agents and fleet workers)
266
267 Children inherit the session posture faithfully rather than a bare
268 auto-approve bit:
269
270 - **Auto-Review**: a worker's held call goes through the same deterministic
271 policy (proven-safe calls run; publish-like and destructive background work
272 is hard-blocked) and, for holds it cannot prove safe, the same one-shot
273 model guardian using the child's own session client. No prompt is ever
274 opened for a child; an unavailable guardian denies, fail closed.
275 - **Ask**: a call the role may delegate runs. A held call is raised as an
276 approval prompt in the parent's UI (`agent:<id>:approval:<n>`) when the
277 host is an interactive TUI; the worker waits visibly (`waiting for user`)
278 and the person's answer is routed back to it, whether the parent turn is
279 idle or itself awaiting an approval. Hosts that cannot prompt deny with the
280 reason.
281 - **Full Access**: ordinary calls run; destructive detached work still fails
282 closed, because children are background workers.
283
284 Role posture and the execution envelope are checked before and after this
285 gate and never widen. Every decision a person did not make at a prompt is
286 written to the audit log and to the child's transcript as a one-line note
287 (`Auto-Review allowed 'bash' (low risk, model guardian): …`), visible when
288 the worker is focused.
289
290 ## Small-Screen Status Behavior
291
292 When terminal height is constrained, the status area compacts first so header/chat/composer/footer remain visible:
293
294 - Loading and queued status rows are budgeted by available height.
295 - Queued previews collapse to compact summaries when full previews do not fit.
296 - `/queue` workflows remain available; compact status only affects rendering density.
297
298 ## Workspace Boundary and Trust Mode
299
300 By default, file tools are restricted to the `--workspace` directory. Enable trust mode to allow file access outside the workspace:
301
302 ```text
303 /trust on
304 ```
305
306 Bare `/trust` (like `/trust status`) only *reports* the current setting — it
307 does not enable anything. Use `/trust off` to restrict access again.
308
309 Full Access enables trust mode automatically.
310
311 ## MCP Behavior
312
313 MCP tools are exposed as `mcp_<server>_<tool>` and use the same approval flow as
314 built-in tools. Read-only MCP helpers may auto-run in Ask and Auto-Review when
315 policy permits; MCP tools with possible side effects require approval. Full
316 Access does not bypass hard policy holds.
317
318 A tool's own MCP annotations count only as far as their source is trusted. A
319 tool from a reviewed, enabled plugin that declares `readOnlyHint: true` runs
320 like the built-in read helpers, with no prompt; the same claim from any other
321 server is ignored. A tool that declares `destructiveHint: true` never gets
322 that relaxation, even from a reviewed plugin, and its approval card says the
323 server marked it destructive. Full Access still runs it without a prompt, like
324 any other tool that would ask.
325
326 See `MCP.md`.
327
328 ## Related CLI Flags
329
330 Run `codewhale --help` for the canonical list. Common flags:
331
332 - `-p, --prompt <TEXT>`: one-shot prompt mode (prints and exits)
333 - `codewhale exec --auto --output-format stream-json <PROMPT>`: run the tool-backed non-interactive agent and emit one JSON object per line for harnesses and backend wrappers. Exit codes: `0` on success, `1` for genuine task/agent failures, `75` (`EX_TEMPFAIL`) when the turn ended on a retryable infrastructure failure (provider/transport `network`/`timeout` after all in-session retries) so harnesses can tell a retryable infra exit apart from a task failure; the terminal stream `metadata` event's `error_category` carries the same classification
334 - `codewhale exec --prompt-file <PATH>` / `cat prompt.txt | codewhale exec --prompt-file -`: read the prompt from a file or stdin instead of argv, for prompts past the OS per-argument limit (~128 KiB on Linux). Conflicts with a positional prompt, and a positional `-` is literal prompt text; `--prompt-file -` is refused with `--parent-death-watch`, which owns stdin
335 - `codewhale exec --resume <ID|PREFIX> <PROMPT>` / `--session-id <ID|PREFIX>`: continue a saved session non-interactively
336 - `codewhale exec --continue <PROMPT>`: continue the most recent saved session for this workspace non-interactively
337 - `codewhale fork <ID|PREFIX>` / `codewhale fork --last`: copy a saved session into a new sibling session; forked sessions retain additive parent-session metadata and show that lineage in session listings
338 - `--model <MODEL>`: when using the `codewhale` facade, forward a DeepSeek model override to the TUI
339 - `--workspace <DIR>`: workspace root for file tools
340 - `-r, --resume <ID|PREFIX|latest>`: resume a saved session
341 - `-c, --continue`: resume the most recent session in this workspace
342 - `--max-subagents <N>`: clamp to `1..=128`
343 - `--mouse-capture` / `--no-mouse-capture`: opt in or out of internal mouse scrolling, transcript selection, right-click context actions, and transcript scrollbar dragging. Mouse capture is enabled by default on non-Windows terminals and on Windows Terminal/ConEmu/Cmder so drag selection copies only transcript text, removes visual wrap-column line breaks from paragraphs, and stays scoped to the transcript pane; hold Shift while dragging or use `--no-mouse-capture` for raw terminal selection. It defaults off on legacy Windows console (CMD without `WT_SESSION` / `ConEmuPID`) and inside JetBrains JediTerm — PyCharm/IDEA/CLion/etc. — where the terminal advertises mouse support but forwards SGR mouse events as raw text (#878, #898). Use `--mouse-capture` to opt in anywhere it's defaulted off. Raw terminal selection may cross the right workbar and include visual wraps because the terminal, not the TUI, owns the selection.
344 - `--profile <NAME>`: select config profile
345 - `--config <PATH>`: config file path
346 - `-v, --verbose`: verbose logging
347
348 ## Branching and Rollback
349
350 Codewhale has three related but intentionally separate recovery paths:
351
352 - `codewhale fork <ID>` creates a new saved session from an existing saved
353 conversation and records the source session id. This is the safe way to
354 explore a different answer path without overwriting the original session.
355 - Esc-Esc backtrack rewinds the live transcript to a previous user prompt and
356 restores that prompt into the composer for editing.
357 - `/restore` and the `revert_turn` tool restore workspace files from side-git
358 snapshots. `/restore list [N]` lists more snapshot options before choosing a
359 rollback point. They do not rewrite conversation history.
360
361 A Pi-style in-file tree browser is a larger UI/data-model project. v0.8.40
362 ships the bounded fork/backtrack primitives and explicit lineage metadata.
363
363 lines MARKDOWN