-
Notifications
You must be signed in to change notification settings - Fork 48
Comparing changes
Open a pull request
base repository: rivet-dev/secure-exec
base: v0.3.1
head repository: rivet-dev/secure-exec
compare: v0.3.2
- 6 commits
- 55 files changed
- 2 contributors
Commits on Jun 25, 2026
-
fix(runtime): strip module shebang, stream large http responses, reje…
…ct oversized vm.fetch by content-length (#130) - v8-runtime: strip a leading #!shebang in build_module_source so the patched Claude agent SDK (which begins with #!/usr/bin/env node) parses in guest V8 instead of SyntaxError-crashing the adapter on session/new (host Node strips it; the guest loader did not). - v8-bridge: ServerResponseBridge streams a single res.end(body) to the connection socket in bounded slices (incremental byteLength) instead of buffering the whole body + its serialize/transmit copies, which tripped the isolate heap-limit OOM guard on multi-MB responses. Socket-backed path only; loopback http unchanged. - sidecar: vm.fetch rejects a response whose declared Content-Length exceeds VM_FETCH_BUFFER_LIMIT_BYTES before stalling on a body it cannot stream through the bounded kernel socket buffer; keeps the per-VM configured-limit payload check intact. - limits-inventory: classify DEFAULT_HEAP_LIMIT_MB (policy) and MAX_V8_USERLAND_CODE_BYTES (invariant). Co-authored-by: Claude Opus 4.8 (1M context) <[email protected]>
Configuration menu - View commit details
-
Copy full SHA for 2eb88d8 - Browse repository at this point
Copy the full SHA 2eb88d8View commit details -
fix(sidecar): shadow-walk skip + bound undici pool to stop the net-br…
…idge leak (#128) Three native-sidecar fixes behind long-lived VM latency/stall. 1) Read-side shadow-tree re-walk Read-side guest fs ops (Exists/Stat/Lstat/ReadFile/Pread) reconcile the host shadow tree into the kernel VFS, re-reading+re-writing EVERY file on EVERY op (O(whole tree), super-linear). Add an rsync-style (size,mode,mtime) lstat skip for unchanged files. Test read_side_ops_skip_unchanged_shadow_files: warm read over an unchanged 800-file tree >4x cheaper than cold (cold=22.7s, warm=28ms debug). 2) EventEmitter shim: spurious MaxListenersExceededWarning ensureEventEmitterInitialized() defaulted _maxListenersWarned but not _maxListeners, so emitters that acquire _events outside our ctor (undici's Client/Pool/Agent) had _maxListeners=undefined and 'total <= undefined' warned on the FIRST listener. Default _maxListeners so the threshold is meaningful. 3) undici client-per-request leak (the real net-bridge leak) The bridge's UndiciAgent was created with an UNBOUNDED per-origin pool. Requests that overlap while clients are still connecting each find every client kNeedDrain and spawn a fresh Client+socket -- and for HTTPS the LLM path is HTTP/2 (ALPN), so each spawn is a whole new h2 session. The synchronous bridge reads widen that connect window (the #122 per-payload macrotask yield only helps h1 same-socket reuse, nothing for the h2 connect-window herd). Over a long many-call turn the abandoned clients accumulate connect/close/drain/error/finish/readable/end/ terminated listeners without bound -> http2 degradation -> 'Request was aborted.' Bound connections (6, browser-like; h2 multiplexes within each) so excess requests queue on existing clients instead of spawning new ones. Test keepalive_no_listener_leak now drives CONCURRENT requests (the trigger) and asserts the host-side connection count stays bounded: 160 requests over 6 connections with the cap vs 16 (2x concurrency) without it. A process.on('warning') handler surfaces any MaxListenersExceededWarning to stderr (the warning alone is insufficient -- leaked listeners spread across per-client emitters). Co-authored-by: Claude Opus 4.8 (1M context) <[email protected]>
Configuration menu - View commit details
-
Copy full SHA for 1225be9 - Browse repository at this point
Copy the full SHA 1225be9View commit details -
fix(execution): size the wasm runner V8 heap so warmup stops OOMing (#…
…129) The wasm runner isolate is started with JavascriptExecutionLimits::default(), so its V8 heap falls back to isolate::DEFAULT_HEAP_LIMIT_MB (128 MiB -- the per-GUEST isolate budget). But the runner is trusted infrastructure that must compile the WASI runtime + the guest's wasm module (e.g. bash.wasm) into its own heap before the guest runs, and that routinely exceeds 128 MiB. The near-heap-limit guard then terminates the isolate with an uncatchable, message-less exception, so warmup dies and surfaces as the opaque 'WebAssembly warmup exited with status 1 (Error: null)' (ERR_AGENTOS_NODE_SYNC_RPC). A clean release hits this too. Size the runner heap explicitly (default 2048 MiB, operator-tunable via AGENTOS_WASM_RUNNER_HEAP_LIMIT_MB) instead of leaving it on the per-guest default. This does NOT weaken guest isolation: the guest module's memory/fuel/stack stay bounded separately, Rust-side, from request.limits. The value is a V8 heap ceiling (heap_limits(0, cap)), committed only as used. Unit test wasm_runner_heap_limit_defaults_and_honors_operator_override covers the default (> 128), a positive override, and zero/non-numeric fallback. Co-authored-by: Claude Opus 4.8 (1M context) <[email protected]>
Configuration menu - View commit details
-
Copy full SHA for 02564e2 - Browse repository at this point
Copy the full SHA 02564e2View commit details -
fix: plug twelve runtime memory leaks across sidecar, kernel, VFS, V8 (…
…#131) A leak audit of the VM runtime found tracking maps/registries populated on create but released only on a happy-path teardown (skipped on error '?' or never), plus per-timer threads with no cancellation. Each fix releases on every termination path; each ships a fast safeguard-firing test. sidecar: - dispose_vm_internal removes per-VM tracking on every exit path (VM removed before the fallible teardown half; cleanup runs unconditionally, error surfaced after) and the dispose_session/remove_connection loops attempt every item and aggregate errors instead of '?'-ing out (H1). - extension_process_output_buffers cleared on VM disposal, not just on successful handoff (M6). - disposed sessions are now untracked from the stdio active_sessions set (M5). - loopback-TLS endpoints remove their own registry entry on Drop instead of relying on the lazy retain() sweep (L4). - new additive Extension::on_session_disposed hook, fired on DisposeReason::ConnectionClosed, so extensions (e.g. ACP) can free per-session state on client disconnect (enables agent-os H4). sidecar-browser: vms/contexts maps cleared on every dispose path (H1). execution: bridge/kernel timer threads are delay-capped and cancellable via a generation check + clear-on-teardown, so guest timers can't exhaust OS threads or outlive their session (H2, M3). v8-runtime: VM_CONTEXTS slots evicted on context finalize, not only on error, so reused isolates don't hit MAX_VM_CONTEXTS (M1); pending promise-resolver Globals reset before the isolate is dropped on every run_event_loop exit (Shutdown/abort), fixing the leak and a V8 lifetime-contract violation (M2). kernel: socket ids allocated only after the backlog check passes, so a full-backlog connect failure no longer consumes an id (M4). vfs: rename rolls back staged snapshot entries on copy/rename failure (L2); InMemoryMetadataStore gains delete_snapshot() and a real gc() that reclaims unreferenced blocks (L3). L1 (bounded, documented Box::into_raw isolate handle) intentionally left as-is. Co-authored-by: Claude Opus 4.8 (1M context) <[email protected]>
Configuration menu - View commit details
-
Copy full SHA for f183ed2 - Browse repository at this point
Copy the full SHA f183ed2View commit details
Commits on Jun 26, 2026
-
Configuration menu - View commit details
-
Copy full SHA for 1f13c36 - Browse repository at this point
Copy the full SHA 1f13c36View commit details -
fix(sidecar): classify new limit constants, tolerate stale sidecar re…
…sponses, fix service-test build (#133) Fixes surfaced while syncing agent-os against latest secure-exec main: 1. limits: classify DEFAULT_WASM_RUNNER_HEAP_LIMIT_MB (#129) and MAX_TIMER_DELAY_MS (#131) — both added without inventory entries, so limits_audit failed on main. 2. sidecar: accept_sidecar_response drops a stale sidecar_response with no matching pending request (UnmatchedResponse) or already completed (DuplicateResponse) instead of failing the whole sidecar — a per-VM callback can be answered by the host after that VM is disposed on the shared sidecar process. Real protocol violations stay fatal. 3. tests: re-export crate::EventSinkTransport into the source-included service test crate (#132 added the use in src/service.rs without the matching test re-export, breaking 'cargo test -p secure-exec-sidecar --test service' compilation). Co-authored-by: Claude Opus 4.8 (1M context) <[email protected]>
Configuration menu - View commit details
-
Copy full SHA for d8a4435 - Browse repository at this point
Copy the full SHA d8a4435View commit details
This comparison is taking too long to generate.
Unfortunately it looks like we can’t render this comparison for you right now. It might be too big, or there might be something weird with your repository.
You can try running this command locally to see the comparison on your machine:
git diff v0.3.1...v0.3.2