返回 DeepSeek-Reasonix
GUIDE.md
根目录 / docs / GUIDE.md
1 # Reasonix Guide
2
3 <a href="../README.md">README</a>
4 &nbsp;·&nbsp;
5 <a href="./GUIDE.zh-CN.md">简体中文</a>
6 &nbsp;·&nbsp;
7 <a href="./SPEC.md">Spec</a>
8
9 > Day-to-day configuration and usage. For the engineering contract and internals
10 > (data types, registries, package layout, roadmap), see the **[Spec](./SPEC.md)**.
11
12 ## Contents
13
14 - [Configuration](#configuration)
15 - [CLI reference](./CLI.md)
16 - [Environment variables](#environment-variables)
17 - [Serve web frontend](#serve-web-frontend)
18 - [Configuration paths](./CONFIG_PATHS.md)
19 - [Reasoning language](./REASONING_LANGUAGE.md)
20 - [Task contracts and pause policy](./TASK_CONTRACT.md)
21 - [Custom OpenAI-compatible providers](#custom-openai-compatible-providers)
22 - [Desktop hooks](#desktop-hooks)
23 - [Keyboard shortcuts](#keyboard-shortcuts)
24 - [Permissions & sandbox](#permissions--sandbox)
25 - [Capability diagnostics](#capability-diagnostics)
26 - [Plugins (MCP)](#plugins-mcp)
27 - [Slash commands](#slash-commands)
28 - [Embedded documentation retrieval](#embedded-documentation-retrieval)
29 - [@ references](#-references)
30 - [Two-model collaboration](#two-model-collaboration)
31
32 ## Configuration
33
34 Resolution order: **flag > `./reasonix.toml` > the user config file >
35 built-in defaults**. Starting with **Reasonix v1.8.1**, the user config lives at
36 `~/.reasonix/config.toml` on macOS/Linux and
37 `%AppData%\reasonix\config.toml` on Windows; see
38 [Configuration paths](./CONFIG_PATHS.md) for migration and related data paths.
39 Fields marked user/global only are not overridden by `./reasonix.toml`.
40 Provider entries name secrets with `api_key_env`, while the secret values live in
41 Reasonix's global `<Reasonix home>/.env`, shared by CLI and desktop. Project
42 `.env`, home `.env`, inherited shell environment variables, legacy credentials,
43 and the OS keyring are not provider-key runtime fallbacks; legacy credentials are
44 only migration sources. Project `.env` still feeds workspace-scoped,
45 non-provider `${VAR}` expansion for MCP/plugin settings without importing
46 provider keys or Reasonix control variables. See
47 [Configuration paths](./CONFIG_PATHS.md) for the full `config.toml` and `.env`
48 structure.
49
50 For the desktop and CLI usage of visible reasoning language, see
51 [Reasoning language](./REASONING_LANGUAGE.md).
52
53 ```toml
54 default_model = "deepseek-flash" # executor; set [agent].planner_model to add a planner
55 # language = "zh" # ui language; empty = auto-detect from $LANG / $REASONIX_LANG
56
57 [ui]
58 # shortcut_layout = "desktop" # classic|desktop; compatibility setting
59 # cursor_shape = "bar" # block|underline|bar; CLI/TUI text cursor
60 show_turn_usage = false # hide per-request token/cost receipts in the TUI; default true
61
62 [agent]
63 reasoning_language = "auto" # visible reasoning text: auto|zh|en
64 # plan_mode_read_only_commands = ["gh issue view"] # legacy compatibility only; Plan bash now uses Permissions
65 # planner_model = "deepseek-pro" # optional low-frequency planner
66 # subagent_model = "deepseek-pro" # optional default for runAs=subagent skills
67 # subagent_models = { review = "deepseek-pro", security_review = "deepseek-pro" }
68 # max_subagent_depth = 2 # nested delegation depth; set 1 for the old single-layer boundary
69 # max_subagent_concurrency = 6 # session-wide sub-agent concurrency (task/fleet/skills)
70 # max_parallel_writers = 3 # concurrent writers with non-overlapping write_paths
71 tool_result_snip_ratio = 0.6 # shorten stale tool output before summary compaction
72
73 [[providers]]
74 name = "deepseek-flash"
75 kind = "openai"
76 base_url = "https://api.deepseek.com"
77 model = "deepseek-v4-flash"
78 api_key_env = "DEEPSEEK_API_KEY"
79 # also preset: deepseek-pro
80
81 [tools]
82 enabled = [] # omit/empty = all built-ins
83 bash_timeout_seconds = 120 # foreground safety cap; set 0 for no tool-local cap
84 mcp_startup_timeout_seconds = 30 # background initialize + tools/list safety cap
85 mcp_call_timeout_seconds = 300 # default MCP call safety cap; per-plugin/tool overrides may raise it
86
87 [environment]
88 enabled = true # inject a stable startup summary of OS, shell, and common tools
89 # [environment.tools]
90 # go = "/opt/homebrew/bin/go" # optional explicit trusted path; workspace-local paths are not auto-executed
91
92 [skills]
93 # paths = ["~/my-skills", "../shared/skills"] # extra custom skill roots
94 # excluded_paths = ["~/.agents/skills"] # hide convention roots without deleting folders
95 # disabled_skills = ["review"] # hide skills until /skill enable <name>
96
97 [permissions]
98 mode = "ask" # writer fallback when no rule matches: ask|allow|deny
99 deny = ["Bash(rm -rf*)", "Bash(git push*)"] # hard-blocked in every mode
100 allow = ["Bash(go test:*)"] # never prompted
101
102 [sandbox]
103 # workspace_root = "" # file-writers confined here; empty = current dir
104 # allow_write = ["/tmp"] # extra dirs write_file/edit_file/multi_edit/move_file may touch
105 # forbid_read = ["${HOME}/.ssh"] # paths the agent must not read or list
106
107 [serve]
108 auth_mode = "none" # none|token|password; use auth before binding beyond localhost
109 # token = "" # optional fixed token; empty token mode generates one at startup
110 # password_hash = "" # bcrypt hash generated with reasonix serve --hash-password --password '...'
111 # behind_proxy = false # true only behind a trusted reverse proxy
112
113 [[plugins]]
114 name = "example"
115 command = "reasonix-plugin-example"
116 startup_timeout_seconds = 60 # optional initialize + tools/list cap
117 call_timeout_seconds = 600 # optional per-server MCP call timeout
118 tool_timeout_seconds = { "generate_video" = 1800 } # optional raw MCP tool names
119 ```
120
121 For the full schema and every field's contract, see [`SPEC.md` §5](./SPEC.md#5-configuration-toml).
122
123 Installed and project-configured MCP servers need no per-tool trust
124 list. The dedicated two-model Planner may use every non-destructive MCP tool,
125 even when the server omits `readOnlyHint`; strict read-only sub-agents still
126 require `readOnlyHint: true` and no `destructiveHint`.
127
128 `[agent].plan_mode_read_only_commands` is also retained for config round trips,
129 but the main Plan workflow no longer has a separate bash allowlist or trust
130 prompt. Bash classification and approval use the same Permissions rules in Plan
131 and Standard mode; the Sandbox remains the filesystem, process, and network
132 boundary. Dedicated planner and read-only subagent runners keep their own strict
133 read-only tool registry and foreground-command classifier.
134
135 ### Environment variables
136
137 Most day-to-day settings belong in `config.toml` or the global Reasonix `.env`
138 described above. The variables below are process-level advanced switches; set
139 them before launching Reasonix. Project `.env` files are not a runtime source for
140 Reasonix control variables.
141
142 ### CLI telemetry
143
144 The CLI can send a once-per-day anonymous active-install ping and bounded,
145 content-free event counters to `https://crash.reasonix.io`. Configure the
146 user-global policy with:
147
148 ```bash
149 reasonix config telemetry # print the effective mode
150 reasonix config telemetry auto # default: local interactive TTY only
151 reasonix config telemetry on # also allow local headless `reasonix run`
152 reasonix config telemetry off # disable and delete pending counter files
153 ```
154
155 On the first eligible release-build interactive session, Reasonix explains the
156 exact data boundary and asks once before any telemetry request. The prompt is
157 `[Y/n]`: pressing Enter, `y`, or `yes` stores `auto`; `n` or `no` stores `off`
158 and deletes pending counters. After the choice is saved, enabled reporting is
159 silent and the prompt is not shown again. If the preference cannot be saved,
160 nothing is uploaded.
161
162 Reporting is always disabled in CI, development builds, and when
163 `DO_NOT_TRACK` is set or `REASONIX_TELEMETRY=0`. Under `auto`, redirected/piped
164 or otherwise non-interactive sessions do not report. When no choice has been
165 saved yet, these ineligible sessions neither prompt nor report. Network failures
166 after consent are silent and never change stdout, stderr, or the process exit
167 code; unsent counters stay in a bounded local queue for a later invocation.
168
169 The ping contains a dedicated random 128-bit CLI install ID, CLI version, OS,
170 architecture, and the `cli` surface marker. Counter batches use that same ID for
171 daily active-install deduplication and contain only fixed buckets such as CLI
172 mode/profile, permission/session mode, turn latency, finish reason, cache-hit
173 range, generic Provider/tool error class, compaction, recovery counters, and
174 normalized UI language. This ID is separate from the desktop install ID and is
175 not an account, hardware, repository, or session identifier.
176
177 Reasonix never uploads prompts, answers, reasoning, tool names/arguments/output,
178 paths, repositories/branches, session IDs, exact token or cost values,
179 Provider/model names, base URLs, or environment variables.
180
181 ### CLI crash reports
182
183 An unhandled Go panic that reaches the CLI entrypoint is saved locally as a sanitized report under
184 `<Reasonix home>/cli-crash-reports`. Reasonix keeps at most 10 files with owner-only
185 permissions. The panic value is never serialized. Absolute source paths become
186 `<path>/<file>.go:<line>`, function arguments are removed, and the same secret,
187 token, email, and long-identifier scrubbers run both when saving and immediately
188 before sending.
189
190 Crash reports are never uploaded automatically. Review and manage them with:
191
192 ```bash
193 reasonix report # preview newest; prompt before sending on a TTY
194 reasonix report list # list local reports
195 reasonix report show [ID] # preview without sending
196 reasonix report send [ID] # explicit send; delete locally only after success
197 reasonix report delete [ID] # delete without sending
198 ```
199
200 Piped or redirected `reasonix report` calls only preview and never prompt or
201 send. The CLI telemetry setting does not auto-send or auto-delete
202 these separately reviewed reports. Runtime fatal throws, operating-system kills,
203 and panics in unwrapped background goroutines cannot be recovered by Go and do
204 not produce this local report.
205
206 ## Serve web frontend
207
208 `reasonix serve` starts the same local engine behind a browser UI. Use it when
209 you want a desktop-style surface without installing the desktop app, when running
210 Reasonix on a remote development box through a tunnel, or when you want a
211 shareable view of a live session.
212
213 ```bash
214 cd your-project
215 reasonix serve
216 # open http://127.0.0.1:8787
217 ```
218
219 By default it listens on `127.0.0.1:8787` with `auth_mode = "none"`. Keep that
220 default for local-only use. If you bind outside loopback, expose it through a
221 tunnel, or put it behind a reverse proxy, enable authentication before sharing
222 the URL:
223
224 ```bash
225 reasonix serve --auth token
226 reasonix serve --addr 0.0.0.0:8787 --auth token
227 reasonix serve --auth password --password 'temporary-password'
228 ```
229
230 Token mode prints a share URL with `?token=...`; pass `--token` or set
231 `[serve].token` to reuse a stable token. Password mode requires either
232 `--password` at startup or a stored bcrypt hash:
233
234 ```bash
235 reasonix serve --hash-password --password 'strong-password'
236
237 # <Reasonix home>/config.toml
238 [serve]
239 auth_mode = "password" # none|token|password
240 password_hash = "$2a$12$..."
241 behind_proxy = true # only behind a trusted reverse proxy
242 ```
243
244 The web UI exposes chat, tool approvals, session history, rewind/fork/summarize,
245 model and reasoning-effort controls, Goal, a live todo panel fed by the
246 `todo_write` tool, extension status/card/form/notification surfaces, and
247 provider balance when configured. Extension-hosted providers appear in the
248 model picker. Run `/reload` while idle to fail-atomically reload extension
249 sidecars and the runtime generation without restarting Serve. Use `--model`,
250 `--max-steps`, or `--resume` for one-off launches; otherwise `serve` uses the
251 user-global `default_model`.
252
253 If the selected Provider has no saved API key, a loopback-bound Serve still
254 starts and shows a Provider setup page instead of failing before the browser can
255 connect. After authentication, enter the key there; Reasonix writes it to this
256 host's global credential file with restricted permissions, rebuilds the active
257 controller in the same process, and opens the normal UI. The credential-writing
258 endpoint is disabled for non-loopback listeners. For a remote SSH window,
259 "this host" means the remote host reached through the SSH tunnel; the key is
260 not copied from the desktop machine.
261
262 ## Editor integrations over ACP
263
264 `reasonix acp` exposes Reasonix as an ACP v1 stdio agent for editors and other
265 host clients. The dedicated **[ACP editor integration](./ACP.md)** guide covers
266 startup, capability negotiation, session lifecycle, independent model/work/
267 collaboration/approval controls, client filesystem and terminal capabilities,
268 MCP servers, permission requests, and the Reasonix mid-turn steering extension.
269
270 ## Remote SSH
271
272 The remote module runs Reasonix on a remote host and reaches it over your own
273 SSH connection — VS Code Remote-SSH style. It bootstraps a persistent headless
274 `reasonix serve` on the remote host, forwards a local loopback port to it, and
275 opens the existing serve web client through that tunnel. The agent, its tools,
276 and its files all live on the remote host at full fidelity; nothing runs through
277 a lossy file proxy. V1 supports Linux and macOS remote hosts.
278
279 Hosts live in a user-global `[remote]` section of `config.toml`. Like
280 `[secrets]`, a project `reasonix.toml` cannot inject or override remote hosts —
281 a cloned repo can never steer where Reasonix opens SSH connections. Credentials
282 follow the provider idiom: the host names an env var (`passphrase_env`,
283 `password_env`) whose value lives in Reasonix's global `.env`; key material
284 itself is never stored — `identity_file` is a path.
285
286 ```toml
287 [remote]
288 [[remote.hosts]]
289 name = "gpu-box"
290 host = "203.0.113.7"
291 user = "dev"
292 identity_file = "~/.ssh/id_ed25519"
293 workspace = "~/projects/app"
294 serve_install = "auto" # Remote CLI: auto | npm | upload | never
295
296 [[remote.hosts.forwards]]
297 type = "local" # local (-L) | remote (-R)
298 bind = "127.0.0.1:5432"
299 target = "127.0.0.1:5432"
300 ```
301
302 CLI:
303
304 ```bash
305 reasonix remote add gpu-box dev@203.0.113.7 --workspace '~/projects/app'
306 reasonix remote import --all # import aliases; ssh -G resolves Include/Match rules when connecting
307 reasonix remote test gpu-box # dial + auth + host-key confirmation
308 reasonix remote connect gpu-box --open # bootstrap serve, tunnel, open the URL
309 reasonix remote serve status gpu-box
310 reasonix remote fs ls gpu-box:'~/projects/app'
311 ```
312
313 Hosts with `use_ssh_config` enabled resolve the final effective configuration
314 through the local OpenSSH `ssh -G`, including `Include`, wildcard `Host`,
315 `Match` (including `Match exec`), repeated `IdentityFile`, `ProxyJump`, and
316 `IdentitiesOnly`. Import stores the original alias instead of a stale snapshot.
317
318 `connect` is a foreground supervisor (like `ssh -N` plus the serve bootstrap):
319 it keeps the tunnel and configured forwards alive, auto-reconnects with
320 exponential backoff if the link drops, and re-attaches forwards on reconnect.
321 Ctrl-C disconnects the local side only — the remote serve keeps running, so the
322 next `connect` reuses it. There is no background daemon in V1.
323
324 Host keys are verified against your OpenSSH `~/.ssh/known_hosts` (read-only)
325 plus a Reasonix-managed `~/.reasonix/remote/known_hosts`. A first-seen key
326 prompts for trust-on-first-use and is recorded in the managed file; a key that
327 contradicts a recorded one is a hard error that names the offending line and is
328 never auto-accepted.
329
330 Remote-side state lives under the remote host's `~/.reasonix/remote/`:
331 `serve-<workspace-slug>.json` (pid, bound loopback address, workspace),
332 `serve-<slug>.token` (0600; the auth token, passed to serve via `--token-file`
333 so it never appears in `ps`), and `serve-<slug>.log`.
334
335 In the desktop app, manage hosts under **Settings -> Remote SSH**, then use the
336 status-bar chip or the host row's **Remote explorer** button to browse and edit
337 files over SFTP, manage port forwards, and start/open the remote workspace.
338 Opening a workspace creates a separate native Reasonix window, similar to a
339 VS Code Remote SSH window. The primary window owns the SSH tunnel; the remote
340 window is an isolated, lightweight shell and does not restore or acquire local
341 conversation sessions. The remote web page uses the provider configuration and
342 API keys on the **remote** host — the desktop never exposes its own providers
343 to a remote host. If that host is missing the selected Provider's API key, the
344 window shows the authenticated setup page first, saves the key only in the
345 remote Reasonix credential file, and activates the Provider without restarting
346 the remote Serve process. A transient SSH outage keeps the remote window open;
347 the desktop reconnects in the background, re-attaches its loopback forward, and
348 reloads the window against the recovered Serve. An authentication or host-key
349 failure is terminal and closes the unusable remote window instead.
350
351 ## Custom OpenAI-compatible providers
352
353 In the desktop app, open **Settings -> Model -> Access -> Add model service ->
354 Custom provider** for proxies, aggregators, or self-hosted services that speak
355 the OpenAI-compatible chat API or Anthropic-compatible Messages API.
356
357 For common providers, choose **Add model service -> Recommended preset** instead.
358 The official DeepSeek service continues to use its specially adapted OpenAI Chat
359 Completions path by default; add the optional **DeepSeek Anthropic** preset only
360 when Anthropic Messages compatibility is needed. The two entries do not replace
361 each other. Reasonix can prefill editable custom-provider entries for Kimi CN,
362 Kimi Global,
363 Kimi Coding Plan, MiMo API, MiMo Anthropic, MiMo Token Plan CN/SGP/AMS and their
364 Anthropic-compatible variants, MiniMax CN/Global API, MiniMax CN/Global
365 Anthropic, GLM CN, Z.AI Global, GLM/Z.AI Coding Plan OpenAI-compatible and
366 Anthropic-compatible endpoints, OpenCode Go, OpenCode Go Anthropic, OpenCode Zen
367 Anthropic, Qwen/DashScope CN/Global, Qwen Coding Plan CN/Global
368 OpenAI-compatible and Anthropic-compatible endpoints, StepFun OpenAI-compatible
369 and Anthropic-compatible endpoints, NovitaAI, GMI Cloud, Vercel AI Gateway,
370 HuggingFace Router, NVIDIA NIM, KiloCode, and Ollama Cloud. Plan names describe
371 the access/payment route; they include CN/Global only when the provider exposes
372 distinct regional endpoints. Kimi Coding Plan is therefore a dedicated plan
373 endpoint, while Kimi direct API is split into CN and Global. The preset path
374 usually needs only the provider API key: the key value is stored in Reasonix home
375 `.env`, while `config.toml` stores the endpoint, model list, key
376 environment-variable name, context window, vision model metadata, proxy bypass
377 for China-only endpoints, MiniMax `reasoning_split`, GLM/MiniMax thinking
378 heuristics, Anthropic-compatible Bearer auth where needed, Ollama Cloud
379 max-effort support, and OpenCode Go per-model reasoning overrides. The OpenCode
380 Go preset includes its native `kimi-k3` subscription route with image input,
381 `high`/`max` reasoning effort, and a 1,048,576-token context window. Existing untouched
382 OpenCode Go preset installs are upgraded automatically; edited model catalogs
383 are preserved. The Kimi CN and Kimi Global direct-API presets also include
384 `kimi-k3` with image input, a 1,048,576-token context window, and the official
385 `low`/`high`/`max` effort scale (default `max`). For the official K3 endpoints,
386 Reasonix preserves complete assistant messages across turns, sends output limits
387 as `max_completion_tokens`, and omits K3's fixed sampling parameters. Untouched
388 legacy Kimi direct-API catalogs are upgraded automatically without changing the
389 default model; custom catalogs and endpoints are preserved. After adding a
390 preset, open its provider card if you need to change models, headers, endpoint,
391 or compatibility settings.
392
393 Fill **API address** with the provider endpoint that should receive the standard
394 chat path. In this mode Reasonix previews and sends chat requests to:
395
396 ```text
397 <API address>/chat/completions
398 ```
399
400 Enable **Full URL** when the service gives you a complete request URL, for
401 example `https://gateway.example.com/v1/chat/completions`. Reasonix then sends
402 chat requests directly to that URL and does not append `/chat/completions`. The
403 preview under the field shows the exact request URL that will be used.
404
405 Model discovery uses the API address to try likely model-list URLs such as
406 `/models` and `/v1/models`. If the gateway requires a separate model-list
407 endpoint, open **Compatibility settings** and set `models_url`, for example
408 `https://gateway.example.com/v1/models`. If discovery is not available, fill the
409 model list manually.
410
411 **Full URL** still uses the OpenAI-compatible chat request body. It does not
412 switch the request schema to the OpenAI Responses API.
413
414 ### Compatibility settings
415
416 The **Compatibility settings (usually leave unchanged)** section is for gateways
417 whose authentication, model-list endpoint, or reasoning/thinking request shape
418 differs from the normal OpenAI-compatible defaults. Leave these fields at their
419 defaults unless the provider documentation or a proxy error tells you otherwise.
420 For Anthropic-compatible services, such as some coding-plan endpoints, choose
421 **Anthropic-compatible** as the connection protocol before saving.
422
423 | Field | What it controls | When to change it |
424 | --- | --- | --- |
425 | `api_key_env` | The environment-variable name used for this provider's API key. Desktop-saved key values are stored in Reasonix home `.env` under this name; the TOML config stores only the name. | Change it when several providers need distinct keys, or leave it blank for a service that does not require an API key. |
426 | `models_url` | The URL used only for model discovery. Chat requests still use the API address or Full URL above. | Set it when `/models` or `/v1/models` is not where the gateway exposes its model list. |
427 | Extra request headers | Static HTTP headers, one `Header: value` per line. | Use for gateways such as OpenRouter that require `HTTP-Referer`, `X-Title`, or similar site headers. Keep bearer/API keys in the key field instead of duplicating them here. |
428 | Extra request body | A JSON object merged into the top-level chat request body. | Use only for provider-specific flags such as `{"enable_thinking": true}`. Reasonix still owns core fields such as `model`, `messages`, `tools`, `stream`, and `thinking`, and null values are rejected. |
429 | Authorization: Bearer | For Anthropic-compatible providers, sends the saved API key as `Authorization: Bearer <key>` instead of `x-api-key`. | Enable it only when the gateway documents Bearer auth, such as MiniMax Global or Vercel AI Gateway. |
430 | Model capability mode | Which reasoning request protocol Reasonix should use for this provider. | Keep **Auto-detect** unless the gateway is misdetected or the model docs require a specific reasoning format. |
431 | Thinking override | Provider-specific override for `thinking.type`. | Keep **Auto** unless the backend documents `enabled`, `disabled`, or `adaptive`. Unsupported values can make some OpenAI-compatible gateways reject the request. |
432 | Balance URL | Optional endpoint for wallet/balance lookup. | Set it when the provider exposes a balance endpoint and you want the desktop status bar to show it. |
433 | Context window | The provider-wide token budget Reasonix uses for automatic context cleanup. `0` disables automatic compaction. | Set it to the provider's model context limit; use a per-model override below when selected models differ. |
434
435 Each selected model also has an optional **Context window** input. Leave it blank
436 to inherit the provider-wide value, or enter a positive token count to override
437 that value for this model. This avoids premature compaction for long-context
438 models and provider errors for shorter-context models sharing the same endpoint.
439 Use the context-window limit from the model documentation, not the maximum output
440 tokens. For example, 128K commonly means `128000`; if the provider documents
441 `131072`, use that exact value. Values below 16384 show a non-blocking warning
442 because they can trigger frequent compaction and reduce cache hit rates.
443
444 Model capability mode options:
445
446 | Option | Effect |
447 | --- | --- |
448 | Auto-detect (recommended) | Reasonix chooses the request shape from model capability metadata and endpoint detection. |
449 | DeepSeek thinking | Uses DeepSeek-style thinking control, including `thinking.type` and DeepSeek-supported reasoning depth. |
450 | OpenAI reasoning | Uses the standard OpenAI-compatible `reasoning_effort` levels. |
451 | Plain chat | Sends no reasoning or thinking control fields. Use this for text-only proxies that reject reasoning parameters. |
452
453 Thinking override options:
454
455 | Option | Effect |
456 | --- | --- |
457 | Auto (provider default) | Does not write an explicit provider-level `thinking` override. Reasonix uses the provider/model default behavior. |
458 | Enabled | Sends `thinking.type = "enabled"` for compatible providers. |
459 | Disabled | Sends `thinking.type = "disabled"` for compatible providers. On DeepSeek-style providers this also avoids sending a reasoning depth hint. |
460 | Adaptive (self-adjusting) | Sends or preserves `thinking.type = "adaptive"` only for providers that document adaptive thinking, such as MiniMax-M3-style endpoints. |
461
462 Some OpenAI-compatible gateways require non-standard top-level request body
463 fields. Add them with `extra_body` on the provider entry:
464
465 ```toml
466 [[providers]]
467 name = "spark"
468 kind = "openai"
469 base_url = "https://maas-coding-api.cn-huabei-1.xf-yun.com/v2"
470 models = ["xopglm52"]
471 api_key_env = "SPARK_API_KEY"
472 extra_body = { enable_thinking = true }
473 ```
474
475 `extra_body` is merged into the chat JSON request body. Reasonix keeps core
476 fields such as `model`, `messages`, `tools`, `stream`, and `thinking` under its
477 own control.
478
479 ## Desktop hooks
480
481 Desktop hooks run local commands at lifecycle events such as `SessionStart`,
482 `UserPromptSubmit`, `PreToolUse`, and `PreCompact`. A successful `SessionStart`
483 hook may write plain text to stdout, or return JSON with
484 `hookSpecificOutput.additionalContext`; Reasonix injects that text once into the
485 next real user turn as `<hook-context event="SessionStart">...</hook-context>`.
486 This is intended for plugin or workflow bootstrap context, including
487 Superpowers-style startup instructions, without baking that workflow into
488 Reasonix's system prompt.
489
490 Plugin packages can provide this startup context through
491 `hooks/session-start-codex` or a plugin-root `CLAUDE.md`. Claude-style
492 `.claude/settings.json` command hooks are also mapped to matching Reasonix hook
493 events.
494
495 The injected hook context is dynamic current-turn context. It does not change
496 the stable system prompt, memory prefix, or tool schema, though dynamic content
497 can still reduce cache reuse for that turn. The detailed desktop hook schema and
498 loading model are documented in [the Chinese desktop hooks guide](./DESKTOP_HOOKS.zh-CN.md).
499
500 ## Keyboard shortcuts
501
502 Shortcuts are documented by client because users usually look for the keys that
503 work in the surface they are using. Desktop keeps its Plan toggle, while the CLI
504 cycles Ask, Auto, and Plan with `Shift+Tab`. Desktop uses `Cmd+Y` on macOS or
505 `Ctrl+Y` elsewhere for YOLO by default. If YOLO is rebound on Windows/Linux,
506 `Ctrl+Y` becomes the standard composer redo fallback. Desktop paste stays on the
507 platform paste key; in the CLI, terminal-native text paste and
508 application-owned image paste use separate shortcuts.
509
510 `[ui].shortcut_layout` is still accepted for old configs, but the shortcut
511 behavior below is unified across layouts.
512
513 For CLI/TUI text input, `[ui].cursor_shape` accepts `underline`, `block`, or
514 `bar`. The default is `bar`: it remains easy to locate without covering
515 double-width CJK characters in mixed-language input. Set it to `block` for a
516 traditional terminal cursor or `underline` for a lower-profile cursor. This
517 setting does not change desktop or web text fields.
518
519 ### Desktop GUI
520
521 Desktop shortcuts are managed from **Settings → Shortcuts**. Pick a configurable
522 row, press a new key combination, and Reasonix saves it for the desktop app.
523 Standard editing shortcuts such as Undo and Redo are shown as locked rows because
524 the WebView's native text history uses those platform chords. Conflicting
525 bindings are rejected so one shortcut never triggers two actions. Press `?` or
526 use the help button in the topic bar to open the shortcuts sheet; it is generated
527 from the same shortcut registry, so it reflects any custom bindings.
528
529 Global shortcuts:
530
531 | Key or control | What it does | Notes |
532 | --- | --- | --- |
533 | `Cmd+K` on macOS, `Ctrl+K` on Windows/Linux | Toggles the command palette | The palette focuses search when it opens; `Esc` closes it. |
534 | `Cmd+,` on macOS, `Ctrl+,` on Windows/Linux | Opens Settings | Use **Shortcuts** in Settings to customize desktop bindings. |
535 | `Cmd+W` on macOS, `Ctrl+W` on Windows/Linux | Closes the active top tab | The last tab is kept by the normal close-tab guard. |
536 | `Cmd+B` / `Ctrl+B` | Shows or hides the left sidebar | Same action as clicking the sidebar toggle. |
537 | `Cmd+Shift+B` / `Ctrl+Shift+B` | Expands or collapses the most recent shell output | Same action as clicking the collapsed shell-output hint. |
538 | `Cmd+1`-`Cmd+9` on macOS, `Ctrl+1`-`Ctrl+9` elsewhere | Jumps to the matching visible chat in the sidebar | Hold `Cmd`/`Ctrl` briefly to reveal the numbered badges. Existing custom shortcuts that already use the same key take precedence. |
539 | `Cmd++`, `Cmd+-`, `Cmd+0` on macOS; `Ctrl++`, `Ctrl+-`, `Ctrl+0` elsewhere | Increases, decreases, or resets text size | `=` is accepted for the plus key on keyboards that report it that way. |
540 | `?` | Opens the keyboard shortcuts sheet | The sheet shows the current effective desktop bindings. |
541
542 Composer shortcuts:
543
544 | Key or control | What it does | Notes |
545 | --- | --- | --- |
546 | `Enter` | Sends the current message | IME composition confirmation is left alone. |
547 | `Shift+Enter` | Inserts a newline | The composer keeps focus. |
548 | `Shift+Tab` | Toggles Plan on/off | Plan changes the workflow instruction; built-in writers keep the active Ask/Auto/YOLO and Sandbox boundary, while MCP writer/destructive targets stay hard-blocked for the whole planning phase. |
549 | `Cmd+Z` on macOS, `Ctrl+Z` on Windows/Linux | Undoes the latest composer edit | Native typing stays in the WebView history; Reasonix-managed paste, cut, folded blocks, and structured tokens are restored as complete transactions. |
550 | `Cmd+Shift+Z` on macOS, `Ctrl+Shift+Z` on Windows/Linux | Redoes the latest composer edit | On Windows/Linux, `Ctrl+Y` is also accepted after the YOLO shortcut has been rebound. |
551 | `Cmd+Y` / `Ctrl+Y` (default) | Toggles YOLO on/off | Turning YOLO off restores the previous Ask/Auto base when known. The current binding is shown in **Settings → Shortcuts**. |
552 | `Cmd+V` on macOS, `Ctrl+V` on Windows/Linux | Pastes clipboard content | Clipboard images are attached; images can also be dropped into the composer. |
553 | Plain `Up` / `Down` at the prompt boundary | Recalls older or newer submitted prompts | Modified arrows and native text navigation stay with the textarea. |
554 | `Esc` while a turn is running | Cancels the running turn | If the turn has not produced a response yet, the draft is restored. |
555
556 Menus and controls:
557
558 | Key or control | What it does | Notes |
559 | --- | --- | --- |
560 | `Up` / `Down` in slash, `@`, or past-chat menus | Moves the highlighted item | Past-chat search uses the same navigation keys. |
561 | `Enter` / `Tab` in those menus | Accepts the highlighted item | Directory-like entries can keep the menu open for the next level. |
562 | `Esc` in those menus | Closes the current menu or returns from past-chat search | Regular typing continues after the menu closes. |
563 | Ask / Auto / YOLO approval controls | Picks the tool approval posture directly | Clicking these controls is unchanged by keyboard shortcuts. |
564 | Tool approval card | `Left` / `Right`, `Enter`, `1`-`4`, `Esc` | Move the highlighted action, confirm it, pick a numbered action, or deny. The default highlighted action is Allow once. |
565 | Plan approval card | `Left` / `Right`, `Enter`, `1`-`3`, `Esc` | Move between Revise plan, Start execution, and Exit plan. The default highlighted action is Start execution. |
566 | Plan control | Toggles Plan on/off | Same mode as `Shift+Tab`. |
567 | Goal item in the collaboration menu | Starts, views, or clears Goal | Goal is not in any keyboard cycle. |
568
569 ### CLI / TUI
570
571 The composer uses theme-coloured top and bottom borders and a slim bar cursor by
572 default. Long drafts grow to the available maximum height; once they overflow,
573 wheel events inside the composer scroll the draft without moving the insertion
574 cursor, while wheel events in the transcript keep scrolling the conversation.
575 Use `/theme auto|light|dark` to select the background mode, or `/theme <style>`
576 to select one of the named accent palettes shown by bare `/theme`.
577
578 The responsive footer keeps the active Ask/Auto/Plan or YOLO posture and current
579 interaction state on the left. On wider terminals, model, effort, and work mode
580 stay together on the right; a second row shows available Git identity, cache hit
581 rate, context use, compaction headroom, jobs, and balance. `ready` is the idle
582 composer state, not a model-health check. Pickers, approvals, image paste, shell
583 mode, and other active interactions replace it. Narrow terminals move, wrap, or
584 compact whole groups; labels and displayed work-mode values follow `/language`,
585 while `/work-mode` command arguments remain the stable English identifiers.
586
587 Chat and transcript shortcuts:
588
589 | Key or command | What it does | Notes |
590 | --- | --- | --- |
591 | `Enter` | Sends the current message | While a turn is running, non-empty input is queued as follow-up feedback. |
592 | `Shift+Enter`, `Alt+Enter`, or `Ctrl+J` | Inserts a newline | Plain `Enter` is reserved for send/confirm. |
593 | Plain `Up` / `Down` while idle | Recalls older or newer submitted prompts | In a running turn, the same keys navigate queued follow-up feedback. |
594 | `PageUp` / `PageDown` | Scrolls the transcript | Works regardless of the current chat state. |
595 | `Ctrl+Home` / `Ctrl+End` | Jumps to the top or bottom of the transcript | Useful after long tool output. |
596 | `Ctrl+L` or `/cls` | Clears only the visible transcript | The LLM context, session file, tools, memory, and plugins stay loaded. Use `/clear` when you want to discard the conversation context. |
597 | `Esc` | Backs out of the current action | It un-sends a just-submitted turn before any reply, cancels a running turn, or clears non-empty input. |
598 | Double `Esc` on an empty idle composer | Opens the rewind picker | Same entry point as `/rewind`. |
599 | Transcript text selection | Copies transcript text | Releasing an in-app drag writes through the verified native clipboard path in a local session (`pbcopy` on macOS, the available Wayland/X11 tool on Linux, or the Windows clipboard). SSH falls back to OSC 52 and labels the fallback instead of claiming native success. `Ctrl+C`/`Super+C`/`Meta+C` or right-clicking the active selection copies it again. |
600 | Composer text selection | Selects, copies, or replaces draft text | Releasing an in-app drag copies the selection through the same verified clipboard path as transcript text. Typing or pasting replaces the selection; arrow keys collapse it. |
601 | Right-click with no active selection | Pastes clipboard text locally | In a local session with in-app mouse capture on, Reasonix reads text only and routes it through the normal bracketed-paste handling. Over SSH, use the terminal paste shortcut because the remote process cannot read the local clipboard; `/mouse` restores the terminal's native right-click menu. Right-click with an active selection still copies that selection. |
602 | `/mouse` | Toggles in-app mouse capture | Off hands the mouse back to your terminal, restoring its native click-drag selection and right-click context menu, at the cost of in-app drag-select, the transcript scrollbar, and wheel-scroll. Set `REASONIX_DISABLE_MOUSE=1` to start every session with it off. |
603 | `Ctrl+C` | Copies, cancels, clears, or quits | Copies an active transcript or composer selection first. Otherwise it cancels a running turn, clears non-empty input, or quits on a second empty-composer press. |
604 | `Ctrl+D` | Quits the TUI | Immediate quit. |
605 | Your terminal's text-paste shortcut | Pastes text | Text stays on the terminal's bracketed-paste path (`Cmd+V` on macOS, commonly `Ctrl+Shift+V` on Linux, and the terminal's configured shortcut elsewhere). Reasonix consumes the resulting paste event and never probes for an image first. |
606 | `Ctrl+V` on macOS/Linux; `Alt+V` on Windows | Pastes a clipboard image | Image paste is a separate application action. The footer shows `Pasting image…` while the clipboard is read, then inserts an editable `[image #N]` token at the cursor. |
607 | `/paste-image` | Pastes a clipboard image | Command form of the same image-only action. |
608 | A line starting with `!` | Runs a shell command directly | The command runs locally without asking the model. |
609
610 Mode and display shortcuts:
611
612 | Key or command | What it does | Notes |
613 | --- | --- | --- |
614 | `Shift+Tab` | Cycles Ask → Auto → Plan → Ask | YOLO remains outside this composer-mode cycle; the footer shows the active mode. |
615 | `Ctrl+Y` | Toggles YOLO on/off | Turning YOLO off restores the previous Ask/Auto base when known. Terminals that forward Command/Super may also send `Cmd+Y`, but `Ctrl+Y` is the reliable terminal shortcut. |
616 | `--yolo`, `--dangerously-skip-permissions` | Starts chat in YOLO | Same runtime mode as `Ctrl+Y`. |
617 | `/work-mode [economy|balanced|delivery]` | Shows or switches the current session's work mode | `/profile` is a compatibility alias. Switching rebuilds the runtime atomically, preserves the conversation and approval posture, and is blocked while work is active. |
618 | `/theme [auto|light|dark|style]` | Shows or switches the CLI theme | Bare `/theme` lists background modes and named accent palettes. The choice is saved to the user config; `REASONIX_THEME` and `REASONIX_THEME_STYLE` can override it for one run. |
619 | `Ctrl+O` | Toggles verbose reasoning display | Also available through `/verbose`. |
620 | `Ctrl+B` | Expands or collapses long shell output | Long shell-output hint lines can also be clicked in the transcript; text selection is handled in-app while the full-screen TUI has mouse reporting enabled. |
621 | `/goal <objective>`, `/goal --research <objective>`, `/goal --simple <objective>`, `/goal status`, `/goal clear` | Starts, checks, or clears Goal | Goal is not in any keyboard cycle; clearly long-horizon goals automatically enable AutoResearch after Goal is explicitly started. |
622 | `/migrate`, `/migrate --from <legacy-dir>` | Retries legacy migration or imports sessions from a chosen v0.x source | Use `--from` for custom Windows v0.52 install/data directories; it imports sessions only. See [Configuration paths](./CONFIG_PATHS.md). |
623
624 Picker and approval shortcuts:
625
626 | Context | Keys | What they do |
627 | --- | --- | --- |
628 | Slash or `@` completion | `Up` / `Down`, `Ctrl+P` / `Ctrl+N`, `Tab` / `Enter`, `Esc` | Move, accept, or close the completion menu. |
629 | Tool approval prompt | `y`/`1`, `a`/`2`, `p`/`3`, `n`/`4`, `Enter`, `Esc`, `Ctrl+C` | Allow once, allow for session, persist allow, deny, accept default allow once, deny, or cancel the turn. |
630 | Ask question card | `Up`/`Down` or `j`/`k`, `Left`/`Right` or `h`/`l`, `Space`, `Enter`, `1`-`9`, `Esc`, `Ctrl+C` | Navigate answers/tabs, toggle multi-select answers, submit/activate, pick numbered options, dismiss, or cancel the turn. |
631 | Rewind picker | `Up`/`Down` or `j`/`k`, `Enter`, `b`, `c`, `d`, `f`, `s`, `u`, `Esc` | Choose a turn, apply both/conversation/code/fork/summarize actions, or go back/close. |
632 | Model, provider, or resume picker | `Up`/`Down` or `Ctrl+P`/`Ctrl+N`; `j`/`k` while search is empty; type to filter; `Enter`; `Esc` | Search, select an item, or close the picker. Once search input starts, `j`/`k` become query text. `/provider` opens that provider's model list. |
633 | MCP import picker | `Up`/`Down` or `j`/`k`, `Space`, `Enter`, `Esc` / `Ctrl+C` | Move, select servers, import selected servers, or cancel. |
634 | MCP manager | `Up`/`Down` or `j`/`k`, `Enter`, `Left`/`Right` or `h`/`l`, `r`, number keys, `q` / `Ctrl+C` | Navigate server lists/details, refresh, choose actions, or close. |
635 | `/clear` confirmation | Arrow keys or `j`/`k` / `Tab`, `Enter`, `y`, `n`, `Esc` / `Ctrl+C` | Toggle Clear/Cancel, confirm clear, or cancel. |
636
637 Mode meanings:
638
639 | Mode | Meaning |
640 | --- | --- |
641 | Ask | Prompts for fallback writer approvals. |
642 | Auto | Auto-allows fallback approvals; explicit `ask` / `deny` rules still apply. |
643 | YOLO | Skips ordinary tool approval prompts; `deny`, user `ask` questions, and plan approval prompts still wait. |
644 | Plan | Directs the model to plan first — a plan-first workflow, not an all-tools read-only mode. Built-in writers still follow the active Ask/Auto/YOLO rules and Sandbox; installed MCP writers, destructive targets, and readers from unauthorized servers are hard-blocked for the whole planning phase (approval cannot release them; they return once Plan exits), and explicit phase-only tools such as `complete_step` wait until approval. |
645 | Goal | Pursues a saved objective until complete, blocked, or cleared. |
646
647 ## Permissions & sandbox
648
649 Permissions gate each tool call: `deny` > `ask` > `allow` > fallback. Bash and
650 file mutation tools require approval by default; read-only tools generally do
651 not. Approvals are stored and matched as permission rules, not button labels:
652 for example `Bash(npm run build)`, `Bash(npm run test:*)`, and `Edit(docs/**)`.
653 `reasonix` can grant Bash as an exact command or as a conservative command
654 prefix (for example `Bash(go test:*)`), while file-editing tools share session
655 edit grants and persist path-scoped rules such as `Edit(src/app.go)`.
656 Parameter/arithmetic expansions, assignments, heredocs, file redirects, and globs cannot reuse a bare
657 Bash, prefix, or glob allow; a user-approved reusable choice saves the whole
658 command as `Bash=<literal>`. They still follow normal fallback, so Auto executes
659 them without an extra prompt. Command/process substitution, a dynamic command
660 name, `eval`, `source`, shell `-c`, inline runtime code, and unparseable forms
661 require a human in interactive Ask/Auto. Headless Ask/Auto/DontAsk reject that
662 nested/indirect class unless an exact literal exists; YOLO may bypass it.
663 Advanced users can set `[permissions] allow_dynamic_bash = true` to let an
664 Allow fallback, including Auto, cover that class; explicit `ask` and `deny`
665 rules still take precedence.
666 Because a headless run has no approval UI, the default Ask posture also fails
667 closed on ordinary writer fallback and explicit ask rules. Use
668 `reasonix run --auto ...`, `-y`, or `--permission-mode auto` when unattended
669 automation should allow ordinary writer fallback; configured `ask` and `deny`
670 rules always remain authoritative.
671
672 Ask is not read-only: after approval, a writer can still run. Permissions decide
673 whether to allow or prompt; the Sandbox is the enforced capability boundary.
674 The sandbox remains a second boundary after authorization; confinement cannot
675 make ambiguous command parsing safe to authorize automatically.
676
677 Permissions are *policy* (which calls to allow / prompt). The **sandbox** is
678 *enforcement*: the file-writers (`write_file` / `edit_file` / `multi_edit` / `move_file`)
679 refuse any path outside `[sandbox] workspace_root` (default: the current dir, so
680 edits stay in the project), resolving symlinks and `..` so a link can't tunnel
681 out. `forbid_read` optionally hides sensitive files or directories from the agent's
682 read/list/search tools; use absolute paths or `${HOME}` / `${VAR}` references,
683 not `~`, because config expansion is environment-variable based. `bash` is
684 itself jailed by default when an OS sandbox is available (`[sandbox] bash`,
685 Seatbelt on macOS and bubblewrap on Linux):
686 commands may write only those same roots plus platform-specific command
687 temp/cache roots, cannot read configured `forbid_read` roots while the OS
688 sandbox is active, and reach the network only when `[sandbox] network` is set.
689 Reasonix always removes saved provider and bot credential variables from tool
690 subprocess environments and automatically adds its global credential `.env` to
691 the runtime read-deny boundary. Project `.env` files keep their existing
692 workspace-scoped behavior.
693
694 **Session-private temporary directory.** Within one logical chat session, Bash
695 commands share a private temporary directory so consecutive calls can exchange
696 files through `$TMPDIR` (and, on Linux under bubblewrap, through literal
697 `/tmp`). No user setup is required: Reasonix automatically exports `TMPDIR`,
698 `TMP`, and `TEMP` for Bash and client-owned ACP terminals. The directory is
699 created lazily, is never the host public temporary root, and is rotated on
700 `/new`, `/clear`, resume of another session, and branch switches.
701 Model/settings hot rebuilds keep the same directory. Temporary files are not
702 durable storage: resume across process restarts does not restore them, and
703 scripts that need long-lived data should write into the workspace or a
704 user-specified path.
705
706 Reasonix-generated and project scripts should use the standard temporary
707 environment variables rather than hard-coding `/tmp`; users should not set
708 these variables themselves. For example:
709
710 ```sh
711 tmp_file="${TMPDIR:?}/result.json"
712 ```
713
714 ```powershell
715 $tmpFile = Join-Path $env:TEMP "result.json"
716 ```
717
718 | Platform | `$TMPDIR` / `$TMP` / `$TEMP` | Literal `/tmp` |
719 | --- | --- | --- |
720 | Linux + bubblewrap | Virtual `/tmp` (bound to the private dir) | Shared for the session (not a fresh empty tmpfs each call) |
721 | macOS Seatbelt | Host path of the private dir (allowed by policy) | Host macOS temporary directory; scripts should use `$TMPDIR` |
722 | Windows (no OS Bash sandbox) | Host path of the private dir | Not promised to match (e.g. Git Bash `/tmp`) |
723
724 Independent sandboxes such as MCP servers keep their own isolation and do not
725 inherit the chat session's temporary directory. An approved sandbox-escape
726 command still receives the private temp environment variables, but on Linux its
727 literal `/tmp` is no longer mapped by bubblewrap.
728
729 **Windows note:** Reasonix does not ship an OS-level Bash sandbox on Windows.
730 The effective mode is fixed to `off`; even an older config containing
731 `bash = "enforce"` resolves to `off`, `reasonix doctor` flags the ignored value,
732 and the desktop selector is read-only. Bash commands therefore run unconfined,
733 while the dedicated file tools still enforce `workspace_root`, `allow_write`,
734 and `forbid_read` in process. Saved credential variables are still removed from
735 the child environment, but an approved unconfined shell runs as the user and is
736 not a security boundary for other user-readable files.
737
738 When no OS sandbox backend is available, `bash = "enforce"` refuses bash
739 execution instead of running unconfined. Install the platform sandbox backend
740 (bubblewrap/`bwrap` on Linux, `sandbox-exec` on macOS) or set
741 `[sandbox] bash = "off"` to explicitly restore the pre-1.16 unconfined shell
742 behavior. On Windows the compatible value is always `off`.
743
744 For coding-quality reports, run `reasonix doctor quality <branch-id-or-path>`
745 (add `--json` for structured output). This reads the selected session but emits
746 only content-free counts and profile categories: model family, runtime profile,
747 collaboration / approval modes, message and tool-call counts, verification and persisted
748 compaction-summary counts, plus desktop token/cache telemetry when available.
749 It omits transcript text, paths, session identifiers, tool arguments and output,
750 endpoints, and custom model names, so the result is suitable for a public issue
751 or Discussion. This differs from `reasonix doctor session`, whose support zip
752 contains the complete unredacted transcript and must remain in a trusted support
753 channel.
754
755 ## Capability diagnostics
756
757 Use this when a skill, slash command, hook, plugin package, MCP server, or
758 `AGENTS.md` is missing, shadowed, disabled, or fails to start. Full flag
759 reference, JSON schema, and issue codes:
760 **[Capability diagnostics](./CAPABILITY_DIAGNOSTICS.md)**.
761
762 ```bash
763 # Static (default): no network, no MCP child processes
764 reasonix doctor capabilities
765
766 # Machine-readable (stdout is pure JSON)
767 reasonix doctor capabilities --json
768
769 # Another workspace root
770 reasonix doctor capabilities --root /path/to/project
771
772 # Live MCP probe — only when you explicitly allow starting third-party servers
773 reasonix doctor capabilities --live --timeout 5s
774 ```
775
776 | Surface | How |
777 | --- | --- |
778 | CLI | `reasonix doctor capabilities` (above) |
779 | Desktop | **Settings → Diagnostics** — refresh, copy redacted JSON, optional “include current session runtime” (reads the active tab Host only; does **not** start MCP) |
780 | Agent | `/reasonix-guide` (built-in inline skill) or ask naturally; it prefers static doctor JSON before `--live` |
781
782 Exit code `0` allows warnings/info; `1` means at least one `error` (or a live
783 start failure); `2` is bad flags. This is separate from `reasonix doctor`
784 (providers/sandbox) and `reasonix plugin doctor <name>` (one package).
785
786 ## Plugins (MCP)
787
788 Reasonix is an MCP client. A `[[plugins]]` entry's `type` selects the transport:
789 `stdio` (default) launches a local subprocess (`command`/`args`/`env`); `http`
790 (Streamable HTTP) connects to a remote `url` with optional static `headers`
791 (`${VAR}` / `${VAR:-default}` expanded from the environment, so tokens stay out
792 of the file); `sse` connects to servers that still use the legacy persistent
793 GET + announced POST endpoint transport.
794
795 Browse the official MCP Registry from **Settings → MCP servers → Browse
796 registry**, or use `reasonix mcp browse [query]` and
797 `reasonix mcp install <registry-name>`. Registry access is explicit and never
798 runs during startup. Entries that need secrets or required arguments are shown
799 as manual setup instead of being installed with an incomplete configuration;
800 query-specific cached results remain available during a registry outage.
801
802 The normal setup path is intentionally one step. Use Desktop's **Add and
803 connect**, `/mcp add`, or ask Reasonix to install a package or URL. These
804 explicit installs are saved to the user-global `config.toml` and are also
805 authorization: the server connects in the current session, and no second trust
806 step appears now or on the next startup. Servers declared by the current
807 project's `reasonix.toml` or `.mcp.json` remain in that project and are trusted
808 without a separate launch confirmation. Explicit deny rules still win. The
809 server's calls run
810 directly, including tools that declare `destructiveHint`. The dedicated Planner
811 still refuses destructive tools, and strict read-only sub-agents still expose
812 only hinted non-destructive readers.
813
814 MCP names are resolved once per workspace. Project declarations override
815 same-name global installs; inside a project, `reasonix.toml` overrides
816 `.mcp.json`. Editing updates the effective declaration in its original file,
817 and removing a higher-priority declaration reveals the next one instead of
818 deleting every same-name entry.
819
820 stdio servers keep one process for initialize, reads, and writes, so stateful
821 servers such as browsers retain sessions and open pages. Because an OS sandbox
822 is fixed when a process starts, this shared process uses the server's normal
823 process sandbox for every call; `readOnlyHint` and read-only sub-agent filtering
824 are dispatch policy, not a second per-call process sandbox.
825
826 Tools surface to the model as `mcp__<server>__<tool>`. A tool declaring MCP's
827 `readOnlyHint: true` joins parallel dispatch and the strict read-only tool
828 surfaces. Installing a server or declaring it in project configuration
829 authorizes the dedicated Planner to use all of its non-destructive
830 tools without another per-tool setting; strict read-only research sub-agents
831 receive only hinted non-destructive readers. Tools without the hint remain
832 write-capable for scheduling and mutation accounting. While planning, built-in
833 writers keep the ordinary permission posture. The dedicated Planner permits
834 authorized non-destructive MCP (including opaque writers) but hard-blocks
835 destructive or unauthorized targets; a single-model Plan without that dedicated
836 Planner keeps the older writer/destructive block until Plan exits.
837
838 Installing an MCP server is the authorization decision. After installation, all
839 of its tools run directly without a second server-level, per-tool, writer, or
840 destructive approval setting. Explicit global deny rules still win. The host
841 keeps `readOnlyHint` and `destructiveHint` internally for parallel scheduling,
842 Plan restrictions, strict read-only sub-agents, and cached-to-live safety
843 reclassification; these hints do not add user configuration.
844 Reasonix deliberately trusts an installed server to describe those hints
845 honestly. Planner/read-only filtering is therefore a workflow boundary for
846 trusted servers, not containment against a malicious MCP server; explicit deny
847 rules and the process sandbox remain host-controlled boundaries.
848
849 The retired `trusted_read_only_tools`, `default_tools_approval_mode`,
850 `tools.<raw>.approval_mode`, and `approvals_reviewer` fields are ignored when
851 loading older files and removed the next time Reasonix saves that MCP entry.
852
853 A server's **prompts** surface as `/mcp__<server>__<prompt>` slash commands
854 (positional args after the command); its **resources** are pulled in by writing
855 `@<server>:<uri>` in a message; `/mcp` lists connected servers and what each
856 exposes. `make build` also produces `bin/reasonix-plugin-example` — a runnable
857 reference stdio server (`echo`, `wordcount`, a `review` prompt, a style-guide
858 resource) you can copy.
859
860 ```toml
861 [[plugins]] # local stdio server
862 name = "example"
863 command = "reasonix-plugin-example"
864 # startup_timeout_seconds = 60 # optional initialize + tools/list cap
865 # call_timeout_seconds = 600 # optional per-server MCP call timeout
866 # tool_timeout_seconds = { "generate_video" = 1800 } # optional raw MCP tool names
867
868 [[plugins]] # remote server over Streamable HTTP
869 name = "stripe"
870 type = "http"
871 url = "https://mcp.stripe.com"
872 headers = { Authorization = "Bearer ${STRIPE_KEY}" }
873 ```
874
875 Enabled MCP servers start connecting automatically in the background after a
876 session begins, so chat stays usable while tools come online. Use `/mcp` or the
877 desktop MCP panel to refresh status, reconnect a server, inspect failures, or
878 disable a server for the current session. For a read-only config/runtime health
879 report across skills, hooks, packages, and MCP (without changing settings), see
880 [Capability diagnostics](./CAPABILITY_DIAGNOSTICS.md)
881 (`reasonix doctor capabilities` or **Settings → Diagnostics**).
882
883 An interactive caller waits only briefly for a cold server. If that wait ends,
884 the shared startup continues in the background rather than being killed and
885 restarted; retry the tool after it comes online. `mcp_startup_timeout_seconds`
886 (default `30`) bounds the full launch, authorization, initialize, and
887 `tools/list` sequence. `mcp_call_timeout_seconds` applies only after the server
888 is connected. Either value can be overridden per server.
889
890 **Already have an `.mcp.json`?** Drop it in the project root and Reasonix
891 reads it as-is — the `mcpServers` spec (`command`/`args`/`env`, `type`/`url`/
892 `headers`, `${VAR}` expansion) maps field-for-field onto `[[plugins]]`. Both
893 sources are merged; on a name collision `reasonix.toml` wins.
894
895 ```json
896 {
897 "mcpServers": {
898 "filesystem": { "command": "npx", "args": ["-y", "@modelcontextprotocol/server-filesystem", "/path"] },
899 "stripe": { "type": "http", "url": "https://mcp.stripe.com", "headers": { "Authorization": "Bearer ${STRIPE_KEY}" } }
900 }
901 }
902 ```
903
904 **Upgrading from `0.x`?** Your old `~/.reasonix/config.json` is still read for its
905 `mcpServers` (honouring `mcpDisabled`) as a lowest-priority source, so MCP servers
906 keep working — move them into `reasonix.toml`'s `[[plugins]]` or a `.mcp.json` when
907 convenient.
908
909 ## Slash commands
910
911 In an interactive `reasonix` session, built-in commands (`/compact`, `/new`, `/clear`, `/rewind`,
912 `/tree`, `/branch`, `/switch`, `/todo`, `/model`, `/work-mode`, `/mcp`, `/skills`, `/hooks`,
913 `/memory`, `/goal`, `/output-style`, `/sandbox`, `/language`,
914 `/reasoning-language`, `/help`) run
915 locally — `/help` lists them all. Built-in **skills** such as `/init`,
916 `/explore`, `/test`, and `/reasonix-guide` also appear in the slash menu and via
917 `run_skill` (bodies load on demand; only the index line is cache-stable). Use
918 `/reasonix-guide` when you need config or capability troubleshooting; it points
919 at `reasonix doctor capabilities` (see
920 [Capability diagnostics](./CAPABILITY_DIAGNOSTICS.md)). `/new` starts a new
921 session while saving the previous transcript for history/resume; `/clear` asks
922 for confirmation, then discards the current context without saving it. `/tree`
923 shows saved conversation branches, `/branch [name]` forks the current
924 conversation tip, `/branch <turn> [name]` forks from an earlier checkpointed
925 turn, and `/switch <id|name>` loads another branch. **Custom commands** are
926 Markdown files under `.reasonix/commands/` (project) or `~/.reasonix/commands/`
927 (user) — `review.md` becomes `/review`, a subdirectory namespaces it
928 (`git/commit.md` → `/git:commit`). The body is a prompt template; invoking the
929 command sends it as a turn.
930
931 ### Subagent profiles
932
933 Subagent profiles are manual Skills with `runAs: subagent` and
934 `invocation: manual`. They are stored in the same project/global Skill roots as
935 the desktop settings page, so profiles created on either surface are immediately
936 available to the other after the session refreshes. In interactive chat, invoke
937 one with `/<name> <task>`; Reasonix runs an isolated child loop and keeps only
938 the task and final answer in the parent conversation.
939
940 The headless CLI provides explicit management and execution commands without
941 changing the ordinary `reasonix run` task semantics:
942
943 ```bash
944 reasonix subagent list
945 reasonix subagent create reviewer --description "Review changes" --prompt-file reviewer.md --tools read_file,grep,bash
946 reasonix subagent edit reviewer --effort high --model deepseek-pro
947 reasonix subagent try reviewer "review the current diff" # always read-only
948 reasonix subagent run reviewer "review and fix the current diff"
949 reasonix subagent delete reviewer --yes
950 ```
951
952 `create` defaults to project scope when a workspace is available and to global
953 scope otherwise; pass `--scope project|global` to choose explicitly. `edit`
954 changes only explicitly supplied fields, and an empty value such
955 as `--model=` or `--tools=` clears that field. The profile editors deliberately
956 refuse custom-path or richer hand-authored Skills so they cannot discard
957 frontmatter, references, or scripts; manage those files through the Skills
958 workflow instead. Built-in profiles have no editable file, so `edit` accepts
959 only `--model` and `--effort` for them and stores the same per-name overrides as
960 the desktop settings page.
961
962 See [Subagent profiles](./SUBAGENT_PROFILES.md) for the complete CLI reference,
963 Skill file format, model precedence, safety behavior, and troubleshooting.
964
965 Context Engine v2 separates two intentionally different layers:
966
967 - **Standing instructions** come from hierarchical `REASONIX.md`, `AGENTS.md`,
968 and `CLAUDE.md` files. Put rules here when they must be present on every
969 relevant turn. User-global files load first, then workspace and deeper target
970 directories; within one directory, `.local.md` variants win.
971 - **Background memory** stores one durable fact per Markdown file. Each fact has
972 an immutable ID, monotonic revision, timestamps, independent `type`
973 (`user`, `feedback`, `project`, `reference`) and `scope` (`project`,
974 `global`), plus freshness metadata. Facts may be stale, so they never outrank
975 the current request or standing instructions.
976
977 Reasonix automatically recalls a small set of relevant facts before each real
978 user turn. It searches the raw user message, suppresses generic requests such as
979 "continue", prefers project facts over equivalent global fallbacks, down-ranks
980 stale facts, and appends at most four facts / 2,400 characters to the user turn.
981 This dynamic suffix does not rewrite the cache-stable system prompt or tool
982 schemas. Use `/memory recall` to see the selected IDs, scores, reasons,
983 freshness, budget, and suppression decision.
984
985 New, bounded, non-sensitive project/reference facts can be created
986 automatically with no setup or approval click. Global facts, user preferences,
987 feedback, updates, duplicates, sensitive/oversized content, and every `forget`
988 still require explicit confirmation. The storage layer makes the automatic
989 grant create-only, so it cannot overwrite a fact that appears concurrently.
990 A top-level headless controller may use the same one-shot low-risk create path;
991 sub-agents and headless surfaces without the owning scoped controller fail closed.
992
993 `forget` archives rather than permanently deletes. Every update snapshots the
994 previous revision; restore and archive recovery always create a higher revision
995 instead of overwriting history:
996
997 ```text
998 /memory instructions
999 /memory recall
1000 /memory revisions <id-or-name>
1001 /memory restore <id-or-name> <revision>
1002 /memory archived
1003 /memory recover <archive-path>
1004 ```
1005
1006 The desktop Context Center shows the same provenance, conflicts, revision
1007 history, recall trace, and recovery actions. Opening its Suggestions tab scans
1008 recent local user turns automatically; candidates are deduplicated against both
1009 memory scopes and instruction bodies, but nothing is saved until the user
1010 accepts it. Remote workspaces never fall back to local desktop memory or
1011 sessions.
1012
1013 Legacy facts are upgraded in place with deterministic IDs and revision 1;
1014 missing scope is inferred from the containing directory. Migration is
1015 idempotent, old clients retain safe routing, and legacy Memory v5 transcripts
1016 remain readable. For the complete behavior and privacy/cache contract, see
1017 [`Context Engine v2`](SESSION_MEMORY_RETRIEVAL.md).
1018
1019 ```markdown
1020 ---
1021 description: Review the staged diff
1022 argument-hint: [focus-area]
1023 ---
1024 Review the staged diff. Focus on $ARGUMENTS, list bugs with file:line.
1025 ```
1026
1027 `$ARGUMENTS` expands to all space-separated args, `$1`…`$N` to positional ones.
1028 MCP prompts also appear here as `/mcp__<server>__<prompt>`.
1029
1030 ## Embedded documentation retrieval
1031
1032 Reasonix bundles the Markdown files from `docs/` and the reviewed
1033 `release-notes/releases.json` catalog into each CLI and Desktop build. The
1034 read-only `docs` tool searches that exact offline corpus with local BM25
1035 retrieval and can read a complete matching section with source provenance. It
1036 renders every release in both languages under paths such as
1037 `changelog/v1.19.5.md` and `changelog/v1.19.5.zh-CN.md`, so questions about a
1038 specific version, upgrades, fixes, or known risks work offline. The agent should
1039 use the tool before web search or assumptions when a question concerns Reasonix
1040 configuration, CLI/Desktop behavior, release history, permissions, MCP, memory,
1041 recovery, providers, or maintainer workflows.
1042
1043 No setup, network connection, vector database, or embedding service is needed.
1044 Search results prefer the query language while retaining explicit `en`,
1045 `zh-CN`, audience, and catalog filters. Balanced and Delivery profiles expose the
1046 tool directly; Economy connects the `docs` source on demand. Every result reports
1047 the product version, immutable source revision, and corpus SHA-256 digest. Release
1048 CI compiles the CLI and rejects publication unless that embedded manifest matches
1049 the candidate's `docs/*.md`, `release-notes/releases.json`, and build identity. A
1050 newer online `main-v2` page therefore cannot silently replace version-matched
1051 local guidance or release history.
1052
1053 Use `/docs` to inspect the bundled corpus identity and usage examples without
1054 calling a model. Use `/docs <question>` (for example,
1055 `/docs 1.19.5 changelog`) to make Reasonix search the corpus locally first and
1056 then pass the version-matched evidence to the currently configured AI for a
1057 sourced answer. This command path does not depend on the model deciding to call
1058 the `docs` tool, while ordinary natural-language questions may still use the
1059 tool automatically. Existing custom commands and compatible plugin or skill
1060 aliases keep ownership of `/docs`; when that happens, CLI and Desktop normally
1061 expose the built-in corpus as `/reasonix:docs` instead. If that qualified name is
1062 also already owned, Reasonix selects the next free `reasonix:`-qualified fallback
1063 without displacing it. A remote Desktop uses the host's resolved command catalog,
1064 so the displayed entry always matches what that host will execute.
1065
1066 Pull requests that change user-visible CLI, Desktop, configuration, provider,
1067 permission, or tool behavior must declare whether embedded documentation was
1068 updated. When no documentation change is needed, the declaration must explain
1069 why the existing version-matched guidance remains correct.
1070
1071 ## Goal and AutoResearch
1072
1073 Goal is the unified runtime for long-running objectives. Ordinary `/goal`
1074 objectives stay lightweight: Reasonix keeps working until the goal is complete,
1075 blocked, paused, or cleared. When a goal is clearly long-horizon, Goal
1076 automatically enables the AutoResearch strategy instead of requiring a separate
1077 `/auto-research` skill; `auto-research` is not listed as a standalone built-in
1078 skill in Settings -> Skills or the slash menu. Ordinary chat never changes the
1079 collaboration mode implicitly; choose Goal in the composer or use `/goal` to
1080 start a long-running objective.
1081
1082 Goal runs under a per-class **turn** budget: simple goals get 10 turns, write
1083 goals 20 turns, and AutoResearch goals 40 turns; four consecutive turns without
1084 host-verifiable progress pause the goal. Cumulative token usage is still tracked
1085 and shown for diagnostics, but there is **no token hard limit** and no
1086 pre-provider request admission. In Goal mode, a bare bug/crash/exception
1087 statement defaults to the write turn class unless the user asks only for
1088 analysis/explanation or forbids changes. A paused goal keeps its todos, Delivery
1089 checkpoint, and runtime history — use `/goal resume` to continue (turn-budget
1090 pauses add one more slice of turns of the same class), or `/goal pause` to pause
1091 a running goal manually. `/goal status` shows the full runtime summary (turns
1092 used/limit, tokens used, no-progress, extensions). At the end of every goal turn
1093 the model reports its disposition through the structured `update_goal` tool
1094 (continue/complete/blocked); when no report arrives, an independent bounded
1095 evaluator judges the turn once, and any evaluator failure pauses the goal
1096 instead of continuing silently.
1097
1098 For complex work, write the objective as a
1099 [task contract](./TASK_CONTRACT.md): Context, Request, Output format,
1100 Constraints, and Pause policy. Goal mode treats those sections as the boundary
1101 for autonomous work. It keeps going with sensible defaults unless the next step
1102 requires an irreversible or externally visible operation, a scope change, or
1103 information only the user can provide.
1104
1105 AutoResearch is enabled for goals with strong signals such as "keep
1106 researching", "long-running", "thoroughly", "debug until the root cause is
1107 clear", "do not spin", "run experiments", "verify repeatedly", or "turn this
1108 into a complete plan". It can also trigger when the objective combines multiple
1109 phases such as research/diagnosis, implementation/fixing, verification/testing,
1110 optimization/documentation/release, or when the user names an existing
1111 `.reasonix/autoresearch/<task-id>/` directory. Advanced users can force it with
1112 `/goal --research <objective>` or force lightweight Goal with
1113 `/goal --simple <objective>`. Outside an explicitly started Goal, those signals
1114 remain ordinary chat text and do not create durable AutoResearch state.
1115
1116 Once AutoResearch is active, the agent treats the goal as a stateful research
1117 loop instead of a chat-only continuation. It creates or reuses a project-local
1118 `.reasonix/autoresearch/<task-id>/` directory. For new tasks, the default id
1119 shape is `YYYYMMDD-HHMMSS-slug`, such as `20260618-224530-cache-audit`; Reasonix
1120 checks the project directory first and appends `-2`, `-3`, and so on only if
1121 that id already exists. The task state includes `task_spec.md`, `progress.json`,
1122 `findings.jsonl`, `directions_tried.json`, and `iteration_log.jsonl`, records
1123 each iteration's direction, evidence, verification result, and blocker, and uses
1124 `stale_count` to detect repeated weak progress. Repeated stalls force a
1125 structural pivot, such as changing evidence source, entrypoint, test oracle,
1126 decomposition, benchmark, or worker strategy, rather than retrying the same
1127 tactic.
1128
1129 Workers and subagents may explore independently, but the orchestrator owns the
1130 canonical state files. Completion requires a requirement-by-requirement evidence
1131 audit against `task_spec.md`; a passing narrow check is not treated as proof of a
1132 broad requirement. Dynamic run state stays in `.reasonix/autoresearch/...`, not
1133 in `REASONIX.md`, `AGENTS.md`, project memory, tool schemas, or the cache-stable
1134 system prompt. Public publishing, destructive operations, credentials, payments,
1135 and external notifications still follow the normal approval, privacy, and cache
1136 gates.
1137
1138 ## @ references
1139
1140 Embed `@` references in a message and Reasonix resolves them before sending, as
1141 tagged context blocks: `@path/to/file` (or `@dir`) injects a local file's
1142 contents (or a directory listing), and `@<server>:<uri>` injects an MCP
1143 resource. A local path is only treated as a reference when it actually exists,
1144 so ordinary `@mentions` stay literal. Typing `/` or `@` opens an autocomplete
1145 menu — slash commands, or hierarchical file navigation (one directory level at a
1146 time, descend into folders) plus MCP resources.
1147
1148 ## Two-model collaboration
1149
1150 `reasonix setup` manages providers, model lists, credentials, connection tests,
1151 and the default model. It stages changes until Save and exit, and synchronizes
1152 provider access with the desktop app. See the [CLI reference](./CLI.md#configure-providers).
1153 Running two models together (executor + planner, separate cache-stable sessions)
1154 is a one-line edit afterwards — set `planner_model` to any other enabled provider:
1155
1156 ```toml
1157 [agent]
1158 planner_model = "deepseek-pro" # used as the low-frequency planner
1159 ```
1160
1161 The planner sees loaded `REASONIX.md` / `AGENTS.md` memory and a small read-only
1162 research tool set, so it can inspect relevant files before handing a plan to the
1163 executor. Writer and workflow tools remain executor-only.
1164
1165 Reasonix routes each turn deterministically without another classifier model:
1166 questions, short follow-ups, clear atomic edits, and bounded read-only actions
1167 go straight to the executor; bounded implementation work may receive a short
1168 light plan. Ambiguous, cross-surface, structured, high-risk, active-Goal, or
1169 Delivery work receives a full plan unless the request is clearly atomic or
1170 read-only. Explicit Plan Mode
1171 remains a separate host workflow and is never planned twice. An explicit
1172 `plan first` / `先规划` request forces planning, while `just do it` / `直接改`
1173 goes directly to the executor. Execution boundaries are recognized across the
1174 request, not only at its beginning, while quoted examples are ignored. Bare
1175 plan-first requests continue from the planner to the executor automatically.
1176 Requests that explicitly say to wait for confirmation pause at the host
1177 approval boundary and continue to the executor after approval. Only an
1178 explicit `plan only` / `不要执行` request ends the
1179 current turn with the plan persisted and no execution; a later user instruction
1180 can continue in the same session. The phase detail records a privacy-safe route,
1181 depth, and reason code for diagnosis without logging the user prompt.
1182
1183 Light plans contain a compact objective, at most four ordered steps, likely
1184 touchpoints, and the main verification. Full plans distinguish verified from
1185 candidate touchpoints and add relevant non-goals, risks, acceptance criteria,
1186 command-level verification, and rollback guidance when the operation is hard to
1187 reverse. These contracts are part of one stable planner system prompt; only the
1188 small per-turn depth instruction is appended to the user turn, preserving the
1189 planner's prefix cache after the one-time prompt upgrade. The host also gives
1190 light and full research different per-turn round budgets. If a planner still
1191 does not finalize after its bounded research and finalization round, ordinary
1192 plan-and-execute work continues with the executor using the original task.
1193 Plan-only and approval-gated requests remain fail-closed, and the incomplete
1194 planner turn is rolled back instead of leaving an unusable continuation tail.
1195
1196 Reasonix manages normal execution automatically: if an active todo produces no
1197 new completion, unique read, command, or mutation for 8 tool-call rounds, the
1198 host asks the executor to reassess. After 16 no-progress rounds it pauses with
1199 saved work that can be resumed in the next user turn. Exact repeats do not count
1200 as progress; new host-observed work renews the lease. Two-level task lists keep
1201 the same single-current contract: the active level-1 sub-step is the one
1202 `in_progress` item while its level-0 phase stays `pending`; sub-steps are worked
1203 and signed off in order, and once every sub-step has completed the phase itself
1204 becomes `in_progress` for its own final sign-off.
1205
1206 Existing `[agent].max_steps` and `planner_max_steps` keys remain syntactically
1207 accepted during upgrades, but their values are ignored and removed with a
1208 one-time notice. This prevents a stale hidden limit from truncating automatic
1209 progress or inherited subagent work. Use the one-off CLI `--max-steps` flag when
1210 an explicit run budget is needed; unattended bots retain `[bot].max_steps`.
1211
1212 Subagent skills inherit the executor model by default. Set `subagent_model` to
1213 run them on another configured model, or use `subagent_models` to override only
1214 specific skills such as `review` or `security_review`.
1215
1216 Subagents may delegate one more layer by default: the root session is depth 0,
1217 first-layer subagents are depth 1, and the maximum `max_subagent_depth = 2`
1218 means a depth-1 workflow can dispatch a depth-2 reviewer or implementer. Depth-2
1219 subagents do not receive recursive agent/skill tools. Set
1220 `agent.max_subagent_depth = 1` to restore the old single-layer boundary. This is
1221 intended for workflows such as Superpowers where a workflow skill may dispatch a
1222 reviewer subagent, while still avoiding unbounded recursion and background
1223 fanout.
1224
1225 Use `read_only_task` when planning needs isolated, deeper research without
1226 granting write-capable delegation. Use `read_only_skill` when the same need is
1227 best expressed through an existing skill. Both run ephemeral read-only
1228 subagents with only read-only research tools plus safe foreground bash, return
1229 only the final answer, and do not create resumable subagent transcripts.
1230 Read-only nested delegation may be available until `max_subagent_depth` is
1231 reached, but writer-capable `task` / `run_skill` remain unavailable inside these
1232 read-only child registries. In token economy mode, connect this narrow surface
1233 with `connect_tool_source(source="read_only_skill")` when that isolation is
1234 required; loading the full `skills` source in Plan is allowed, and subsequent
1235 writer calls still pass through Permissions/Sandbox.
1236
1237 Every strict read-only child is built through one shared construction
1238 pairing — `RunReadOnlySubAgentWithSession` / `NewReadOnlyAgent` — which marks
1239 the child permanently read-only and applies a final registry filter. The filter
1240 removes writers, destructive MCP targets, readers from unauthorized servers,
1241 and every host-mutating tool. User-installed and project-configured servers are
1242 authorized immediately. Eligible readers may still start on demand. These are
1243 the strict read-only entrances:
1244
1245 | Entrance | Purpose |
1246 | --- | --- |
1247 | `read_only_task` | Isolated read-only research child from the main session |
1248 | `parallel_tasks` (read-only) | Concurrent read-only research children |
1249 | `fleet` with `read_only: true` | Parallel profile-aware batch (forced read-only per item) |
1250 | `read_only_skill` | The same isolation driving an existing skill |
1251 | `reasonix review` (CLI) | Read-only review of a diff or branch |
1252 | Desktop preview/review subagents | Read-only desktop analysis surfaces |
1253
1254 In persisted sessions, `parallel_tasks` and `fleet` return a bounded preview
1255 plus one `Subagent reference` per completed child instead of concatenating every
1256 full answer into a truncation-prone tool result. The parent can call
1257 `read_subagent_result` with that reference and page by `offset_bytes`; results
1258 are scoped to the current conversation lineage and workspace. Headless runs
1259 without a persisted parent session remain ephemeral and receive fair bounded
1260 previews, but cannot mint durable references.
1261
1262 The interactive two-model Planner uses a dedicated construction path
1263 (`NewPlannerAgent`): it still blocks bash, file writers, and ordinary writers,
1264 but may call authorized, non-destructive MCP through the fixed
1265 `use_capability` proxy without requiring `readOnlyHint`. Direct `mcp__*`
1266 schemas never enter the Planner tool list, so MCP install/connect churn does
1267 not change the Planner cache prefix after the one-time schema upgrade. Missing
1268 `readOnlyHint` no longer blocks the Planner; tools with `destructiveHint` are
1269 zero-exec and should be written into the plan for the Executor.
1270 In Balanced two-model sessions the Executor has its own frontend for the same
1271 stable proxy, so an `auto_start=false` or destructive capability discovered by
1272 the Planner remains callable by capability ID after handoff. Planner and
1273 Executor ledgers/audits stay isolated and only the Host connection is shared.
1274
1275 Ordinary `task` / `fleet` sub-agents also get the same fixed proxy (session-
1276 shared Host and connections, per-agent frontend/ledger) and may call installed
1277 or project-configured MCP without `readOnlyHint`. Those calls use the trusted
1278 MCP permission path (live authorization plus explicit deny only); writer and
1279 destructive calls are still serialized, recorded as mutations, and subject to
1280 Delivery evidence/lease guards rather than Planner handoff. Strict
1281 `read_only_task` / `read_only_skill` / review sub-agents share the stable proxy
1282 schema and connection reuse but keep the strict execution gate
1283 (`authorized && readOnlyHint && !destructiveHint`). Profile `allowed-tools`
1284 MCP names convert to capability-id allowlists on the proxy; children never
1285 inherit dynamic `mcp__*` schemas.
1286
1287 Inside a strict child, `use_capability` re-checks the resolved target before
1288 commit/permission/hooks/execution. An unconnected eligible MCP reader may start
1289 on demand from the current schema cache. Before `tools/call`, cached
1290 `readOnlyHint`/`destructiveHint` facts are checked against the live
1291 initialize/tools-list result; a reader-to-writer change or destructive promotion
1292 means zero executions and a normal retry through the current boundary. A
1293 schema-only change refreshes the cache for the next session without interrupting
1294 the authorized call. Runtime enablement, authorization, and the complete
1295 connection identity are checked again immediately before dispatch, so a
1296 same-name client from another project/tab cannot be reused accidentally. An
1297 unauthorized server cannot raise privileges there. This strict-child boundary
1298 is narrower than the dedicated Planner: the Planner accepts authorized opaque
1299 non-destructive MCP, while a strict child requires an explicit reader hint and
1300 never exposes writers at all.
1301
1302 Choose the startup runtime profile with
1303 `--profile economy|balanced|delivery` (for example, `reasonix run --profile
1304 delivery "fix and verify this bug"`). Economy starts with nine tools: direct
1305 read/bash/edit/write, background-shell lifecycle controls, `ask`, and
1306 `connect_tool_source`. Embedded docs, dedicated search/file/workflow tools,
1307 session history, memory mutation, slash commands, Skills, MCP, LSP, web access,
1308 installation, and subagents are connected only when the task needs them.
1309 Balanced is the default with the complete tool surface; when a distinct Planner is configured, both
1310 Planner and Executor add the fixed `use_capability` proxy. The proxy schema is
1311 stable, but the Balanced Executor deliberately retains direct `mcp__*` tools,
1312 so its overall provider tool prefix may still change when those direct tools
1313 are installed, connected, or refreshed. Delivery keeps that complete surface,
1314 adds one stable proxy tool (`use_capability`) for on-demand MCP inspect/call
1315 without schema churn, and adds a stable contract to establish acceptance
1316 criteria, fix root causes, verify the result, and review the final diff. The
1317 host enforces that contract: mutations and verification commands are blocked
1318 until a concrete `todo_write` acceptance list exists; a changed result cannot
1319 finalize until it has been reviewed, verified after the latest mutation, and
1320 signed off with `complete_step`; Skill/MCP `require`/`prefer` routes must be
1321 invoked or declined with host-proven reasons; and medium/high-risk changes
1322 require structured review (and security review when high). Meta tools such as
1323 `task`, `run_skill`, and `review` are not counted as mutations by themselves —
1324 only real child writes are. Read-only analysis remains available without
1325 forcing a write.
1326 Inside an interactive TUI session, use `/work-mode` to inspect the current
1327 choice or `/work-mode economy|balanced|delivery` to switch it. `/profile` is a
1328 compatibility alias. The switch atomically rebuilds the controller while
1329 preserving history, the session path, leases, and the Ask/Auto/YOLO posture; it
1330 is rejected while a turn, approval/question, background job, or another runtime
1331 switch is active. A failed build leaves the previous controller usable. This
1332 command changes only the current session and does not persist a new global
1333 default. Crossing profiles creates one new provider cache prefix. Within
1334 Balanced and Delivery the system contract and tool schema then stay stable; in
1335 Economy each successful `connect_tool_source` call adds the connected schemas
1336 to the next request, creating one more prefix that stays stable until the tool
1337 surface changes again.
1338
1339 Desktop tabs expose the same three choices and persist Economy or Delivery;
1340 legacy empty/`full` values remain Balanced.
1341
1342 For interactive frontends, Plan Mode is always an explicit user choice. Select
1343 Plan in the desktop collaboration-mode control or cycle to Plan with
1344 `Shift+Tab` in the CLI. Reasonix first drafts a plan, then waits for approval
1345 before the workflow switches to implementation. Tool calls made while drafting
1346 still use the current Permissions and Sandbox. Legacy `agent.auto_plan` and
1347 `agent.auto_plan_classifier` values are ignored and removed from the user config
1348 during upgrade. The visible reasoning language can be changed with
1349 `/reasoning-language auto|zh|en` in the
1350 session, or `reasonix config reasoning-language auto|zh|en` in a shell/script.
1351 Pass `--local`
1352 to the reasoning-language shell command only when you intentionally want a
1353 project-local override.
1354
1355 The why behind separate sessions (keeping each model's prefix cache-stable) is in
1356 [`SPEC.md` §3.5](./SPEC.md#35-two-model-collaboration-coordinator).
1357
1357 lines MARKDOWN