Runtime safety: mandatory policy and real cancellation - #181
Conversation
Review: approved ✅ — this is the most important PR in the stackThe bug being fixed is real and was severe. On Verified in the diff
Two behavior changes worth recording (neither blocking):
Validation: CI green both runners. Locally at the stack tip: typecheck, lint |
…ajors (#215) Covers the 31-PR Codex alignment stack (#180-#210) plus the dependency work (#211-#214, #155, #177-#179). Leads with the security section because that is what this release is: the central tool gate could be skipped entirely when `mode` was omitted (#181), and the desktop renderer held provider credentials (#192). Upgrade notes call out the two things a user could otherwise be surprised by — the ~6.7 MB → ~115 MB desktop size increase from the Node sidecar, and that the plugin capability RPC is not an OS boundary. Co-authored-by: t <t@t> Co-authored-by: Claude Opus 5 <[email protected]>
`deepcode mcp serve` exposes Read/Write/Edit/Bash/Grep/Glob to whatever MCP client connects — usually another agent. It called `tool.execute` directly: no mode, no permission rules, no file contract, no PreToolUse hooks. The CLI did not pass a sandbox config either, so Bash ran unsandboxed as well. This is the same shape as the `runAgent` bypass fixed in #181, in an entry point that fix did not reach. DEVELOPMENT_PLAN §"风险" listed it — "`deepcode mcp serve` 反向暴露的线程/权限模型缺失", with the mitigation "M3 出独立 design doc". The design doc was never written and the feature shipped anyway. Every call now goes through `dispatchToolCall`. `gate` is a required field on `BuildMcpServerOpts` rather than an optional one, because AGENTS.md's rule is that safety must not depend on a host remembering an argument — optional is how this happened. Nobody is attached to that pipe, so `ask` is refused rather than granted; otherwise "whoever connected" becomes the authority on what may run. A permissive `permissions.defaultMode` is clamped to `default` through the same `resolveTriggerMode` a scheduled job uses, since `bypassPermissions` is a decision about sitting at a REPL. `--mode` is the explicit opt-in back out, and `--sandbox` now applies too. Directory trust gates project settings, so an untrusted checkout cannot widen the posture of the server serving it. This is breaking: a peer can now do what `permissions.allow` says and nothing else. That is the point, and the startup banner says which mode is in effect. Co-Authored-By: Claude Opus 5 <[email protected]>
Summary
Validation
pnpm docs:checkpnpm lint(3 pre-existing warnings, 0 errors)pnpm format:checkpnpm typecheckpnpm testpnpm buildcargo check --manifest-path apps/desktop/src-tauri/Cargo.tomlcargo test --manifest-path apps/desktop/src-tauri/Cargo.toml(29 passed)Stack
Depends on #180. This is the safety/cancellation slice of PR 1 in
docs/CODEX_ALIGNMENT_PLAN.md; RuntimeHost assembly and background ownership can follow without weakening these invariants.