Repository navigation
Trial sandboxes get their own network behind an allowlisting proxy - #1214
Merged
Merged
Conversation
Each sandbox now unshares its network, holding only its own loopback. An allowlisting CONNECT proxy runs outside it on a Unix socket bound into the sandbox; a socat relay inside turns 127.0.0.1:3128 into that socket, and the Harness reaches its provider through HTTPS_PROXY. The proxy allows only that Harness's provider hosts from #1009's lists and refuses names resolving to loopback or to the host's own addresses. Trial sessions switch each Harness's web search off by its own flag (agy has none); OpenCode's Trial config denies webfetch and websearch.
Void a Trial whose Harness ignores the proxy at the DNS step too: DNS and unreachable-network wordings now map to session_unavailable, with trial-level cases. Share one provider-host table and one provider-name parse between the proxy and the sandbox. Correct the hand-written site pages that said Trials run without a sandbox.
…id=6178ceda-3074-4c42-a5f0-d7f9fdc9a360]: Subscription quota exhausted. Your usage window resets at 2026-10-24T03:28:16Z. (rate_limit_error)) 2026-10-24T02:17:33Z, host stephens. Uncommitted work at the time of failure is included in this commit.
JacobStephens2
marked this pull request as draft
October 24, 2026 02:17
JacobStephens2
marked this pull request as ready for review
October 24, 2026 03:36
This was referenced Oct 24, 2026
Merged
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.
Summary
Each Trial sandbox now has its own network, holding only its own loopback. An allowlisting CONNECT proxy outside bwrap reaches only that Harness's provider hosts from #1009. It checks names before DNS, refuses loopback and the host's addresses (including IPv4-mapped IPv6), and dials only the checked addresses.
A Harness that ignores the proxy has no route; known network/DNS failures produce a Void Trial. Trial invocations disable web tools for Claude, Codex, Grok, Muse and OpenCode. agy's missing search-off control remains a Spec decision in #1215. Protocol and hand-written site pages describe the Trial sandbox.
CONNECT tunnels remain reusable after long model calls and forward EOF while allowing the provider's final response. A private network adapter lets the successful CONNECT/request/response test use local sockets without weakening production policy.
Closes #1013
Test seams
sandbox::prepare/Launch::command): proxy routing and isolation from the host network.proxy::start), address policy (address_refusal), and tunnel forwarding (read_head→relayover local sockets): allowed traffic, refusal, and connection reuse.Adapter::trial_session) and Trial result protocol (thirdshift --trial): web-search settings and Void Trials.Evidence
After: retained regressions pass:
proxy::tests::mapped_loopback_and_host_addresses_are_refused,proxy::tests::connect_tunnels_remain_writable_after_waiting_for_a_model_response, andproxy::tests::connect_tunnels_forward_half_closes_and_the_final_response. The original idle and closure reproduction commands also pass after the fixes.cargo test --bin thirdshift -- proxy::tests sandbox::tests harness::: 211 passed, 0 failed, 2 existing ignored tests. Includes sandbox/provider reachability, GitHub/loopback/host refusal, no route without the proxy, per-Harness web-tool settings, and deterministic CONNECT request/response forwarding.cargo fmt --checkandcargo clippy --all-targets -- -D warnings: passed.cargo test --bin thirdshift sandbox::tests::a_sandboxed_process_reaches_an_allowed_host_through_the_proxy -- --exact --nocapture: passed with no environment skip; the sandbox reached the real allowed host through the proxy.3bc774e9, including the Linux Rust suite./usr/bin/time -p scripts/affected-tests issue-977: passed — 43 site tests and 2,526 Rust tests, with 58 existing Rust skips. Wall time 2,341.88 s (39m 02s), including compilation; the Rust build took 2m 05s and nextest execution took 2,146.862 s. No full-suite rerun was started after CI succeeded on this head.Merge Danger
Door: two-way
Reverting restores the previous Trial networking; no data migration.
Blast Radius: Trials
Ordinary Runs keep their existing networking and web tools. Sandboxed Trials require socat; unavailable sandbox dependencies produce a Void Trial. OpenCode Trials must name a supported provider.
THIRDSHIFT_TRIAL_NO_SANDBOXretains its existing escape-hatch behavior.Unaddressed findings
Standards
None. All four findings were addressed: idle forwarding, injectable network I/O, the duplicate agy override, and EOF propagation. Each behavior finding was reproduced with the reviewer's written command before fixing it; regressions are retained.
Spec
src/harness/adapter.rs:42-44, which returns the unchanged code-review invocation;src/harness/agy.rs:156-159records the limitation. The initial and follow-up source checks failed as reported; a passing suite is not evidence that search is disabled.docs/research/eval-sandboxes.md:831records no CLI/settings switch and server-sidegoogle_searchbeyond the proxy. Whether to block agy Trials or permit that exception belongs to the Day shift/Spec authors. Existing open #1215 already records this finding, its evidence, PR Trial sandboxes get their own network behind an allowlisting proxy #1214 and why that call is not the implementer's; it has onlyneeds-triage. No duplicate issue was created. The acceptance criterion remains unmet for agy.Security
None. Scoped security review (guidance mode, one session, no delegated auditors) of the issue-1013 diff against pinned merge base
c63c2a46: readsrc/proxy.rs, thesrc/sandbox.rsproxy/relay/namespace wiring, thetrial_sessionoverrides insrc/harness/plus the default insrc/harness/adapter.rs, the Trial gating insrc/session.rs, and the void-DNS strings insrc/trial.rs, with the local-IPC and resource-exhaustion attack-class guidance (the repo has noSECURITY.mdor threat model). Temporary adversarial CONNECT probes (userinfo, paths, queries, bracketed names, IP literals, wrong methods, mixed clean/loopback/host/unspecified/mapped DNS sets) all stayed refused while clean allowlisted names tunneled; the probes were reverted afterward.proxy::tests(11 passed),harness::(177 passed),sandbox::(23 passed),--test trial(17 passed). No introduced finding had a failing proof-of-concept, so nothing was fixed or left unaddressed here.Security review outcome
No unaddressed introduced findings.
Review coverage
Independent Standards and Spec reviews used
issue-977(c63c2a4622bddc3f9bc8484c8054547069ae62e2) as the fixed point. Each axis read all 17 changed files, including supporting standards/domain/ADR context, with one follow-up on the fixes. No generated-output exclusions and no unread changed files. The final EOF shutdown fix was made and validated by the implementer after the Standards follow-up raised it.Final reports, including initial/follow-up findings, dispositions and each axis's combined files-read list:
.thirdshift-review-Xuk0v5/standards.md.thirdshift-review-Xuk0v5/spec.mdStandards: 4 addressed, worst found P1 idle forwarding (fixed). Spec: 2 addressed, 1 deferred, worst remaining P1 agy web-search control (#1215).
Built with codex · gpt-6.1-sol · xhigh