Repository navigation
Record Custom runner sessions and enforce Trial accounting - #2227
Merged
Merged
Conversation
Owner
Author
|
Delivery completed on agent-authored or reviewed head adfe490. |
Adds regressions for two Spec review findings (expected to fail before the fix): a timed-out runner with provider traffic must stay failed, and the Trial-wide web-search scan must skip events another Arm's build wrote. Also covers the provider-traffic and crossed-Harness accounting gap rules directly, documents native web-search Voiding, refreshes code navigation pointers and names test modules for their selectors. Co-Authored-By: Claude <noreply@anthropic.com>
… scans Accounting gaps now judge only an outcome the runner reported in a valid result.json, so timeouts, runners that could not start and broken runner protocol keep their failed classification (outer supervision keeps precedence, #1468). The Trial-wide web-search scan skips events this build cannot decode, as the other Session-trace readers do, instead of aborting the Experiment on a native Arm's newer trace. Co-Authored-By: Claude <noreply@anthropic.com>
Sandboxed code reaches the host's record socket, and the host process that runs concurrent Trials sits outside the Trial memory cap. Cap unfinished frame bytes and open connections, release closed connections' descriptors, and return each poll to supervision within 50 ms so the Trial timeout and quota pauses still apply.
This was referenced Nov 14, 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
Custom runner sessions now become retained, priced Session traces, and Trials whose evidence breaks the sandbox's accounting become Void Trials. Closes #2191.
Evidence
Execution evidence
Local Rust builds were unavailable in the final session: the host has no C compiler, and the proposed zig
ccshim was denied. So review findings were checked through CI's full suite on each pushed head.44a0cb99(new tests, no fix).evals::experiment::execution::custom::tests::timed_out_runner_after_provider_traffic_stays_failedpanicked:Some("accounting gap: 0 recorded sessions, 0 Harness sessions, 1 provider connections, 1 Harness runs across the proxy (codex)").…::web_search_scan_skips_events_from_other_arm_buildspanicked:unknown variant `event_from_a_newer_arm_build`. The two new accounting-gap trigger tests passed.After: CI run 43650177112 on
fe577acb: all four Rust shards, strict Clippy/tooling, Console and site tests passed. That green run on the final head is the full-suite validation;scripts/affected-testscould not be run locally.cargo test --test experiments custom_runner_records_live_harness_sessions_with_roles -- --nocapturefailed withassert isinstance(request['record_command'], list)/AssertionError; the Trial outcome wasfailedinstead ofdelivered.After: Same command:
1 passed; 0 failed.cargo test --test experiments native_trials_with_normalized_web_search_calls_are_void -- --nocapturefailed withleft: String("delivered"),right: "void".After: Same command:
1 passed; 0 failed.cargo test --test experiments experiment_trace_contains_trials_and_graders_and_reports_arm_usage -- --exact --nocapturefailed withinvalid type: map, expected f64.After: Same command:
1 passed; 0 failed.custom_runner::missing_declared_credentials_void_custom_trials_without_using_ambient_keys, run with a PATH excludingsocat, failed withsandbox_unavailableinstead ofsession_unavailable, matching CI.After: Same test:
1 passed; 0 failed.npm run docs:check --prefix site: exit 0 after regenerating the manual.c2a8474d): sandboxed code can reach the host'srecord_commandsocket, and the host process that runs concurrent Trials sits outside the Trial memory cap. Before: four regression tests incustom::recording::testsfailed onfe577acb. An endless frame left67218496 bytes bufferedon the host. A flood of frames held one poll for6.11s, pausing timeout and quota checks. 128 closed connections kept 128 host descriptors. 65 open connections were all accepted. After:cargo test --bin thirdshift custom:::15 passed; 0 failed. Unfinished frames are capped at 64 MiB in total and open connections at 64, closed connections are released, and each poll returns within 50 ms.cargo test --test experiments custom_runner: 27 passed, including live recording and quota pauses. The 6 failures all reportsocat is not on PATHon this host, as do 20 sandbox unit tests inscripts/affected-tests.Visual evidence
The manual's Void list and Custom runner paragraph (this session's changes). Before is the previously published head
adfe4909; the changed paragraph is outlined.Manual: Void causes — 1440×900
Manual: Void causes — 390×844
Manual: Custom runner sessions — 1440×900
Manual: Custom runner sessions — 390×844
Earlier captures of the branch's site changes, before against
issue-1468:Homepage: Experiments workflow — 1440×900 / 390×844
How it works: Experiments — 1440×900 / 390×844
Architecture: Experiments and Scores — 1440×900 / 390×844
Manual: Custom runner contract — 1440×900 / 390×844
Test seams
thirdshift experiment: Custom runner recording, quota pauses, Void classification, role accounting and leak decisions, with retained evidence read throughexperiments --sessionand OTLP export.custom::collect: real Recorder andsessions.jsonimport with fixed proxy evidence, covering each accounting-gap trigger and the precedence of supervised failures.custom::web_search: real OTLP log files, including events from another Arm's build.custom::sessions::import: real input files converted to standard OTLP and read through the existing usage and OTLP readers, including filename confinement.Recorder::start/poll/finish: real Unix sockets plus native Trial-home evidence verify live retained usage.Review coverage
The final review pinned
refs/remotes/origin/issue-1468...adfe4909. Both Standards and Spec read all 22 changed files. Standards excluded the generatedsite/docs/index.htmlafter reviewingdocs/guide.mdandsite/generate-docs.mjs, withnpm run docs:check --prefix siteexiting 0. Spec read that output's changed hunk. No follow-up pass was needed.Not reviewed: the files changed by the review fixes. Those are
docs/code-navigation.md,docs/trial.mdand the newsrc/evals/experiment/execution/custom/tests.rs, plus fix edits to these files:src/evals/experiment/execution/custom.rs,src/evals/experiment/execution.rs,src/evals/experiment/execution/custom/recording.rs(test-module rename)src/evals/experiment/execution/custom/sessions/tests.rs(test rename)docs/guide.md,docs/eval-tasks.md,docs/experiment-results.mdandsite/docs/index.html(regenerated)Spec findings, 3 actionable, all addressed:
Standards findings, 12 actionable: fixed the native web-search Void docs, the stale
docs/code-navigation.mdpointers and the non-selectable test-module name. The rest are below.Unaddressed findings
Standards
accounting_gap,fix_leaked) already sit under the same definition.custom. Declined (judgement call). Thecollectbranch (src/evals/experiment/execution/custom.rs:42-45) letsweb_searchtake precedence over the accounting-gap check that follows it. The post-collection check insrc/evals/experiment/execution.rscovers native Trials. Moving modules would not change behaviour.collectreads Recorder fields; repeated flag-and-first-limit merging. Declined (judgement call). The merge happens in one function, and Recorder is private toexecution::custom(recording.rs:15).Sourceinimport. Declined (judgement call). It is a two-variant enum matched within one function (sessions.rs:51-91).Source::Sdk => Harness::Codexandwith_harnessclearingversion. Declined. Codex is chosen becauseinput_excludes_cache()is false for it (src/harness.rs:76-78), which is the SDK records' cache-inclusive input after conversion. The trace's Harness label is then overwritten assdk.arm.runnerandrecorderas paired Options. Declined (judgement call).recorderis built fromarm.runner(src/evals/experiment/execution.rs:202-207), so the two cannot diverge.session,output,request.json) that the version-1 runner contract indocs/eval-tasks.mdpublishes.proxy::AccountingtoTraffic. Declined (naming judgement). Its doc comment (src/proxy.rs:319-320) says what it holds.Spec
None.
Security
None. The one introduced finding, unbounded host-side reads from the
record_commandsocket, is fixed inc2a8474dwith regression tests.Security review outcome
No unaddressed introduced findings.
Merge Danger
Door: two-way
Blast Radius: Experiments
Changes Custom runner evidence collection and Trial Void classification. Existing OTLP consumers use the same representation; runner protocol mistakes remain local to one Trial.
Built with claude 2.1.322 · claude-opus-5-5 · high