Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion desktop/frontend/src/components/ApprovalModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ export function ApprovalModal({
}) {
const t = useT();
const isPlanApproval = approval.tool === "exit_plan_mode";
const isPlanModeReadOnlyCommand = approval.tool === "plan_mode_read_only_command";
const toolLabel = isPlanModeReadOnlyCommand ? "bash" : approval.tool;
const isFreshHumanApproval = requiresFreshHumanApproval(approval.tool);
const subject = approval.subject.trim();
const subjectSummary = subject.split(/\r?\n/).find((line) => line.trim())?.trim() ?? "";
Expand Down Expand Up @@ -298,7 +300,7 @@ export function ApprovalModal({
barRef={cardRef}
titleId="tool-approval-title"
title={t("approval.toolPending")}
badges={<PromptBadge>{approval.tool}</PromptBadge>}
badges={<PromptBadge>{toolLabel}</PromptBadge>}
meta={toolMeta}
headerActions={
<>
Expand Down
13 changes: 13 additions & 0 deletions docs/GUIDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ planner_max_steps = 0 # user/global only; planner read-only tool-call
reasoning_language = "auto" # visible reasoning text: auto|zh|en
# plan_mode_allowed_tools = ["custom_reader"] # extra read-only custom tools only;
# # does not unlock blocked tools or unsafe bash
# plan_mode_read_only_commands = ["gh issue view", "gh pr diff"] # extra read-only shell prefixes for planning
# planner_model = "deepseek-pro" # optional low-frequency planner
# subagent_model = "deepseek-pro" # optional default for runAs=subagent skills
# subagent_models = { review = "deepseek-pro", security_review = "deepseek-pro" }
Expand Down Expand Up @@ -127,6 +128,18 @@ compatibility escape valve. It never unlocks known blocked plan-mode tools such
as `bash`, `task`, writers, installers, or memory mutation tools, and it never
bypasses bash's plan-mode safety checks.

Use `[agent].plan_mode_read_only_commands` when plan-mode research needs a
specific shell command that Reasonix cannot classify but you know is read-only,
such as `gh issue view` or an internal query CLI. Entries are concrete command
prefixes, not tool names: `["gh issue view"]` permits `gh issue view 4572`, while
`bash`, `sh`, and other shell interpreters are ignored. Shell operators,
redirection, command substitution, background execution, and unsafe built-in
command flags remain blocked while planning. In interactive plan mode, Reasonix
can also ask you to trust a concrete unknown query prefix the first time it is
needed; the persistent choice writes the same
`[agent].plan_mode_read_only_commands` entry. Auto/YOLO approval never answers
this trust prompt.

### Environment variables

Most day-to-day settings belong in `config.toml` or the global Reasonix `.env`
Expand Down
9 changes: 9 additions & 0 deletions docs/GUIDE.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ planner_max_steps = 0 # 仅用户/全局;规划器只读工具调
reasoning_language = "auto" # 可见思考过程语言:auto|zh|en
# plan_mode_allowed_tools = ["custom_reader"] # 仅声明额外只读自定义工具;
# # 不能解锁被计划模式阻断的工具或 unsafe bash
# plan_mode_read_only_commands = ["gh issue view", "gh pr diff"] # 计划模式额外只读 shell 前缀
# planner_model = "deepseek-pro" # 可选的低频规划器
# subagent_model = "deepseek-pro" # runAs=subagent skill 的默认模型
# subagent_models = { review = "deepseek-pro", security_review = "deepseek-pro" }
Expand Down Expand Up @@ -116,6 +117,14 @@ planner / read-only research 可用的可信只读工具。优先使用 MCP 只
再在 plugin 上写 `trusted_read_only_tools`,`plan_mode_allowed_tools` 保留为兼容逃生阀。它不再解锁 `bash`、`task`、
写文件工具、安装器、记忆变更工具等计划模式已知阻断项,也不会绕过 bash 在计划模式下的安全检查。

当计划阶段需要运行 Reasonix 尚不能自动分类、但你确认只读的 shell 查询命令时,使用
`[agent].plan_mode_read_only_commands`,例如 `gh issue view`、`gh pr diff` 或内部只读查询 CLI。
这里声明的是具体命令前缀,不是工具名:`["gh issue view"]` 会允许 `gh issue view 4572`,
但 `bash`、`sh` 等 shell 解释器前缀会被忽略。shell 操作符、重定向、命令替换、后台进程、
以及内置命令里的写能力参数在计划模式下仍会被阻断。交互式计划模式第一次需要某个未知查询前缀时,
Reasonix 也可以提示你确认是否信任它为只读;选择持久信任会写入同一个
`[agent].plan_mode_read_only_commands` 配置。Auto/YOLO 审批不会替用户回答这个信任提示。

### 环境变量

多数日常设置应写在 `config.toml` 或前文提到的 Reasonix 全局 `.env` 中。下面这些变量是进程级高级开关;
Expand Down
25 changes: 17 additions & 8 deletions docs/MIGRATING.md
Original file line number Diff line number Diff line change
Expand Up @@ -103,14 +103,23 @@ and DeepSeek prefix-cache–oriented design.
external tools**: `[agent].plan_mode_allowed_tools` now only declares extra
read-only custom/external tools. It no longer unlocks known blocked plan-mode
tools such as `bash`, `task`, writers, installers, or memory mutation tools, and
unsafe bash commands still remain blocked. An MCP/plugin tool whose read-only
status comes from the server's untrusted `readOnlyHint` is confirmed the first
time an interactive plan-mode run needs it; choose the persistent option to
write the plugin-level `trusted_read_only_tools` raw-name list. Auto/YOLO tool
approval does not answer this trust prompt, although a session or persistent
trust choice prevents repeat prompts for the same MCP tool. Non-interactive
runs still fail closed, so pre-seed `trusted_read_only_tools` or declare a
concrete `mcp__<server>__<tool>` when no user can approve. In the desktop MCP
unsafe bash commands still remain blocked. To migrate old
`plan_mode_allowed_tools = ["bash", ...]` configs, move concrete read-only
shell prefixes such as `gh issue view` or internal query CLIs to
`[agent].plan_mode_read_only_commands`; do not declare shell interpreters or
writer-capable commands there. Interactive plan-mode runs can also ask you to
trust a concrete unknown query prefix once, and the persistent choice writes
the same `plan_mode_read_only_commands` entry. Auto/YOLO tool approval does
not answer this bash trust prompt. Use `read_only_task` / `read_only_skill`
instead of trying to unlock `task` / `run_skill` while planning. An MCP/plugin tool
whose read-only status comes from the server's untrusted `readOnlyHint` is
confirmed the first time an interactive plan-mode run needs it; choose the
persistent option to write the plugin-level `trusted_read_only_tools` raw-name
list. Auto/YOLO tool approval does not answer this trust prompt, although a
session or persistent trust choice prevents repeat prompts for the same MCP
tool. Non-interactive runs still fail closed, so pre-seed
`trusted_read_only_tools` or declare a concrete `mcp__<server>__<tool>` when no
user can approve. In the desktop MCP
panel, expand a server and use **Pre-trust read-only** for currently listed
`readOnlyHint` tools, per-tool **Pre-trust** for audited readers, or
**Untrust** to remove a tool; those actions write the same
Expand Down
13 changes: 11 additions & 2 deletions docs/SPEC.md
Original file line number Diff line number Diff line change
Expand Up @@ -316,8 +316,16 @@ func (p Policy) Decide(toolName string, readOnly bool, args json.RawMessage) Dec
decision: `auto`, `yolo`, and the approved-plan execution window do not answer
it, but an explicit session grant still prevents repeat prompts for the same
tool. Non-interactive sessions and declined approvals remain fail-closed.
Writers, installers, memory mutation, process
control, and `complete_step` (read-only yet post-approval only, so it
Bash is gated separately: built-in read-only commands and concrete prefixes
declared in `[agent].plan_mode_read_only_commands` may run. Interactive
controllers may also ask once before running an unknown query-shaped prefix
and may remember a persistent approval as the same
`plan_mode_read_only_commands` entry. This bash trust prompt is also a fresh
user decision: `auto`, `yolo`, and the approved-plan execution window do not
answer it, while explicit session/persistent trust prevents repeat prompts for
that prefix. Shell operators, background execution, shell interpreters, and
unsafe arguments stay blocked while planning. Writers, installers, memory
mutation, process control, and `complete_step` (read-only yet post-approval only, so it
self-reports plan-unsafe) are refused; the enforced invariant is
PlanSafe ⇒ ReadOnly. An untrusted read-only MCP/plugin tool is therefore
blocked until the user approves or pre-trusts it, and it is excluded from
Expand Down Expand Up @@ -523,6 +531,7 @@ memory_compiler = { enabled = true, verbosity = "observe" } # user/global only
reasoning_language = "auto" # visible reasoning text: auto|zh|en
# plan_mode_allowed_tools = ["custom_reader"] # extra read-only declarations for custom tools;
# # cannot unlock known blocked tools or unsafe bash
# plan_mode_read_only_commands = ["gh issue view", "gh pr diff"] # extra read-only shell prefixes for plan mode
# planner_model = "deepseek-pro" # optional: two-model collaboration (low-frequency planner)
# subagent_model = "deepseek-pro" # optional default for runAs=subagent skills
# subagent_models = { review = "deepseek-pro", security_review = "deepseek-pro" }
Expand Down
Loading
Loading