Skip to content

fix(runner): safe hardening from the stack review pass#5248

Merged
mmabrouk merged 2 commits into
big-agentsfrom
feat-stack-review-fixes
Jul 12, 2026
Merged

fix(runner): safe hardening from the stack review pass#5248
mmabrouk merged 2 commits into
big-agentsfrom
feat-stack-review-fixes

Conversation

@mmabrouk

Copy link
Copy Markdown
Member

Context

Three Codex reviews ran over the stack below (#5243, #5244, #5245). Each found a mix of real bugs, design questions, and small gaps. This PR lands only the fixes that are mechanical, carry no design decision, and need no live check. The design calls (the ask authorization model, how the bearer token reaches the harness) and the one change that needs a live Claude run (MCP version negotiation) are left for you to decide on their own PRs.

It sits on top of the stack as a separate PR for one reason: GitButler cannot move a new edit down onto an already-applied lower lane, and the tree is shared with other sessions right now, so retro-fitting each fix into its own feature PR was not safe. Every fix is mapped to its PR below, and the whole set merges with the stack.

Changes

Grouped by the PR whose review each fix answers.

Relay (#5243)

  • relay.ts: every relay-file removal now runs under a timeout. A hung Daytona moveFs/delete used to block pickup, the stale sweep, and shutdown forever, and the 30s safety poll could never fire because the loop was stuck before it. A timed-out removal is now treated as a failed removal, kept in the retry set, and the loop keeps going.
  • relay-watch.ts: a safety-poll miss is now tied to the watch generation that missed it, so a later clean exit of that same generation cannot erase it. Before this, repeated missed notifications could sit at one miss forever and never demote to polling. Also, the window-size fallback now rejects partial garbage ("30000junk" used to parse as 30000).

Shim (#5244)

  • tool-mcp-stdio.ts: answer MCP ping with {} instead of a -32601 error (a health-checking client could otherwise treat the shim as dead and tear it down). Return proper JSON-RPC errors for bad input (-32700 for unparseable, -32600 for an invalid request) instead of silently dropping it. Added a comment stating the at-least-once delivery contract. Version negotiation is unchanged on purpose (that needs a live Claude run).
  • tool-mcp-assets.ts: cache the shim bundle by path and write the bundle and specs concurrently, instead of three serial Daytona round trips and a fresh disk read on every acquire.
  • Tests: restored the direct "client-only tool on Daytona is refused" case, and pinned the Pi vs non-Pi ask guard wiring so a future change that flattened it would fail. Updated the build:extension docs to say it bundles both the Pi extension and the shim.

Continuation (#5245)

  • tool-mcp-http.ts: authenticate before the method check, so an unauthenticated GET or DELETE gets 401 rather than 405. Added auth tests: missing token, wrong scheme, empty and whitespace-only tokens, and a check that an unauthorized call reaches neither the callback executor nor the client relay.

Tests

cd services/runner && pnpm test && pnpm run typecheck. All new and changed tests pass. The four failures that remain are pre-existing on this stack and unrelated to these fixes: code-tool.test.ts, sandbox-agent-qa-transcript-replay (x2), and sandbox-agent-run-plan hasApiKey.

Not in this PR

Left for a decision or a live check, and called out on the feature PRs:

https://claude.ai/code/session_0127AM79khCdvD2b8BG2joZL

@vercel

vercel Bot commented Jul 12, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
agenta-documentation Ready Ready Preview, Comment Jul 12, 2026 8:15pm

Request Review

@coderabbitai

coderabbitai Bot commented Jul 12, 2026

Copy link
Copy Markdown

Review Change Stack

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: e62ef26d-2a73-4e37-8c49-b156ff573dd4

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

The runner updates MCP shim bundling and uploads, hardens relay removal and watch accounting, authenticates MCP HTTP requests before method checks, adds JSON-RPC error handling, and expands sandbox-agent validation tests.

Changes

Runner MCP and relay behavior

Layer / File(s) Summary
MCP bundle delivery
services/runner/AGENTS.md, services/runner/README.md, services/runner/src/engines/sandbox_agent/tool-mcp-assets.ts, services/runner/tests/unit/tool-mcp-assets.test.ts
Documents shim bundling, caches bundle contents by path, uploads bundle and specs concurrently, and tests both behaviors.
Relay removal and watch accounting
services/runner/src/tools/relay.ts, services/runner/src/tools/relay-watch.ts, services/runner/tests/unit/relay-watch.test.ts
Adds timeout-bounded relay-file removal, preserves retry tracking, records missed watch generations, and requires integer watch-window values.
MCP authentication and JSON-RPC contracts
services/runner/src/tools/tool-mcp-http.ts, services/runner/src/tools/tool-mcp-stdio.ts, services/runner/tests/unit/tool-bridge.test.ts, services/runner/tests/unit/tool-mcp-stdio.test.ts
Authenticates HTTP requests before method dispatch and adds explicit invalid-request, ping, and parse-error JSON-RPC responses with tests.
Sandbox-agent policy and planning validation
services/runner/tests/unit/sandbox-agent-orchestration.test.ts, services/runner/tests/unit/sandbox-agent-run-plan.test.ts
Tests Pi execution denial for unapproved tools and early rejection of unsupported Claude Daytona client-only tools.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 inconclusive)

Check name Status Explanation Resolution
Title check ❓ Inconclusive The title is related to the runner hardening changes but is too generic to identify the main fixes. Use a more specific title such as "fix(runner): harden relay, MCP stdio, and request handling".
✅ Passed checks (4 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 60.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description check ✅ Passed The description clearly explains the runner hardening fixes and matches the changeset.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat-stack-review-fixes

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@mmabrouk

Copy link
Copy Markdown
Member Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 12, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@mmabrouk mmabrouk added the needs-review Agent updated; awaiting Mahmoud's review label Jul 12, 2026
mmabrouk added 2 commits July 12, 2026 20:46
Addresses the mechanical review findings on #5243, #5244, and #5245 that carry
no design decision and need no live verification. Landed as one commit on top
of the stack because GitButler cannot retro-assign a new delta onto a lower
applied lane; each fix is mapped to its PR below.

Relay (#5243):
- relay.ts: bound every relay-file removal with a timeout so a hung daemon
  deletion can no longer wedge pickup, stale-sweep, or shutdown; a timed-out
  removal is treated as failed and the loop continues.
- relay-watch.ts: tie a safety-poll miss to the active watch generation so a
  later zero-exit of the same generation cannot erase it (the demotion counter
  now accumulates); validate the whole watch-window string instead of
  parseInt accepting partial garbage.

Shim (#5244):
- tool-mcp-stdio.ts: answer MCP 'ping' with an empty result; return -32700 on
  unparseable input and -32600 on an invalid request; document the
  at-least-once relay delivery contract. Protocol-version negotiation is left
  unchanged (that needs a live check).
- tool-mcp-assets.ts: cache the shim bundle by path and write bundle + specs
  concurrently, removing avoidable serial Daytona round trips.
- restored the direct client-only Daytona refusal test; pinned the Pi vs
  non-Pi ask guard wiring; updated the build:extension docs.

Continuation (#5245):
- tool-mcp-http.ts: authenticate before the method check so an unauthenticated
  GET/DELETE gets 401, not 405.
- added auth tests: unauthorized GET/DELETE, wrong scheme, empty and
  whitespace tokens, and that neither the callback executor nor the client
  relay runs on an unauthorized call.

Deferred (need a design decision or a live check, not in this commit): the
non-Pi ask authorization model (#5244), the bearer-in-argv delivery (#5245),
MCP protocol-version negotiation (#5244).

Claude-Session: https://claude.ai/code/session_0127AM79khCdvD2b8BG2joZL
@mmabrouk mmabrouk marked this pull request as ready for review July 12, 2026 19:44
@dosubot dosubot Bot added size:L This PR changes 100-499 lines, ignoring generated files. bug Something isn't working labels Jul 12, 2026
@mmabrouk mmabrouk added lgtm This PR has been approved by a maintainer and removed bug Something isn't working size:L This PR changes 100-499 lines, ignoring generated files. needs-review Agent updated; awaiting Mahmoud's review labels Jul 12, 2026
@mmabrouk mmabrouk force-pushed the feat-client-tool-continuation-v1 branch from 6ab5d45 to 43ed55a Compare July 12, 2026 20:13
@mmabrouk mmabrouk force-pushed the feat-stack-review-fixes branch from ba3e125 to fff45dc Compare July 12, 2026 20:13
@dosubot dosubot Bot added the size:L This PR changes 100-499 lines, ignoring generated files. label Jul 12, 2026
@mmabrouk mmabrouk deleted the branch big-agents July 12, 2026 20:30
@mmabrouk mmabrouk changed the base branch from feat-client-tool-continuation-v1 to big-agents July 12, 2026 20:30
@mmabrouk mmabrouk closed this Jul 12, 2026
@mmabrouk mmabrouk reopened this Jul 12, 2026
@mmabrouk mmabrouk merged commit fc06269 into big-agents Jul 12, 2026
20 checks passed
@mmabrouk mmabrouk deleted the feat-stack-review-fixes branch July 12, 2026 20:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

lgtm This PR has been approved by a maintainer size:L This PR changes 100-499 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant