
Choose how vx treats inputs that move
cache.inputStability picks which writes to an input during a run count, and whether one warns or fails the run. vx is tested in Git 3 repositories, and the benchmark pages show plain figures.
An input written while its task runs no longer reaches the cache, on CI too. The sandbox names the grant that fixes a denial, more refusals carry stable codes, and the reference works offline.

vx 0.0.633 to 0.0.635 shipped from 2026-10-09 to 2026-10-12. This batch keeps a result vx cannot vouch for out of the cache, lets you pick how tasks are scheduled, and gives agents and people more to act on: the grant a sandbox denial needs, a code for every refusal, and the reference without a network.
In this release
When a task’s input is written while the task runs, vx keeps the result
but does not save it, on CI too: an edit undone mid-run, or another task
changing the file and putting it back, cannot be told from no edit. A
task that rewrites its own input with the same bytes (tsdown’s
package.json) opts into rewrittenInputs: 'compare', and
VX_REWRITTEN_INPUTS=compare sets that default for every task.
$ vx run build --all...[vx] @demo/ui#build: `package.json` changed after its key was taken — the result stands, but is not saved under a key that no longer describes it$ VX_REWRITTEN_INPUTS=compare vx run build --allPRs #3407, #3420. Deep dive: When an input moves mid-run
schedule in vx.workspace.ts picks which ready task starts first:
most-work (the default), critical-path, direct-dependents or
ready-order. The default costs what it did; another strategy is
computed only when you name it. @vzn/vx-schedule-history now carries
its timings between CI runners in a file, and a run with nothing changed
no longer rewrites them (from 407 to 148 ms at 168,000 rows).
$ vx run build --all --dryPRs #3381, #3384, #3410. Deep dive: Which task runs first?
A sandboxed task that reads or writes a path it did not declare fails,
and now ends with the grants that would have allowed it. vx last --format json and MCP getFailures carry the same grants as
sandboxFix. A credential path is named apart, never in the line.
$ vx run build --all...fix: exec.sandbox.allow: { read: ['tsconfig.json'], write: ['dist/'] }PR #3414. Deep dive: A glob that stops at the fence
--affected and git failures, unknown dependsOn targets and
overlapping outputs now carry their own VX_E_ codes, and every code
links to the section that says how to fix it.
$ vx run build --all --affected=nope --format json{"ok":false,"error":{"code":"VX_E_AFFECTED_BASE","message":"vx run: git ref \"nope\" did not resolve. Pass a branch or commit you have locally.","docs":"https://vznjs.github.io/vx/cli/#vx_e_affected_base"}}vx last --failed and MCP getFailures replay the latest failed run. A
failed task now carries fixedIn, the first later run where it passed,
so an agent does not chase a failure that is already gone.
$ vx last --failed --format jsonPR #3393.
vx docs <query> searches the CLI and config reference shipped inside
the binary, with no network. vx docs <code> prints the fix for an
error code. MCP searchDocs gives agents the same search.
$ vx docs VX_E_AFFECTED_BASEPRs #3366, #3368. Deep dive: The reference, offline
@vzn/vx-lockfile adds vx prune --production: a lockfile and package
set for a runtime image, without the dev tools.
$ vx prune @demo/api --productionPR #3367. Deep dive: A runtime image without the dev tools
vx init --dry --format json prints the plan, and MCP planInit returns it.
A config file .gitignore would drop gets a note: with the line that
keeps it. A migrated build carries its cache block as a TODO, ready to
fill with the real inputs and outputs.
$ vx init --dry --format jsonThe npm package now starts vx from sh, not Node: vx --version
through node_modules/.bin went from 56 to 14 ms. A cold run skips the
cache probe on an empty local cache and checks the lockfile once, and a
run where every task is a cache hit skips the schedule stage.
$ npx @vzn/vx --versionPRs #3428, #3382, #3378, #3380, #3433.
v34: the first run drops the
index once, and artifact files stay and are used again on their next
hit (#3352).@vzn/vx-ci’s github() returns undefined outside GitHub Actions,
and core skips an undefined, null or false plugin entry. Code
that reads its fields must handle undefined
(#3406).PreparedRun.priorities is now a function that
returns the schedule stage’s weights, and the stage runs after setup,
only when a task will start
(#3433).npm install -D @vzn/vx@latestA standalone binary updates itself with vx upgrade.