Add P0 execution substrate behind frozen MCP tools - #46
Merged
Merged
Conversation
Land command/exec-shaped Runner DTOs, a gateway-owned PermissionProfile and operator Environment registry, in-memory resource serialization, and an opt-in ContainerRunner over CodeSpace JSON. Default exec stays host InProcessRunner; linux-container environments fail closed. Isolated codespace-codex-runtime takes process-hardening and UDS only. Co-authored-by: Cursor <cursoragent@cursor.com>
Keep MCP schemas frozen. Exec DTOs send WorkspaceRoot and runner-local env defaults instead of host absolute cwd or gateway PATH. PermissionProfile gains a process_exec axis; path globs stay domain-only. Rename ContainerRunner to UdsRunner so Host+UDS is transport, not Linux isolation. Leases distinguish request-owned patch locks from process-owned exec occupancy, with release_process and ProcessExited. Runner errors split execution from before-dispatch and ambiguous transport; apply_patch records unknown on socket loss instead of rejected. Co-authored-by: Cursor <cursoragent@cursor.com>
Gateway allocates a unique 0700 leaf and always binds runner.sock; workers do not chmod /tmp or other parents. Live sockets are connect-probed and unlinked only on ConnectionRefused leftovers. RuntimeProcess owns the child, directory, and socket, with Hello readiness and kill_on_drop. Protocol mismatch answers then closes; calls have a transport deadline. Replay stays same-connection. Binary tests and CODESPACE_RUNTIME_BIN cover the FS path. MCP schemas stay frozen. Co-authored-by: Cursor <cursoragent@cursor.com>
RuntimeProcess already owns the child in a wait task with kill_on_drop. Drop and wait_exit now only Notify that task to Child::start_kill, so a reaped PID cannot be reused as a SIGKILL target. Co-authored-by: Cursor <cursoragent@cursor.com>
CARGO_BIN_EXE_* is set for integration tests, not lib unit tests, so clippy --all-targets on crates/codex-runtime no longer fails compiling src/lib.rs. Co-authored-by: Cursor <cursoragent@cursor.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Issue
Closes #
Summary
P0 execution substrate lands behind the existing MCP tools. Gateway maps
exec_commandonto command/exec-shaped Runner DTOs (cwd,env, timeout, output cap,tty: false, policy summary) withoutwork_id/operation_id.crates/policyownsPermissionProfile(Read/Write/Deny, independentprocess_exec, and a recorded network axis) and operator-registered Environments.linux-containermay be configured but exec/patch fail closed withUNAUTHORIZED. Store leases are generalized into an in-memory resource serializer; SQLite schema is unchanged;apply_patchand live shells still take workspace-exclusive ownership (WORKSPACE_BUSY).Default backend remains host
InProcessRunner. Opt-inCODESPACE_RUNNER=udsusesUdsRunnerover a CodeSpace-owned framed JSON RPC. The isolatedcodespace-codex-runtimeworker uses pinned Codex execution primitives (codex-process-hardening,codex-uds) and dispatches the sameInProcessRunneroperations.apply_patchremains one Runner RPC.The UDS path is a same-host transport boundary, not Linux/container isolation. Gateway-owned workers use a unique private
0700runner directory, live-socket connect probing,Helloreadiness, a transport deadline, process-exit events, and owned child lifecycle. Response-loss cases distinguish confirmed execution errors from transport ambiguity: patch may becomeUnknown, while ambiguous exec keeps its process-owned workspace lease until worker/process resolution.Contract changes
None. Live tools,
LIVE_TOOLS, and MCP fields stay frozen: noenvironment_id, noprocess_resize.workspace_infodoes not expose environment ids. Public MCP paths remain workspace-relative. Runner wire request ids are internal and separate fromoperation_id,operation_key, andprocess_id.Tests / CI
Coverage added or updated for:
linux-containerexec/patch rejection before operation minting.Hello, protocol mismatch handling, and transport timeout behavior.Unknowninstead ofRejected.crates/codex-runtime/tests/runtime_binary.rs.CI runs:
./scripts/check-no-model-deps.shcargo check --workspace --offline --all-targetscargo clippy --workspace --offline --all-targets -- -D warningscargo test --workspace --offlinecrates/patchandcrates/codex-runtimepython3 -B scripts/check_docs.pySecurity / architecture notes
approved/user_idstill do not raise the profile.linux-containeris a closed runner failure, not a host sandbox claim.domain,policy,runner,store,server) still have nocodex-*path dependencies or Codex types. Approved Codex dependencies remain isolated incrates/patchandcrates/codex-runtime.Out of scope
PTY /
process_resize,codex-file-systemintegration, Linux sandbox/Landlock/seccomp, network enforcement/proxy, approval tools, diff/audit ledger, internal watch,codex-file-search, remote Environment, Git/worktree provisioning, compose→exec, and making UDS the default backend.This PR remains draft until P0 review/CI is complete.