Skip to content

🤖 tests: run the MCP Apps suite in the bug-bash sandbox through the provider proxy - #6073

Merged
ThomasK33 merged 6 commits into
mainfrom
tests/5714-b1-mcp-apps
Oct 10, 2026
Merged

ThomasK33 merged 6 commits into
mainfrom
tests/5714-b1-mcp-apps

Conversation

@ThomasK33

Copy link
Copy Markdown
Member

Summary

Runs the MCP Apps e2e suite (make mcp-apps-e2e) inside the bug-bash sandbox, with its agent.act explorer reaching the model only through the A2 provider proxy. The host pause stays for every other model-driven run, and on the host the suite still refuses. This is PR B1 of the #5714 plan, stacked on C2 (#6072).

Refs #5714

Background

#5815 paused every model-driven bug-bash run on the host, because model output picks actions there. A1 (#6059) and A2 (#6065) added a dormant provider proxy with a policy and a spend ledger. C (#6069) and C2 (#6072) made container cleanup and crash recovery safe. B1 is the first PR that turns the proxy on, for the MCP Apps suite only. make bug-bash (e2e explore) follows in B2.

Implementation

  1. sandbox/launch.ts accepts a second job kind: e2e run --config e2e.mcpapps.config.ts. Before any docker command it refuses without BUGBASH_BUDGET_USD, without ANTHROPIC_API_KEY plus ANTHROPIC_BASE_URL, with a non-Anthropic BUGBASH_MODEL, and with any BUGBASH_SCENARIO. It starts the proxy on <jobDir>/proxy/sock, registers its close as a stop hook, mounts the socket folder read-only at /repo/.sandbox-proxy, and logs one proxy: summary line. A proxied call that costs more than its reserved bound fails the job with exit 5.
  2. The new sandbox/inContainer.ts holds the isolation guard that entry.ts and mcpapps/hostPause.ts share: BUGBASH_CONTAINER=1, docker-init as PID 1, only lo, and (for model-driven jobs) a real socket at the mount. It also holds the 127.0.0.1:4141 TCP forwarder that entry.ts starts, because the AI SDK speaks TCP.
  3. e2e.mcpapps.config.ts gives the agents createAnthropic({ baseURL: <forwarder>, apiKey: placeholder })(BUGBASH_MODEL). The default model is anthropic:claude-sonnet-5-5.
  4. startApp.ts (appSwitches) turns off agent tools, terminals and project automation for every model-driven job, also with the mock app AI.
  5. BUGBASH_MODEL left PASS_ENV. The launcher sets it per job kind, so a repro job never gets an explorer model.
  6. The coordinator's review follow-ups for A2 and C: the proxy bounds its refusal log (first 20 lines, then counts per reason), keeps the reservation when a message_delta lowers or nulls a usage count, and waits until its socket file is gone after close(). runJob() now takes the docker-run flags and the command apart, so CALLER_FLAG checks only the flags (e2e's -g after the image passes). Cleanup returns unknown when more than one container matches the name and labels.

Threat-model claims wired here

ID Claim Where B1 wires or tests it
S1 Model-driven commands run only in a sandbox container with the proxy socket inContainer.ts guard used by entry.ts and mcpapps/hostPause.ts. Tests: a fake /proc + /sys + socket root passes, the host and a regular file in place of the socket refuse
S2 Model-driven jobs start only with the proxy, repro jobs stay model-free "a repro job gets no proxy and no explorer model, whatever the host sets"
S3 Agent tools, terminals and project automation off in every model-driven job "a model-driven job gets every kill switch, also with the mock app AI"
P1, P2, P4, P5, P6, P8 Proxy route, header, body, content, bounds and close rules Unchanged from A1/A2. B1 wires them by routing the explorer through the proxy
P3 Only the job's models The job allowlist is the explorer model only (the app AI is the mock)
P7 Reservation before dispatch, run-wide ledger One Ledger per job with the BUGBASH_BUDGET_USD cap. The host probe of the real app AI moves to B2 with the real app AI
P9 The key never reaches the container "an MCP Apps job reaches the model only through its proxy, with the host key": the fake docker checks every --env value against the key

