Extend SandboxMode enforcement from bash to the filesystem tools, the sandbox RFC's deferred cross-family phase. - dsh-sandbox-policy (new, ctx.sandboxPolicy): the single home for the deployment default mode + workspaceRoot and the per-session override event, renamed bash/sandbox-mode -> sandbox/mode and moved here with its fold/setter. Decouples the bash seam from dsh-session. - dsh-fs-sandbox (new): SandboxedFileSystem extends LocalFileSystem and fences write/edit by the per-call mode (read-only denies, workspace-write contains to the workspace + temp roots via the shared writableRoots, danger passes through); reads pass through. Structured FS_SANDBOX_DENIED; in-lock parent re-canonicalization. A policy fence in trusted code, not a kernel boundary. - dsh-sandbox: the shared escalation kit (writableRoots, the strictly-wider ladder, denial/hint markers, approveEscalation) both tool families use; approveEscalation takes a structural approver so dsh-sandbox gains no approval/agent dependency, and both tools stay duplication-free. - tool-fs: write/edit advertise sandbox_permissions/justification under a confining ctx.fs, map FS_SANDBOX_DENIED to the shared [sandbox: ...] marker, and resolve the same one-approved-wider retry. - examples/acp-agent: composes sandbox-policy + fs-sandbox, drops the gating that disabled the fs stack under confined modes. RFC docs/rfc/implemented/feature/2026-07-14-cross-family-fs-sandbox.md; the old sandbox RFC's In-process/deferred/FAQ sections updated to shipped fact.
DeepSeek Harness Runtime Wheel
English | 中文
Runtime carrier package for the Python SDK (dist deepseek-harness-runtime-bin, module deepseek_harness_runtime): it locates the bundled runtime binaries the deepseek-harness client spawns, and ships the default configuration behind zero-config runs.
Runtime carriers
Two carriers coexist under src/deepseek_harness_runtime/runtime/, both injected by the repo's scripts/build-exe-for-python-sdk.ts build and both gitignored:
- exe (production) — single-file executables
dsh-jsonrpc-agent-pkg-<platform>-<arch>(platform:linux/macos; arch:x64/arm64). No Node installation needed on the target machine. This is the only carrier that ships in wheel distributions; this package does not publish sdists. - node (dev-only) — the full deploy closure under
runtime/node/(package.json+node_modules/), executed asnode runtime/node/node_modules/@deepseek-ai/dsh-jsonrpc-agent/lib/bin.json a system Node >= 22.19. It is the current checkout's source build, meant for repo-local development and verification only; it is never selected automatically and is excluded from distributions.
Both carriers hold the same content, defined once: the package.json at this package's root is the deploy root of the single-exe pipeline — a pure dependency manifest (no code of its own) whose dependency closure IS both the plugin set compiled into the exe and the tree materialized into runtime/node/. Adding a plugin to the distribution means adding one dependency line there and rebuilding.
Missing carriers raise FileNotFoundError naming the acquisition routes: build via scripts/build-exe-for-python-sdk.ts in a deepseek-harness checkout, or install the matching platform runtime wheel produced by the build-exe-for-python-sdk CI workflow. The workflow retains wheels rather than standalone executable archives. Acquisition strategy is deliberately separate from the lookup interface, so an on-demand download can replace it later without touching callers.
Each wheel contains exactly one executable. The fixed tags are py3-none-manylinux_2_28_x86_64, py3-none-manylinux_2_28_aarch64, and py3-none-macosx_11_0_arm64; the build hook rejects py3-none-any, absent or multiple executables, and unsupported platform tags. The repository root package.json supplies the shared version for this package and the SDK, and a python-vX.Y.Z release tag must match it.
Resolution API
resolve_bundled_launch_args(mode=None) -> tuple[str, ...]— the argv tuple that launches the bundled runtime:(exe_path,)in exe mode,(node_path, bin_js_path)in node mode. Mode selection: explicit argument >DSH_RUNTIME_MODEenv var (exe|node) > automatic. Automatic resolution finds the production exe ONLY — the dev-only node carrier must be opted into explicitly so a production deployment can never silently ride on a source build.bundled_runtime_path() -> Path— the platform exe path (exe carrier only; the node carrier has no single-path equivalent and launches via the argv tuple above).bundled_default_config_path() -> Path— the checked-in default config (see below).bundled_package_dir() -> Path— the installed package data root.
Zero-config design
The runtime binary always demands an explicit config ($DSH_CORDIS_CONFIG, or a config path as an argv positional argument) and exits loudly without one — that hard semantic is part of the runtime's design and this package does not soften it. The bin (dsh-jsonrpc-agent) boots only the plugins the config lists; the serving surface (the stdio JSON-RPC server) is itself one of its entries (@deepseek-ai/dsh-jsonrpc), and without it the booted agent has no channel to the outside. This package checks in runtime/cordis.yml (the JSON-RPC serving entry, agent core, preloaded DeepSeek adapter, JSONL session persistence, local bash, each parameterized by the DSH_* env vars the SDK sets); when the caller uses no explicit config channel, the deepseek_harness client injects that file's path via DSH_CORDIS_CONFIG (injection conditions: sdk README). Zero-config is thus an explicit, visible parameter pass in the wrapper, not a hidden fallback in the runtime.