/** * `agent exec --sandbox` (#396, rev 23; more modes and `--sandbox-fallback` * #482, rev 26) and the truthful `native_sandbox` / `approvals` report on the * `start` event and in `agent scan --json`. * * Vocabulary (doc/agent-exec-protocol.md §3.2): * native_sandbox * read-only the vendor CLI refuses every file write and every * shell command (its own sandbox, or its own deny rules) * workspace-write the vendor CLI confines writes to the cwd (and the * CLI's temp/state dirs) * restricted #482: the CLI's own approval rules apply and anything * they would ask about is refused (headless). What that * covers is the CLI's rule set, incl. the user's own * allow rules — not a file-system boundary * full the runtime has a native sandbox and it is OFF this * turn (e.g. codex danger-full-access, grok `off`) * none the runtime has no native sandbox monomind drives; * the CLI runs with the user's own file-system rights * monomind claude only: no vendor sandbox, monomind enforces * the access mode itself (canUseTool + PreToolUse) * approvals * off native tool calls run without asking (yolo/always-approve) * on the CLI's own approval rules apply; a call that would ask is * refused, since a headless turn has nobody to answer * n/a no native approval step (claude: monomind decides each call; * vercel: no native tools) * * Strictness, tightest first: read-only > restricted > workspace-write > full * (SANDBOX_RANK). `restricted` sits above workspace-write because every CLI * that has it refuses shell commands and file edits under its default rules * (antigravity still writes its own temp dir), but below read-only because * the user's own allow rules (and, for opencode, an agent's own permission * block) can widen it. * * `--sandbox full` is always accepted and means "today's default": monomind * adds no native sandbox. It never loosens a runtime whose own default is * tighter (dsh stays workspace-write). The other modes are listed only where * the vendor CLI really has them and they were checked: * codex — `--sandbox read-only|workspace-write` (codex-cli 0.156 --help; * behaviour verified with `codex sandbox`, see cli-sandbox.ts). * grok — `--sandbox read-only|workspace` profiles (grok 1.0.13: both * resolve and start the Landlock/bwrap sandbox, an unknown * profile is rejected — see cli-sandbox.ts). * dsh — DSH_PERMISSION_MODE `read-only|workspace-write` (dsh-runner- * stream.ts, captured live when the runner was built). * copilot — #482, copilot 1.0.89, live: without --allow-all-tools a tool * call that needs approval is refused ("Permission denied and * could not request permission from user"): `restricted`. * `--deny-tool=write --deny-tool=shell` (deny beats every allow * rule, `copilot help permissions`): `read-only`. * `--allow-tool=write --deny-tool=shell` without * --allow-all-paths: edits only under the cwd, --add-dir and * the temp dir (an absolute path outside and a symlink out of * the cwd were both refused), no shell: `workspace-write`. * antigravity — #482, agy 1.2.13, live: without * --dangerously-skip-permissions shell commands and file writes * are auto-denied, in the cwd too (only the temp dir is * writable by agy's default rules), and the turn then ends * with no reply: `restricted`. Its `--sandbox` * switch failed here ("connecting to sandbox server") and the * model retried with the sandbox bypassed, so it is not used. * opencode — #482, opencode 1.18.32, live: OPENCODE_PERMISSION set to * `ask` for edit/bash/task/external_directory, every ask * rejected: `restricted` (not read-only: an agent's own * `permission` block in the user's or project's opencode.json * overrides it — verified). * pi — #482: `--tools read,grep,find,ls` (pi's documented read-only * mode, already `--access read`, #388): `read-only`. * claude — #482: scoped/read access only. monomind's canUseTool + * PreToolUse gate runs no native tool that is not allow-listed, * so no native Write/Edit/NotebookEdit ever runs and Bash runs * only the caller's --allow-bash-prefix commands: `read-only` * and `workspace-write` (native_sandbox "monomind"). * Not the others: qwen/kimicode/cline/aider are not installed here * (unverified), crush and hermes have no mode monomind can drive headless. */ import type { RuntimeKind } from './daemon.js'; export type SandboxMode = 'read-only' | 'restricted' | 'workspace-write' | 'full'; export declare const SANDBOX_MODES: readonly SandboxMode[]; export type NativeSandbox = SandboxMode | 'none' | 'monomind'; export type Approvals = 'off' | 'on' | 'n/a'; export interface SandboxReport { native_sandbox: NativeSandbox; approvals: Approvals; } /** #482: what to do when the runtime lacks the requested `--sandbox` mode. */ export type SandboxFallback = 'fail' | 'strictest' | 'run'; export declare const SANDBOX_FALLBACKS: readonly SandboxFallback[]; /** The `--sandbox` values each runtime accepts (`agent scan --json` sandbox_modes). */ export declare const RUNNER_SANDBOX_MODES: Record; /** The accepted modes; claude with `--access full` has only `full` (the * allow-list is off and the SDK sandbox is not wired into agent exec). */ export declare function sandboxModes(runtime: string, access?: 'scoped' | 'read' | 'full'): readonly SandboxMode[]; /** Tightest first (see the module doc). */ export declare const SANDBOX_RANK: Record; /** * #482 `--sandbox-fallback strictest`: the requested mode when the runtime * has it; else the loosest supported mode that is still at least as strict * (so nothing is loosened and as much of the request as possible is kept); * else — every supported mode is looser — the tightest one there is. */ export declare function strictestFallback(requested: SandboxMode, modes: readonly SandboxMode[]): SandboxMode; export interface ResolvedSandbox { /** The mode handed to the runner, reported as `sandbox_applied` * (undefined = no `--sandbox`). */ mode?: SandboxMode; error?: string; /** Why `mode` differs from the request (a `status` notice), if it does. */ notice?: string; } /** * The mode a turn really runs in for `--sandbox `. A mode the * runtime lacks is an error under `fallback: 'fail'` (the default), else * replaced (`strictest`, or `full` = the runtime default for `run`) with a * notice. An org role below 'push' (MONOMIND_GIT_LEVEL in `--env` or in * monomind's own env) then runs codex/grok in workspace-write * (cli-sandbox.ts); the flag may tighten that but never loosen it. */ export declare function resolveSandbox(runtime: string, requested: SandboxMode | undefined, envs: Array | undefined>, opts?: { fallback?: SandboxFallback; access?: 'scoped' | 'read' | 'full'; }): ResolvedSandbox; /** * What the vendor CLI really runs with this turn. `sandbox` is the mode * handed to the runner (undefined = no `--sandbox`); `env` is the runner's * env (MONOMIND_GIT_LEVEL / DSH_PERMISSION_MODE are read from it, as the * runners do). */ export declare function sandboxReport(runtime: string, opts: { access: 'scoped' | 'read' | 'full'; sandbox?: SandboxMode; env?: Record; }): SandboxReport; /** #482 scan field: what each accepted mode reports on a scoped turn. */ export declare function sandboxModeReports(runtime: string): Partial>; //# sourceMappingURL=runner-sandbox.d.ts.map