Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
58 commits
Select commit Hold shift + click to select a range
4a88a47
sandbox: translate the containment policy onto the veth the packets a…
Sep 11, 2026
5c38b8f
sandbox: put the interface filters in the launch path, not beside it
Sep 11, 2026
ff2dc5f
sandbox: make the runsc gate measure what it claims, on a real kernel
Sep 11, 2026
d65a749
sandbox: round-2 revise WIP — strict tc readback, cancellation custod…
Sep 11, 2026
9657581
sandbox: wire the evidence validator in, and give acceptance one comm…
Sep 11, 2026
3cb4495
sandbox: verify a real tc capture, and refuse every substitution in b…
Sep 11, 2026
0e4b507
sandbox: read the skipped lines too — statistics and action bookkeepi…
Sep 11, 2026
f15e7e3
sandbox live: let an integrated leg carry its own [sandbox] section
Sep 11, 2026
4f593c0
sandbox live: author the missing IPv6, both-runtime and pinhole legs …
Sep 11, 2026
04ea546
sandbox: exercise the cancellation bound instead of only reading it
Sep 11, 2026
98f1190
sandbox live: make the matrix survive its own first real run
Sep 14, 2026
7eae391
sandbox: permit only ND control traffic so v6 denial means something
Sep 14, 2026
fe82eb4
sandbox live: truncate the short plan by v4 count, not by a fixed tail
Sep 14, 2026
2857c56
sandbox: check the ND ordering guard by the message the guard now emits
Sep 14, 2026
53f4103
sandbox evidence: refuse a case record that states a field twice
Sep 14, 2026
5a78169
sandbox netns: keep custody of a sidecar whose command was cancelled
Sep 14, 2026
c856bf5
sandbox netns: actually bound the removal that called itself bounded
Sep 14, 2026
4d46b2e
sandbox live: score a denial only when the connection was denied
Sep 14, 2026
ed44aab
sandbox iface: read a statistics line by grammar, not by blacklist
Sep 14, 2026
c01e35a
test(sandbox): make the integrated matrix measure the merged DNS seam
Sep 14, 2026
f8b075e
docs(sandbox): stop this file's fixture reading as proof that DNS works
Sep 14, 2026
3a43ad0
fix(sandbox): keep sidecar custody until the container is shown gone,…
Sep 14, 2026
5d7837d
test(sandbox): measure the custody rule at the site that applies it, …
Sep 14, 2026
df93a55
fix(sandbox): tie every saved case to the test that asserts it, and m…
Sep 14, 2026
13745fd
fix(sandbox): fence a delayed create, hold custody until the containe…
Sep 14, 2026
c57e6c2
fix(sandbox): fence the sidecar create, keep custody through a signal…
Sep 14, 2026
d6774e4
sandbox_netns: confine the docker test seam to cfg(test)
Sep 14, 2026
e725c38
sandbox_netns: take the docker client as an argument and let cleanup …
Sep 14, 2026
f1a655c
sandbox: bound the create flow, prove cancellation hit it, install on…
Sep 15, 2026
42754c0
sandbox: keep cleanup custody past the bound, and bound the whole cre…
Sep 15, 2026
e424aa1
sandbox: make the outstanding-writer gate deterministic, not a race
Sep 15, 2026
4bfcbe3
sandbox: state the writer's disposition on the deadline path, either way
Sep 15, 2026
407faff
sandbox: transfer cleanup ownership instead of ending it, and ticket …
Sep 15, 2026
2726a86
sandbox: make the cleanup handoff atomic with settlement, and never d…
Sep 15, 2026
2f08f60
sandbox: custody that does not end while the process lives
Sep 15, 2026
d715d47
sandbox: lifecycle-ordered discharge, complete ambiguity record, thre…
Sep 15, 2026
93bc9a9
sandbox: wake waiters when an attempt starts; F3b gate on ordering, n…
Sep 15, 2026
16f9032
sandbox: adopt per-job cleanup-after stamp and expiry sweep primitives
Sep 15, 2026
6590c56
sandbox: stamp job-owned helpers with the same seat, expiry and job a…
Sep 15, 2026
d314352
seller node: sweep expired job containers every 300s on the run loop
Sep 15, 2026
ea84d96
sandbox: tests for the per-job expiry sweep
Sep 15, 2026
4dd2942
retire process-lifetime custody now that the expiry sweep owns late c…
Sep 15, 2026
a337dda
compile the holder cleanup path without the acp feature
Sep 15, 2026
ebc69d1
bound the sweep pass in wall clock and keep it off the run loop
Sep 15, 2026
fbaf972
correct the provenance line in 16f9032d
Sep 15, 2026
f29028d
live: re-cut the sweep acceptance rows and add the helper-stamp row
Sep 15, 2026
d1c3709
live: make the helper row name what the sweep saw when it goes red
Sep 15, 2026
c64e4d3
test: measure the descendant-pipe fixture's budget instead of guessin…
Sep 15, 2026
647c457
sandbox sweep: report refusals, rotate the pass, carry the deadline
Sep 15, 2026
98436f5
sweep: read a holder's job from its own label, not the helper's
Sep 15, 2026
8bb6005
sandbox_netns: resolve the sweep's job id per role, not first-column-…
Sep 16, 2026
806d1d1
seller_exec: prove a seller deadline reaches a real daemon label and …
Sep 16, 2026
3a1beac
test(996): guard the deadline's real entry point, and isolate the liv…
Sep 17, 2026
a5fa204
Merge MakePrisms/main (7d36a548) into w-gvisor-interface-impl2
Sep 17, 2026
f4e4eed
test(sandbox_netns_live): complete two struct literals main's merge l…
Sep 17, 2026
73ef6f0
fix(sandbox_netns): let sweep_seat exist in the default build
Sep 17, 2026
8ef30aa
test(seller_exec): give the live scope panic-safe ownership of what i…
Sep 17, 2026
5a4c34b
test(seller_exec): close R3 F1/F4 — acquisition-state ownership, non-…
Sep 18, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion crates/maxplayer-core/src/delivery_orchestrator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -583,7 +583,10 @@ fn drive_acp_agent(
&inputs.prompt,
workdir,
&identity,
AgentRunTimeout::JobDeadline(timeout),
AgentRunTimeout::JobDeadline {
remaining: timeout,
deadline_unix: inputs.deadline_unix,
},
Some(env.clone()),
// Servers only: the HOST mounted this container, so there is nothing to mount here.
JobAttachments { mcp_servers: inputs.mcp_servers.clone(), extra_mounts: Vec::new() },
Expand Down
13 changes: 11 additions & 2 deletions crates/maxplayer-core/src/held_tool.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1701,7 +1701,7 @@ mod live_tests {
let McpServer::Stdio(entry) = &attachments.mcp_servers[drive] else { panic!("stdio entries") };
let mut command = vec![entry.command.clone()];
command.extend(entry.args.iter().cloned());
let prepared = prepare_launch(&command, &policy, &workdir, &identity, Duration::from_secs(120))
let prepared = prepare_launch(&command, &policy, &workdir, &identity, Duration::from_secs(120), None)
.await
.expect("prepare the launch");
let mut servers = prepared.mcp_servers.clone();
Expand Down Expand Up @@ -1970,7 +1970,16 @@ mod live_tests {
prompt,
&workdir,
&identity,
crate::seller_exec::AgentRunTimeout::JobDeadline(Duration::from_secs(420)),
crate::seller_exec::AgentRunTimeout::JobDeadline {
remaining: Duration::from_secs(420),
// The absolute second this window ends at, taken HERE at construction — the
// one instant at which `now + remaining` IS the deadline rather than a guess.
deadline_unix: std::time::SystemTime::now()
.duration_since(std::time::UNIX_EPOCH)
.expect("a clock")
.as_secs()
+ 420,
},
None,
attachments,
)
Expand Down
17 changes: 17 additions & 0 deletions crates/maxplayer-core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,23 @@ mod sandbox_dns_live;
/// against its base to tell a regression from a preexisting condition. HARNESS ONLY.
#[cfg(all(test, feature = "acp", feature = "wallet"))]
mod sandbox_egress_live;
/// Offline validation of a *saved* live containment matrix: the record a live run writes down, and
/// the checks that say whether it actually covers every required case.
///
/// The live gates in `tests/sandbox_netns_live.rs` are `#[ignore]`d, so an ordinary `cargo test`
/// reports them as ignored and proves nothing about containment. This module is what the offline
/// acceptance entrypoint runs instead: it fails on a missing, duplicated, unknown or unscored case,
/// and on a record that does not name the commit, artifact and host it came from. Ungated for the
/// same reason as the policy modules below — a gate that can be compiled out is not a gate.
pub mod sandbox_evidence;
/// The same policy, on the interface the packets actually leave by.
///
/// `sandbox_net`'s rules live on the host kernel's `OUTPUT` chain, which a gVisor payload never
/// traverses: it runs its own netstack and hands finished packets to the namespace's veth. This
/// module translates the very same rendered policy into `tc`/`flower` filters on that veth, so the
/// containment stops depending on which runtime the job was launched under. Ungated for the same
/// reason as the renderer it derives from.
pub mod sandbox_iface;
/// Host-side network containment for a docker job (#797): which destinations a job may reach, and
/// the `iptables` rules that enforce it on the two chains container traffic actually splits across.
///
Expand Down
15 changes: 15 additions & 0 deletions crates/maxplayer-core/src/sandbox_dns_live.rs
Original file line number Diff line number Diff line change
Expand Up @@ -414,6 +414,8 @@ async fn contained_delivery(
workdir.path(),
&identity(),
Duration::from_secs(900),
// A live DNS probe, not a job — see the egress probe: no job deadline exists to carry.
None,
)
.await
.expect("containment must be established");
Expand Down Expand Up @@ -819,6 +821,8 @@ async fn gate_a_scenario(tag: &str) -> GateA {
workdir.path(),
&identity(),
Duration::from_secs(300),
// A live DNS probe, not a job: no job deadline exists to carry.
None,
)
.await
.expect("containment must be established");
Expand Down Expand Up @@ -922,6 +926,8 @@ async fn diagnose_v6_resolver_reachability_inside_containment() {
workdir.path(),
&identity(),
Duration::from_secs(300),
// A live DNS probe, not a job: no job deadline exists to carry.
None,
)
.await
.expect("containment must be established");
Expand Down Expand Up @@ -990,6 +996,8 @@ async fn diagnose_v6_resolver_outside_the_denied_ranges() {
workdir.path(),
&identity(),
Duration::from_secs(300),
// A live DNS probe, not a job: no job deadline exists to carry.
None,
)
.await
.expect("containment must be established");
Expand Down Expand Up @@ -1037,6 +1045,8 @@ async fn a_truncated_udp_answer_falls_back_to_tcp_53_inside_containment() {
workdir.path(),
&identity(),
Duration::from_secs(300),
// A live DNS probe, not a job: no job deadline exists to carry.
None,
)
.await
.expect("containment must be established");
Expand Down Expand Up @@ -1094,6 +1104,8 @@ async fn host_stub_discovery_hands_the_job_a_canonical_upstream_not_the_stub() {
workdir.path(),
&identity(),
Duration::from_secs(300),
// A live DNS probe, not a job: no job deadline exists to carry.
None,
)
.await
.expect("containment must be established from discovered resolvers");
Expand Down Expand Up @@ -1139,6 +1151,8 @@ async fn no_usable_resolver_refuses_before_a_holder_or_a_payload_exists() {
workdir.path(),
&identity(),
Duration::from_secs(300),
// A live DNS probe, not a job: no job deadline exists to carry.
None,
)
.await
.err()
Expand Down Expand Up @@ -1184,6 +1198,7 @@ async fn a_failed_installer_destroys_the_holder_and_leaves_nothing_to_launch_int
None,
true,
vec![RESOLVER_V4.to_owned()],
2_000_000_000,
)
.await;
let error = result.err().expect("an installer that cannot apply must fail the launch");
Expand Down
3 changes: 3 additions & 0 deletions crates/maxplayer-core/src/sandbox_egress_live.rs
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,9 @@ async fn contained_run(tag: &str, runtime: &str) -> (String, String, String) {
workdir.path(),
&identity(),
Duration::from_secs(300),
// A live egress probe, not a job: there is no job deadline to carry, so the stamp falls
// back to this probe's own lifetime rather than inventing an absolute one.
None,
)
.await
.expect("containment must establish");
Expand Down
Loading
Loading