Skip to content

Conversation

@stippi
Copy link
Owner

@stippi stippi commented Nov 10, 2025

No description provided.

- CLI and run configs now accept/persist sandbox policies, and README/docs describe the flags. - Session configs/tests
carry sandbox settings, and command execution is wrapped by the new SandboxedCommandExecutor to honor policies. -
Utility modules and docs were updated to reflect the new crate boundaries and sandbox scaffolding.
... already given in lib.rs before including the module.
- Added a real macOS seatbelt pipeline: SandboxedCommandExecutor now wraps restricted policies by spawning
/usr/bin/sandbox-exec with a generated SBPL derived from SessionConfig.sandbox_policy. See
crates/code_assistant/src/utils/sandboxed_executor.rs and the new policy builder in crates/sandbox/src/seatbelt.rs (+
embedded .sbpl profiles). Non-macOS hosts still fall back with a warning. - Covered the new behavior with integration
tests in crates/code_assistant/src/tests/sandbox_tests.rs, verifying read-only denial, workspace-root allowance, and
path-escape blocking. - Exposed sandbox selection end-to-end in the GPUI: a new SandboxSelector component
(crates/code_assistant/src/ui/gpui/sandbox_selector.rs) sits beside the model selector, InputArea emits SandboxChanged,
backend persists it via the new BackendEvent::ChangeSandboxPolicy, SessionManager stores it, and UI updates arrive
through UiEvent::UpdateSandboxPolicy. RootView keeps the dropdown in sync per session, and terminal/ACP backends handle
the new responses. Key wiring touches include crates/code_assistant/src/ui/backend.rs,
crates/code_assistant/src/session/manager.rs, crates/code_assistant/src/ui/gpui/{input_area.rs,root.rs,mod.rs},
crates/code_assistant/src/ui/ui_events.rs, and terminal state.
- Added SandboxContext to track canonical writable roots and reuse them across sessions; SessionInstance now owns an
Arc<SandboxContext> and keeps it in sync with init_path reloads (crates/code_assistant/src/session/instance.rs:14-86,
crates/sandbox/src/context.rs:1-44). SandboxAwareProjectManager registers every resolved project path with the context,
so agent sessions automatically learn about additional roots as they’re opened
(crates/code_assistant/src/config.rs:20-102). SessionManager threads the context through to both the wrapped project
manager and the sandboxed executor (crates/code_assistant/src/session/manager.rs:273-320).

Command Permissions

- Introduced SandboxCommandRequest and extended the CommandExecutor trait to accept optional per-command metadata
(crates/command_executor/src/lib.rs:1-64). DefaultCommandExecutor, SandboxedCommandExecutor, ACP’s terminal executor,
and all mocks implement the new signature; the sandboxed executor now merges session policy, registered roots, and
per-command hints before launching seatbelt, and propagates network flags via env vars
(crates/command_executor/src/default_executor.rs:1-80, sandboxed_executor.rs:1-340,
crates/code_assistant/src/acp/terminal_executor.rs:10-131, crates/code_assistant/src/tests/mocks.rs:1-220). Test helpers
and ACP handlers now pass the extra argument (usually None) wherever execute is called
(crates/code_assistant/src/tests/sandbox_tests.rs:1-90, crates/code_assistant/src/tests/mocks.rs:560-590).

Tool & Explorer Integration

- ExecuteCommandTool and WriteFileTool derive a sandbox request from the selected project root so every shell command
and formatter run is scoped to the proper directory (crates/code_assistant/src/tools/impls/execute_command.rs:1-240,
write_file.rs:1-220). fs_explorer::Explorer now canonicalizes the project root up front, resolves every user-supplied
path lexically, and rejects accesses that escape the root; added the tiny path-clean dependency to handle non-existent
paths safely (crates/fs_explorer/src/Cargo.toml:9-15, src/explorer.rs:1-730).
- Introduced a permissions module with a generic mediator interface plus an AcpPermissionMediator that calls ACP’s
session/request_permission. It snapshots the current tool call (via the new ACPUserUI::tool_call_update) and sends
permission options (“Allow this command” vs “Deny”), using tokio::task::block_in_place to drive the ACP connection
synchronously so the future stays Send. - AgentComponents/Agent now accept an optional permission_handler. ACP sessions
create one (using the live ACPUserUI + AgentSideConnection) and pass it through SessionManager::start_agent_for_message;
other entry points pass None.

Tool Context & Command Execution

- Extended ToolContext with an optional permission_handler. All context construction sites (agent runner, MCP handler,
tests/mocks) now populate the new field (defaulting to None outside ACP). - ExecuteCommandTool consults the handler
before running a command: it packages command line + working dir into a PermissionRequest and aborts if the user denies.
The sandbox request logic remains unchanged, so approved commands still run inside the configured sandbox.

Supporting Changes

- Added SandboxAwareProjectManager roots into SandboxContext and ensured SessionManager threads the context and
permission handler when spawning agents. - Updated the ACP agent path to keep both the concrete Arc<ACPUserUI> (for
permission snapshots) and the trait object Arc<dyn UserInterface> (for the session manager), and wired the mediator only
when the client connection is available. - Updated docs (docs/sandbox-plan.md) to note that Phase 1 path hardening is
mostly done and that the permission UX is now being implemented via ACP.
- execute_command now treats sandbox blocks as normal tool failures and only prompts when the LLM explicitly opts in.
The new ask_user_approval flag on ExecuteCommandInput/schema lets the model request an escalation; after approval the
tool sets SandboxCommandRequest::bypass_sandbox so the SandboxedCommandExecutor re-runs the command outside Seatbelt
(crates/code_assistant/src/tools/impls/execute_command.rs:15, crates/command_executor/src/lib.rs:16,
crates/command_executor/src/sandboxed_executor.rs:57). If the user denies, the tool surfaces a clear error; approvals
(Allow once / Allow always) reuse the recorded decision on subsequent calls.

- The ACP permission mediator now offers “Allow always” and remembers that choice per session. Selecting it toggles an
atomic flag so future ask_user_approval requests for execute_command auto-grant without UI round-trips
(crates/code_assistant/src/permissions/acp.rs:13). PermissionDecision gained GrantedOnce/GrantedSession variants so
tools can distinguish scopes (crates/code_assistant/src/permissions/mod.rs:27).

- ToolTestFixture can host mock permission mediators, and the execute_command test suite was expanded to cover the new
flows (no prompt, denial, sandbox bypass) ensuring the bypass_sandbox bit and permission call counts behave as expected
(crates/code_assistant/src/tests/mocks.rs:1006, crates/code_assistant/src/tools/impls/execute_command.rs:360).
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.

2 participants