A sandboxed task reads what it depends on, and nothing beside it
A sandboxed task can read the outputs of the tasks it depends on, in any project, and never their sources. With hermetic: true it reads nothing of the machine you did not name.
sandbox
sandbox
One project builds a tool, every other project runs it, and each stays
in its sandbox. The tool’s sources stay hidden.
flowchart LR
S[tools/src] -->|tools#build| O[tools/out]
O -->|readable| A[app#build, sandboxed]
S -.->|hidden| A
vx: the sandbox hid paths outside the project that exist on this machine, which are not reported as violations: /work/demo/packages/tools/src/greet.sh. If the task reads one, grant it, e.g. `allow: { read: ['../tools/src/greet.sh'] }`.
[vx] exit 127 is the shell's "command not found": cat is /usr/bin/cat on the host, but no sandbox grant reads it, so inside the sandbox it is not there — add it (or its directory) to exec.sandbox.allow.read
└─packages/app#build──(124ms)failed (exit 127)
The task reached for the host’s cat and found nothing. vx names the
host path and the grant that would fix it. A build cannot lean on a tool
that only your laptop has.
A cache is only correct if the declared inputs are every file the task reads. Instead of guessing that set, vx runs a task with the declared paths as the only workspace files it can touch, and fails the run on an undeclared one of its own.
correctness
One test suite, six task runners, the same 984 cases
984 task-runner cases, compiled from the test suites of Nx, Turborepo, Vite Task, moon, Nix and vx, run sandboxed against all six. Every result is on one page.