Validation

  1. Unit tests: 200 pass in tests/bugbash/, including the failing-first tests above.
  2. Transport check with the fake upstream, real Docker: 226 calls settled through the read-only socket mount, 0 policy refusals, 9 budget refusals at the $1 test cap, and the container was removed by its cidfile ID. That run used an earlier work-in-progress commit (34eb9e50ac). The paid run below covers the final head. The suite itself fails there by design, because the fake model drives no useful actions.
  3. Stop handling, real Docker: SIGINT gives exit 130 and removes the container. SIGKILL of the launcher gives exit 137, and the lifeline ends the container.
  4. Functional acceptance (the paid MCP Apps run) follows as a PR comment.

Risks

Test-only code. The new runtime surface is the proxy socket on the host and the forwarder in the container. Both exist only during a make mcp-apps-e2e run, which needs an explicit budget and key. The host pause still refuses every other model-driven run.

Known gaps:

  1. The mode 0700 checks are tested only under umask 022.
  2. No mutation test covers the await on close() in the launcher.
  3. After a SIGKILL of the launcher, its /tmp job folder, its docker client folder and its xum-bugbash-proxy-* folder stay behind.
  4. e2e's exit 3 collides with the launcher's unknown exit 3.
  5. AGENTS.md still says mcp-apps-e2e is paused. PR D updates the docs.

Generated with xum • Model: anthropic:claude-opus-5-5 • Thinking: high • Cost: $78.21

@ThomasK33
ThomasK33 added this pull request to stack #6070 October 10, 2026 17:01
@ThomasK33

Copy link
Copy Markdown
Member Author

@codex review

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 10, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-10T18:10:24.444010Z 74c5794 Manual request
🔒 Security Review ✅ Completed 2026-10-10T18:13:36.511109Z 74c5794 Manual request
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 93cc4128c0

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread tests/bugbash/startApp.ts
@chatgpt-codex-connector

Copy link
Copy Markdown

🛡️ Codex Security Review · Automatically triggered

Security review completed. No security issues were found in this pull request.

Reviewed commit: 93cc4128c0

View security finding report

Only the user who started this review can view the report in Codex.

ℹ️ About Codex security reviews in GitHub

This is an experimental Codex feature. Security reviews are triggered when:

  • You comment "@codex security review"
  • A regular code review gets triggered (for example, "@codex review" or when a PR is opened), and you’re opted in so security review runs alongside code review

Once complete, Codex will leave suggestions, or a comment if no findings are found.

@ThomasK33
ThomasK33 force-pushed the tests/5714-b1-mcp-apps branch from 93cc412 to 1411ebb Compare October 10, 2026 17:18
@ThomasK33

Copy link
Copy Markdown
Member Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

🛡️ Codex Security Review · Automatically triggered

Security review completed. No security issues were found in this pull request.

Reviewed commit: 1411ebba24

View security finding report

Only the user who started this review can view the report in Codex.

ℹ️ About Codex security reviews in GitHub

This is an experimental Codex feature. Security reviews are triggered when:

  • You comment "@codex security review"
  • A regular code review gets triggered (for example, "@codex review" or when a PR is opened), and you’re opted in so security review runs alongside code review

Once complete, Codex will leave suggestions, or a comment if no findings are found.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 1411ebba24

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread tests/bugbash/sandbox/launch.ts
Comment thread tests/bugbash/sandbox/launch.ts Outdated
Comment thread Makefile Outdated
Comment thread Makefile Outdated
@ThomasK33

Copy link
Copy Markdown
Member Author

Paid MCP Apps runs (functional acceptance of B1)

