Version Packages - #49
Open
github-actions[bot] wants to merge 1 commit into
Open
Conversation
github-actions
Bot
force-pushed
the
changeset-release/main
branch
3 times, most recently
from
August 10, 2026 18:42
9e3446a to
b4ea84a
Compare
github-actions
Bot
force-pushed
the
changeset-release/main
branch
10 times, most recently
from
August 14, 2026 18:37
cd14c8f to
bf7667d
Compare
github-actions
Bot
force-pushed
the
changeset-release/main
branch
7 times, most recently
from
August 25, 2026 12:59
c6e96c2 to
9445937
Compare
github-actions
Bot
force-pushed
the
changeset-release/main
branch
from
August 26, 2026 21:57
9445937 to
816dcc8
Compare
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.
This PR was opened by the Changesets release GitHub action. When you're ready to do a release, you can merge this and publish to npm yourself or setup this action to publish automatically. If you're not ready to do a release yet, that's fine, whenever you add more changesets to main, this PR will be updated.
Releases
@iso4/sandbox@0.5.0
Minor Changes
c6c7d13: chore: bump the v8 crate 130 → 147 (V8 13.0 → 14.7)
The serialization format is unchanged, so
@iso4/sandboxand@iso4/v8-*still pair exactly as before. Most native paths are 10–47 % faster.
344d259: feat: capacity manager — memory budget and
sandbox.stats()(feat: capacity manager — autodetected limits, queue policy, runtime.stats() #65)New
memoryBudgetMbdecides how many isolates stay alive, container-aware bydefault, while
maxIsolatesstill caps concurrent runs.sandbox.stats()returns a capacity snapshot over a control connection outside the run pool.
a5a6739: fix: connection integrity and result correlation (Cross-run confused deputy via stale promise continuations; generalize the bridge slot into a run-id invalidation primitive #73)
Every
Resultis matched against the run that asked for it, and a connectionwhose frame alignment is in doubt is replaced rather than reused.
maxIsolatesis now a capacity rather than a fixed set of connections, and there is a new
host-detected error code
ERR_PROTOCOL_DESYNC.e074119: feat: RSS watermark + scored eviction —
heapUsed × idleTime(feat: eviction scoring — heapUsed x idleTime with watermarks #66)The memory budget is enforced against the runtime's own process RSS: at the
mark, idle warm instances are evicted by score and new warm admissions stop
until RSS falls back to 80 % of it.
sandbox.stats()gainsbudgetBytes,rssBytesandunderPressure; the instance-count cap is gone.b45658c: feat: host → sandbox function calls —
prefix.call({ export, args })andrun({ code, call })(feat: host → sandbox function calls (call(exportPath, args)) forexport default { fetch }#58)Call a function that already lives in the sandbox, addressed by export path,
with arguments crossing as one V8 blob. An export that cannot cross no longer
fails a plain run — it is reported in the new
skippedExportsinstead.911a82d: refactor: remove runtime V8 snapshot creation — prefixes are validated source, re-evaluated per run (V8 14.7
create_blobraces on the process-shared read-only heap — concurrentprepare()segfaults the child #60, Execution model v2: remove runtime snapshots, add warm isolates #61, refactor: remove runtime snapshotting — prepare() validates and caches prefix source #62)The public API and the wire protocol are unchanged, but per-run latency now
includes prefix evaluation, and a nondeterministic prefix produces per-run
values. Closes the intermittent child-process crash under concurrent
prepare().cf851bf: feat: sandbox web runtime —
Headers,Request,Response,URL,TextEncoderand friendsRequest,ResponseandHeaderscross the boundary as real instances ratherthan flattening to plain objects. New error code
ERR_TYPE_NOT_SERIALIZABLEfor values that cannot cross; streams are deliberately unsupported.
467479f: feat!: replace the WireValue codec with V8 serialization blobs
Protocol version 1 → 2, so
@iso4/sandboxand@iso4/v8-*must be updatedtogether and a mismatch now fails at
createSandbox().Date,Map,Set,RegExp,Error, typed arrays and cycles round-trip as real instances, anddense payloads are ~5.9× faster.
b2a19f8: feat: warm isolate registry — prefix runs reuse resident isolates (feat: warm isolate registry with taint-and-evict #64)
Warmth is a cache and never a guarantee: module-scope state may survive between
runs on an instance and may be evicted at any time. Breaking —
limits.memoryMbmoves to
createSandbox({ memoryMb })with the default raised to 128 MB; newERR_WARMUP_LIMITand a newheapUsedBytesresult field.ea8937f: feat: widen
HostExportDatato everything V8 serialization carriesDate,RegExp,Error,Map,Set,ArrayBuffer, typed arrays,DataViewand cycles now cross as real instances. Host-module data leaves are no longer
inspected at registration, so an unsupported value fails with the serializer's
own error rather than one naming the exact leaf path.
Patch Changes
f1a2e24: fix: Request/Response clone() no longer shares its body buffer
A cloned Request or Response now gets its own copy of a buffer body, so
mutating one side's bytes no longer reaches through to the other.
5ca5ab9: perf: receive large results without stalling the host
Incoming chunks are joined once per frame instead of re-concatenated per
chunk. A 15 MB result now takes ~19 ms rather than ~1.2 s.
5a5cfbe: fix: reject a supplied-but-malformed per-run global override
A per-run
globalsoverride that is present but not a function (e.g. a tenanthandler that resolves to
undefined) now throws instead of silently fallingback to the precompile-time default, matching the imports side.
5ca5ab9: fix: stop the runtime when the host exits without
dispose()A last-resort
exithook now ends it.dispose()is still the only completeanswer, since a host killed by a signal runs no JavaScript.
3637971: fix: WHATWG-compliant URL in the sandbox
The sandbox
URLis now backed natively by the ada parser (the one Node.jsuses) and passes the WPT URL test suite, including IDNA, relative resolution
and non-special schemes.
URL.parse,URL.canParseand the previouslymissing component setters are now available.
1925209: fix: top-level
awaitin prefix code no longer failsprepare()(fix: top-levelawaitfails in every prefix —await 1is enough to breakprepare()#55)The runtime now drains the microtask queue until the prefix's evaluation
promise settles. Two new error codes state the remaining limits:
ERR_PREFIX_BRIDGE_CALLandERR_PREFIX_DID_NOT_SETTLE.c0de1ab: fix: preserve an own
__proto__key crossing into the sandboxRebuilding a host-supplied plain object no longer triggers the prototype setter,
so an own-enumerable
__proto__key (e.g. fromJSON.parse) crosses as datainstead of being silently dropped.
cf037f8: perf: cut fixed per-run overhead — ~4 % hot-run latency, ~6 % throughput
Per-run trace logs are off by default; set
ISO4_V8_TRACE=1to restore them.Prefix snapshots are shared by handle instead of copied twice per run.
9819e84: fix: reject URL credentials and control-char statusText in the sandbox
new Request(url)now throws when the URL includes credentials (fetch spec),and
new Responserejects astatusTextcontaining control characters(mirroring workerd) — so these fail on the user's line rather than host-side.
51e824d: fix: keep resource limits armed through result serialization
Serializing a run's result executes guest getters, so it now stays under the
run's CPU, wall and memory budgets; serialization time counts against
cpuTimeMs/wallTimeMs.343da7a: fix: replace the argv auth token with a kernel-enforced private socket directory
The runtime socket now lives in a fresh owner-only (0700) per-sandbox directory, so access is enforced by the kernel at connect time. The token is gone from the spawn args and the wire handshake (
@iso4/sandboxand@iso4/v8-*are released in lockstep).5ca5ab9: fix: clean up the runtime process when
createSandbox()failsA failed startup left the runtime running with no
Sandboxto dispose it. Aruntime that exits during startup is now reported with its exit code instead
of a socket timeout.
ba357d0: fix: identify runtime web types independently of one another during serialization
Serializing a
Headers,RequestorResponseno longer fails just because sandbox code removed or shadowed one of the other classes onglobalThis.@iso4/fetch@0.0.2
Patch Changes
7fb2cde: fix: resolve DNS only for authorized requests
DNS is no longer resolved before the allow/deny check, so a denied host is
never looked up — closing a covert-lookup channel and an internal-network
oracle. The private/reserved-IP block now runs at connection time (for allowed
requests only) and
SafeFetchRequest.resolvedIpis alwaysnull.5ca5ab9: fix: reach origins that resolve to IPv6
DNS pinning forced IPv4, so an IPv6-only host was unreachable and could end
the host process. Literal IPv6 URLs now resolve too, and
::is treated asreserved.
939afdd: fix: a matched host claims the origin for scheme and port
A request whose host matches a rule but uses a disallowed scheme or port is now
denied, matching the route behaviour, instead of falling through to the
policycallback.1c8cc0a: fix: match request paths literally instead of decoding them
The route allowlist now matches the path exactly as it is sent, with no
percent-decoding, so an encoded slash can no longer make the matched path differ
from the path on the wire.
./..are still normalised by the URL parser.fd0cd30: fix: strip credentials on cross-origin redirects
Following a redirect to a different origin now drops
authorization,cookieand
proxy-authorization, and a method-changing redirect dropscontent-*headers, matching undici's redirect handling.
c501131: fix:
setBodyno longer depends onthisctx.req.setBodycan now be destructured or passed as a callback withoutthrowing; it writes the request body through a closure like
headerandsetUrl.d544d5b: fix:
timeoutMsbounds the whole request, not each redirect hopA single deadline now spans the entire redirect chain, so a redirecting request
can no longer run for
(maxRedirects + 1)times the configured timeout.@iso4/v8-darwin-arm64@0.5.0
@iso4/v8-darwin-x64@0.5.0
@iso4/v8-linux-arm64-gnu@0.5.0
@iso4/v8-linux-x64-gnu@0.5.0