Skip to content

feat(sandbox): gate outside-sandbox file access through an approval modal#696

Merged
esengine merged 1 commit into
mainfrom
feat/outside-sandbox-approval
May 12, 2026
Merged

feat(sandbox): gate outside-sandbox file access through an approval modal#696
esengine merged 1 commit into
mainfrom
feat/outside-sandbox-approval

Conversation

@esengine

Copy link
Copy Markdown
Owner

Summary

Adds an approval-gated escape hatch from the project sandbox, so the model can read/write files outside the reasonix code --dir root after the user explicitly approves — mirroring what run_command already does for shell allowlists.

When a filesystem tool resolves a path that escapes the sandbox:

  1. safePath now distinguishes "sandbox-relative model convention" (/src/foo.ts, ../escape) from "absolute system path the user might actually want" (/Users/foo/..., /etc/..., C:\Users\...). The former still throws as before; the latter routes to the gate.
  2. A new path_access PauseGate kind blocks the tool until the user resolves the modal.
  3. PathConfirm renders three options:
    • allow once — approves this access; session cache covers follow-up reads in the same directory without re-prompting (cleared on process exit).
    • always allow — appends the directory prefix to projects[root].pathAllowed in ~/.reasonix/config.json. Subsequent sessions skip the prompt.
    • deny — tool throws user denied access to <path> (with optional context via Tab).
  4. Parallel reads under the same prefix de-dupe via an in-flight Promise so one modal covers all of them.

Mirror of the shell-allowlist machinery: same ConfirmationChoice shape, same per-project persistence shape, same Tab-to-add-context UX, same audit semantics.

Safety property preserved: without a gate listener (i.e. headless / non-interactive contexts), outside-sandbox paths still refuse rather than silently succeed.

Closes #684

Test plan

  • tests/filesystem-outside-sandbox.test.ts — 8 cases: gate dispatched with right payload, deny throws, run_once dedups follow-up reads, relative escape still refused, /src/foo.ts convention preserved, write_file routes with intent=write, Windows drive-letter routing, allowlist exposed.
  • tests/config.test.ts — pathAllowed CRUD + coexistence with shellAllowed on the same project entry.
  • tests/filesystem-tools.test.ts — replaced the legacy "POSIX-absolute remaps into sandbox" assertion with the new "no escape without consent" one + kept the /<sandbox-relative> model-convention case.
  • npx vitest run — 2681 passed / 2 skipped (174 → 175 files)
  • npm run lint — clean
  • npm run typecheck — clean

…odal

Filesystem tools now route any absolute-system path that escapes the
project sandbox (`/Users/foo`, `/etc/...`, `C:\Users\...`) through a
new PathConfirm modal: allow once / always allow this directory / deny.
Mirrors the existing run_command flow — a shared PauseGate kind
`path_access`, a per-project `pathAllowed` list persisted in
~/.reasonix/config.json, and a session-scoped run-once cache so
follow-up reads under an approved directory don't re-prompt.

Closes #684
@esengine esengine merged commit 08a41e7 into main May 12, 2026
3 checks passed
@esengine esengine deleted the feat/outside-sandbox-approval branch May 12, 2026 08:38
esengine added a commit that referenced this pull request May 12, 2026
…il, CardStream fix (#705)

npm-only release. The Tauri desktop source is in the repo and the CLI
subcommand works, but installer bundles for macOS / Windows / Linux
don't ship this round (separate release once signing's settled).

Highlights:
- Tauri desktop client with multi-tab concurrent runtimes (#689)
  plus a near-full polish pass: wallet balance, version chip, active-
  plan rail, abortable pause-gates, edit-gate pill, en + zh-CN i18n,
  shared pause-policy module dedup'd with the CLI TUI (#701)
- checkpoint API + git-changes panel in the embedded dashboard (#682)
- outside-sandbox file access approval modal (#696)
- MCP loading pill + readiness gate on tool dispatch (#687)
- escalate-after flag for flash → pro threshold (#699)

Fixes:
- CardStream Maximum-update-depth crash, quantize window so boundary
  cards stop oscillating (#700, #702)
- `reasonix code` bridges config key to env + lazy subagent client so
  fresh installs can reach the setup wizard (#703)
- pinned-mode scroll shrinks coalesced (#666), generic CSI key decode
  (#692), shell-confirm preview clamp (#691), frontmatter BOM/folded
  lines (#690), MCP error classification (#688), and more
ChasLui pushed a commit to ChasLui/DeepSeek-Reasonix that referenced this pull request May 23, 2026
…odal (esengine#696)

Filesystem tools now route any absolute-system path that escapes the
project sandbox (`/Users/foo`, `/etc/...`, `C:\Users\...`) through a
new PathConfirm modal: allow once / always allow this directory / deny.
Mirrors the existing run_command flow — a shared PauseGate kind
`path_access`, a per-project `pathAllowed` list persisted in
~/.reasonix/config.json, and a session-scoped run-once cache so
follow-up reads under an approved directory don't re-prompt.

Closes esengine#684
ChasLui pushed a commit to ChasLui/DeepSeek-Reasonix that referenced this pull request May 23, 2026
…il, CardStream fix (esengine#705)

npm-only release. The Tauri desktop source is in the repo and the CLI
subcommand works, but installer bundles for macOS / Windows / Linux
don't ship this round (separate release once signing's settled).

Highlights:
- Tauri desktop client with multi-tab concurrent runtimes (esengine#689)
  plus a near-full polish pass: wallet balance, version chip, active-
  plan rail, abortable pause-gates, edit-gate pill, en + zh-CN i18n,
  shared pause-policy module dedup'd with the CLI TUI (esengine#701)
- checkpoint API + git-changes panel in the embedded dashboard (esengine#682)
- outside-sandbox file access approval modal (esengine#696)
- MCP loading pill + readiness gate on tool dispatch (esengine#687)
- escalate-after flag for flash → pro threshold (esengine#699)

Fixes:
- CardStream Maximum-update-depth crash, quantize window so boundary
  cards stop oscillating (esengine#700, esengine#702)
- `reasonix code` bridges config key to env + lazy subagent client so
  fresh installs can reach the setup wizard (esengine#703)
- pinned-mode scroll shrinks coalesced (esengine#666), generic CSI key decode
  (esengine#692), shell-confirm preview clamp (esengine#691), frontmatter BOM/folded
  lines (esengine#690), MCP error classification (esengine#688), and more
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

沙箱只能在特定项目下运行,能不能弄成全局的

1 participant