Two runs of make mcp-apps-e2e (Sonnet 5.5 explorer through the job's proxy, mock app AI). Total list-price spend: $3.1785 of an $8 cap.

Run 1 Run 2
Head 93cc4128c0 1411ebba24
BUGBASH_BUDGET_USD 8 6.39 (the rest of the $8)
Suite 12 of 14 passed 14 of 14 passed
Proxy 132 settled, 0 kept in full, 0 refused 125 settled, 0 kept in full, 0 refused
Spend (list price) $1.6051 $1.5734
App kill switches absent (the Codex P1 bug) all three set in every app server
Job exit / make exit 1 / 2 0 / 0
Wall time 590 s 559 s
Cleanup removed (ID from the cidfile), 0 containers left removed (ID from the cidfile), 0 containers left
  1. Run 1 ran before the Codex P1 fix: the app servers had no XUM_DISABLE_* switches, so it does not count for S3. Its two failures were "the card buttons show keyboard focus" on web and phone: the explorer's Tab presses never reached the 'Show input/output' toggle. Run 2 passed that test on both targets.
  2. Run 2, S3: a read-only docker exec sampler read /proc/*/environ of every app process in the container (4 dist/cli/index.js server processes and 2 mcpapps/server.mjs processes). Each had XUM_DISABLE_AGENT_TOOLS=1, XUM_DISABLE_PROJECT_AUTOMATION=1 and XUM_DISABLE_TERMINALS=1.
  3. Cost bound (plan item 12): boundExceeded = 0 in both runs. The highest per-call reservation was $0.5702 (run 1) and $0.5701 (run 2), the highest settled cost $0.0461, and the highest settled-to-reserved ratio 0.129.
  4. Real request shape (a host-side tap that recorded shapes and usage only, no bodies or header values except anthropic-beta and anthropic-version): top-level keys max_tokens, messages, model, output_config, system, tool_choice, tools (2 calls per run without tools and tool_choice), anthropic-beta: structured-outputs-2025-11-13 only, anthropic-version: 2023-06-01, 23 untyped tools, at most 4 images per call, max_tokens 16,384, no thinking, no streaming. A1's beta allowlist and top-level key list hold. The key list is not tightened here: B2's real app AI streams and can send other keys.

Generated with xum • Model: anthropic:claude-opus-5-5 • Thinking: high

@ThomasK33

Copy link
Copy Markdown
Member Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Can't wait for the next one!

Reviewed commit: 6744b1ef05

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@chatgpt-codex-connector

Copy link
Copy Markdown

🛡️ Codex Security Review · Automatically triggered

Security review completed. No security issues were found in this pull request.

Reviewed commit: 6744b1ef05

View security finding report

Only the user who started this review can view the report in Codex.

ℹ️ About Codex security reviews in GitHub

This is an experimental Codex feature. Security reviews are triggered when:

  • You comment "@codex security review"
  • A regular code review gets triggered (for example, "@codex review" or when a PR is opened), and you’re opted in so security review runs alongside code review

Once complete, Codex will leave suggestions, or a comment if no findings are found.

Base automatically changed from tests/5714-c2-sandbox-recover to main October 10, 2026 17:49
…et removal

Follow-ups from the coordinator's clean-context review of the proxy PR, landing in B1
where the proxy first runs:
- Refusals cost the container nothing, so only the first 20 are logged in full. After
  that stats().refusedBy counts them per category: the reason up to its first quoted
  (container-chosen) name, so the keys stay the fixed reason texts.
- A message_delta that lowers or nulls a usage count of message_start keeps the
  reservation instead of settling on the lower number.
- close() waits for both listeners to close, and a test checks that no socket file is
  left in the job folder.

---

_Generated with `xum` • Model: `anthropic:claude-opus-5-5` • Thinking: `high` • Cost: `$52.06`_

<!-- mux-attribution: model=anthropic:claude-opus-5-5 thinking=high costs=52.06 -->
…rovider proxy

PR B1 of the #5714 sandbox plan (MCP Apps only; `e2e explore` and the real app AI are B2).

- launch.ts: a second job kind, `e2e run --config e2e.mcpapps.config.ts`. Before any docker
  command it needs BUGBASH_BUDGET_USD, ANTHROPIC_API_KEY and ANTHROPIC_BASE_URL and an
  anthropic: explorer model, and it refuses BUGBASH_SCENARIO. It starts the provider proxy
  on a socket in the job folder (0700), mounts that folder read-only at
  /repo/.sandbox-proxy, closes the proxy as a stop hook, writes one record per call to
  `<output>.proxy.jsonl` on the host, logs the spend, and exits 5 when a call cost more
  than its bound.
- inContainer.ts: the sandbox check (marker, docker-init as PID 1, only loopback) and the
  proxy check; entry.ts forwards 127.0.0.1:4141 to the socket for a model-driven job.
- mcpapps/hostPause.ts passes only in a model-driven sandbox; there the MCP Apps agents get
  BUGBASH_MODEL through the forwarder with a placeholder key. e2e.config.ts (repros) keeps
  no model.
- startApp.ts: a model-driven job gets all three kill switches with the mock app AI too.
- inputs.ts: the host's BUGBASH_MODEL no longer passes; the launcher sets it per kind.
- Makefile: mcp-apps-e2e builds dist and runs the launcher.
- fakeUpstream.ts: a command mode for the zero-cost transport check.

---

_Generated with `xum` • Model: `anthropic:claude-opus-5-5` • Thinking: `high` • Cost: `$52.06`_

<!-- mux-attribution: model=anthropic:claude-opus-5-5 thinking=high costs=52.06 -->
…ambiguous ps match

- runner.ts: runJob() takes the docker-run flags and the command (image first)
  apart, and CALLER_FLAG checks only the flags, so the job's own arguments
  (e2e's `-g`) pass. A comment records that `--detach` and `--rm=false` are not
  refused, and when they must be.
- runner.ts: the name-and-labels lookup returns unknown when more than one
  container matches, instead of removing the first.
- Tests for both.

---
_Generated with [`xum`](https://github.com/coder/xum) • Model: `anthropic:claude-opus-5-5` • Thinking: `high`_
e2e starts the app with only `command.env`, and e2e.config.ts's allowlist
omits BUGBASH_MODEL_DRIVEN, so startApp.ts never saw it and left agent tools,
terminals and project automation on in the sandboxed MCP Apps job (Codex P1).
The MCP Apps config loads only in a model-driven sandbox job, so it sets the
marker itself. Real-Docker check: the app server's environ in the container
had no XUM_DISABLE_* before, and all three after.

---
_Generated with [`xum`](https://github.com/coder/xum) • Model: `anthropic:claude-opus-5-5` • Thinking: `high`_
…ed proxy close, run paths

- launch.ts: refuse a BUGBASH_MODEL the proxy cannot price before any docker
  command (every call would refuse). A stop now outranks exit 5: the bound-miss
  line is still logged, and exit 3 (unknown cleanup) still outranks both.
- proxy.ts: close() waits at most 5 s for the aborted calls and the listeners,
  inside the launcher's 10 s stop-hook bound, and rejects if a call is still
  open. Test: calls stuck before the upstream headers, mid-stream and on a client
  that never reads, plus an idle connection, all settle at once as `kept`.
- Makefile: mcp-apps-e2e pins BUGBASH_AI_RESOLVED=mock too, and the output path
  carries the shell PID, so two runs in the same second do not share it.

---
_Generated with [`xum`](https://github.com/coder/xum) • Model: `anthropic:claude-opus-5-5` • Thinking: `high`_
@ThomasK33
ThomasK33 force-pushed the tests/5714-b1-mcp-apps branch from 6744b1e to 501bed2 Compare October 10, 2026 17:49

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 501bed2e09

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread tests/bugbash/sandbox/launch.ts Outdated
The launcher's record callback threw inside the proxy's call handler, and
close() swallowed it, so a job could exit with its own code while
`<output>.proxy.jsonl` missed calls (Codex). The launcher now keeps the first
write error (its errno code only) and reports it as a proxy fault: exit 5, with
the same precedence as a bound miss.

---
_Generated with [`xum`](https://github.com/coder/xum) • Model: `anthropic:claude-opus-5-5` • Thinking: `high`_
@ThomasK33

Copy link
Copy Markdown
Member Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Keep them coming!

Reviewed commit: 74c579435f

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@chatgpt-codex-connector

Copy link
Copy Markdown

🛡️ Codex Security Review · Automatically triggered

Security review completed. No security issues were found in this pull request.

Reviewed commit: 74c579435f

View security finding report

Only the user who started this review can view the report in Codex.

ℹ️ About Codex security reviews in GitHub

This is an experimental Codex feature. Security reviews are triggered when:

  • You comment "@codex security review"
  • A regular code review gets triggered (for example, "@codex review" or when a PR is opened), and you’re opted in so security review runs alongside code review

Once complete, Codex will leave suggestions, or a comment if no findings are found.

@ThomasK33
ThomasK33 added this pull request to the merge queue Oct 10, 2026
Merged via the queue into main with commit c69ab67 Oct 10, 2026
33 checks passed
@ThomasK33
ThomasK33 deleted the tests/5714-b1-mcp-apps branch October 10, 2026 18:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant