
The sandbox says what it refused
On Linux, the vx installed from npm reports a write its sandbox refused, with the grant to add, and blocks unix sockets again. A sandbox that reads none of its project offers the whole-project grant.
A build an incremental tool cut short is not saved, and a run refuses an install the lockfile does not name. vx lock names an ignored .env file and a variable the command never gets. Workers plan from their own warm-ups.

This release closes the ways an everyday workspace cached a wrong build under a green run.
A build that leftover state cut short is not saved. A run refuses an install the lockfile does not name.
vx lock says what a key misses, vx init writes a config a plain
tsc builds, and workers plan from their own warm-ups.
This release is breaking. Read the breaking changes first.
In this release
tsc -b keeps its state in tsconfig.tsbuildinfo, beside the sources
and outside dist/.
After an edit, vx emptied dist/ before the miss. The state still said
the rest was built, so tsc emitted one file and the partial dist/
was saved.
Now a miss stamps such files before its command: a file git ignores, or
a .tsbuildinfo, that the task declares neither input nor output.
If one changed, the result stands but is not saved, and the line names the fix.
$ vx run build --filter packages/lib[vx] packages/lib#build: tsconfig.tsbuildinfo changed while the task ran, but the task declares it neither input nor output — the result stands, but is not saved: a tool that reads such a file back (an incremental build's state) builds from it, not from the inputs; declare it in outputs.files ('tsconfig.tsbuildinfo'), so a miss starts without it and a hit restores itWith the file in outputs.files, a miss starts without it and a hit
restores it. A state file that claims no built output is left alone:
Vite’s and create-vue’s noEmit builds keep caching.
See Caching.
The key hashes the lockfile, never node_modules.
A git pull that brought a lockfile change, run before the install,
built against the old packages and saved the output under the new
lockfile’s key.
Now a run whose cached tasks key on the lockfile refuses while
node_modules is not the install the lockfile names. It names the
package and the install that fixes it.
$ vx run build --all✗ vx run plugin '@vzn/vx-lockfile' failed in key: node_modules was installed from a different bun.lock (packages/ui's is-number is 7.0.0, the lockfile names 5.0.0) — run `bun install`pnpm(), bun(), npm() and yarn() each read the record their
manager leaves of its install. A match is remembered, so a warm run
compares nothing.
See Lockfile plugins.
A glob reads only what git lists. inputs: { files: ['**'] } over a
Vite or Next app keyed everything but the ignored .env.local the build
reads, with no word.
inputs.env only keys a variable; the command gets what
exec.env.passThrough gives it. A build keyed on VITE_API_URL alone
moved its key and built every bundle without the value.
vx lock now names both.
$ vx lock✓ vx lock 2 project configs → .vx/projects.lock.json! vx lock packages/web#build: inputs leave out git-ignored .env.local (matched by **) — a glob reads only what git lists; name it as a literal input ('.env.local') to key on it! vx lock packages/web#build: inputs.env keys VITE_API_URL, which a bundler writes into its output, but the command never gets it — add it to exec.env.passThroughThe .env note also prints on the miss. A glob over vx’s own
vx.lock.json no longer takes it for an ignored file.
See vx lock.
A default NestJS app broke twice on the vx.config.ts that vx init
writes.
tsc on moduleResolution: node reads no exports map, so
@vzn/vx/config did not resolve. A tsconfig with no include took the
config into the build, and dist/main.js became dist/src/main.js.
Now the import resolves there, and vx init and a migration name each
tsconfig that would compile the config they write.
$ vx init vx init 0.0.655 from no turbo.json or nx.json files .vx/workspace.ts vx.config.ts .vx/.gitignore .vx/.gitattributes note tsconfig.json names no "include", so tsc compiles vx.config.ts too and its output moves (dist/main.js becomes dist/src/main.js): add "vx.config.ts" to "exclude" there lock 1 project config → .vx/projects.lock.json
next bunx @vzn/vx-migrate to make package.json scripts tasks, or declare a task in vx.config.ts, then vx lock && vx run <task>The cache block a migration suggests now keys the whole package,
inputs: { files: ['**'] }, and says to narrow it.
See vx init.
A distributed run kept each worker’s warm-up time in a cache entry, which a fresh cache lost.
Now a warm-up is timed like a task and kept in history, which
@vzn/vx-history shares. The next run’s plan counts what a worker
of that size took to join.
$ VX_DTE_RUN=$(uuidgen) vx run build --all workers linux.small#1 left 1 done · warm-up 0.3s · packages/app#build linux.small#2 left 2 done · warm-up 0.2s · packages/ui#build, packages/lib#build asked 2 at 0.1s for 3 tasks (3 measured), plan 1.5s ideal 1.3s: each task as long as it took, placed perfectly, holding 4.2 core-s at least drift +0.1s past ideal total cpu utilization machine 16% · tasks 0% · worker 6% · held 5.6 core-sThe plan also seeks the earliest end that packs onto fewer workers, books every task at least one core, and keeps an idle worker over one the CI has not started.
See Distributed task execution.
SIGTERM sent to the whole process group under a relaying parent is one stop, not a kill of every task mid-cleanup.PATH runs with it on the worker.vx cache clean no longer fails a run waiting on the same cache directory.text or eol attributes are no longer hashed on every run.@vzn/vx-migrate accepts Nx 22 to 24; sandboxed nx-exec tasks run on Nx 24.@vzn/vx-lockfile keys linked folders each manager left out of its lockfile.vx upgradeRun vx lock after upgrading. Every cached task misses once.
vx-cache-v56: the local cache starts empty once.@vzn/vx-lockfile digests changed: vx lock --check fails on the old lock.TaskExecutor keys → grouped under capabilities and distribution; any other key refuses the run.TaskOutcome fields → grouped under cache, timing, usage, placement, attempts and sandbox.Cache memo methods → cache.memo.<name>; its record* methods are removed.lockfileClaim’s importers → links.PLUGIN_HOOKS gains measures, before schedule.@vzn/vx-dte-server’s token exports → @vzn/vx-devtools.@vzn/vx no longer ships index.ts or config/index.ts at its root.See also Upgrading.