feat(sandbox): acked delivery, exec deadlines and cancel-on-disconnect
Stacked on #619.
At-least-once work delivery. Poll returns at most PRELOOP_SANDBOX_POLL_BATCH items (default 64) and keeps them in flight keyed by work id until the agent reports; unacknowledged items are redelivered after PRELOOP_SANDBOX_DELIVERY_TIMEOUT_SECS (default 120) and when the provider re-registers. The agent dedupes by work id (running/done) and re-reports stored results instead of re-executing.
Reliable reports. The agent retries Report / ReportExec with jittered exponential backoff (cap 15 s) until success or fencing. ReportExec carries a per-exec sequence (generation-scoped); the service drops duplicates/out-of-order batches and closes the caller's stream on the exit event. A lost exit no longer hangs the caller.
Deadlines. timeout_secs = 0 gets PRELOOP_SANDBOX_EXEC_TIMEOUT_SECS (default 3600); drivers kill and report exit 124. Snapshot waits are bounded by the work timeout. Stale execs/pending are swept.
Caller disconnect. Dropping the exec stream queues CancelExec; the agent calls the new optional Driver::cancel_exec (SmolVM kills the exec child, exit 130) and the service drops its exec state.
Agent loop. Jittered poll backoff (0.5ā15 s); work runs under a semaphore (PRELOOP_SANDBOX_AGENT_CONCURRENCY, default 32).
Tests: batch cap, redelivery + re-register release, sequence ordering + close-on-exit, default deadline, disconnect cancel, lost ReportExec retried, redelivered create not re-executed, bounded snapshot wait; unit tests for the cancel race, jitter window and fencing.
Lockfile: one first-party edge (rand on preloop-sandbox; already locked).
Summary by cubic
Sandbox work delivery is now at-least-once and every exec is bounded by a deadline; disconnected callers cancel their exec instead of leaving it running.
Delivery and deadlines
Pollreturns at mostPRELOOP_SANDBOX_POLL_BATCH(default 64) items and keeps them in flight until acked byReport; unacked items are redelivered afterPRELOOP_SANDBOX_DELIVERY_TIMEOUT_SECS(default 120 s) or when a provider re-registers.- Agents dedupe by work id and re-report stored results instead of re-executing; work runs under a semaphore (
PRELOOP_SANDBOX_AGENT_CONCURRENCY, default 32). ReportandReportExecare retried with jittered exponential backoff (capped 15 s);ReportExecbatches carry per-exec sequences so retries are dropped.timeout_secs = 0means the service deadline (PRELOOP_SANDBOX_EXEC_TIMEOUT_SECS, default 3600 s). Drivers kill the command at it (exit 124), and overdue execs are swept to the same exit 124, never an error.- Provider and host-tool waits run through the shared bounded-deadline runners instead of unbounded child waits.
Cancel-on-disconnect
- Dropping the exec stream queues
CancelExec; the agent calls the new optionalDriver::cancel_exec(SmolVM kills the exec child, exit 130) and the service drops the exec state. - SmolVM wraps streaming commands in a guest shell that records the PID and start time; on deadline or cancel a follow-up
machine execterminates the process group (SIGTERM then SIGKILL), guarding against PID reuse. preloop sandbox execinstalls a SIGINT listener before sending the request, so an inheritedSIG_IGNprocess can still stop the pump loop and trigger the cancel path.