Sandboxed Code Agent (Loopback Only, Deny .env)
This playbook builds a code-reading assistant that can run Bash and NodeRepl inside the native srt sandbox with loopback-only network access and protected secrets, while recalling prior context from local journal memory. Every capability here is config-driven — no code required.
On macOS, mono-agent can install the exact pinned SRT runtime into its private user cache; no global srt or PATH mutation is required. This recipe uses fallback: "fail-closed", so an absent, corrupt, or non-enforcing engine stops the command — a sandbox_prepare_failed tool result — instead of running it on the host.
Who this is for
Section titled “Who this is for”For an optional long-running watch in Telegram, Slack, or an existing web
conversation, enable processJobs.enabled and monitors.enabled.
Use Monitor’s dedupe: "batch" for repeated redraws and
min_wake_interval_ms to space intermediate wakes. The host ceiling is
monitors.maxWakeIntervalMs (default/cap 300000); the receipt reports the
effective policy. wake_on: "exit" with default dedupe/interval sends only a
terminal wake with a bounded tail. Keep finite CI work as a terminating
background process job when only the final result matters. See
Monitors for accounting and bounds. Never automatically
recreate a cancelled watch.
Security team deploying an internal code assistant.
An agent that can read repos and run shell commands or run-scoped JavaScript inside the native srt sandbox with loopback-only network access and protected secrets, recalling context from local memory.
Features used
Section titled “Features used”sandbox.mode— native (srt-wrapped commands) vs offsandbox.network-policy— enforcednone/localhost/allowlist/allsandbox.filesystem-scopes— readable/writable roots + deny-write globssandbox.fallback—fail-closedvsunsafe-host-processwhensrtis unavailabletool-policy.allow-all— allow-all tools (["*"]); the sandbox, not an allowlist, is what constrains the code toolsmemory.journal— local journal recall for prior context
Configuration
Section titled “Configuration”{ "runtime": { "model": "openai-codex:gpt-5.6-terra" }, "tools": { "allowedTools": ["*"] }, "sandbox": { "mode": "native", "network": { "mode": "localhost" }, "readableRoots": ["."], "writableRoots": ["."], "denyWrite": [".env", ".env.*", ".git/config", ".git/hooks/**"], "fallback": "fail-closed" }}The denyWrite globs above are the built-in defaults — listed explicitly here to make the secret-protection contract obvious. Relative readableRoots/writableRoots entries resolve against the workspace. The matching env vars are MONO_AGENT_SANDBOX_MODE, MONO_AGENT_SANDBOX_NETWORK, MONO_AGENT_SANDBOX_READABLE_ROOTS, MONO_AGENT_SANDBOX_WRITABLE_ROOTS, MONO_AGENT_SANDBOX_DENY_WRITE, and MONO_AGENT_SANDBOX_FALLBACK.
mono-agent init --model openai-codex:gpt-5.6-terra --memory journal- Run
mono-agent sandbox status, thenmono-agent sandbox setupon macOS. Setup installs in the private cache and runs the full functional check. Usemono-agent sandbox checkto re-prove it later. - Leave
tools.allowedToolsat the allow-all default (["*"]) — under allow-all the code tools (Read/Write/Edit/Glob/Grep/Bash/NodeRepl) are already available, and the sandbox, not an allowlist, is what constrains them. Configuresandbox.modenative +network.modelocalhost + the deny-write defaults. (To harden further you can still narrowallowedToolsto a specific set, but it is not what makes this agent safe.) - Keep
fallbackatfail-closed(do NOT setunsafe-host-process). mono-agent validate --preset code-sandbox; theSandboxsection should beok. If it iswaitingwithsandbox_unavailable,startwill not silently relax the policy. A corrupt managed install never falls back to aPATHcommand.mono-agent start, thenmono-agent status; confirm the sandbox line reportseffective: native, thesrtengine present, andfallback active: no.- Ask the agent to inspect the repo, run a Bash command, and evaluate
const n = 40followed byn + 2throughNodeRepl; confirm REPL state persists for the run, external network calls are blocked while loopback still works, and it cannot write.env.