fix(docker): tmpfs /tmp mounted rw,exec,size=128m

Docker Desktop's default noexec on tmpfs broke the "download a CLI
to /tmp, chmod +x, run it" workflow — exactly what the doc-gardener
inspector needs to verify docs.mcpproxy.app against the real
mcpproxy binary. Previously the agent spent ~10 minutes in a self-
debug loop discovering the noexec, falling back to /home/agent,
running into externally-managed Python, missing python3-venv, etc.

With /tmp exec, the inspector's own install pipeline works on the
first try: curl | tar | chmod | run. First real run produced a
72-claim drift report (21 matched / 1 drifted / 50 missing) against
mcpproxy v0.24.4 in ~8 minutes, no REVISE loop.

The 64m → 128m bump gives breathing room for curl'd tarballs that
need a temp extraction directory alongside the final binary.

Inspector prompt updated to tell the agent about the /tmp install
path explicitly and forbid the previous /home/agent detours. Also
updated the coordinator brief template to match.

Note the image itself is UNCHANGED — we deliberately do NOT bake
mcpproxy (or any other domain-specific tool) into synapbus-agent.
The image stays a blank Linux shell with Node + Python + core tools,
and each example's prompt teaches its agent how to install whatever
it needs. This keeps the gardener universal: swap in any other docs
domain and the inspector figures out what to install on demand.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Algis Dumbris
2026-04-15 13:07:58 +03:00
co-authored by Claude Opus 4.6
parent bdec096190
commit ddbb1bd329
4 changed files with 13 additions and 4 deletions
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+6 -1
View File
@@ -44,7 +44,12 @@ RUN curl -fsSL https://deb.nodesource.com/setup_${NODE_MAJOR}.x | bash - \
&& npm config set update-notifier false
# Agent CLIs. Install globally so any user inside the container can
# call them. Pinned versions are accepted via build args above.
# call them. Pinned versions are accepted via build args above. Any
# domain-specific CLIs (mcpproxy, terraform, aws, ...) are NOT baked
# in — the agent downloads and runs them on demand inside the sandbox.
# That's the whole point of the "universal gardener" design: the image
# is a blank Linux shell with enough language runtimes to install
# anything else, and every example is self-contained in its prompt.
RUN npm install -g \
@google/gemini-cli@${GEMINI_CLI_VERSION} \
@anthropic-ai/claude-code@${CLAUDE_CODE_VERSION}
+5 -1
View File
@@ -241,8 +241,12 @@ func (h *Harness) buildRunArgs(
}
// Read-only root + tmpfs scratch unless explicitly disabled.
// The tmpfs mount is `exec` so agents can download and run small
// binaries there (e.g. a CLI the verifier needs to invoke). Without
// `exec` Docker Desktop's default "noexec" on tmpfs breaks any
// `chmod +x && ./binary` workflow inside the sandbox.
if dockerCfg.ReadOnlyRoot == nil || *dockerCfg.ReadOnlyRoot {
args = append(args, "--read-only", "--tmpfs", "/tmp:rw,size=64m")
args = append(args, "--read-only", "--tmpfs", "/tmp:rw,exec,size=128m")
}
if dockerCfg.Memory != "" {