返回 DeepSeek-Reasonix
GUIDE.md
根目录 / docs / GUIDE.md
1 # Reasonix Guide
2
3 Provider model capability metadata is documented in
4 [`MODEL_CAPABILITIES.md`](./MODEL_CAPABILITIES.md).
5
6 <a href="../README.md">README</a>
7 &nbsp;·&nbsp;
8 <a href="./GUIDE.zh-CN.md">简体中文</a>
9 &nbsp;·&nbsp;
10 <a href="./SPEC.md">Spec</a>
11
12 > Day-to-day configuration and usage. For the engineering contract and internals
13 > (data types, registries, package layout, roadmap), see the **[Spec](./SPEC.md)**.
14
15 ## Contents
16
17 - [Configuration](#configuration)
18 - [Billing and display currency](./BILLING.md)
19 - [CLI reference](./CLI.md)
20 - [Environment variables](#environment-variables)
21 - [Web frontend](#web-frontend)
22 - [Configuration paths](./CONFIG_PATHS.md)
23 - [Reasoning language](./REASONING_LANGUAGE.md)
24 - [Task contracts and pause policy](./TASK_CONTRACT.md)
25 - [Custom OpenAI-compatible providers](#custom-openai-compatible-providers)
26 - [Desktop hooks](#desktop-hooks)
27 - [Keyboard shortcuts](#keyboard-shortcuts)
28 - [Permissions & sandbox](#permissions--sandbox)
29 - [File deliverables and the `present` tool](./PRESENT_TOOL.md)
30 - [Capability diagnostics](#capability-diagnostics)
31 - [Plugins (MCP)](#plugins-mcp)
32 - [Slash commands](#slash-commands)
33 - [Embedded documentation retrieval](#embedded-documentation-retrieval)
34 - [@ references](#-references)
35 - [Two-model collaboration](#two-model-collaboration)
36
37 ## Configuration
38
39 Resolution order: **flag > `./reasonix.toml` > the user config file >
40 built-in defaults**. Starting with **Reasonix v1.8.1**, the user config lives at
41 `~/.reasonix/config.toml` on macOS/Linux and
42 `%AppData%\reasonix\config.toml` on Windows; see
43 [Configuration paths](./CONFIG_PATHS.md) for migration and related data paths.
44 Fields marked user/global only are not overridden by `./reasonix.toml`.
45 Provider entries name secrets with `api_key_env`, while the secret values live in
46 Reasonix's global `<Reasonix home>/.env`, shared by CLI and desktop. Project
47 `.env`, home `.env`, inherited shell environment variables, legacy credentials,
48 and the OS keyring are not provider-key runtime fallbacks; legacy credentials are
49 only migration sources. Project `.env` still feeds workspace-scoped,
50 non-provider `${VAR}` expansion for MCP/plugin settings without importing
51 provider keys or Reasonix control variables. See
52 [Configuration paths](./CONFIG_PATHS.md) for the full `config.toml` and `.env`
53 structure.
54
55 For the desktop and CLI usage of visible reasoning language, see
56 [Reasoning language](./REASONING_LANGUAGE.md).
57
58 ```toml
59 default_model = "deepseek-flash" # executor; set [agent].planner_model to add a planner
60 # language = "zh" # ui language; empty = auto-detect from $LANG / $REASONIX_LANG
61
62 [ui]
63 # shortcut_layout = "desktop" # classic|desktop; compatibility setting
64 # cursor_shape = "bar" # block|underline|bar; CLI/TUI text cursor
65 show_turn_usage = false # hide per-request token/cost receipts in the TUI; default true
66
67 [agent]
68 reasoning_language = "auto" # visible reasoning text: auto|zh|en
69 # plan_mode_read_only_commands = ["gh issue view"] # legacy compatibility only; Plan bash now uses Permissions
70 # planner_model = "deepseek-pro" # optional low-frequency planner
71 # subagent_model = "deepseek-pro" # optional default for runAs=subagent skills
72 # subagent_models = { review = "deepseek-pro", security_review = "deepseek-pro" }
73 # max_subagent_depth = 2 # nested delegation depth; set 1 for the old single-layer boundary
74 # max_subagent_concurrency = 6 # session-wide sub-agent concurrency (task/fleet/skills)
75 # max_parallel_writers = 3 # concurrent writers with non-overlapping write_paths
76 # compact_ratio = 0.80 # sole auto trigger; presets 0.70 / 0.80 / 0.85
77 # max_output_tokens = 0 # auto: official DeepSeek omits the field (server 384K) until the window is tight
78 # max_output_tokens = 32768 # optional cost cap; still clipped to physical remaining
79 # max_output_tokens = 65536 # optional cost cap
80 # max_output_tokens = -1 # force-omit the wire field; compact if the known auto budget no longer fits
81 # max_output_tokens never changes compact_ratio; 0 is the provider auto value, not "skip local checks"
82
83 [[providers]]
84 name = "deepseek-flash"
85 kind = "openai"
86 base_url = "https://api.deepseek.com"
87 model = "deepseek-flash"
88 api_key_env = "DEEPSEEK_API_KEY"
89 web_search = true
90 # also preset: deepseek-pro
91
92 [tools]
93 enabled = [] # omit/empty = all built-ins
94 bash_timeout_seconds = 120 # foreground safety cap; set 0 for no tool-local cap
95 mcp_startup_timeout_seconds = 30 # background initialize + tools/list safety cap
96 mcp_call_timeout_seconds = 300 # default MCP call safety cap; per-plugin/tool overrides may raise it
97
98 [environment]
99 enabled = true # inject a stable startup summary of OS, shell, and common tools
100 offline = false # set true when outbound network access is unavailable; prevents futile retries
101 # [environment.tools]
102 # go = "/opt/homebrew/bin/go" # optional explicit trusted path; workspace-local paths are not auto-executed
103
104 [skills]
105 # paths = ["~/my-skills", "../shared/skills"] # extra custom skill roots
106 # excluded_paths = ["~/.agents/skills"] # hide convention roots without deleting folders
107 # disabled_skills = ["review"] # hide skills until /skill enable <name>
108
109 [permissions]
110 mode = "ask" # writer fallback when no rule matches: ask|allow|deny
111 deny = ["Bash(rm -rf*)", "Bash(git push*)"] # hard-blocked in every mode
112 allow = ["Bash(go test:*)"] # never prompted
113
114 [sandbox]
115 # workspace_root = "" # file-writers confined here; empty = current dir
116 # allow_write = ["/tmp"] # extra dirs write_file/edit_file/multi_edit/move_file may touch
117 # forbid_read = ["${HOME}/.ssh"] # paths the agent must not read or list
118
119 [serve]
120 auth_mode = "none" # none|token|password; use auth before binding beyond localhost
121 # token = "" # optional fixed token; empty token mode generates one at startup
122 # password_hash = "" # bcrypt hash generated with reasonix serve --hash-password --password '...'
123 # behind_proxy = false # true only behind a trusted reverse proxy
124
125 [[plugins]]
126 name = "example"
127 command = "reasonix-plugin-example"
128 startup_timeout_seconds = 60 # optional initialize + tools/list cap
129 call_timeout_seconds = 600 # optional per-server MCP call timeout
130 tool_timeout_seconds = { "generate_video" = 1800 } # optional raw MCP tool names
131 ```
132
133 For the full schema and every field's contract, see [`SPEC.md` §5](./SPEC.md#5-configuration-toml).
134
135 Installed and project-configured MCP servers need no per-tool trust
136 list. The dedicated two-model Planner may use every non-destructive MCP tool,
137 even when the server omits `readOnlyHint`; strict read-only sub-agents still
138 require `readOnlyHint: true` and no `destructiveHint`.
139
140 `[agent].plan_mode_read_only_commands` is also retained for config round trips,
141 but the main Plan workflow no longer has a separate bash allowlist or trust
142 prompt. Bash classification and approval use the same Permissions rules in Plan
143 and Standard mode; the Sandbox remains the filesystem, process, and network
144 boundary. Dedicated planner and read-only subagent runners keep their own strict
145 read-only tool registry and foreground-command classifier.
146
147 ### Environment variables
148
149 Most day-to-day settings belong in `config.toml` or the global Reasonix `.env`
150 described above. The variables below are process-level advanced switches; set
151 them before launching Reasonix. Project `.env` files are not a runtime source for
152 Reasonix control variables.
153
154 ### CLI telemetry
155
156 The CLI can send a once-per-day anonymous active-install ping and bounded,
157 content-free event counters to `https://crash.reasonix.io`. Configure the
158 user-global policy with:
159
160 ```bash
161 reasonix config telemetry # print the effective mode
162 reasonix config telemetry auto # default: local interactive TTY only
163 reasonix config telemetry on # also allow local headless `reasonix run`
164 reasonix config telemetry off # disable and delete pending counter files
165 ```
166
167 On the first eligible release-build interactive session, Reasonix explains the
168 exact data boundary and asks once before any telemetry request. The prompt is
169 `[Y/n]`: pressing Enter, `y`, or `yes` stores `auto`; `n` or `no` stores `off`
170 and deletes pending counters. After the choice is saved, enabled reporting is
171 silent and the prompt is not shown again. If the preference cannot be saved,
172 nothing is uploaded.
173
174 Reporting is always disabled in CI, development builds, and when
175 `DO_NOT_TRACK` is set or `REASONIX_TELEMETRY=0`. Under `auto`, redirected/piped
176 or otherwise non-interactive sessions do not report. When no choice has been
177 saved yet, these ineligible sessions neither prompt nor report. Network failures
178 after consent are silent and never change stdout, stderr, or the process exit
179 code; unsent counters stay in a bounded local queue for a later invocation.
180
181 The ping contains a dedicated random 128-bit CLI install ID, CLI version, OS,
182 architecture, and the `cli` surface marker. Counter batches use that same ID for
183 daily active-install deduplication and contain only fixed buckets such as CLI
184 surface, permission/session mode, turn latency, finish reason, cache-hit
185 range, generic Provider/tool error class, compaction, recovery counters, and
186 normalized UI language. This ID is separate from the desktop install ID and is
187 not an account, hardware, repository, or session identifier.
188
189 Reasonix never uploads prompts, answers, reasoning, tool names/arguments/output,
190 paths, repositories/branches, session IDs, exact token or cost values,
191 Provider/model names, base URLs, or environment variables.
192
193 ### CLI crash reports
194
195 An unhandled Go panic that reaches the CLI entrypoint is saved locally as a sanitized report under
196 `<Reasonix home>/cli-crash-reports`. Reasonix keeps at most 10 files with owner-only
197 permissions. The panic value is never serialized. Absolute source paths become
198 `<path>/<file>.go:<line>`, function arguments are removed, and the same secret,
199 token, email, and long-identifier scrubbers run both when saving and immediately
200 before sending.
201
202 Crash reports are never uploaded automatically. Review and manage them with:
203
204 ```bash
205 reasonix report # preview newest; prompt before sending on a TTY
206 reasonix report list # list local reports
207 reasonix report show [ID] # preview without sending
208 reasonix report send [ID] # explicit send; delete locally only after success
209 reasonix report delete [ID] # delete without sending
210 ```
211
212 Piped or redirected `reasonix report` calls only preview and never prompt or
213 send. The CLI telemetry setting does not auto-send or auto-delete
214 these separately reviewed reports. Runtime fatal throws, operating-system kills,
215 and panics in unwrapped background goroutines cannot be recovered by Go and do
216 not produce this local report.
217
218 ## Web frontend
219
220 For local use, `reasonix web` starts the browser UI and opens it in your default
221 browser. Inside an interactive CLI session, `/web` snapshots the current session,
222 restores the terminal, and opens an explicit `/sessions/<id>#token=...` deep link.
223 Even a never-used session keeps its reserved ID without forcing an empty
224 transcript onto disk, so the first Web turn continues the same session identity.
225
226 ```bash
227 cd your-project
228 reasonix web
229 ```
230
231 Use `reasonix web --no-open` when you want to start the foreground Web server
232 and print its URL without opening a browser tab. The lower-level
233 `reasonix serve` command starts the same engine without opening a browser by
234 default. It remains the right entry point for remote development boxes,
235 supervisors, tunnels, reverse proxies, and shareable authenticated sessions.
236
237 `reasonix web` starts at `127.0.0.1:8787`, automatically tries 8788, 8789, and
238 so on when a port is busy (up to 100 retries), and defaults to a newly generated
239 token even when `[serve].auth_mode` is `none`. Each live process registers a
240 single-writer heartbeat file under `<Reasonix home>/server/instances/`; clean
241 shutdown removes its own file, while later instances lazily remove records whose
242 owner process is confirmed dead. Multiple Web instances can therefore share one
243 Reasonix home without overwriting registry state. The process stays attached to
244 the terminal; stop it with Ctrl-C.
245
246 An explicit `reasonix web --auth none` disables the default token and should be
247 used only when the listener is intentionally trusted. `reasonix serve` keeps its
248 backward-compatible, config-driven `auth_mode = "none"` default on
249 `127.0.0.1:8787`.
250
251 Without authentication (`auth_mode = "none"`, the `serve` default) reads stay
252 open on the listener, but every state-changing request, approvals included,
253 needs the launch token:
254
255 - Serve writes the token to a 0600 file under `<Reasonix home>/remote/` and
256 prints only its path next to an `approvals:` link; append
257 `#token=<file contents>` to open it in a browser. A managed launch with
258 `--token-file` names that file instead. Token mode prints its `share:` link
259 the same way.
260 - Send it as `Authorization: Bearer <token>`, or open the link once so the page
261 sets its cookie. Without it the request answers 403 `launch_token_required`.
262 - Prefer `--token-file` over `--token`: argv is visible to other processes,
263 sandboxed ones included. A plaintext `[serve].token` in the global
264 config is readable from inside the sandbox; keep the secret in a file.
265 - On macOS and Linux the OS sandbox denies the remote state directory and any
266 `--token-file`. Windows has no bash sandbox, so there nothing keeps an agent
267 command from reading the file.
268 - `[serve]` is read from the user config only; a project `reasonix.toml`
269 cannot set it.
270
271 If you bind Serve outside loopback, expose it through a tunnel, or put it behind
272 a reverse proxy, enable authentication before sharing the URL:
273
274 ```bash
275 reasonix serve --auth token
276 reasonix serve --addr 0.0.0.0:8787 --auth token
277 reasonix serve --auth password --password 'temporary-password'
278 ```
279
280 Token mode prints a share URL with `#token=...`; the Web page exchanges the
281 fragment for an HttpOnly cookie before starting API or SSE requests, keeping the
282 token out of request URLs, browser history, referrers, and access logs. Pass `--token` or set
283 `[serve].token` to reuse a stable token. Password mode requires either
284 `--password` at startup or a stored bcrypt hash:
285
286 ```bash
287 reasonix serve --hash-password --password 'strong-password'
288
289 # <Reasonix home>/config.toml
290 [serve]
291 auth_mode = "password" # none|token|password
292 password_hash = "$2a$12$..."
293 behind_proxy = true # only behind a trusted reverse proxy
294 ```
295
296 The web UI exposes chat, tool approvals, session history, rewind/fork/summarize,
297 model and reasoning-effort controls, Goal, a live todo panel fed by the
298 `todo_write` tool, extension status/card/form/notification surfaces, and
299 provider balance when configured. Extension-hosted providers appear in the
300 model picker. Serve can keep several sessions active at once: creating or
301 resuming another session detaches a busy turn instead of cancelling it, and the
302 session list continues to report that background activity. Run `/reload` while
303 idle to fail-atomically reload extension sidecars and the runtime generation
304 without restarting Serve. Use `--model`, `--max-steps`, or `--resume` for
305 one-off launches; otherwise `serve` uses the user-global `default_model`.
306
307 If the selected Provider has no saved API key, a loopback-bound Serve still
308 starts and shows a Provider setup page instead of failing before the browser can
309 connect. After authentication, enter the key there; Reasonix writes it to this
310 host's global credential file with restricted permissions, rebuilds the active
311 controller in the same process, and opens the normal UI. The credential-writing
312 endpoint is disabled for non-loopback listeners. For a remote SSH window,
313 "this host" means the remote host reached through the SSH tunnel; the key is
314 not copied from the desktop machine.
315
316 ## Editor integrations over ACP
317
318 `reasonix acp` exposes Reasonix as an ACP v1 stdio agent for editors and other
319 host clients. The dedicated **[ACP editor integration](./ACP.md)** guide covers
320 startup, capability negotiation, session lifecycle, independent model/work/
321 collaboration/approval controls, client filesystem and terminal capabilities,
322 MCP servers, permission requests, and the Reasonix mid-turn steering extension.
323
324 ## Remote SSH
325
326 The remote module runs Reasonix on a remote host and reaches it over your own
327 SSH connection — VS Code Remote-SSH style. It bootstraps a persistent headless
328 `reasonix serve` on the remote host, forwards a local loopback port to it, and
329 opens the existing serve web client through that tunnel. The agent, its tools,
330 and its files all live on the remote host at full fidelity; nothing runs through
331 a lossy file proxy. V1 supports Linux and macOS remote hosts.
332
333 The dedicated **[Remote sessions](./REMOTE_SESSIONS.md)** guide covers host
334 configuration (`[remote]` in `config.toml`), SSH-config resolution and import,
335 the `reasonix remote` CLI, the remote serve bootstrap and its install ladder,
336 the remote session lifecycle and takeover, the desktop remote workspace, the
337 `remote` and `local-proxy` credential modes, connection failure semantics, and
338 troubleshooting.
339
340 ## Custom OpenAI-compatible providers
341
342 In the desktop app, open **Settings -> Model -> Access -> Add model service ->
343 Custom provider** for proxies, aggregators, or self-hosted services that speak
344 the OpenAI-compatible chat API or Anthropic-compatible Messages API.
345
346 For common providers, choose **Add model service -> Recommended preset** instead.
347 New official DeepSeek entries use Chat Completions by default and enable
348 independent `web_search`; the same `DEEPSEEK_API_KEY` works across supported
349 protocols. On startup, Reasonix upgrades unmodified legacy
350 `deepseek-flash` / `deepseek-pro` entries that still use the official endpoint
351 and standard key/model settings. Customized official Chat Completions entries
352 keep their protocol choice and show an **Upgrade protocol** action in Settings.
353 Proxy endpoints, custom headers, and capability overrides do not trigger a
354 protocol migration. Separately, the version 11 catalog upgrade appends
355 `deepseek-flash` once to existing official model lists, including customized
356 lists. It preserves the selected/default model and later user deletion. Existing
357 separately named `deepseek-anthropic` entries remain compatible, but that
358 redundant preset is no longer offered for new access. Reasonix can prefill editable custom-provider entries for Kimi CN,
359 Kimi Global,
360 Kimi Coding Plan, MiMo API, MiMo Anthropic, MiMo Token Plan CN/SGP/AMS and their
361 Anthropic-compatible variants, MiniMax CN/Global API, MiniMax CN/Global
362 Anthropic, GLM CN, Z.AI Global, GLM/Z.AI Coding Plan OpenAI-compatible and
363 Anthropic-compatible endpoints, OpenCode Go, OpenCode Go Anthropic, OpenCode Go
364 DeepSeek Anthropic, OpenCode Go DeepSeek Responses, OpenCode Zen
365 Anthropic, Qwen/DashScope CN/Global, Qwen Coding Plan CN/Global
366 OpenAI-compatible and Anthropic-compatible endpoints, StepFun OpenAI-compatible
367 and Anthropic-compatible endpoints, NovitaAI, GMI Cloud, Vercel AI Gateway,
368 HuggingFace Router, ModelScope, NVIDIA NIM, KiloCode, and Ollama Cloud. Plan names describe
369 the access/payment route; they include CN/Global only when the provider exposes
370 distinct regional endpoints. Kimi Coding Plan is therefore a dedicated plan
371 endpoint, while Kimi direct API is split into CN and Global. The preset path
372 usually needs only the provider API key: the key value is stored in Reasonix home
373 `.env`, while `config.toml` stores the endpoint, model list, key
374 environment-variable name, context window, model capability metadata, proxy bypass
375 for China-only endpoints, MiniMax `reasoning_split`, GLM/MiniMax thinking
376 heuristics, Anthropic-compatible Bearer auth where needed, Ollama Cloud
377 max-effort support, and OpenCode Go per-model reasoning overrides. New official DeepSeek Anthropic, Responses, and Chat Completions catalogs offer
378 `deepseek-flash` and `deepseek-v4-pro`. The retired `deepseek-v4-flash` and
379 `deepseek-v4-flash-vision-exp` IDs remain valid for saved references. Settings derives image support from
380 model capability metadata. Each model also has an Image input Auto / On / Off
381 selector. For an ID-only relay list, unknown means unrecognized, not confirmed
382 text-only: select On after confirming support with the relay, then save. See the
383 [image input guide](MODEL_CAPABILITIES.md#set-image-input-for-a-relay-model).
384 Composer
385 and `@` user images are sent as official visual input using the three documented
386 shapes: inline base64 `data:` URLs for local files, `http(s)` image URLs as-is,
387 and Files API `file-api-` ids (local images over 32 MiB on official DeepSeek are
388 uploaded automatically). Chat Completions uses `image_url` or `file`, Anthropic
389 uses `image`+`source.base64|url|file`, and Responses uses `input_image`.
390 Flash and its retired aliases accept images; V4 Pro remains text-only. The dedicated
391 OpenCode Go DeepSeek Anthropic and DeepSeek Responses presets expose the verified
392 Flash routes and enable provider-side `web_search` by default; the Responses
393 variant uses stateless context replay. The existing mixed OpenCode Go Anthropic
394 preset remains scoped to Qwen and MiniMax so server tools are not sent to
395 unverified models. DeepSeek Pro remains on the Chat Completions preset because
396 live Anthropic and Responses requests currently fail in the OpenCode Go upstream
397 conversion. The OpenCode Go preset includes its native `kimi-k3` subscription
398 route with image input,
399 `high`/`max` reasoning effort, and a 1,048,576-token context window. Existing untouched
400 OpenCode Go preset installs are upgraded automatically; edited model catalogs
401 are preserved. The Kimi CN and Kimi Global direct-API presets also include
402 `kimi-k3` with image input, a 1,048,576-token context window, and the official
403 `low`/`high`/`max` effort scale (default `max`). For the official K3 endpoints,
404 Reasonix preserves complete assistant messages across turns, sends output limits
405 as `max_completion_tokens`, and omits K3's fixed sampling parameters. Untouched
406 legacy Kimi direct-API catalogs are upgraded automatically without changing the
407 default model; custom catalogs and endpoints are preserved. After adding a
408 preset, open its provider card if you need to change models, headers, endpoint,
409 or compatibility settings.
410
411 Fill **API address** with the provider endpoint that should receive the standard
412 chat path. In this mode Reasonix previews and sends chat requests to:
413
414 ```text
415 <API address>/chat/completions
416 ```
417
418 Enable **Full URL** when the service gives you a complete request URL, for
419 example `https://gateway.example.com/v1/chat/completions`. Reasonix then sends
420 chat requests directly to that URL and does not append `/chat/completions`. The
421 preview under the field shows the exact request URL that will be used.
422
423 Model discovery uses the API address to try likely model-list URLs such as
424 `/models` and `/v1/models`. If the gateway requires a separate model-list
425 endpoint, open **Compatibility settings** and set `models_url`, for example
426 `https://gateway.example.com/v1/models`. If discovery is not available, fill the
427 model list manually.
428
429 **Full URL** still uses the OpenAI-compatible chat request body. It does not
430 switch the request schema to the OpenAI Responses API.
431
432 ### Compatibility settings
433
434 The **Compatibility settings (usually leave unchanged)** section is for gateways
435 whose authentication, model-list endpoint, or reasoning/thinking request shape
436 differs from the normal OpenAI-compatible defaults. Leave these fields at their
437 defaults unless the provider documentation or a proxy error tells you otherwise.
438 For Anthropic-compatible services, such as some coding-plan endpoints, choose
439 **Anthropic-compatible** as the connection protocol before saving.
440
441 | Field | What it controls | When to change it |
442 | --- | --- | --- |
443 | `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. |
444 | `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. |
445 | 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. |
446 | 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. |
447 | 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. |
448 | 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. |
449 | 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. |
450 | 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. |
451 | 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. |
452
453 Each selected model also has an optional **Context window** input. Leave it blank
454 to inherit the provider-wide value, or enter a positive token count to override
455 that value for this model. This avoids premature compaction for long-context
456 models and provider errors for shorter-context models sharing the same endpoint.
457 Use the context-window limit from the model documentation, not the maximum output
458 tokens. For example, 128K commonly means `128000`; if the provider documents
459 `131072`, use that exact value. Values below 16384 show a non-blocking warning
460 because they can trigger frequent compaction and reduce cache hit rates.
461
462 ### Self-hosted runtimes: the runtime's limit, not the model's
463
464 For a local server, the number that governs the request is the **runtime's
465 configured context length**, which is usually far below what the model was
466 trained for. Ollama serves its own 4096-token default unless
467 `OLLAMA_CONTEXT_LENGTH` is set or the Modelfile carries `PARAMETER num_ctx`, so a
468 262K-context model routinely runs at 4096. Its OpenAI-compatible `/v1` surface
469 has no field for `num_ctx`, so the value cannot be raised per request and has to
470 be set on the server.
471
472 Runtimes differ in what they do when the prompt exceeds that limit:
473
474 | Runtime | Prompt over the limit |
475 | --- | --- |
476 | Ollama | `200 OK`, prompt **silently truncated** |
477 | LM Studio | depends on its context-overflow policy; `truncateMiddle` and `rollingWindow` truncate silently, and an OpenAI-compatible client cannot select the policy per request |
478 | llama.cpp server | HTTP 400, `the request exceeds the available context size` |
479 | vLLM | HTTP 400, `the engine prompt length ... exceeds the max_model_len` |
480
481 The last two fail loudly, so you will see them. The silent cases are the
482 dangerous ones, because the symptom does not look like truncation:
483
484 - the model ignores its tools, or invents tool names that do not exist — the tool
485 schemas are the largest part of the prefix and the first thing cut;
486 - it answers as though it never saw the system prompt or your actual question;
487 - it reads as a weak model rather than a misconfigured server.
488
489 Reasonix detects a silently truncated prompt from the token counts the provider
490 reports and warns once per session. Check the server first — `ollama ps` shows
491 the context each loaded model is actually running with — then set **Context
492 window** to that same number.
493
494 Model capability mode options:
495
496 | Option | Effect |
497 | --- | --- |
498 | Auto-detect (recommended) | Reasonix chooses the request shape from model capability metadata and endpoint detection. |
499 | DeepSeek thinking | Uses DeepSeek-style thinking control, including `thinking.type` and DeepSeek-supported reasoning depth. |
500 | OpenAI reasoning | Uses the standard OpenAI-compatible `reasoning_effort` levels. |
501 | Plain chat | Sends no reasoning or thinking control fields. Use this for text-only proxies that reject reasoning parameters. |
502
503 Thinking override options:
504
505 | Option | Effect |
506 | --- | --- |
507 | Auto (provider default) | Does not write an explicit provider-level `thinking` override. Reasonix uses the provider/model default behavior. |
508 | Enabled | Sends `thinking.type = "enabled"` for compatible providers. |
509 | Disabled | Sends `thinking.type = "disabled"` for compatible providers. On DeepSeek-style providers this also avoids sending a reasoning depth hint. |
510 | Adaptive (self-adjusting) | Sends or preserves `thinking.type = "adaptive"` only for providers that document adaptive thinking, such as MiniMax-M3-style endpoints. |
511
512 Some OpenAI-compatible gateways require non-standard top-level request body
513 fields. Add them with `extra_body` on the provider entry:
514
515 ```toml
516 [[providers]]
517 name = "spark"
518 kind = "openai"
519 base_url = "https://maas-coding-api.cn-huabei-1.xf-yun.com/v2"
520 models = ["xopglm52"]
521 api_key_env = "SPARK_API_KEY"
522 extra_body = { enable_thinking = true }
523 ```
524
525 `extra_body` is merged into the chat JSON request body. Reasonix keeps core
526 fields such as `model`, `messages`, `tools`, `stream`, and `thinking` under its
527 own control.
528
529 ## Desktop hooks
530
531 Desktop hooks run local commands at lifecycle events such as `SessionStart`,
532 `UserPromptSubmit`, `PreToolUse`, and `PreCompact`. A successful `SessionStart`
533 hook may write plain text to stdout, or return JSON with
534 `hookSpecificOutput.additionalContext`; Reasonix injects that text once into the
535 next real user turn as `<hook-context event="SessionStart">...</hook-context>`.
536 This is intended for plugin or workflow bootstrap context, including
537 Superpowers-style startup instructions, without baking that workflow into
538 Reasonix's system prompt.
539
540 Plugin packages can provide this startup context through
541 `hooks/session-start-codex` or a plugin-root `CLAUDE.md`. Claude-style
542 `.claude/settings.json` command hooks are also mapped to matching Reasonix hook
543 events.
544
545 The injected hook context is dynamic current-turn context. It does not change
546 the stable system prompt, memory prefix, or tool schema, though dynamic content
547 can still reduce cache reuse for that turn. The detailed desktop hook schema and
548 loading model are documented in [the Chinese desktop hooks guide](./DESKTOP_HOOKS.zh-CN.md).
549
550 ## Keyboard shortcuts
551
552 Shortcuts are documented by client because users usually look for the keys that
553 work in the surface they are using. On Desktop, `Shift+Tab` toggles Plan and
554 permission presets stay in the composer menu. In the CLI, `Shift+Tab` cycles
555 Read only → Workspace write → YOLO → Plan, while `Ctrl+Y` toggles YOLO
556 directly. YOLO is the visible label for the canonical `danger-full-access`
557 permission preset. Desktop paste stays on the platform paste key; in the CLI,
558 terminal-native text paste and application-owned image paste use separate shortcuts.
559
560 `[ui].shortcut_layout` is still accepted for old configs, but the shortcut
561 behavior below is unified across layouts.
562
563 For CLI/TUI text input, `[ui].cursor_shape` accepts `underline`, `block`, or
564 `bar`. The default is `bar`: it remains easy to locate without covering
565 double-width CJK characters in mixed-language input. Set it to `block` for a
566 traditional terminal cursor or `underline` for a lower-profile cursor. This
567 setting does not change desktop or web text fields.
568
569 ### Desktop GUI
570
571 The Desktop Todo shelf derives its label from both `todo_write` and the owning
572 tab's runtime: active work is **In progress**, an approval or question is
573 **Waiting for input**, and an idle/restored current item is **Ready to continue**.
574 The latter exposes a **Continue** action that rechecks the captured tab before
575 sending, so a rapid tab switch cannot route stale work into another session.
576
577 Desktop shortcuts are managed from **Settings → Shortcuts**. Pick a configurable
578 row, press a new key combination, and Reasonix saves it for the desktop app.
579 Standard editing shortcuts such as Undo and Redo are shown as locked rows because
580 the WebView's native text history uses those platform chords. Conflicting
581 bindings are rejected so one shortcut never triggers two actions. Press `?` or
582 use the help button in the topic bar to open the shortcuts sheet; it is generated
583 from the same shortcut registry, so it reflects any custom bindings.
584
585 Global shortcuts:
586
587 | Key or control | What it does | Notes |
588 | --- | --- | --- |
589 | `Cmd+K` on macOS, `Ctrl+K` on Windows/Linux | Toggles the command palette | The palette focuses search when it opens; `Esc` closes it. |
590 | `Cmd+,` on macOS, `Ctrl+,` on Windows/Linux | Opens Settings | Use **Shortcuts** in Settings to customize desktop bindings. |
591 | `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. |
592 | `Cmd+B` / `Ctrl+B` | Shows or hides the left sidebar | Same action as clicking the sidebar toggle. |
593 | `Cmd+Shift+B` / `Ctrl+Shift+B` | Expands or collapses the most recent shell output | Same action as clicking the collapsed shell-output hint. |
594 | `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. |
595 | `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. |
596 | `?` | Opens the keyboard shortcuts sheet | The sheet shows the current effective desktop bindings. |
597
598 Composer shortcuts:
599
600 | Key or control | What it does | Notes |
601 | --- | --- | --- |
602 | `Enter` | Sends the current message | IME composition confirmation is left alone. |
603 | `Shift+Enter` | Inserts a newline | The composer keeps focus. |
604 | `Shift+Tab` | Toggles Plan on/off | Plan changes the workflow instruction while the selected permission preset remains active. |
605 | `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. |
606 | `Cmd+Shift+Z` on macOS, `Ctrl+Shift+Z` on Windows/Linux | Redoes the latest composer edit | Uses the platform-native editing history. |
607 | `Cmd+V` on macOS, `Ctrl+V` on Windows/Linux | Pastes clipboard content | Clipboard images are attached; images can also be dropped into the composer. On official DeepSeek, `deepseek-flash` and `deepseek-v4-flash` accept images natively; V4 Pro stays text-only. |
608 | Plain `Up` / `Down` at the prompt boundary | Recalls older or newer submitted prompts | Modified arrows and native text navigation stay with the textarea. |
609 | `Esc` while a turn or compaction is running | Cancels the cancellable foreground operation | A compaction stop preserves the draft and queued messages; an unanswered turn restores its draft. |
610
611 Menus and controls:
612
613 | Key or control | What it does | Notes |
614 | --- | --- | --- |
615 | `Up` / `Down` in slash, `@`, or past-chat menus | Moves the highlighted item | Past-chat search uses the same navigation keys. |
616 | `Enter` / `Tab` in those menus | Accepts the highlighted item | Directory-like entries can keep the menu open for the next level. |
617 | `Esc` in those menus | Closes the current menu or returns from past-chat search | Regular typing continues after the menu closes. |
618 | Read only / Workspace write / Full access | Selects the current session permission preset | Settings controls only the default for new sessions. |
619 | Tool approval card | `Left` / `Right`, `Enter`, `1`-`3`, `Esc` | Move between Allow once, Allow for this session, and Deny. The default is Allow once. |
620 | 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. |
621 | Plan control | Toggles Plan on/off | Same mode as `Shift+Tab`. |
622 | Goal item in the collaboration menu | Starts, views, or clears Goal | Goal is not in any keyboard cycle. |
623
624 ### CLI / TUI
625
626 The composer uses theme-coloured top and bottom borders and a slim bar cursor by
627 default. Long drafts grow to the available maximum height; once they overflow,
628 wheel events inside the composer scroll the draft without moving the insertion
629 cursor, while wheel events in the transcript keep scrolling the conversation.
630 Use `/theme auto|light|dark` to select the background mode, or `/theme <style>`
631 to select one of the named accent palettes shown by bare `/theme`.
632
633 The responsive footer keeps the active permission preset, Plan state, and current
634 interaction state on the left. On wider terminals, model and effort
635 stay together on the right; a second row shows available Git identity, cache hit
636 rate, context use, compaction headroom, jobs, and balance. `ready` is the idle
637 composer state, not a model-health check. Pickers, approvals, image paste, shell
638 mode, and other active interactions replace it. Narrow terminals move, wrap, or
639 compact whole groups; visible labels follow `/language`.
640
641 Chat and transcript shortcuts:
642
643 | Key or command | What it does | Notes |
644 | --- | --- | --- |
645 | `Enter` | Sends the current message | While a turn is running, non-empty input is durably queued as a follow-up before the composer clears. |
646 | `Ctrl+Enter` or `/steer <text>` | Adds guidance to the active turn | The guidance is persisted first; if the turn cannot accept it, it remains a normal follow-up. |
647 | `Shift+Enter`, `Alt+Enter`, or `Ctrl+J` | Inserts a newline | Plain `Enter` is reserved for send/confirm. |
648 | Plain `Up` / `Down` while idle | Recalls older or newer submitted prompts | In a running turn, the same keys navigate queued follow-up feedback. |
649 | `PageUp` / `PageDown` | Scrolls the transcript | Works regardless of the current chat state. |
650 | `Ctrl+Home` / `Ctrl+End` | Jumps to the top or bottom of the transcript | Useful after long tool output. |
651 | `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. |
652 | `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. |
653 | Double `Esc` on an empty idle composer | Opens the rewind picker | Same entry point as `/rewind`. |
654 | 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. |
655 | 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. |
656 | 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. |
657 | `/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. Remote (SSH) sessions start with capture off so native selection works out of the box; `REASONIX_DISABLE_MOUSE=0` forces capture on everywhere. Over SSH the TUI also enables synchronized output (mode 2026) so repaints do not flicker on the round trip; set `REASONIX_DISABLE_SYNC_OUTPUT=1` to opt out. |
658 | `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. |
659 | `Ctrl+D` | Quits the TUI | Immediate quit. |
660 | 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. |
661 | `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. |
662 | `/paste-image` | Pastes a clipboard image | Command form of the same image-only action. |
663 | A line starting with `!` | Runs a shell command directly | The command runs locally without asking the model. |
664
665 `/queue list` shows bounded previews without loading full bodies. Use `/queue
666 show|edit|delete|move`, `/queue pause|resume`, and `/queue retry|refresh` to
667 inspect or manage pending work. After crash recovery the inbox is paused, so
668 review it and run `/queue resume` before dispatch continues. Each item is
669 limited to 4 MiB; a session accepts at most 64 items and 64 MiB total.
670
671 Mode and display shortcuts:
672
673 | Key or command | What it does | Notes |
674 | --- | --- | --- |
675 | `Shift+Tab` | Cycles Read only → Workspace write → YOLO → Plan | YOLO applies `danger-full-access`; leaving Plan returns to Read only. |
676 | `Ctrl+Y` | Toggles YOLO | Entering YOLO applies `danger-full-access`; pressing it again restores the prior safe permission preset. |
677 | `--permission-mode read-only|workspace-write|danger-full-access` | Selects the initial permission preset | New sessions default to `workspace-write`. |
678 | `/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. |
679 | `Ctrl+O` | Toggles verbose reasoning display | Also available through `/verbose`. |
680 | `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. |
681 | `/goal <objective>`, `/goal status`, `/goal pause`, `/goal resume`, `/goal clear` | Starts, checks, pauses, resumes, or clears Goal | A Goal is unbounded unless `[agent].goal_token_budget` is set. |
682 | `/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). |
683
684 Picker and approval shortcuts:
685
686 | Context | Keys | What they do |
687 | --- | --- | --- |
688 | Slash or `@` completion | `Up` / `Down`, `Ctrl+P` / `Ctrl+N`, `Tab` / `Enter`, `Esc` | Move, accept, or close the completion menu. |
689 | 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. |
690 | 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. |
691 | 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. |
692 | 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. |
693 | MCP import picker | `Up`/`Down` or `j`/`k`, `Space`, `Enter`, `Esc` / `Ctrl+C` | Move, select servers, import selected servers, or cancel. |
694 | 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. |
695 | `/clear` confirmation | Arrow keys or `j`/`k` / `Tab`, `Enter`, `y`, `n`, `Esc` / `Ctrl+C` | Toggle Clear/Cancel, confirm clear, or cancel. |
696
697 Mode meanings:
698
699 | Mode | Meaning |
700 | --- | --- |
701 | Read only | Reads the workspace; writes and external side effects require a scoped authorization. |
702 | Workspace write | Writes inside the workspace and private session temporary directory. This is the default. |
703 | Full access | Runs as the current OS user without Reasonix filesystem or network sandboxing. Explicit host deny rules still apply before launch. |
704 | Plan | Plans before implementation. State-changing actions are blocked until approval, including Full access, proxy tools, and subagents. After approval, ordinary permissions and sandbox rules still apply. |
705 | Goal | Pursues a saved objective until complete, blocked, or cleared. |
706
707 ## Permissions & sandbox
708
709 The active permission preset supplies the enforced filesystem boundary for
710 Bash, file tools, background processes, and subagents. `workspace-write` runs
711 ordinary builds, tests, pipes, command substitutions, and inline scripts without
712 syntax-based prompts while confining writes to the workspace and private session
713 temporary directory. A write outside that boundary can be allowed once or for
714 the displayed directory during the current session. Permanent approval is not
715 offered.
716
717 Configured `deny` rules always win. Installed MCP servers and plugins are trusted
718 in `workspace-write`; unknown side-effect capabilities in `read-only` still need
719 authorization. If the platform sandbox is unavailable, restricted presets fail
720 closed instead of offering an unconfined retry.
721
722 Permissions are *policy* (which calls to allow / prompt). The **sandbox** is
723 *enforcement*: they are two layers. A permitted call still cannot write outside
724 the approved roots. The file-writers (`write_file` / `edit_file` / `multi_edit` / `move_file`)
725 refuse any path outside `[sandbox] workspace_root` (default: the current dir, so
726 edits stay in the project), resolving symlinks and `..` so a link can't tunnel
727 out. Writing outside the workspace is an interactive *extend write access*
728 approval (once / this session / add to project `reasonix.toml` / deny), not a
729 sandbox escape. Bash must name those directories with `additional_write_dirs`
730 plus a `justification`; the host does not infer paths from the command text.
731 Headless `reasonix run` does not prompt: pass `--add-dir` or configure
732 `[sandbox].allow_write`. The whole home directory can be approved with a
733 high-risk warning; the filesystem root and Reasonix session/state paths cannot. `forbid_read` optionally hides sensitive files or directories from the agent's
734 read/list/search tools; use absolute paths or `${HOME}` / `${VAR}` references,
735 not `~`, because config expansion is environment-variable based. `bash` is
736 itself jailed by default when an OS sandbox is available (`[sandbox] bash`,
737 Seatbelt on macOS and bubblewrap on Linux):
738 commands may write only those same roots plus platform-specific command
739 temp/cache roots, cannot read configured `forbid_read` roots while the OS
740 sandbox is active, and reach the network only when `[sandbox] network` is set.
741 Reasonix always removes saved provider and bot credential variables from tool
742 subprocess environments. On macOS and Linux it also automatically adds the
743 global credential `.env` to the runtime read-deny boundary. Windows does not:
744 it has no OS-level shell sandbox, and denying the current user would also deny
745 the host settings process. Project `.env` files keep their existing
746 workspace-scoped behavior.
747
748 **Git metadata is host-protected.** Inside the bash sandbox, the Git
749 configuration and hooks of the workspace repository stay read-only, because the
750 host's own git reads them.
751
752 The repository is the one git itself discovers from each writable root. A
753 `.git` file is followed to the gitdir it names the way git resolves it,
754 relative to the file with symlinks followed, so the protection lands on what
755 git will read. Protected:
756
757 - `.git` itself, the gitdir, the common dir and every symlink on the way to
758 them: none can be removed, renamed or replaced by a symlink.
759 - `config`, `config.worktree`, `commondir` and `hooks/` of the gitdir and of
760 the common dir.
761 - `config`, `config.worktree` and `commondir` of each existing `worktrees/*`
762 entry, and `config` and `config.worktree` of entries created later.
763 - `config`, `config.worktree`, `commondir` and `hooks/` of each submodule
764 gitdir under `modules/`, existing or created later.
765
766 Everything else under `.git` (objects, refs, index, logs, lock files) stays
767 writable, so add, commit, branch, checkout, merge, rebase, stash, tag and
768 worktree creation keep working. These operations change:
769
770 | Operation | In the sandbox |
771 | --- | --- |
772 | `git config` without `--global`, `git remote add` / `set-url`, `git branch -m`, `git submodule init`, `git submodule update --init`, `git sparse-checkout init`, `git maintenance register`, `git init` in an existing repository | Fails |
773 | Installing a hook into `.git/hooks` | Fails |
774 | `git worktree remove` / `prune` of a linked worktree that existed before the command | Fails; one added in the same command can be removed |
775 | Cloning a new submodule (`git submodule add`, `git submodule update` for one not yet cloned) | Fails on macOS; on Linux the clone lands but its config entry does not |
776 | `git branch --set-upstream-to`, `git checkout --track`, `git push -u` | Reports the refused write but exits 0; no upstream is recorded |
777
778 To add or initialise submodules, run it outside the sandbox (in a terminal, or through an approved danger-full-access retry); updating submodules that are
779 already cloned works inside it.
780
781 When a command's output names one of these paths, the bash result says so with
782 `sandbox.git_metadata_protected`, also when git exited 0. `additional_write_dirs` cannot grant it.
783
784 A protected file that already has another hard link refuses every confined
785 command with `sandbox.git_metadata_linked`, because a write through the other
786 name would reach it; the user removes that link outside the sandbox.
787
788 Limits:
789
790 - On Linux, bubblewrap can only mount over paths that exist and cannot pin a
791 symlink. Creating an absent `commondir`, `config.worktree` or hooks
792 directory, or swapping a symlink on the `gitdir:` path, is not stopped there.
793 - Closing that on Linux is the host's side: its own git has to pin its git and
794 common directories instead of rediscovering them.
795 - Existing worktree and submodule gitdirs get exact rules, up to 128 each on
796 macOS and 512 on Linux.
797 - On macOS, patterns cover the rest and gitdirs created later. They skip
798 `refs/` and `logs/`, so a branch or tag named `config` or `hooks` stays
799 writable, but a new submodule named `hooks` is protected whole.
800 - On macOS with more than 128 worktrees, `git worktree add` fails; past 128
801 submodules each command starts about 0.1 s slower.
802 - On Linux, past 512 gitdirs the whole `worktrees/` or `modules/` directory is
803 mounted read-only, and a command can cause that by planting `HEAD` files.
804 A command can likewise plant a submodule gitdir with a hard-linked config,
805 after which every confined command is refused until the user removes it.
806 - A repository created by a sandboxed command is protected from the next
807 command on.
808 - A `.git` made unrecognisable to git (for example a corrupted `HEAD`) sends
809 git's discovery further up.
810 - A repository nested in the workspace that is not a submodule gitdir under
811 `modules/` is not protected, including one a command creates and records as
812 a gitlink.
813 - The host can run such a repository's configuration through its gitlink
814 unless the host's own git excludes it.
815 - Hooks that `core.hooksPath` points outside `.git`, and files `include.path`
816 names, are ordinary workspace files.
817 - Windows has no shell sandbox, so none of this is enforced there.
818
819 **Session-private temporary directory.** Within one logical chat session, Bash
820 commands share a private temporary directory so consecutive calls can exchange
821 files through `$TMPDIR` (and, on Linux under bubblewrap, through literal
822 `/tmp`). No user setup is required: Reasonix automatically exports `TMPDIR`,
823 `TMP`, and `TEMP` for Bash and client-owned ACP terminals. The directory is
824 created lazily, is never the host public temporary root, and is rotated on
825 `/new`, `/clear`, resume of another session, and branch switches.
826 Model/settings hot rebuilds keep the same directory. Temporary files are not
827 durable storage: resume across process restarts does not restore them, and
828 scripts that need long-lived data should write into the workspace or a
829 user-specified path.
830
831 Reasonix-generated and project scripts should use the standard temporary
832 environment variables rather than hard-coding `/tmp`; users should not set
833 these variables themselves. For example:
834
835 ```sh
836 tmp_file="${TMPDIR:?}/result.json"
837 ```
838
839 ```powershell
840 $tmpFile = Join-Path $env:TEMP "result.json"
841 ```
842
843 | Platform | `$TMPDIR` / `$TMP` / `$TEMP` | Literal `/tmp` |
844 | --- | --- | --- |
845 | Linux + bubblewrap | Virtual `/tmp` (bound to the private dir) | Shared for the session (not a fresh empty tmpfs each call) |
846 | macOS Seatbelt | Host path of the private dir (allowed by policy) | Host macOS temporary directory; scripts should use `$TMPDIR` |
847 | Windows (no OS sandbox) | Host path of the private dir | Not promised to match (e.g. Git Bash `/tmp`) |
848
849 Independent sandboxes such as MCP servers keep their own isolation and do not
850 inherit the chat session's temporary directory. An approved sandbox-escape
851 command still receives the private temp environment variables, but on Linux its
852 literal `/tmp` is no longer mapped by bubblewrap.
853
854 **Windows note:** Windows has no OS-level shell sandbox. The restricted-token
855 backend is retired from enforcement because denying the current user's own SID
856 locked hosts out of their credential store and the token broke common
857 toolchains. Permission presets still apply as Reasonix tool-layer
858 boundaries: Read only refuses file writes and asks before every shell command,
859 and Workspace write keeps file tools inside `workspace_root` and `allow_write`
860 and asks before writing elsewhere. Shell commands in every preset run as the
861 current OS user without confinement, so `[sandbox] network` and shell-level
862 `forbid_read` are not enforced there; dedicated file tools still honor
863 `forbid_read`. Saved credential variables are removed from child environments,
864 but local tools run as the user and can deliberately read other user-readable
865 files. `[sandbox] bash = "enforce"` resolves to `off` on Windows and
866 `reasonix doctor` reports the ignored value.
867
868 When no OS sandbox backend is available, `bash = "enforce"` refuses bash
869 execution instead of running unconfined. Install the platform sandbox backend
870 (bubblewrap/`bwrap` on Linux, `sandbox-exec` on macOS) or set
871 `[sandbox] bash = "off"` to explicitly restore the pre-1.16 unconfined shell
872 behavior.
873
874 For coding-quality reports, run `reasonix doctor quality <branch-id-or-path>`
875 (add `--json` for structured output). This reads the selected session but emits
876 only content-free counts and profile categories: model family, runtime profile,
877 collaboration / approval modes, message and tool-call counts, verification and persisted
878 compaction-summary counts, plus desktop token/cache telemetry when available.
879 It omits transcript text, paths, session identifiers, tool arguments and output,
880 endpoints, and custom model names, so the result is suitable for a public issue
881 or Discussion. This differs from `reasonix doctor session`, whose support zip
882 contains the complete unredacted transcript and must remain in a trusted support
883 channel.
884
885 ## Capability diagnostics
886
887 Use this when a skill, slash command, hook, plugin package, MCP server, or
888 `AGENTS.md` is missing, shadowed, disabled, or fails to start. Full flag
889 reference, JSON schema, and issue codes:
890 **[Capability diagnostics](./CAPABILITY_DIAGNOSTICS.md)**.
891
892 ```bash
893 # Static (default): no network, no MCP child processes
894 reasonix doctor capabilities
895
896 # Machine-readable (stdout is pure JSON)
897 reasonix doctor capabilities --json
898
899 # Another workspace root
900 reasonix doctor capabilities --root /path/to/project
901
902 # Live MCP probe — only when you explicitly allow starting third-party servers
903 reasonix doctor capabilities --live --timeout 5s
904 ```
905
906 | Surface | How |
907 | --- | --- |
908 | CLI | `reasonix doctor capabilities` (above) |
909 | Desktop | **Settings → Diagnostics** — refresh, copy redacted JSON, optional “include current session runtime” (reads the active tab Host only; does **not** start MCP) |
910 | Agent | `/reasonix-guide` (built-in inline skill) or ask naturally; it prefers static doctor JSON before `--live` |
911
912 Exit code `0` allows warnings/info; `1` means at least one `error` (or a live
913 start failure); `2` is bad flags. This is separate from `reasonix doctor`
914 (providers/sandbox) and `reasonix plugin doctor <name>` (one package).
915
916 ## Plugins (MCP)
917
918 Reasonix is an MCP client. A `[[plugins]]` entry's `type` selects the transport:
919 `stdio` (default) launches a local subprocess (`command`/`args`/`env`); `http`
920 (Streamable HTTP) connects to a remote `url` with optional static `headers`
921 (`${VAR}` / `${VAR:-default}` expanded from the environment, so tokens stay out
922 of the file); `sse` connects to servers that still use the legacy persistent
923 GET + announced POST endpoint transport.
924
925 For a remote HTTP server without a static `Authorization` header, an
926 authentication challenge is shown as **Sign in**. Run
927 `reasonix mcp auth <name>` in the CLI, or click **Sign in** for that server in
928 the Desktop MCP panel. Reasonix performs OAuth metadata discovery, dynamic
929 client registration, PKCE S256 authorization, and refresh-token
930 rotation. Discovery and token requests use the same Reasonix network-proxy
931 settings as the MCP connection.
932
933 OAuth client and token state is kept outside the workspace in the server's
934 private Reasonix state directory, written with mode `0600`, and bound to the
935 full configured resource URL. An explicit static `Authorization` header always
936 takes precedence. **Clear authentication** removes only Reasonix's local OAuth
937 state; it does not sign out the third-party browser session. Reasonix opens the
938 browser only after an explicit sign-in action, never automatically from a
939 background tool-call failure. Removing the MCP server also removes its local
940 OAuth state unless a lower-priority declaration for the same resource becomes
941 effective.
942
943 Browse the official MCP Registry from **Settings → MCP servers → Browse
944 registry**, or use `reasonix mcp browse [query]` and
945 `reasonix mcp install <registry-name>`. Registry access is explicit and never
946 runs during startup. Entries that need secrets or required arguments are shown
947 as manual setup instead of being installed with an incomplete configuration;
948 query-specific cached results remain available during a registry outage.
949
950 The normal setup path is intentionally one step. Use Desktop's **Add and
951 connect**, `/mcp add`, or ask Reasonix to install a package or URL. These
952 explicit installs are saved to the user-global `config.toml` and are also
953 authorization: the server connects in the current session, and no second trust
954 step appears now or on the next startup. Servers declared by the current
955 project's `reasonix.toml` or `.mcp.json` remain in that project and are trusted
956 without a separate launch confirmation. Explicit deny rules still win. The
957 server's calls run
958 directly, including tools that declare `destructiveHint`. The dedicated Planner
959 still refuses destructive tools, and strict read-only sub-agents still expose
960 only hinted non-destructive readers.
961
962 MCP names are resolved once per workspace. Project declarations override
963 same-name global installs; inside a project, `reasonix.toml` overrides
964 `.mcp.json`. Editing updates the effective declaration in its original file,
965 and removing a higher-priority declaration reveals the next one instead of
966 deleting every same-name entry.
967
968 stdio servers keep one process for initialize, reads, and writes, so stateful
969 servers such as browsers retain sessions and open pages. Because an OS sandbox
970 is fixed when a process starts, this shared process uses the server's normal
971 process sandbox for every call; `readOnlyHint` and read-only sub-agent filtering
972 are dispatch policy, not a second per-call process sandbox.
973
974 Tools surface to the model as `mcp__<server>__<tool>`. A tool declaring MCP's
975 `readOnlyHint: true` joins parallel dispatch and the strict read-only tool
976 surfaces. Installing a server or declaring it in project configuration
977 authorizes the dedicated Planner to use all of its non-destructive
978 tools without another per-tool setting; strict read-only research sub-agents
979 receive only hinted non-destructive readers. Tools without the hint remain
980 write-capable for scheduling and mutation accounting. While planning, built-in
981 writers keep the ordinary permission posture. The dedicated Planner permits
982 authorized non-destructive MCP (including opaque writers) but hard-blocks
983 destructive or unauthorized targets; a single-model Plan without that dedicated
984 Planner keeps the older writer/destructive block until Plan exits.
985
986 Installing an MCP server is the authorization decision. After installation, all
987 of its tools run directly without a second server-level, per-tool, writer, or
988 destructive approval setting. Explicit global deny rules still win. The host
989 keeps `readOnlyHint` and `destructiveHint` internally for parallel scheduling,
990 Plan restrictions, strict read-only sub-agents, and cached-to-live safety
991 reclassification; these hints do not add user configuration.
992 Reasonix deliberately trusts an installed server to describe those hints
993 honestly. Planner/read-only filtering is therefore a workflow boundary for
994 trusted servers, not containment against a malicious MCP server; explicit deny
995 rules and the process sandbox remain host-controlled boundaries.
996
997 The retired `trusted_read_only_tools`, `default_tools_approval_mode`,
998 `tools.<raw>.approval_mode`, and `approvals_reviewer` fields are ignored when
999 loading older files and removed the next time Reasonix saves that MCP entry.
1000
1001 A server's **prompts** surface as `/mcp__<server>__<prompt>` slash commands
1002 (positional args after the command); its **resources** are pulled in by writing
1003 `@<server>:<uri>` in a message; `/mcp` lists connected servers and what each
1004 exposes. `make build` also produces `bin/reasonix-plugin-example` — a runnable
1005 reference stdio server (`echo`, `wordcount`, a `review` prompt, a style-guide
1006 resource) you can copy.
1007
1008 ```toml
1009 [[plugins]] # local stdio server
1010 name = "example"
1011 command = "reasonix-plugin-example"
1012 # startup_timeout_seconds = 60 # optional initialize + tools/list cap
1013 # call_timeout_seconds = 600 # optional per-server MCP call timeout
1014 # tool_timeout_seconds = { "generate_video" = 1800 } # optional raw MCP tool names
1015
1016 [[plugins]] # remote server over Streamable HTTP
1017 name = "stripe"
1018 type = "http"
1019 url = "https://mcp.stripe.com"
1020 headers = { Authorization = "Bearer ${STRIPE_KEY}" }
1021 ```
1022
1023 Enabled MCP servers start connecting automatically in the background after a
1024 session begins, so chat stays usable while tools come online. Use `/mcp` or the
1025 desktop MCP panel to refresh status, reconnect a server, inspect failures, or
1026 disable a server for the current session. For a read-only config/runtime health
1027 report across skills, hooks, packages, and MCP (without changing settings), see
1028 [Capability diagnostics](./CAPABILITY_DIAGNOSTICS.md)
1029 (`reasonix doctor capabilities` or **Settings → Diagnostics**).
1030
1031 An interactive caller waits only briefly for a cold server. If that wait ends,
1032 the shared startup continues in the background rather than being killed and
1033 restarted; retry the tool after it comes online. `mcp_startup_timeout_seconds`
1034 (default `30`) bounds the full launch, authorization, initialize, and
1035 `tools/list` sequence. `mcp_call_timeout_seconds` applies only after the server
1036 is connected. Either value can be overridden per server.
1037
1038 **Already have an `.mcp.json`?** Drop it in the project root and Reasonix
1039 reads it as-is — the `mcpServers` spec (`command`/`args`/`env`, `type`/`url`/
1040 `headers`, `${VAR}` expansion) maps field-for-field onto `[[plugins]]`. Both
1041 sources are merged; on a name collision `reasonix.toml` wins.
1042
1043 ```json
1044 {
1045 "mcpServers": {
1046 "filesystem": { "command": "npx", "args": ["-y", "@modelcontextprotocol/server-filesystem", "/path"] },
1047 "stripe": { "type": "http", "url": "https://mcp.stripe.com", "headers": { "Authorization": "Bearer ${STRIPE_KEY}" } }
1048 }
1049 }
1050 ```
1051
1052 **Upgrading from `0.x`?** Your old `~/.reasonix/config.json` is still read for its
1053 `mcpServers` (honouring `mcpDisabled`) as a lowest-priority source, so MCP servers
1054 keep working — move them into `reasonix.toml`'s `[[plugins]]` or a `.mcp.json` when
1055 convenient.
1056
1057 ## Slash commands
1058
1059 In an interactive `reasonix` session, built-in commands (`/compact`, `/context`, `/new`, `/clear`, `/rewind`,
1060 `/tree`, `/branch`, `/switch`, `/todo`, `/model`, `/mcp`, `/skills`, `/hooks`,
1061 `/memory`, `/goal`, `/output-style`, `/sandbox`, `/language`,
1062 `/reasoning-language`, `/help`) run
1063 locally — `/help` lists them all. Built-in **skills** such as `/init`,
1064 `/explore`, `/test`, and `/reasonix-guide` also appear in the slash menu and via
1065 `run_skill` (bodies load on demand; only the index line is cache-stable). Use
1066 `/reasonix-guide` when you need config or capability troubleshooting; it points
1067 at `reasonix doctor capabilities` (see
1068 [Capability diagnostics](./CAPABILITY_DIAGNOSTICS.md)). `/new` starts a new
1069 session while saving the previous transcript for history/resume; `/clear`
1070 discards the current context without saving it and asks for confirmation. `/tree`
1071 shows saved conversation branches, `/branch [name]` forks the current
1072 conversation tip, `/branch <turn> [name]` forks from an earlier checkpointed
1073 turn, and `/switch <id|name>` loads another branch. **Custom commands** are
1074 Markdown files under `.reasonix/commands/` (project) or `~/.reasonix/commands/`
1075 (user) — `review.md` becomes `/review`, a subdirectory namespaces it
1076 (`git/commit.md` → `/git:commit`). The body is a prompt template; invoking the
1077 command sends it as a turn.
1078
1079 `/compact [focus]` runs as a session maintenance operation. Desktop and remote
1080 clients show one recoverable progress card and keep Stop available while the
1081 summary request can still be cancelled. Messages sent during compaction remain
1082 in the existing session inbox and run in order after compaction finishes or
1083 stops. Stopping compaction does not withdraw those queued messages. If a
1084 summary adapter does not stop within the cancellation grace period, or the
1085 result cannot be saved safely, the session enters an explicit recovery state
1086 instead of accepting a late summary or reporting idle.
1087
1088 Compaction and ordinary turns share one foreground admission gate, including
1089 direct CLI, ACP, Bot, inbox, desktop, and remote entry points. In the terminal
1090 UI, `Esc` stops a cancellable compaction without clearing the current draft.
1091 An empty history or empty selected range completes as “No history to compact”
1092 without calling the summary model. The operation card keeps its error, applied
1093 result, and estimated token change across refreshes and reconnects; a persisted
1094 progress record is marked interrupted only after runtime synchronization proves
1095 that no matching operation is active.
1096
1097 Maintenance owns the shared session runtime as well as the controller, so a
1098 controller replacement cannot take over during compaction. Start and terminal
1099 operation records are durably checkpointed independently of ordinary turns.
1100 If either checkpoint fails, queued work stays behind the recovery barrier.
1101 An older idle snapshot cannot interrupt a newer live operation; inferred
1102 interruptions can be corrected by fresh runtime evidence. Unknown operation
1103 states display an unavailable-record message instead of success. Empty selected
1104 ranges are no-ops only below the hard context limit; an oversized context still
1105 requires safe recovery.
1106
1107 ### Subagent profiles
1108
1109 Subagent profiles are manual Skills with `runAs: subagent` and
1110 `invocation: manual`. They are stored in the same project/global Skill roots as
1111 the desktop settings page, so profiles created on either surface are immediately
1112 available to the other after the session refreshes. In interactive chat, invoke
1113 one with `/<name> <task>`; Reasonix runs an isolated child loop and keeps only
1114 the task and final answer in the parent conversation.
1115
1116 The headless CLI provides explicit management and execution commands without
1117 changing the ordinary `reasonix run` task semantics:
1118
1119 ```bash
1120 reasonix subagent list
1121 reasonix subagent create reviewer --description "Review changes" --prompt-file reviewer.md --tools read_file,grep,bash
1122 reasonix subagent edit reviewer --effort high --model deepseek-pro
1123 reasonix subagent try reviewer "review the current diff" # always read-only
1124 reasonix subagent run reviewer "review and fix the current diff"
1125 reasonix subagent delete reviewer --yes
1126 ```
1127
1128 `create` defaults to project scope when a workspace is available and to global
1129 scope otherwise; pass `--scope project|global` to choose explicitly. `edit`
1130 changes only explicitly supplied fields, and an empty value such
1131 as `--model=` or `--tools=` clears that field. The profile editors deliberately
1132 refuse custom-path or richer hand-authored Skills so they cannot discard
1133 frontmatter, references, or scripts; manage those files through the Skills
1134 workflow instead. Built-in profiles have no editable file, so `edit` accepts
1135 only `--model` and `--effort` for them and stores the same per-name overrides as
1136 the desktop settings page.
1137
1138 See [Subagent profiles](./SUBAGENT_PROFILES.md) for the complete CLI reference,
1139 Skill file format, model precedence, safety behavior, and troubleshooting.
1140
1141 Context Engine v2 separates two intentionally different layers:
1142
1143 - **Standing instructions** come from hierarchical `REASONIX.md`, `AGENTS.md`,
1144 and `CLAUDE.md` files. Put rules here when they must be present on every
1145 relevant turn. User-global files load first, then workspace and deeper target
1146 directories; within one directory, `.local.md` variants win.
1147 - **Background memory** stores one durable fact per Markdown file. Each fact has
1148 an immutable ID, monotonic revision, timestamps, independent `type`
1149 (`user`, `feedback`, `project`, `reference`) and `scope` (`project`,
1150 `global`), plus freshness metadata. Facts may be stale, so they never outrank
1151 the current request or standing instructions.
1152
1153 Reasonix automatically recalls a small set of relevant facts before each real
1154 user turn. It searches the raw user message, suppresses generic requests such as
1155 "continue", prefers project facts over equivalent global fallbacks, down-ranks
1156 stale facts, and appends at most four facts / 2,400 characters to the user turn.
1157 This dynamic suffix does not rewrite the cache-stable system prompt or tool
1158 schemas. Use `/memory recall` to see the selected IDs, scores, reasons,
1159 freshness, budget, and suppression decision.
1160
1161 New, bounded, non-sensitive project/reference facts can be created
1162 automatically with no setup or approval click. Other memory changes follow the
1163 active permission preset and explicit `ask` / `deny` rules. The storage layer
1164 makes the automatic create grant create-only, so it cannot overwrite a fact
1165 that appears concurrently.
1166 A top-level headless controller may use the same one-shot low-risk create path;
1167 sub-agents and headless surfaces without the owning scoped controller fail closed.
1168
1169 `forget` archives rather than permanently deletes. Every update snapshots the
1170 previous revision; restore and archive recovery always create a higher revision
1171 instead of overwriting history:
1172
1173 ```text
1174 /memory instructions
1175 /memory recall
1176 /memory revisions <id-or-name>
1177 /memory restore <id-or-name> <revision>
1178 /memory archived
1179 /memory recover <archive-path>
1180 ```
1181
1182 The desktop Context Center shows the same provenance, conflicts, revision
1183 history, recall trace, and recovery actions. Opening its Suggestions tab scans
1184 recent local user turns automatically; candidates are deduplicated against both
1185 memory scopes and instruction bodies, but nothing is saved until the user
1186 accepts it. Remote workspaces never fall back to local desktop memory or
1187 sessions.
1188
1189 Legacy facts are upgraded in place with deterministic IDs and revision 1;
1190 missing scope is inferred from the containing directory. Migration is
1191 idempotent, old clients retain safe routing, and legacy Memory v5 transcripts
1192 remain readable. For the complete behavior and privacy/cache contract, see
1193 [`Context Engine v2`](SESSION_MEMORY_RETRIEVAL.md).
1194
1195 ```markdown
1196 ---
1197 description: Review the staged diff
1198 argument-hint: [focus-area]
1199 ---
1200 Review the staged diff. Focus on $ARGUMENTS, list bugs with file:line.
1201 ```
1202
1203 `$ARGUMENTS` expands to all space-separated args, `$1`…`$N` to positional ones.
1204 MCP prompts also appear here as `/mcp__<server>__<prompt>`.
1205
1206 ## Embedded documentation retrieval
1207
1208 Reasonix bundles the Markdown files from `docs/` and the reviewed
1209 `release-notes/releases.json` catalog into each CLI and Desktop build. The
1210 read-only `docs` tool searches that exact offline corpus with local BM25
1211 retrieval and can read a complete matching section with source provenance. It
1212 renders every release in both languages under paths such as
1213 `changelog/v1.19.5.md` and `changelog/v1.19.5.zh-CN.md`, so questions about a
1214 specific version, upgrades, fixes, or known risks work offline. The agent should
1215 use the tool before web search or assumptions when a question concerns Reasonix
1216 configuration, CLI/Desktop behavior, release history, permissions, MCP, memory,
1217 recovery, providers, or maintainer workflows.
1218
1219 No setup, network connection, vector database, or embedding service is needed.
1220 Search results prefer the query language while retaining explicit `en`,
1221 `zh-CN`, audience, and catalog filters. The docs capability is exposed through
1222 the unified `use_capability` surface for every task. Every result reports
1223 the product version, immutable source revision, and corpus SHA-256 digest. Release
1224 CI compiles the CLI and rejects publication unless that embedded manifest matches
1225 the candidate's `docs/*.md`, `release-notes/releases.json`, and build identity. A
1226 newer online `main-v2` page therefore cannot silently replace version-matched
1227 local guidance or release history.
1228
1229 Use `/docs` to inspect the bundled corpus identity and usage examples without
1230 calling a model. Use `/docs <question>` (for example,
1231 `/docs 1.19.5 changelog`) to make Reasonix search the corpus locally first and
1232 then pass the version-matched evidence to the currently configured AI for a
1233 sourced answer. This command path does not depend on the model deciding to call
1234 the `docs` tool, while ordinary natural-language questions may still use the
1235 tool automatically. Existing custom commands and compatible plugin or skill
1236 aliases keep ownership of `/docs`; when that happens, CLI and Desktop normally
1237 expose the built-in corpus as `/reasonix:docs` instead. If that qualified name is
1238 also already owned, Reasonix selects the next free `reasonix:`-qualified fallback
1239 without displacing it. A remote Desktop uses the host's resolved command catalog,
1240 so the displayed entry always matches what that host will execute.
1241
1242 Pull requests that change user-visible CLI, Desktop, configuration, provider,
1243 permission, or tool behavior must declare whether embedded documentation was
1244 updated. When no documentation change is needed, the declaration must explain
1245 why the existing version-matched guidance remains correct.
1246
1247 ## Goal
1248
1249 Goal is the unified runtime for long-running objectives. Reasonix keeps working
1250 until the goal is complete, blocked, paused, or cleared. Ordinary chat never
1251 changes collaboration mode implicitly; choose Goal in the composer or use
1252 `/goal` to start a long-running objective.
1253
1254 Goal has no default model-round, cross-Run turn, wall-clock, or numeric
1255 no-progress limit. It continues until completion, a genuine user/external
1256 blocker, manual stop/pause, an unrecoverable external error, or an explicit
1257 user-selected budget. To place an optional ceiling on an unattended loop, set:
1258
1259 ```toml
1260 [agent]
1261 goal_token_budget = 20000000
1262 ```
1263
1264 The default is `0` (off). Reaching a positive token budget produces one summary
1265 and a resumable `budget_spend` pause. `/goal resume` grants a fresh configured
1266 slice while cumulative Goal statistics remain intact. Explicit positive
1267 `max_steps`, task time, and task cost budgets remain available as well.
1268 Cumulative rounds, tokens and real provider requests are tracked and shown as
1269 statistics; a token limit appears only when explicitly configured. A paused
1270 goal keeps its objective and runtime history — use `/goal resume` to continue,
1271 or `/goal pause` to pause a running goal manually. `/goal status` shows rounds,
1272 requests and tokens. Exact consecutive tool calls receive reminders at the
1273 third, fifth, and eighth occurrence; the calls still execute. An active, armed
1274 goal continues after an ordinary model final through the runtime idle driver;
1275 there is no per-turn `continue` report. The model uses `update_goal(complete)`
1276 when it judges the whole objective finished and `update_goal(blocked)` for a
1277 concrete persistent blocker. No evaluator, todo percentage or host quality
1278 gate decides completion. Restoring, importing or forking loads the durable
1279 goal disarmed; a directly authorized user turn or explicit UI action must
1280 resume it.
1281
1282 For complex work, write the objective as a
1283 [task contract](./TASK_CONTRACT.md): Context, Request, Output format,
1284 Constraints, and Pause policy. Goal mode treats those sections as the boundary
1285 for autonomous work. It keeps going with sensible defaults unless the next step
1286 requires an irreversible or externally visible operation, a scope change, or
1287 information only the user can provide.
1288
1289 Legacy simple/write/research classes and Goal sidecars are read only at the
1290 explicit compatibility/import boundary. There is no separate research runtime
1291 to configure. Current Goal state is a versioned `goal/state` projection in the
1292 linear v3 session, and activation is process-local. Legacy
1293 `.reasonix/autoresearch/<task-id>/` archives remain read-only. Deprecated
1294 budget flags are accepted for compatibility but hidden from help and
1295 completion.
1296
1297 ### Model task progress
1298
1299 `todo_write` updates progress for the current top-level turn. A newly admitted
1300 Goal round starts with a fresh todo plan; compaction, steer and interactive
1301 answers inside that round keep the current list. The host does not finish todos
1302 when a turn or Goal ends. `complete_step` is absent from discovery; an old call
1303 returns a normal `tool_retired` result and never changes task state.
1304
1305 ## @ references
1306
1307 Embed `@` references in a message and Reasonix resolves them before sending, as
1308 tagged context blocks: `@path/to/file` (or `@dir`) injects a local file's
1309 contents (or a directory listing), and `@<server>:<uri>` injects an MCP
1310 resource. A local path is only treated as a reference when it actually exists,
1311 so ordinary `@mentions` stay literal. Typing `/` or `@` opens an autocomplete
1312 menu — slash commands, or hierarchical file navigation (one directory level at a
1313 time, descend into folders) plus MCP resources.
1314
1315 ## Two-model collaboration
1316
1317 `reasonix setup` manages providers, model lists, credentials, connection tests,
1318 and the default model. It stages changes until Save and exit, and synchronizes
1319 provider access with the desktop app. See the [CLI reference](./CLI.md#configure-providers).
1320 Running two models together (executor + planner, separate cache-stable sessions)
1321 is a one-line edit afterwards — set `planner_model` to any other enabled provider:
1322
1323 ```toml
1324 [agent]
1325 planner_model = "deepseek-pro" # used as the low-frequency planner
1326 ```
1327
1328 The planner sees loaded `REASONIX.md` / `AGENTS.md` memory and a small read-only
1329 research tool set, so it can inspect relevant files before handing a plan to the
1330 executor. Writer and workflow tools remain executor-only.
1331
1332 Reasonix routes each turn deterministically without another classifier model.
1333 Ordinary requests always stay with the executor. The dedicated planner runs
1334 only for an explicit `plan first` / `先规划` request, an explicit wait-for-
1335 approval boundary, an explicit `plan only` / `不要执行` request, or Goal
1336 start. Wording such as "complex refactor" or "fix login" does not start the
1337 planner. There is no automatic planning depth. Explicit Plan Mode
1338 remains a separate host workflow on the executor and is never planned twice.
1339 `just do it` / `直接改` also stays with the executor. Execution boundaries are
1340 recognized across the request, not only at its beginning, while quoted
1341 examples are ignored. Bare plan-first requests continue from the planner to
1342 the executor automatically. Requests that explicitly say to wait for
1343 confirmation pause at the host approval boundary and continue to the executor
1344 after approval. Only an explicit `plan only` / `不要执行` request ends the
1345 current turn with the plan persisted and no execution; a later user instruction
1346 can continue in the same session. The phase detail records a privacy-safe route
1347 and reason code for diagnosis without logging the user prompt.
1348
1349 The planner uses one stable system prompt. A small host-authored
1350 `<planner-turn>` block names the explicit route and preserves the planner
1351 prefix cache after the one-time prompt upgrade. The plan should separate
1352 verified from candidate touchpoints and include non-goals, risks, acceptance
1353 criteria, and command-level verification when evidence supports them. The
1354 planner must call `submit_plan`; a prose reply without a submitted plan is a
1355 protocol error. If a planner still does not finalize after its bounded
1356 research and finalization round, the turn fails closed on every route and the
1357 executor is not started. The incomplete planner turn is rolled back instead of
1358 leaving an unusable continuation tail.
1359
1360 Ordinary clean finals end the turn. Goal, review, and guardian flows keep
1361 their own continuation constraints. In Goal mode, if an active todo produces
1362 no new completion, unique read, command, or mutation past the stall threshold,
1363 the host forces a smaller step, different tool/approach, focused delegation,
1364 or a real blocker report, then execution continues. Exact repeats do not count
1365 as progress; new host-observed work renews the lease. Two-level task lists keep
1366 the same single-current contract: the active level-1 sub-step is the one
1367 `in_progress` item while its level-0 phase stays `pending`; sub-steps are worked
1368 and signed off in order, and once every sub-step has completed the phase itself
1369 becomes `in_progress` for its own final sign-off.
1370
1371 Existing `[agent].max_steps` and `planner_max_steps` keys remain syntactically
1372 accepted during upgrades, but their values are ignored and removed with a
1373 one-time notice. This prevents a stale hidden limit from truncating automatic
1374 progress or inherited subagent work. Use the one-off CLI `--max-steps` flag when
1375 an explicit run budget is needed; unattended bots retain `[bot].max_steps`,
1376 where `0` means continuous execution and a positive value is explicit.
1377
1378 **An ordinary chat task has no limit of any kind by default** — not rounds, not
1379 tokens, not time, not money. It runs until the model finishes, an adaptive
1380 guard decides it stopped making progress, or you stop it.
1381
1382 An optional spend gate is available when you want one. It bounds a whole task
1383 (every "continue" included, until you start unrelated work), and on crossing it
1384 the task produces one tool-free summary and pauses; the work is saved and the
1385 next message continues it.
1386
1387 ```toml
1388 [agent]
1389 task_cost_budget = 5.0 # in the model's pricing currency
1390 task_time_budget_minutes = 60 # wall clock across the whole task
1391 ```
1392
1393 Both are off unless set. In particular, `task_time_budget_minutes = 0` (and
1394 legacy negative values) disables the time gate; only a positive value enables
1395 it. Neither has a default, because a stop is a judgement
1396 only you can make: no amount of money is portable across models — a budget
1397 loose enough for a cheap model would land a frontier model within a couple of
1398 answers — and a long task is as often the job you asked for as it is a runaway.
1399
1400 Cost applies only to a priced model. Without a price table that axis stays
1401 inactive rather than reading the task as free; use the time axis for a free or
1402 local model.
1403
1404 Rounds are deliberately not an axis. A turn that reaches a high round count
1405 without spending much is one whose rounds are individually cheap and fast,
1406 which is the case least worth interrupting. Use the one-off `--max-steps` flag
1407 when you specifically want a run bounded by rounds.
1408
1409 Subagent skills inherit the executor model by default. Set `subagent_model` to
1410 run them on another configured model, or use `subagent_models` to override only
1411 specific skills such as `review` or `security_review`.
1412
1413 Subagents may delegate one more layer by default: the root session is depth 0,
1414 first-layer subagents are depth 1, and the maximum `max_subagent_depth = 2`
1415 means a depth-1 workflow can dispatch a depth-2 reviewer or implementer. Depth-2
1416 subagents do not receive recursive agent/skill tools. Set
1417 `agent.max_subagent_depth = 1` to restore the old single-layer boundary. This is
1418 intended for workflows such as Superpowers where a workflow skill may dispatch a
1419 reviewer subagent, while still avoiding unbounded recursion and background
1420 fanout.
1421
1422 Use `read_only_task` when planning needs isolated, deeper research without
1423 granting write-capable delegation. Use `read_only_skill` when the same need is
1424 best expressed through an existing skill. Both run ephemeral read-only
1425 subagents with only read-only research tools plus safe foreground bash, return
1426 only the final answer, and do not create resumable subagent transcripts.
1427 Read-only nested delegation may be available until `max_subagent_depth` is
1428 reached, but writer-capable `task` / `run_skill` remain unavailable inside these
1429 read-only child registries. Every task shares one tool surface: call
1430 `use_capability` for `read_only_skill` and other optional tools. Subsequent
1431 writer calls still pass through Permissions/Sandbox.
1432
1433 Every strict read-only child is built through one shared construction
1434 pairing — `RunReadOnlySubAgentWithSession` / `NewReadOnlyAgent` — which marks
1435 the child permanently read-only and applies a final registry filter. The filter
1436 removes writers, destructive MCP targets, readers from unauthorized servers,
1437 and every host-mutating tool. User-installed and project-configured servers are
1438 authorized immediately. Eligible readers may still start on demand. These are
1439 the strict read-only entrances:
1440
1441 | Entrance | Purpose |
1442 | --- | --- |
1443 | `read_only_task` | Isolated read-only research child from the main session |
1444 | `parallel_tasks` (read-only) | Concurrent read-only research children |
1445 | `fleet` with `read_only: true` | Parallel profile-aware batch (forced read-only per item) |
1446 | `read_only_skill` | The same isolation driving an existing skill |
1447 | `reasonix review` (CLI) | Read-only review of a diff or branch |
1448 | Desktop preview/review subagents | Read-only desktop analysis surfaces |
1449
1450 These children run your configured hooks, each under its own session ID.
1451 The Planner uses `<session>:planner`, derived from the parent session every time
1452 a hook fires, so it follows `/new` and `/clear`. The desktop profile try run
1453 loads the workspace's project hooks and your global hooks, as a chat session in
1454 that workspace would, under `try-subagent:<run>`. `reasonix review` is
1455 different: it runs only your own hooks, meaning global
1456 `<Reasonix home>/settings.json` and installed plugins, under `review:<run>`. It
1457 never runs `.reasonix/settings.json` from the checkout under review, and its
1458 hooks use the `[tools.shell]` from your user `config.toml`, never the checkout's
1459 `reasonix.toml`, because reviewing an untrusted branch must not execute commands
1460 or interpreters that branch configures.
1461
1462 `reasonix review` usually runs inside a checkout you have not vetted, so its
1463 tools, skills and hooks come only from your own configuration. The review
1464 skill resolves from the built-in and your user-level skill directories, never
1465 the checkout's `.reasonix/skills` (or `.agents`, `.agent`, `.claude`). Search
1466 (`[tools.search]`) and the bash sandbox (`[sandbox]`) come from your user
1467 `config.toml`, never the checkout's `reasonix.toml`. The checkout's config still
1468 picks the provider when it sets `default_model`; pass `--model` to choose your
1469 own.
1470
1471 In persisted sessions, `parallel_tasks` and `fleet` return a bounded preview
1472 plus one `Subagent reference` per completed child instead of concatenating every
1473 full answer into a truncation-prone tool result. The parent can call
1474 `read_subagent_result` with that reference and page by `offset_bytes`; results
1475 are scoped to the current conversation lineage and workspace. Headless runs
1476 without a persisted parent session remain ephemeral and receive fair bounded
1477 previews, but cannot mint durable references.
1478
1479 Persisted child results include `status` (`completed`, `partial`, `failed`, or
1480 `cancelled`) and `retryable`. Partial or retryable failed runs retain a visible
1481 answer and reference so the parent can inspect them with `read_subagent_result`
1482 or continue the same `task`/`run_skill` transcript with `continue_from`.
1483
1484 The interactive two-model Planner uses a dedicated construction path
1485 (`NewPlannerAgent`): it still blocks bash, file writers, and ordinary writers,
1486 but may call authorized, non-destructive MCP through the fixed
1487 `use_capability` proxy without requiring `readOnlyHint`. Direct `mcp__*`
1488 schemas never enter the Planner tool list, so MCP install/connect churn does
1489 not change the Planner cache prefix after the one-time schema upgrade. Missing
1490 `readOnlyHint` no longer blocks the Planner; tools with `destructiveHint` are
1491 zero-exec and should be written into the plan for the Executor.
1492 In Balanced two-model sessions the Executor has its own frontend for the same
1493 stable proxy, so an `auto_start=false` or destructive capability discovered by
1494 the Planner remains callable by capability ID after handoff. Planner and
1495 Executor ledgers/audits stay isolated and only the Host connection is shared.
1496
1497 Ordinary `task` / `fleet` sub-agents also get the same fixed proxy (session-
1498 shared Host and connections, per-agent frontend/ledger) and may call installed
1499 or project-configured MCP without `readOnlyHint`. Those calls use the trusted
1500 MCP permission path (live authorization plus explicit deny only); writer and
1501 destructive calls are still serialized, recorded as mutations, and subject to
1502 closed-loop evidence/lease guards rather than Planner handoff. Strict
1503 `read_only_task` / `read_only_skill` / review sub-agents share the stable proxy
1504 schema and connection reuse but keep the strict execution gate
1505 (`authorized && readOnlyHint && !destructiveHint`). Profile `allowed-tools`
1506 MCP names convert to capability-id allowlists on the proxy; children never
1507 inherit dynamic `mcp__*` schemas.
1508
1509 Inside a strict child, `use_capability` re-checks the resolved target before
1510 commit/permission/hooks/execution. An unconnected eligible MCP reader may start
1511 on demand from the current schema cache. Before `tools/call`, cached
1512 `readOnlyHint`/`destructiveHint` facts are checked against the live
1513 initialize/tools-list result; a reader-to-writer change or destructive promotion
1514 means zero executions and a normal retry through the current boundary. A
1515 schema-only change refreshes the cache for the next session without interrupting
1516 the authorized call. Runtime enablement, authorization, and the complete
1517 connection identity are checked again immediately before dispatch, so a
1518 same-name client from another project/tab cannot be reused accidentally. An
1519 unauthorized server cannot raise privileges there. This strict-child boundary
1520 is narrower than the dedicated Planner: the Planner accepts authorized opaque
1521 non-destructive MCP, while a strict child requires an explicit reader hint and
1522 never exposes writers at all.
1523
1524 Reasonix uses **fact-driven execution**. Ordinary requests always enter the
1525 executor. There is no automatic task mode or selectable quality floor. Planner,
1526 Goal, permission, sandbox, and the task contract are independent states.
1527
1528 Ordinary turns end when the model ends normally, even with unfinished todos or failed checks. There are no quality retries or todo-driven continuation rounds. Active Goals alone drive automatic continuation; approved Plans execute as ordinary tasks. Historical checkpoints remain available through an explicit `Continue checks` request, without restoring quality gates. Protocol recovery, cancellation, and resource limits remain independent.
1529
1530 Every task shares the same provider-visible core tool surface: direct
1531 read/bash/edit/write, background-shell lifecycle tools, `ask`/`compress` when
1532 registered, and the stable `use_capability` proxy for optional tools (search,
1533 MCP, skills, subagents, docs, web_fetch, and so on). Calling `use_capability`
1534 never expands the top-level provider schema, so the prompt-cache tool prefix
1535 stays stable across every task. The Harness minimal preset is not a task
1536 complexity mode.
1537
1538 The model decides whether to investigate, update todos, verify changes, or request review. User and project instructions stay in task context. File counts, authentication paths, schemas, migrations, and explicit verification language do not create host acceptance obligations. The host retains action permissions, preapproval Plan write restrictions, sandboxing, workspace leases, and structured-file stale-version protection. An ordinary tool failure does not skip later independent calls in the same batch. Results show actual commands, failures, interruptions, and checks made stale by later edits; model completion reports are separate from these facts.
1539
1540 For interactive frontends, Plan Mode is always an explicit user choice. Select
1541 Plan in the desktop collaboration-mode control or cycle to Plan with
1542 `Shift+Tab` in the CLI. Reasonix first drafts a plan, then waits for approval
1543 before the workflow switches to implementation. Tool calls made while drafting
1544 still use the current Permissions and Sandbox. Legacy `agent.auto_plan` and
1545 `agent.auto_plan_classifier` values are ignored and removed from the user config
1546 during upgrade. The visible reasoning language can be changed with
1547 `/reasoning-language auto|zh|en` in the
1548 session, or `reasonix config reasoning-language auto|zh|en` in a shell/script.
1549 Pass `--local`
1550 to the reasoning-language shell command only when you intentionally want a
1551 project-local override.
1552
1553 The why behind separate sessions (keeping each model's prefix cache-stable) is in
1554 [`SPEC.md` §3.5](./SPEC.md#35-two-model-collaboration-coordinator).
1555
1555 lines MARKDOWN