Files
deepseek-harness/packages/sandbox/sandbox-policy
kingwl 2e7cdddb89 Merge remote-tracking branch 'origin/master' into cross-family-fs-sandbox
# Conflicts:
#	.agents/notes/implemented/feature/2026-07-14-cross-family-fs-sandbox.i18n.yaml
#	.agents/notes/implemented/feature/2026-07-14-cross-family-fs-sandbox.md
#	.agents/notes/implemented/feature/2026-07-14-cross-family-fs-sandbox.zh.md
#	docs/capability-seams.md
#	docs/cordis-catalog/events.md
#	docs/cordis-catalog/services.md
#	docs/event-producer-consumer.md
#	docs/module-graph.md
#	docs/persistence-catalog.md
#	docs/rfc/INDEX.md
#	examples/acp-agent/README.md
#	examples/acp-agent/fs.cordis.snapshot.yml
#	examples/acp-agent/fs.cordis.yml
#	examples/acp-agent/tests/snapshots/escalation-approved/session.jsonl
#	examples/acp-agent/tests/snapshots/escalation-rejected/session.jsonl
#	examples/acp-agent/tests/snapshots/hook-cc-pretool-ask/session.jsonl
#	examples/acp-agent/tests/snapshots/permission-switching/session.jsonl
#	examples/acp-agent/tests/snapshots/workspace-context/system-prompt.expected.md
#	examples/acp-agent/tests/snapshots/workspace-context/tool-schemas.expected.json
#	examples/acp-agent/tests/snapshots/workspace-edit/system-prompt.expected.md
#	examples/acp-agent/tests/snapshots/workspace-edit/tool-schemas.expected.json
#	packages/bash/bash/src/index.ts
#	packages/bash/tool-bash/package.json
#	packages/bash/tool-bash/src/index.ts
#	packages/bash/tool-bash/tests/tools.spec.ts
#	packages/cordis/tool-cordis/src/api-catalog.ts
#	packages/fs/README.md
#	packages/fs/tool-fs/src/edit.ts
#	packages/fs/tool-fs/src/write.ts
#	packages/sandbox/README.md
#	pnpm-lock.yaml
2026-07-20 11:44:37 +08:00
..

dsh-sandbox-policy — the sandbox policy home (ctx.sandboxPolicy)

The single owner of the deployment's sandbox policy: the file-effect SandboxMode a session starts from, the workspace-write boundary root, and the per-session sandbox/mode override every enforcing capability family reads.

Why a shared home

Two families enforce the same mode vocabulary: the sandboxed bash executor (@deepseek-ai/dsh-bash-sandbox) and the sandboxed filesystem provider (@deepseek-ai/dsh-fs-sandbox). If each held its own mode + workspaceRoot config, the two could drift into a split world — bash confined to one root while fs fences another, exactly what the sandbox RFC warns against. Both inject ctx.sandboxPolicy and read the SAME default instead. The cross-family fs sandbox RFC records the decision.

Config

  • mode — the deployment default SandboxMode (read-only / workspace-write / danger-full-access), validated at load. Default read-only (fail-safe).
  • workspaceRoot — the absolute directory workspace-write may write under. Default process.cwd(), resolved absolute either way.

Surface

  • ctx.sandboxPolicy.defaultMode / ctx.sandboxPolicy.workspaceRoot — the deployment default the enforcing implementations read for their resolve fallback and boundary.
  • effectiveSandboxMode(events) — the pure fold of a session's sandbox/mode events (the last switch wins, or undefined). The tool layers apply it to stamp each call, so neither the executor nor the provider depends on session events.
  • setSandboxMode(session, mode) — THE write path for a per-session override: appends exactly one sandbox/mode event. The switch IS its event; nothing mutates the mode out of band.
  • SANDBOX_MODES — every mode, for option advertisement and runtime validation.

The per-session store

A runtime switch (an ACP session/set_config_option, a test scenario) is one log-only sandbox/mode event on the session it applies to. effective = fold(events) ?? the deployment default, so an override survives restart by replay, two sessions never see each other's state, and there is no external config store. The event is log-only (the approval/* precedent): the model learns the mode from the enforcing tools' denial markers, never from the event. Execution honors the fold in each tool layer, weakest-precedence beneath an escalation grant.

Model Experience

Indirectly, through dsh-tool-bash and dsh-tool-fs, which render the effective mode this service holds in their [sandbox: …] denial markers and escalation prompts; the sandbox/mode event itself never reaches the model.

KV Cache effect

No direct invalidation; the named consumers own any request-prefix changes, and the mode is deliberately absent from the prompt.

Known Limitations and Deferred Work

  • workspaceRoot is process-wide and fixed for the service's lifetime — a per-session workspace root is a deferred phase of the sandbox RFC; this package centralizing the root is its groundwork, not its design.
  • File-effect modes onlySandboxMode governs file effects; network and process policy are outside its vocabulary, so no knob here restricts them.