Skip to content
GitHubRSS

Upstream bug ledger

Real Turborepo and Nx bug reports in vx’s scope, each checked against vx and, where vx could have it, held by a test. The survey (2026-09-24) read the two trackers for stale cache hits, key instability, restore and save faults, graph and filter errors, signal and teardown bugs, watch and output faults, and remote-cache failures, then asked of each: does vx have it, and would a test notice if it came back? Where no test would, one was written (item 745); where vx had the bug, it was fixed and the fix’s tests are cited here.

A row is one upstream report, or a few that report one fault. Its verdict is one of:

  • covered: the cited tests would fail if vx had the bug. Rows the survey found untested say “written for this ledger”.
  • n/a: the bug cannot occur in vx; the note says why. A test is cited where one pins the reason.
  • fixed-in-item-N: vx had the bug; STATUS item N fixed it, and its tests are cited. A fix pinned only by a template-titled loop, which the law cannot cite, names the loop in the note.
  • open (id): vx has the bug and the fix is not in yet; the id names it: new: for a fault writing the ledger found, limit: <page> § <heading> for a documented limit, naming the heading that states it.

Every citation is file › "title", the file relative to the repository root and the title exactly as written in the test. tests/upstream-ledger.unsafe.test.ts parses both tables and fails when a cited title is not an it(…) or test(…) title in that file, when a covered row cites nothing, or when an open (limit: …) row names no heading of its page, so a renamed or deleted test cannot leave a row claiming a pin it lost.

issueclassverdictvx testnote
turborepo#14059stale-hit:env-undeclaredn/apackages/vx/tests/orchestrator.test.ts › “undeclared env vars do not leak to the child”taskEnv (packages/vx/src/orchestrator/execute-task.ts) gives a task the essential allowlist, its passThrough names, its define pairs, the bin dirs on PATH and vx’s two run markers (VX_RUN_WORKSPACE, VX_RUN_TASK); no other host variable.
turborepo#10690stale-hit:env-globalcoveredpackages/vx/tests/orchestrator.test.ts › “cache.inputs.env affects the cache key; exec.env.passThrough alone does not”
turborepo#4645, turborepo#1099stale-hit:env-unsetfixed-in-item-739packages/vx/tests/orchestrator.test.ts › “a declared env name UNSET and set to the empty string are different keys”
turborepo#548stale-hit:env-manycoveredpackages/vx/tests/orchestrator.test.ts › “a change to the LAST of thirteen declared env names misses”written for this ledger (item 745)
turborepo#9659, turborepo#10826env:exclusion-ignoredn/aThere is no workspace-level env layer: WORKSPACE_FIELDS (src/workspace/config-schema.ts:33) has no env field. CLAUDE.md § Rejected lists globalEnv; comparison.md § Likely-worth-adding item 4 rejects globalPassThroughEnv with it.
turborepo#4428stale-hit:dotenvcoveredpackages/vx/tests/inputs.test.ts › “src/* folds the dotfile src/.env”
turborepo#13948, turborepo#886stale-hit:global-input-droppedcoveredpackages/vx/tests/stale-hit.test.ts › “a workspace output written mid-run reaches a consumer whose partition was read before it”
turborepo#13918stale-hit:dep-output-snapshotcoveredpackages/vx/tests/stale-hit.test.ts › “a wiped output stops counting as a consumer input on the cache-miss path”
turborepo#13788, turborepo#8051, turborepo#7821stale-hit:hash-before-depsfixed-in-item-743packages/vx/tests/undeclared-writes.test.ts › “seeds A, B, B, A build A, B, B, A: the up-front key is not taken before the producer ran”<br>packages/vx/tests/undeclared-writes.test.ts › “the first run keys the file the producer created, not the run-start listing without it”<br>packages/vx/tests/undeclared-writes.test.ts › “a TRACKED input the producer rewrites is keyed on its new bytes, not its index OID”<br>packages/vx/tests/undeclared-writes.test.ts › “an unsandboxed uncached producer makes its same-project reader unstable”An uncached producer’s writes into its project: a reader there is no longer keyed up front, and the run-start git facts are dropped once the producer exits.
turborepo#10111stale-hit:task-mutates-inputsfixed-in-item-743packages/vx/tests/inputs-moved.test.ts › “is not saved under the key of the bytes it rewrote, so restoring them re-runs it”<br>packages/vx/tests/inputs-moved.test.ts › “an input the task deletes: the entry is withheld”<br>packages/vx/tests/inputs-moved.test.ts › “the project’s package.json, which every key folds: the entry is withheld”<br>packages/vx/tests/in-run-writes.test.ts › “seeds A, B, B, A build A, B, B, A: its reader is not restored ahead of it”<br>packages/vx/tests/in-run-writes.test.ts › “under a read-only cache policy the rewrite still drops what the run knew of the project”A miss re-checks its inputs before it saves; an input its own command changed withholds the save with one status line. A same-project reader folding no key of it is keyed after it, not up front, and a run that saves nothing still drops what it knew of the project (item 750).
turborepo#1146stale-hit:edit-during-runfixed-in-item-743packages/vx/tests/inputs-moved.test.ts › “while the command runs: the entry is withheld, and the restored file rebuilds”<br>packages/vx/tests/inputs-moved.test.ts › “before the task starts, a TRACKED input: its index OID is not trusted past the edit”<br>packages/vx/tests/inputs-moved.test.ts › “before the task starts, an UNTRACKED input: the key re-derived at the command differs”<br>packages/vx/tests/inputs-moved.test.ts › “edited and reverted while the command runs: still withheld, and the next run rebuilds”An input edited and reverted while the command runs is seen too (item 1015). Not seen: a file added under an input glob mid-run.
turborepo#1473, turborepo#7540, turborepo#1323stale-hit:tracked-dirtycoveredpackages/vx/tests/git-oid.test.ts › “edit changes the key; reverting restores the ORIGINAL key before any commit”
turborepo#1280, turborepo#4185, turborepo#9574stale-hit:no-vcscoveredpackages/vx/tests/inputs.test.ts › “the FALLBACK enumeration refuses a non-git dir too, not just the populate”<br>packages/vx/tests/no-git-on-path.test.ts › “vx run build --affected is one line naming the install”<br>packages/vx/tests/no-git-on-path.test.ts › “vx run build --affected=HEAD is one line naming the install”<br>packages/vx/tests/no-git-on-path.test.ts › “vx run build --all is one line naming the install”
turborepo#12554key-unstable:gitignore-dirtycoveredpackages/vx/tests/inputs.test.ts › “gitignored files are excluded (workspace-root .gitignore)”
turborepo#2560key-unstable:gitignored-in-globcoveredpackages/vx/tests/orchestrator.test.ts › “gitignored files do not contribute to the default input set”
turborepo#7784key-unstable:outputs-as-inputscoveredpackages/vx/tests/local-shortcircuit.test.ts › “codegen-into-shared-project dependent is NOT restore-tier (stays exec-tier)”
turborepo#9676key-overbroad:unlisted-filecoveredpackages/vx/tests/parity-turbo.test.ts › “a file outside inputs changes nothing (Turbo: inputs narrows the default)”
turborepo#13384key-overbroad:workspace-wide-depscoveredpackages/vx/tests/orchestrator-run.test.ts › “sibling-package input isolation: editing one package does not bust an unrelated sibling”
turborepo#11025key-overbroad:passthrough-argscoveredpackages/vx/tests/orchestrator-run.test.ts › “forwardArgs do NOT pollute upstream cache keys (dep stays cached across user-args changes)”
turborepo#9218key-overbroad:negation-via-depcoveredpackages/vx/tests/orchestrator.test.ts › “a negated input still excludes when a same-project upstream writes into the inputs”written for this ledger (item 745)
turborepo#8112, turborepo#4522glob:negationcoveredpackages/vx/tests/inputs-resolution.test.ts › “position is irrelevant: a negation listed FIRST still subtracts”<br>packages/vx/tests/orchestrator.test.ts › “composing ’**/*’ with negation works as union-then-subtract”
turborepo#1913, turborepo#3087stale-hit:input-outside-projectcoveredpackages/vx/tests/project-loader.test.ts › “rejects .. path segments in cache.inputs.files”
turborepo#169stale-hit:upstream-sourcecoveredpackages/vx/tests/sandbox-runtime.unsafe.test.ts › “an unkeyed sibling is withheld and the read reported, with the hint (project link)“<br>packages/vx/tests/parity-turbo.test.ts › “an inputs change misses — and cascades to dependents, which fold upstream inputs”
turborepo#2606stale-hit:lockfile-resolutioncoveredpackages/vx/tests/orchestrator-run.test.ts › “workspace fingerprint: pnpm-lock.yaml change busts every task cache”<br>packages/vx-lockfile/tests/pnpm.test.ts › “a dependency bump re-keys only the projects that reach it”
turborepo#12252key-unstable:lockfile-ordercoveredpackages/vx-lockfile/tests/pnpm.test.ts › “is independent of YAML key order”<br>packages/vx/tests/lockfile-claim.test.ts › “the order a COMPONENT pops its members in does not move its digest”
turborepo#5081key-unstable:binary-filecoveredpackages/vx/tests/git-oid.test.ts › “matches git hash-object for empty and binary content”
turborepo#5217key-unstable:checkout-pathcoveredpackages/vx/tests/git-subdir-workspace.test.ts › “the main checkout and a linked worktree at a longer path derive the same keys”written for this ledger (item 745)
turborepo#13651stale-hit:absolute-path-outputn/apackages/vx/tests/cache-dir-selection.test.ts › “the second checkout, at another and longer path, restores what the first saved”An artifact holds outputs by project-relative path (outputs/<rel>, caching.md § Cache write), so a hit restores into the checkout that asks, a shared cacheDir included.
turborepo#702key-collision:projectcoveredpackages/vx/tests/task-hash-derive.test.ts › “a different task id yields a different key”
turborepo#1010stale-hit:cache-disabledcoveredpackages/vx/tests/parity-turbo.test.ts › “a task that loses its cache block moves its key and executes instead of replaying the old entry”written for this ledger (item 745)
turborepo#9681force:ignored-with-remotecoveredpackages/vx/tests/cli.test.ts › “—force skips reads but keeps writes (re-execute + refresh)“<br>packages/vx/tests/layered-cache.test.ts › “get() with remote reads off is a plain local miss: no remote GET, null”
turborepo#3127remote:force-no-overwritecoveredpackages/vx/tests/orchestrator-remote.test.ts › “—force uploads the re-executed artifact over the one the remote holds, and the next cold run is served it”written for this ledger (item 745)
turborepo#13430, turborepo#12645, turborepo#11216restore:symlink-treecoveredpackages/vx/tests/output-shape.test.ts › “a symlink to a directory, or a dangling one, fails the save loudly instead of caching nothing”
turborepo#13042save:symlink-output-rootcoveredpackages/vx/tests/output-shape.test.ts › “saves through the link, hits, and a hit restores the file the link leads to”written for this ledger (item 745)
turborepo#1070save:dangling-symlinkcoveredpackages/vx/tests/output-shape.test.ts › “a symlink to a directory, or a dangling one, fails the save loudly instead of caching nothing”
turborepo#7410restore:long-pathcoveredpackages/vx/tests/artifact-roundtrip.test.ts › “a cache hit restores the produced tree byte- and mode-identically”
turborepo#156, turborepo#1236restore:file-modecoveredpackages/vx/tests/artifact-roundtrip.test.ts › “a cache hit restores the produced tree byte- and mode-identically”
turborepo#10951restore:stale-extra-filescoveredpackages/vx/tests/stale-hit.test.ts › “a STRAY file in a declared output dir is not “up-to-date” — the set must match”
turborepo#6754save:partial-on-abortcoveredpackages/vx/tests/execute-task.test.ts › “an aborted task is never cached — its partial outputs are not replayed next run”
turborepo#12786save:detached-descendantopen (limit: packages/vx/docs/caching.md § Cache write)packages/vx/tests/runner.test.ts › “returns promptly when a backgrounded grandchild holds the pipe open (no hang)”Not a fix: item 742 only documented it. The outputs are what exists when the command exits (caching.md § Cache write); a descendant the command detached has left the process group vx tracks, so the command must wait for it.
turborepo#6749restore:skipped-under-uncachedcoveredpackages/vx/tests/parity-turbo.test.ts › “an uncached task over a cached dependency restores the deleted outputs of the dependency first”written for this ledger (item 745)
turborepo#8476restore:wrong-destinationcoveredpackages/vx/tests/overlapping-outputs.test.ts › “upstream MISS + dependant HIT: build re-runs and wipes dist, individual restores its own rows after”
turborepo#944, turborepo#10400, turborepo#3185, turborepo#3393save:output-outside-projectcoveredpackages/vx/tests/project-loader.test.ts › “rejects .. path segments in cache.outputs.files (data-loss vector)”
turborepo#839cache-corruption:hardlinkn/aAn entry is one <hash>.tar.zst and a restore extracts fresh bytes from it (caching.md § Storage layout, § Cache lookup → restore).
turborepo#10875restore:needless-rewritecoveredpackages/vx/tests/overlapping-outputs.test.ts › “both miss, then both hit up-to-date: the tree is the cold tree, twice”
turborepo#6136save:task-name-charsn/aEntries are stored by key, never by task name: one artifact is <hash>.tar.zst (caching.md § Storage layout).
turborepo#9345hash:non-utf8-namefixed-in-item-739packages/vx/tests/stale-hit.test.ts › “a name that holds U+FFFD as a character is an input like any other”<br>packages/vx/tests/stale-hit.test.ts › “an output by that name fails the save by name, so no hit restores a tree without it”
turborepo#531, turborepo#6729, turborepo#13732hash:directory-entrycoveredpackages/vx/tests/git-oid.test.ts › “a tracked symlink to a directory is an input: retargeting it moves the key, clean or dirty”
turborepo#1103hash:git-noisecoveredpackages/vx/tests/stale-hit.test.ts › “git warning on stderr during the attribute check leaves the key where a quiet git puts it”written for this ledger (item 745)
turborepo#939logs:replay-ordercoveredpackages/vx/tests/output-flow.test.ts › “a replayed dependency frame closes before its live dependent frame opens”written for this ledger (item 745)
turborepo#3272, turborepo#972logs:replay-modecoveredpackages/vx/tests/output-flow.test.ts › “cache hit with replayed stdout → silent”
turborepo#12302remote:integritycoveredpackages/vx-reapi/tests/integrity.test.ts › “readBlob refuses bytes that do not hash to the requested digest”<br>packages/vx-migrate/tests/turbo-cache.test.ts › “signs uploads and refuses a download whose tag does not verify”
turborepo#487, turborepo#2096, turborepo#8772remote:upload-failure-silentcoveredpackages/vx-migrate/tests/remote-cache-degrade.test.ts › “a 413: green, one warning naming the upload, its artifact and the server”<br>packages/vx-migrate/tests/remote-cache-degrade.test.ts › “an upload past its deadline: green, one warning naming the upload and the deadline”written for this ledger (item 745)
turborepo#2081remote:unreachable-silentcoveredpackages/vx-migrate/tests/remote-cache-degrade.test.ts › “a closed port: green, the task executes, and ONE warning names the request and the server”<br>packages/vx-migrate/tests/remote-cache-degrade.test.ts › “a host that does not resolve: green, the task executes, and ONE warning names the request and the server”written for this ledger (item 745)
turborepo#6765, turborepo#7359remote:auth-failurecoveredpackages/vx-migrate/tests/remote-cache-degrade.test.ts › “six projects, one warning — what the adopter reads”
turborepo#5055, turborepo#6921remote:crashcoveredpackages/vx-migrate/tests/remote-cache-degrade.test.ts › “a corrupt artifact degrades to a miss — never a half-restored output”<br>packages/vx/tests/layered-cache.test.ts › “get() that resolves the wrong shape is named as the plugin bug and degraded to a miss”
turborepo#12346remote:upload-skippedcoveredpackages/vx/tests/orchestrator-remote.test.ts › “a cached dependency of an uncached requested task is uploaded and later served remotely”written for this ledger (item 745)
turborepo#8418remote:layer-selection-ignoredcoveredpackages/vx/tests/orchestrator-remote.test.ts › “local:,remote:rw re-executes over a LOCAL-only entry and uploads the result”written for this ledger (item 745)
turborepo#9177remote:wire-content-lengthcoveredpackages/vx-migrate/tests/turbo-cache.test.ts › “put → has / hasMany / get round trip with the spec’s headers and query”<br>packages/vx-migrate/tests/nx-cache.test.ts › “put → get round trip; a miss is 404 → null; a second put of the same hash is the spec’s 409 and fine”
none (found checking turborepo#1103 and turborepo#5081)stale-hit:xdg-attributesfixed-in-item-739packages/vx/tests/stale-hit.test.ts › “takes both files from a git that names them, and nothing else”<br>packages/vx/tests/stale-hit.test.ts › “mirrors the global lookup for a git that does not name it”
turborepo#135graph:same-package-dep-ignoredcoveredpackages/vx/tests/parity-turbo.test.ts › “"dependsOn": ["build"] — a bare name waits on the same package’s task”
turborepo#1212graph:same-package-dep-expands-to-allcoveredpackages/vx/tests/parity-turbo.test.ts › “"dependsOn": ["build"] — a bare name waits on the same package’s task”
turborepo#9589, turborepo#11147graph:missing-task-still-pulls-depscoveredpackages/vx/tests/task-selection.test.ts › “a project without the requested task contributes none of its dependencies”written for this ledger (item 745)
turborepo#10109graph:caret-through-missing-taskcoveredpackages/vx/tests/task-graph.test.ts › “^name passes through deps that lack the task to deeper holders (sparse bridge)”
turborepo#10705graph:caret-upstream-emptycoveredpackages/vx/tests/parity-turbo.test.ts › “"dependsOn": ["^build"] — a package builds after every workspace dependency builds”
turborepo#10785graph:catalog-protocol-edge-missingcoveredpackages/vx/tests/package-graph.test.ts › “a catalog: entry keeps the edge its key names (turborepo#10785)”pinned with item 734, after the survey ran
turborepo#6744graph:workspace-path-aliasfixed-in-item-734packages/vx/tests/package-graph.test.ts › “a workspace: path or alias links the package it points at, not its key (turborepo#6744)”
turborepo#4214, turborepo#8989graph:range-mismatch-treated-as-localfixed-in-item-734packages/vx/tests/package-graph.test.ts › “a range the local version does not satisfy is a registry dependency (turborepo#4214)”
turborepo#12640, turborepo#1601graph:peer-dep-edgesfixed-in-item-734packages/vx/tests/package-graph.test.ts › “an installed entry, not a peer on the same key, decides the edge (turborepo#12640)”
turborepo#9619graph:root-task-shorthand-with-filtercoveredpackages/vx/tests/task-selection.test.ts › “the workspace root listed as a project keeps its task under a negated filter”written for this ledger (item 745)
turborepo#7899graph:root-task-depends-on-workspace-taskn/adocs/schema.md § dependsOn: “Same-project ('name') — name must exist in this project’s tasks map; missing is a hard error at graph-build time.”
turborepo#9072graph:root-task-bare-dep-resolves-to-rootn/adocs/schema.md § dependsOn: “Same-project ('name') — name must exist in this project’s tasks map; missing is a hard error at graph-build time.”
turborepo#5847graph:package-override-drops-base-depsn/acomparison.md § Config schema comparison: “Target defaults / inheritance” (Turbo extends, Nx targetDefaults) is “rejected by design — presets are TS imports”. There is no inherited task to merge.
turborepo#10454graph:plan-lists-missing-taskcoveredpackages/vx/tests/cli.test.ts › “a —dry typo beside good tasks names ONLY the typo”
turborepo#262, turborepo#973, turborepo#675cycle:package-cycle-hangscoveredpackages/vx/tests/task-graph.test.ts › “detects a cross-project cycle”
turborepo#1117cycle:self-dependency-hangscoveredpackages/vx/tests/package-graph.test.ts › “a package that names ITSELF is not its own dependency”
turborepo#1163cycle:false-positive-without-task-cyclecoveredpackages/vx/tests/task-graph.test.ts › “a package cycle between projects that makes no task cycle builds”
turborepo#8484persistent:depends-on-persistentcoveredpackages/vx/tests/persistent.test.ts › “a persistent task over a persistent upstream starts after it, and both stay up for the run”written for this ledger (item 745)
turborepo#4291persistent:concurrency-check-counts-missingn/adocs/schema.md § persistent: “The runner spawns the command but does NOT wait for it to exit.” / “Downstream unblocks on ready, not on exit.”
turborepo#4195persistent:starves-concurrencycoveredpackages/vx/tests/persistent.test.ts › “persistent task with concurrency=1 does not block downstream forever”
turborepo#4438persistent:parallel-flag-validationn/adocs/cli.md § Flags has no --parallel, and docs/schema.md § persistent: “The runner spawns the command but does NOT wait for it to exit.”
turborepo#8915exec:dev-server-exits-earlyfixed-in-item-740packages/vx/tests/keep-alive.test.ts › “a server that exits on stdin EOF stays up while vx runs”A persistent task reads a stdin pipe vx holds open, so a server that exits on EOF (esbuild —watch) stays up.
turborepo#12502exec:child-hangs-under-runnercoveredpackages/vx/tests/terminal.unsafe.test.ts › “cannot open /dev/tty, fails that open at once, and the run completes”written for this ledger (item 745)
turborepo#9651exec:pre-post-lifecycle-scriptsn/adocs/execution.md § One command per task: “exec.command is a single shell command — there’s no multi-step sequence.”
turborepo#1744exec:passthrough-args-leak-to-depscoveredpackages/vx/tests/orchestrator-run.test.ts › “arguments after — reach the named task command and never its dependency”written for this ledger (item 745)
turborepo#339concurrency:limit-ignoredcoveredpackages/vx/tests/scheduler.test.ts › “serializes execution with concurrency = 1”
turborepo#2887concurrency:limit-lost-after-failurecoveredpackages/vx/tests/scheduler.test.ts › “failing tasks keep the concurrency cap, under deps-ok and always alike”written for this ledger (item 745)
turborepo#12251concurrency:deadlock-high-core-countcoveredpackages/vx/tests/scheduler.test.ts › “a worker count far above the task count, the default on 96 cores included, completes”written for this ledger (item 745)
turborepo#10013exit:parallel-should-continuecoveredpackages/vx/tests/scheduler.test.ts › “deps-ok (default): a failure skips dependents, siblings run — unchanged pin”
turborepo#454exit:continue-masks-failurecoveredpackages/vx/tests/parity-turbo.test.ts › “--continue runs dependents past a failure; the run is still red”
turborepo#567exit:false-failurecoveredpackages/vx/tests/git-subdir-workspace.test.ts › “passes under a plain, an -a and a partial commit and keys from the working tree”written for this ledger (item 745)
turborepo#4227exit:signal-death-exits-zerocoveredpackages/vx/tests/signal-death.test.ts › “a SIGKILL the runner saw is named with the OOM killer and a kill”
turborepo#5298, turborepo#5454, turborepo#5098, turborepo#11056exit:failure-reported-successcoveredpackages/vx/tests/cli.test.ts › “exits 1 when a task fails”
turborepo#5403exit:continue-runs-dependents-of-failedcoveredpackages/vx/tests/parity-turbo.test.ts › “a failure skips its dependents and reds the run (Turbo --continue=dependencies-successful; vx default)”
turborepo#4504exit:continue-failure-summary-missingcoveredpackages/vx/tests/failure-recap.test.ts › “seven failures: five tails, then the other two named by id”
turborepo#9693exit:interrupt-code-not-tasksn/adocs/cli.md § vx run, exit-code table: 130 / 143 / 129 is “Interrupted (SIGINT / SIGTERM / SIGHUP)”.
turborepo#444, turborepo#9694, turborepo#10020, turborepo#4274signal:sigint-not-forwardedfixed-in-item-740packages/vx/tests/signal-handling.test.ts › “SIGINT to vx reaches a one-shot task as SIGINT”<br>packages/vx/tests/signal-handling.test.ts › “SIGINT to vx reaches a ready persistent task as SIGINT”<br>packages/vx/tests/watch-signals.test.ts › “SIGINT during the initial run reaches its task as SIGINT”<br>packages/vx/tests/watch-signals.test.ts › “SIGINT while idle reaches the dev server it holds as SIGINT”<br>packages/vx/tests/signal-handling.test.ts › “SIGTERM to vx reaches a one-shot task as SIGTERM”vx forwards the signal it received, SIGINT for Ctrl-C, where it sent SIGTERM for all.
turborepo#12652, turborepo#13097signal:sigint-through-sh-wrapperfixed-in-item-740packages/vx/tests/signal-handling.test.ts › “SIGINT to vx reaches a one-shot task as SIGINT”<br>packages/vx/tests/signal-handling.test.ts › “SIGINT to vx reaches a ready persistent task as SIGINT”<br>packages/vx/tests/watch-signals.test.ts › “SIGINT during the initial run reaches its task as SIGINT”<br>packages/vx/tests/watch-signals.test.ts › “SIGINT while idle reaches the dev server it holds as SIGINT”The task’s own sh now gets SIGINT, so its trap … INT runs.
turborepo#9666signal:parent-sigkill-orphans-childrenfixed-in-item-860packages/vx/tests/keep-alive.test.ts › “a SIGKILLed vx takes an unsandboxed persistent task’s backgrounded server with it”<br>packages/vx/tests/keep-alive.test.ts › “a SIGKILLed vx takes an unsandboxed one-shot task’s backgrounded child with it”<br>packages/vx/tests/sandbox-runtime.unsafe.test.ts › “a traced sandboxed one-shot task’s children die with vx”<br>packages/vx/tests/sandbox-runtime.unsafe.test.ts › “a sandboxed server’s backgrounded and setsid children die with vx”<br>packages/vx/tests/keep-alive.test.ts › “the stdin ends when vx is SIGKILLed, so a server that watches it goes too”A group guard (kill-tree.md, item 860): one sh per vx process reads a pipe only vx writes, lists each spawn’s process group while vx holds it, and SIGKILLs the listed groups when vx’s end closes. It is started at the first spawn, so a warm run pays nothing, and a 600-task cold run is a tie. A Linux sandboxed server already went with vx through --die-with-parent (item 801); a traced sandboxed one-shot, whose strace outlived vx, now goes too. What escapes is a process that left the group with setsid, unsandboxed. PR_SET_PDEATHSIG was measured and refused: +1.2 ms a spawn, and it kills only the process it is set on.
turborepo#1626signal:sighup-orphans-childrencoveredpackages/vx/tests/task-tree-kill.test.ts › “SIGHUP to vx reaps the grandchild and exits 129”<br>packages/vx/tests/task-tree-kill.test.ts › “SIGHUP gives the grandchild its SIGTERM cleanup, not only a death”
turborepo#12786signal:escaped-descendant-early-completeopen (limit: packages/vx/docs/caching.md § Cache write)packages/vx/tests/runner.test.ts › “returns promptly when a backgrounded grandchild holds the pipe open (no hang)”docs/modules/kill-tree.md § What it does NOT do: “Reach a daemon that called setsid itself”. The outputs are what exists when the command exits (caching.md § Cache write); a descendant the command detached has left the process group vx tracks, so the command must wait for it.
turborepo#12920signal:ctrl-c-no-exitcoveredpackages/vx/tests/keep-alive.test.ts › “SIGINT after the summary exits 130 and takes the server down”written for this ledger (item 745)
turborepo#14043signal:shutdown-output-after-exitcoveredpackages/vx/tests/signal-handling.test.ts › “at the moment vx exits on a signal every task process is gone and its pipes are closed”written for this ledger (item 745)
turborepo#13907output:unbounded-bufferingcoveredpackages/vx/tests/output-flow.test.ts › “the tail is bounded and says how much of the head it dropped”
turborepo#2564output:prefix-colour-nondeterministiccoveredpackages/vx/tests/framed-output.test.ts › “is the same escape in another process and in any discovery order”written for this ledger (item 745)
turborepo#897output:replay-loses-colourn/adocs/schema.md § ExecEnv: “CI / FORCE_COLOR / TERM (stdout bytes, and vx caches and replays stdout)… if one does, say so explicitly” (fold it via cache.inputs.env).
turborepo#8961output:runner-noise-on-stderrcoveredpackages/vx/tests/ci-output.test.ts › “a green run writes nothing to stderr: a miss and a hit, with CI set and without”written for this ledger (item 745)
turborepo#972output:replay-notice-when-suppressedcoveredpackages/vx/tests/output-flow.test.ts › “errors-only: success and hits silent, failures framed”
turborepo#10739output:errors-only-empty-groupscoveredpackages/vx/tests/output-flow.test.ts › “resolveOutputView attaches gha only when GITHUB_ACTIONS is truthy”
turborepo#9441watch:output-mode-ignoredcoveredpackages/vx/tests/cli.test.ts › “re-runs the task after a file change, then exits on SIGINT”
turborepo#1319, turborepo#2939filter:exclusion-vs-dependsOnn/adocs/cli.md § vx run: “By default only the project containing the current working directory is selected — dependsOn still expands so the project’s upstream workspace deps run too.”
turborepo#8672filter:negation-drops-root-taskcoveredpackages/vx/tests/filter.test.ts › “a negated name or path keeps the root project”written for this ledger (item 745)
turborepo#9043filter:path-glob-with-exclusioncoveredpackages/vx/tests/filter.test.ts › “a path glob minus one path selects every other app and nothing else”written for this ledger (item 745)
turborepo#8599filter:leading-dot-slash-pathcoveredpackages/vx/tests/filter.test.ts › “—filter ./apps/web selects the member pnpm-workspace.yaml lists as ./apps/*”written for this ledger (item 745)
turborepo#958filter:no-match-runs-everythingcoveredpackages/vx/tests/parity-turbo.test.ts › “a --filter that matches no package refuses the run (Turbo: exits 1 too)”
turborepo#9277, turborepo#11428select:cwd-inference-nondeterministiccoveredpackages/vx/tests/cli.test.ts › “is the deepest project containing the cwd, the same on every run”written for this ledger (item 745)
turborepo#4107filter:intermittent-task-omissioncoveredpackages/vx/tests/persistent.test.ts › “every one of thirteen persistent tasks a filter selects starts at concurrency 2”written for this ledger (item 745)
turborepo#1528filter:changed-prefix-matchcoveredpackages/vx/tests/affected.test.ts › “a change in a sibling-prefix project dir selects exactly that project”
turborepo#1055filter:changed-selects-nothingcoveredpackages/vx/tests/parity-turbo.test.ts › “--filter=[HEAD~1] selects the packages with changed files since a ref”
turborepo#1333filter:changed-root-package-not-foundcoveredpackages/vx/tests/affected.test.ts › “still selects the importer one hop out”
turborepo#11409, turborepo#12594filter:git-range-mishandledcoveredpackages/vx/tests/affected.test.ts › “refuses the range %j before git sees it, naming the base %j”
turborepo#9096filter:name-plus-git-unchanged-errorsn/adocs/cli.md § Filter DSL lists [<git-ref>] only as its own selector (“Projects whose files changed since <git-ref>”).
turborepo#9234, turborepo#1609filter:changed-omits-dependentscoveredpackages/vx/tests/affected-dependents.test.ts › “an edit to lib selects lib AND app, never tool”
turborepo#3432filter:since-merge-base-vs-direct-diffn/adocs/cli.md § --affected: “The diff runs from the merge base of the ref and HEAD, not from the ref itself, so a branch whose base has moved on sees only its own changes — never the files other people landed on main since it forked (Turbo and Nx do the same).”
turborepo#3965filter:changed-includes-unchangedcoveredpackages/vx/tests/affected.test.ts › “ignores changes outside any project directory”
turborepo#9578filter:root-by-namecoveredpackages/vx/tests/filter.test.ts › “the root project is selected by its name, and …name adds its dependents”written for this ledger (item 745)
turborepo#13636affected:filter-not-applied-to-tasksn/adocs/cli.md § Selection: “Combining: every include (--filter <pat>, --affected) is taken first and every ! exclude after them all, as pnpm does, so an exclude removes what any include added, whichever side of it it sits (items 955, 979).”
turborepo#4559, turborepo#9208affected:shallow-clone-missing-objectcoveredpackages/vx/tests/affected-base-notes.test.ts › “in a real depth-2 clone, —affected=HEAD~1 and …[HEAD^] select the change and its dependents”written for this ledger (item 745)
turborepo#9320, turborepo#12650affected:base-ref-only-remotecoveredpackages/vx/tests/affected.test.ts › “returns the remote’s HEAD branch (origin/main) when origin/HEAD is set”
turborepo#10862, turborepo#10688affected:unrelated-packages-selectedcoveredpackages/vx/tests/affected-dependents.test.ts › “an edit to lib selects lib AND app, never tool”
turborepo#10869, turborepo#11144affected:root-manifest-change-selects-allcoveredpackages/vx/tests/affected.test.ts › “a root file that is NOT part of the fingerprint does not widen”
turborepo#2862, turborepo#8125affected:lockfile-change-selects-allcoveredpackages/vx-lockfile/tests/pnpm.test.ts › “--affected selects the projects the bump reaches”
turborepo#12635affected:lockfile-delta-catalogfixed-in-item-747packages/vx-lockfile/tests/yarn.test.ts › “a catalog bump ^6 → ^7 moves the workspace that names catalog: and what links it”<br>packages/vx-lockfile/tests/yarn.test.ts › “a bump inside the catalog range moves the workspace that names catalog:”<br>packages/vx-lockfile/tests/yarn.test.ts › “a named catalog (catalog:<name>) reaches the entries of its package”<br>packages/vx-lockfile/tests/yarn.test.ts › “a scoped package named by a catalog reaches its entries”<br>packages/vx-lockfile/tests/yarn.test.ts › “a bump inside the catalog range re-keys and selects the projects that reach it”<br>packages/vx-lockfile/tests/yarn.test.ts › “a catalog flip the lockfile does not record re-keys and selects every project”<br>packages/vx/tests/fingerprint.test.ts › “a Yarn catalog flip that leaves yarn.lock byte-identical moves the digest (turborepo#12635)“<br>packages/vx-lockfile/tests/pnpm.test.ts › “a catalog bump moves the importer that names catalog: and no other (turborepo#12635)“<br>packages/vx-lockfile/tests/bun.test.ts › “a catalog bump moves every workspace: bun.lock records the catalog (turborepo#12635)”Writing the row found the bug: yarn.lock records a Yarn 4 catalog dependency as "catalog:", not its range, so yarn() reached no entry (a bump inside the range was a stale hit), and a catalog flip to a range the file already resolved left it byte-identical, a stale hit with no plugin at all. yarn() now reaches every entry of the package, and core fingerprints .yarnrc.yml. pnpm and Bun catalogs were already right; the last two rows pin them.
turborepo#14151affected:root-internal-dep-changen/adocs/caching.md step 3: the workspace fingerprint is pnpm-lock.yaml, package-lock.json, npm-shrinkwrap.json, yarn.lock, bun.lock, bun.lockb, pnpm-workspace.yaml, .yarnrc.yml, .npmrc and bunfig.toml.
turborepo#12512affected:upstream-deps-droppedcoveredpackages/vx/tests/parity-turbo.test.ts › “--filter=app selects by package name; dependsOn still pulls its builds in”
turborepo#13790affected:commandless-task-omittedn/adocs/cli.md § --affected: “It selects the CHANGED projects and their dependents.” Selection is per project, never per task.
turborepo#14149affected:negated-global-glob-ignoredcoveredpackages/vx/tests/affected.test.ts › “honours a leading ! as an EXCLUDE, like resolveWorkspaceFiles”
turborepo#14130affected:dot-slash-input-globcoveredpackages/vx/tests/affected.test.ts › “reads a spelling the way the KEY reads it, or —affected skips a stale project”
turborepo#12947, turborepo#12329, turborepo#12338affected:root-relative-inputcoveredpackages/vx/tests/affected-workspace-files.test.ts › “the change re-keys the task AND selects it”
turborepo#7245graph:deleted-package-stalecoveredpackages/vx/tests/orchestrator-run.test.ts › “a package deleted after a warm run and a lock leaves the next run and a frozen run without it”written for this ledger (item 745)
turborepo#2517graph:symlinked-package-dircoveredpackages/vx/tests/workspace.test.ts › “a member directory that is a symlink to a package outside the glob is discovered”written for this ledger (item 745)
turborepo#3766graph:negated-workspace-globfixed-in-item-742packages/vx/tests/workspace.test.ts › “an extglob member pattern is refused by name, not widened (turborepo#3766)”Bun.Glob has no extglob, so every extglob form in a member glob is refused by name, with the ! rewrite for a whole-segment negation.
turborepo#8673watch:deps-first-run-not-awaitedn/adocs/cli.md § vx watch › Lifecycle: “Initial run. Same code path as vx run — same scope resolution, same task graph, same cache behaviour.”
turborepo#12433, turborepo#12505watch:mixed-interruptible-stalln/adocs/cli.md § vx watch › Constraints: “Persistent tasks (exec.persistent) re-spawn each cycle.”
turborepo#9421, turborepo#9328watch:interruptible-killed-not-restartedfixed-in-item-740packages/vx/tests/watch-loop.test.ts › “the dev server stays up while watch idles and is replaced when the next cycle starts”The held server stops when the next cycle starts, not at the end of its own.
turborepo#13115watch:out-of-inputs-change-killsfixed-in-item-740packages/vx/tests/watch-loop.test.ts › “the dev server stays up while watch idles and is replaced when the next cycle starts”On vx the same fault as the row above: the server stopped at the end of each cycle, so it was down whenever watch sat idle.
turborepo#12501, turborepo#8164watch:upstream-build-not-reruncoveredpackages/vx/tests/watch-loop-members.test.ts › “a —filter scope watches its upstream dependencies too: a lib edit is one cycle that rebuilds both”
turborepo#12654watch:upstream-rerun-on-downstream-changen/adocs/cli.md § vx watch › Constraints: “Persistent tasks (exec.persistent) re-spawn each cycle.” … “For dev-server workflows where you want the server to stay up across changes, use the dev tool’s own watch (vite, tsc -b -w, bun --watch) rather than vx watch.”
turborepo#12087, turborepo#10960watch:outputs-retrigger-loopcoveredpackages/vx/tests/watch-rules.test.ts › “drops a task’s own declared outputs, under either watcher, and nothing beside them”
turborepo#13402watch:ignored-dir-burst-rerunscoveredpackages/vx/tests/watch-loop-selfwrite.test.ts › “git-ignored, it never starts a cycle: the edit cycle and its follower, then quiet”
turborepo#8932watch:subdir-root-spurious-rerunscoveredpackages/vx/tests/git-subdir-workspace.test.ts › “git writing its own directory runs no cycle, and an input edit still does”written for this ledger (item 745)
turborepo#11118, turborepo#13925watch:root-input-change-missedcoveredpackages/vx/tests/watch-loop-members.test.ts › “under the root watcher, a root file no key can see is not a cycle; a declared one is”
turborepo#9463watch:atomic-save-missedcoveredpackages/vx/tests/watch-loop.test.ts › “an atomic save by rename is one cycle with the new content, three saves in a row”written for this ledger (item 745)
turborepo#9531watch:single-package-repocoveredpackages/vx/tests/watch-loop.test.ts › “runs, watches, and re-runs once on an edit”written for this ledger (item 745)
turborepo#10122watch:persistent-failure-no-exitn/adocs/cli.md § vx watch › Exit codes: “Re-run cycles whose orchestrator returns { ok: false } do NOT exit the watch loop — a failed cycle just prints the framed FAILED block and waits for the next change.”
turborepo#8802, turborepo#10353env:strict-mode-drops-inherited-varscoveredpackages/vx/tests/env.test.ts › “TMPDIR, TMP and TEMP reach the task unchanged, and what the task exports reaches its children”written for this ledger (item 745)
turborepo#9659env:passthrough-wildcard-mergen/apackages/vx/tests/config-schema-refusals.test.ts › “an env name that no environment can hold is refused in every list”A wildcard in passThrough is refused at load (item 1090; schema.md § ExecEnv), and there is no workspace env layer to merge.
turborepo#11192env:relative-path-resolved-per-taskn/aOf the variables docs/cli.md § Environment variables vx reads lists, only VX_RUN_WORKSPACE holds a path, and vx sets it absolute; --cache-dir is resolved once, relative to cwd.
issueclassverdictvx testnote
nx#27965stale-hit:key-before-upstream-runscoveredpackages/vx/tests/stale-hit.test.ts › “a wiped output stops counting as a consumer input on the cache-miss path”
nx#32214, nx#33379, nx#29685stale-hit:upstream-cascadecoveredpackages/vx/tests/orchestrator.test.ts › “an edit two hops upstream misses the whole chain and reaches the top output”written for this ledger (item 745)
nx#36908, nx#36239stale-hit:external-deps-upstreamcoveredpackages/vx-lockfile/tests/pnpm.test.ts › “a bump behind a link: re-keys the linking project too”
nx#22664, nx#29074stale-hit:tool-versioncoveredpackages/vx-lockfile/tests/pnpm.test.ts › “a dependency bump re-keys only the projects that reach it”
nx#36902stale-hit:undeclared-machine-staten/aCLAUDE.md principle 2: “Explicit over magical. Caching is opt-in; cache.inputs.files is required; no inferred inputs”.
nx#33684, nx#35934restore:non-relocatable-outputsn/aThe key is path-independent by design (see nx#7692).
nx#7692key-unstable:checkout-pathcoveredpackages/vx/tests/cache-dir-selection.test.ts › “the second checkout, at another and longer path, restores what the first saved”written for this ledger (item 745)
nx#36675stale-hit:shared-cache-worktreecoveredpackages/vx/tests/git-subdir-workspace.test.ts › “a worktree sharing the cache directory misses on its own edit and never replays main”written for this ledger (item 745)
nx#18289, nx#18866, nx#33781, nx#34528stale-hit:file-hash-memocoveredpackages/vx/tests/stale-hit.test.ts › “a content change that preserves mtime is not served from the file-hash memo”<br>packages/vx/tests/watch-loop.test.ts › “a git checkout that rewrites twenty inputs is one cycle with the new content (L5)”
nx#23106stale-hit:path-not-in-keycoveredpackages/vx/tests/stale-hit.test.ts › “renaming an input misses and back again restores only the outputs of that name”written for this ledger (item 745)
nx#16270, nx#31574stale-hit:gitignored-inputcoveredpackages/vx/tests/inputs-resolution.test.ts › “REFUSES a gitignored file NAMED explicitly in inputs.files”
nx#19796inputs:gitignore-unignorecoveredpackages/vx/tests/orchestrator-run.test.ts › “gitignore: a directory re-included under an ignored parent is an input, its ignored siblings are not”written for this ledger (item 745)
nx#19392, nx#20216, nx#31067, nx#29824stale-hit:dotenvn/apackages/vx/docs/modules/env.md § What this does NOT do: “Doesn’t read from .env files or anywhere except source.”
nx#21390stale-hit:env-undeclaredcoveredpackages/vx/tests/orchestrator.test.ts › “undeclared env vars do not leak to the child”
nx#30170stale-hit:runtime-inputcoveredpackages/vx/tests/runtime-inputs.test.ts › “runtime output change invalidates the cache (re-executes)”
nx#36629stale-hit:config-subsetn/acaching.md § What’s NOT in the key: “Workspace-root configs (tsconfig.base.json, etc.) are not auto-included — declare them via cache.inputs.workspaceFiles”.
nx#34595stale-hit:input-token-interpolationn/aschema.md inputs.workspaceFiles: “Workspace-root-relative globs — the Turbo $TURBO_ROOT$ / Nx {workspaceRoot} equivalent”.
nx#26880stale-hit:glob-dialectn/aschema.md: “The wildcards are *, **, ? and a brace set {a,b}.” “This holds for every task glob … and for everything read from them (--affected, vx watch, the overlapping-output refusal).”
nx#36845stale-hit:glob-literal-atn/a@ is no wildcard in a task glob: GLOB_WILDCARDS (src/util/paths.ts) is *?{}, and Bun.Glob has no extglob, so @ matches itself. No test pins it.
nx#34225, nx#31264inputs:nested-projectn/aCLAUDE.md principle 6: “Project boundaries are hard. Globs never cross into another project.” caching.md invalidation table: a change in a nested project’s dir is “NOT a trigger for the parent’s files globs”.
nx#11642inputs:negation-tokencoveredpackages/vx/tests/workspace-files.test.ts › “supports ! negation”<br>packages/vx/tests/orchestrator.test.ts › “negation glob in inputs excludes matched files from the cache key”
nx#28047inputs:negation-implicitn/acaching.md step 4: “Project package.json hash — … Folded in implicitly (Turbo / Nx parity)”.
nx#30980inputs:negation-overriddenn/aCLAUDE.md principle 2 (“no inferred inputs”) and Rejected: “Named inputs / globalInputs / globalEnv (TS configs compose)”.
nx#22277, nx#26915, nx#14217, nx#29101key-overbroad:lockfilecoveredpackages/vx-lockfile/tests/pnpm.test.ts › “a dependency bump re-keys only the projects that reach it”
nx#36951key-unstable:node_modules-layoutn/acaching.md step 3: the workspace fingerprint is the bytes of the root lockfiles and install settings (.npmrc, bunfig.toml, .yarnrc.yml), never node_modules.
nx#20929key-unstable:platform-optional-depsn/aSame as the previous row, and caching.md § What’s NOT in the key: “Node / Bun / OS / build-tool versions — unless you declare them.”
nx#22248key-unstable:stale-dep-graphcoveredpackages/vx-lockfile/tests/pnpm.test.ts › “a warm run reads the memo instead of parsing”
nx#35234, nx#18198, nx#16153, nx#35855key-unstable:run-contextfixed-in-item-741packages/vx/tests/stale-hit.test.ts › “the dependant has one key with and without the flag, and it hits”<br>packages/vx/tests/stale-hit.test.ts › “a change to the skipped dependency is a miss, not the old bytes”<br>packages/vx/tests/stale-hit.test.ts › “what a run builds on a skipped, out-of-date dependency is not saved”<br>packages/vx/tests/taint-tracker.test.ts › “a seed is tainted with no failure upstream, and passes it on”--exclude-dependencies narrows the schedule, not the key: a skipped dependency is keyed without running, and what builds on it may hit but does not save.
nx#36939key-unstable:config-mutationcoveredpackages/vx/tests/orchestrator.test.ts › “runs a task and caches the result”<br>packages/vx/tests/orchestrator-run.test.ts › “forwardArgs do NOT pollute upstream cache keys (dep stays cached across user-args changes)”
nx#35297key-unstable:key-ordercoveredpackages/vx/tests/config-eval.test.ts › “a faithful config crosses both paths with the same JSON, the bytes its key folds”<br>packages/vx/tests/plugin-pipeline.test.ts › “the fold is order-independent: two plugins key the same whichever is declared first”
nx#27880key-unstable:file-metadatacoveredpackages/vx/tests/git-oid.test.ts › “edit changes the key; reverting restores the ORIGINAL key before any commit”<br>packages/vx/tests/cache.test.ts › “does not change when only mtime changes (content identical)”
nx#26749key-unstable:output-in-inputscoveredpackages/vx/tests/orchestrator.test.ts › “does not self-invalidate when only its declared outputs change”
nx#33076key-collision:memocoveredpackages/vx/tests/orchestrator-run.test.ts › “sibling-package input isolation: editing one package does not bust an unrelated sibling”
nx#36968stale-hit:config-eval-cachecoveredpackages/vx/tests/config-cache.test.ts › “keys a warm load from the indexed closure, and a preset edit still misses”<br>packages/vx/tests/config-staleness.test.ts › “a re-run in the same process does not serve a cache hit for a changed preset”
nx#35228inputs:special-filecoveredpackages/vx/tests/inputs.test.ts › “neither hangs the run nor enters the key or the artifact”written for this ledger (item 745)
nx#6370inputs:deleted-filecoveredpackages/vx/tests/inputs.test.ts › “deleted-but-tracked files are skipped (existsSync guard)”
nx#37110, nx#36898restore:index-without-artifactcoveredpackages/vx/tests/cache.test.ts › “get() returns null when DB row exists but on-disk artifact was deleted”
nx#36932restore:partial-recordcoveredpackages/vx/tests/aborted-outcome.test.ts › “does not let its dependents cache what they built from its partial outputs”<br>packages/vx/tests/cache-hygiene.test.ts › “SIGTERM mid-task → no entries row, no live or tmp artifact”
nx#32620, nx#22166, nx#18494restore:skip-on-stale-trackingcoveredpackages/vx/tests/parity-turbo.test.ts › “a second run is a cache hit; deleted outputs come back from the cache; logs replay”<br>packages/vx/tests/orchestrator.test.ts › “restores a deleted output file on a cache hit”
nx#30429, nx#31191remote:downloaded-not-restoredcoveredpackages/vx-migrate/tests/nx-cache.test.ts › “a miss uploads; with the local cache wiped the next run restores from the server”
nx#31568, nx#36401restore:outside-workspacecoveredpackages/vx/tests/project-loader.test.ts › “rejects .. in cache.outputs.workspaceFiles (escapes the workspace root)”
nx#37061restore:symlink-dirfixed-in-item-742packages/vx/tests/restore-link-out.test.ts › “is refused by name, the link kept and nothing written through it”An output directory that links out of the project is a user error naming the link and its target; the link is kept, never replaced or written through.
nx#31085restore:symlinks-droppedcoveredpackages/vx/tests/output-shape.test.ts › “a symlink to a directory, or a dangling one, fails the save loudly instead of caching nothing”
nx#32996restore:dir-permissionscoveredpackages/vx/tests/archive-security.test.ts › “directory records with 0644 or 0600 modes never set a directory mode; the file under them lands”written for this ledger (item 745)
nx#34013restore:glob-and-dir-collisioncoveredpackages/vx/tests/artifact-roundtrip.test.ts › “overlapping output globs and directory literals save and restore the exact tree once”written for this ledger (item 745)
nx#35150outputs:negationcoveredpackages/vx/tests/project-loader.test.ts › “rejects a negation in cache.outputs.files (unsupported, silently matches nothing)”
nx#18075outputs:glob-extensioncoveredpackages/vx/tests/artifact-roundtrip.test.ts › “an output glob with a brace extension set captures those extensions and restores them”written for this ledger (item 745)
nx#35817restore:non-atomiccoveredpackages/vx/tests/run-lock-e2e.test.ts › “the race of item 215 cannot start: cold outputs, warm cache, two runs, four rounds”
nx#35079restore:tool-incremental-statecoveredpackages/vx/tests/orchestrator.test.ts › “—force skips reads (re-executes) but still WRITES, refreshing the cache”<br>packages/vx/tests/orchestrator-run.test.ts › “cache-miss exec also cleans declared outputs before running”
nx#36113outputs:overlap-shared-filecoveredpackages/vx/tests/output-collision.test.ts › “refuses the same workspace output claimed by tasks in DIFFERENT projects”
nx#36949restore:undeclared-side-effectn/aCLAUDE.md principle 2 (“Explicit over magical … the sandbox, exec.sandbox, is how a task proves what it touches”).
nx#35403cache:artifacts-without-indexcoveredpackages/vx/tests/cache.test.ts › “is a silent miss; the task runs, the save takes the file over, and the next run hits”written for this ledger (item 745)
nx#36863, nx#35302replay:truncated-outputcoveredpackages/vx/tests/runner.test.ts › “a grandchild that prints within the post-exit drain reaches the live stream and the result”written for this ledger (item 745)
nx#36688replay:missing-log-fatalfixed-in-item-742packages/vx/tests/vanished-artifact.test.ts › “probed in its own slot: runs there”An artifact gone between the probe and the restore is a miss (ArtifactVanishedError) and the task runs. The restore-tier rows (a demoted restore runs after its dependency) are template-titled.
nx#36928evict:orphan-logn/acaching.md § Storage layout: “one entry is one file — eviction is a single unlink; no per-entry manifest, no separate logs/ tree”.
nx#35483evict:orphan-artifactfixed-in-item-742packages/vx/tests/cache-retention.test.ts › “reaps row-less artifacts on its own hourly clock, whatever the index says”<br>packages/vx/tests/cache-retention.test.ts › “reaps row-less artifacts a deleted index left, and says so”cacheRetention sweeps artifacts with no index row on its own clock, at most hourly.
nx#35329evict:shared-unboundedcoveredpackages/vx/tests/cache-retention.test.ts › “evicts from a cache directory outside the workspace, set by cacheDir or —cache-dir”written for this ledger (item 745)
nx#34032evict:concurrent-racefixed-in-item-742packages/vx/tests/run-lock-e2e.test.ts › “vx cache prune waits for a run on the workspace before it evicts”<br>packages/vx/tests/vanished-artifact.test.ts › “probed in its own slot: runs there”A deleting vx cache prune takes the workspace’s run lock; another workspace’s retention on a shared --cache-dir turns the hit into a miss.
nx#28608, nx#28665, nx#28772, nx#28424concurrency:index-dbfixed-in-item-742packages/vx/tests/cache-open-busy.test.ts › “a version row another opener is committing is read, not inserted twice”Two openers of a new cache: the write half re-reads the schema version under BEGIN IMMEDIATE.
nx#35901cache:failed-resultn/acaching.md § Cache write: “If the task exits non-zero, nothing is cached. This is deliberate”.
nx#32610cache:name-special-casefixed-in-item-736packages/vx-migrate/tests/nx.test.ts › “persistence is Nx’s continuous, never the target name: a cached dev caches like gen (nx#32610)”
nx#29854cli:skip-cache-scopecoveredpackages/vx/tests/orchestrator.test.ts › “—force, —no-cache and —cache=local:w re-execute the dependencies of the named task too”written for this ledger (item 745)
nx#37052, nx#36107remote:store-error-fails-runcoveredpackages/vx-migrate/tests/remote-cache-degrade.test.ts › “a 500 on every request degrades to a miss — the task runs and the run is green”<br>packages/vx/tests/layered-cache.test.ts › “save() does not fail when the remote rejects”
nx#36036, nx#31134remote:error-not-misscoveredpackages/vx/tests/layered-cache.test.ts › “get() suppresses remote errors and returns null”<br>packages/vx/tests/orchestrator-remote.test.ts › “a remote that 500s on every request never fails the run (optional cache degrades to miss)”
nx#30338remote:corrupt-entry-stickycoveredpackages/vx-migrate/tests/remote-cache-degrade.test.ts › “a corrupt artifact degrades to a miss — never a half-restored output”<br>packages/vx/tests/layered-cache.test.ts › “get() degrades a corrupt remote artifact to a miss instead of throwing”
nx#36943, nx#30335remote:large-uploadcoveredpackages/vx/tests/artifact-ceiling.test.ts › “is refused at save with one status line, the run green, nothing cached”<br>packages/vx/tests/artifact-ceiling.test.ts › “an ingest enforces it too: remote bytes past it never land”Written for this ledger (item 800): the ceiling is RunOptions.artifactCeiling, a seam only a test sets, and a save refuses a tar past it before it compresses a byte (one stat per output), where the scan used to pay the whole compress and a decode (6 to 14 s on the 2.2 GB probe) and call the outputs corrupt.
nx#33092, nx#30018remote:protocol-headersfixed-in-item-736packages/vx-migrate/tests/nx-cache.test.ts › “put → get round trip; a miss is 404 → null; a second put of the same hash is the spec’s 409 and fine”<br>packages/vx-migrate/tests/turbo-cache.test.ts › “put → has / hasMany / get round trip with the spec’s headers and query”
nx#33335, nx#31535remote:read-only-ignoredcoveredpackages/vx/tests/layered-cache.test.ts › “save() with remote writes off uploads nothing: local entry, no remote PUT”<br>packages/vx/tests/cache.test.ts › “local:rw,remote:r → remote read-only (local stays rw)”
nx#35556remote:store-race-local-writecoveredpackages/vx/tests/layered-cache.test.ts › “save() resolves before a slow remote PUT completes; drainUploads() completes it”
nx#30733remote:restore-enoentcoveredpackages/vx/tests/artifact-roundtrip.test.ts › “a cache hit restores the produced tree byte- and mode-identically”<br>packages/vx-migrate/tests/nx-cache.test.ts › “a miss uploads; with the local cache wiped the next run restores from the server”
nx#36640remote:hang-inherited-stdion/acaching.md § Remote uploads: “the remote PUT is a fire-and-forget background upload … drained before cache.close(), so a short run still ships every artifact before the process exits”.
nx#32779graph:missing-dep-silentfixed-in-item-737packages/vx/tests/task-graph.test.ts › “refuses ^biuld when no project in the workspace declares biuld”
nx#36498graph:dep-name-glob-charscoveredpackages/vx/tests/task-graph.test.ts › “names holding brackets and slashes are literal, exact or inside a pattern”written for this ledger (item 745)
nx#16931graph:dep-name-ambiguityn/avx/docs/schema.md § dependsOn: “'name' — Same-project task name” and “'pkg#name' — The name task in a specific other package”.
nx#33716, nx#29735, nx#27679graph:false-cyclecoveredpackages/vx/tests/task-graph.test.ts › “dedupes diamond dependency: shared upstream node is created once”
nx#28788graph:cycle-stack-overflowfixed-in-item-737packages/vx/tests/task-graph.test.ts › “a 50,000-deep chain plans”<br>packages/vx/tests/task-graph.test.ts › “a 50,000-deep ring is refused as that cycle”
nx#33974graph:lockfile-edges-cyclen/avx/docs/schema.md § dependsOn: “'^name' — nearest-holder frontier. Walk the package dep graph from this project’s direct deps”. An edge is a package.json workspace dependency (cli.md § Filter DSL), never a lockfile entry.
nx#28599graph:dep-order-parallelcoveredpackages/vx/tests/scheduler.test.ts › “runs tasks in dependency order”
nx#26929graph:override-drops-depsn/avx/docs/comparison.md: “Target defaults / inheritance” is “rejected by design — presets are TS imports”.
nx#36489graph:defaults-mergen/aSame as nx#26929: target defaults are rejected by design (vx/docs/comparison.md), and nx() reads Nx’s resolved graph.
nx#14234graph:missing-target-run-manycoveredpackages/vx/tests/task-selection.test.ts › “a bogus BARE task fails the run even when another task resolves”
nx#16147, nx#18437, nx#11984graph:params-forwardn/avx/docs/cli.md § Argument forwarding: “They scope to user-requested tasks only; dependsOn-pulled deps don’t see them (so upstream cache identity stays clean).”
nx#31496continuous:readinesscoveredpackages/vx/tests/persistent.test.ts › “downstream task waits for persistent upstream to become ready”
nx#31494, nx#34117parallel:limit-continuouscoveredpackages/vx/tests/persistent.test.ts › “at concurrency 1 the dependents of a ready persistent task run one at a time”written for this ledger (item 745)
nx#27986continuous:killed-when-dependent-startscoveredpackages/vx/tests/persistent.test.ts › “a ready persistent upstream is alive while its dependent runs”written for this ledger (item 745)
nx#33460, nx#32438signal:orphan-continuouscoveredpackages/vx/tests/signal-handling.test.ts › “the child of a persistent task that traps TERM, INT and HUP is dead after SIGINT or SIGTERM to vx”written for this ledger (item 745)
nx#36682signal:terminal-hangupcoveredpackages/vx/tests/task-tree-kill.test.ts › “SIGHUP to vx reaps the grandchild and exits 129”
nx#11782signal:orphan-child-killcoveredpackages/vx/tests/task-tree-kill.test.ts › “SIGTERM to vx reaps the grandchild and exits 143”<br>packages/vx/tests/task-tree-kill.test.ts › “a timeout reaps a grandchild that ignores SIGTERM”<br>packages/vx/tests/runner.test.ts › “a timed-out shell that dies on the SIGTERM: settle() SIGKILLs the grandchild that ignored it”Item 740 fixed the timeout sibling: a timed-out shell’s exit cleared the SIGKILL, so a grandchild ignoring SIGTERM outlived vx.
nx#23585signal:graceful-shutdownfixed-in-item-740packages/vx/tests/signal-handling.test.ts › “SIGINT to vx reaches a one-shot task as SIGINT”<br>packages/vx/tests/signal-handling.test.ts › “SIGINT to vx reaches a ready persistent task as SIGINT”<br>packages/vx/tests/watch-signals.test.ts › “SIGINT during the initial run reaches its task as SIGINT”<br>packages/vx/tests/watch-signals.test.ts › “SIGINT while idle reaches the dev server it holds as SIGINT”<br>packages/vx/tests/signal-handling.test.ts › “SIGTERM to vx reaches a one-shot task as SIGTERM”vx forwards the signal it received, so a SIGINT-only cleanup runs.
nx#27917signal:kill-during-startn/avx/docs/design/roadmap-1.0.md Milestone 2, row 2.4: “Record the out-of-scope set as final: daemon, JS-function tasks, generators, TUI, …”.
nx#36473signal:stale-marker-after-killfixed-in-item-740packages/vx/tests/run-lock.test.ts › “a lock naming this process’s own pid is stale: a restarted container’s vx wears it”<br>packages/vx/tests/run-lock-recycled.unsafe.test.ts › “a lock whose pid another process now wears is stale: the start time differs”A run lock naming our own pid, or on Linux a pid another process now wears, is stale.
nx#32750signal:hang-no-ttycoveredpackages/vx/tests/ci-output.test.ts › “no escape sequence and no carriage return, on a miss, a hit, a failure, and the readers”
nx#36579signal:hang-foreign-ptyn/avx/docs/design/roadmap-1.0.md Milestone 2, row 2.4 lists TUI in the out-of-scope set.
nx#8286signal:hang-at-exitfixed-in-item-740packages/vx/tests/task-tree-kill.test.ts › “a persistent dependency’s server that ignores SIGTERM does not hang vx’s exit”<br>packages/vx/tests/task-tree-kill.test.ts › “a grandchild’s SIGTERM cleanup gets the grace after its shell has exited”Both teardowns SIGKILL every task group with a member left at the grace, not only the shell.
nx#29204exit:signal-death-successcoveredpackages/vx/tests/signal-death.test.ts › “a SIGKILL the runner saw is named with the OOM killer and a kill”
nx#28477, nx#20285run-commands:parallel-exitfixed-in-item-736packages/vx-migrate/tests/nx.test.ts › “commands run in parallel: a failing check fails the task while the server beside it is up, and TERMs it (nx#28477)”
nx#31307, nx#36520output:pty-swallowcoveredpackages/vx/tests/failure-recap.test.ts › “a task printing 100 lines and exiting 3: lines 71–100, 70 earlier, exit 3”
nx#26553affected:bad-base-exitcoveredpackages/vx/tests/affected.test.ts › “throws UserError when the ref does not resolve”
nx#14202exit:exec-nonzeron/avx/src/util/verbs.ts CORE_VERBS has no exec.
nx#35169run-commands:child-restart-exitn/avx/docs/execution.md § One command per task: “exec.command is a single shell command — there’s no multi-step sequence.”
nx#21779run-commands:sequential-hangcoveredpackages/vx-migrate/tests/nx-command.test.ts › “serial: one command’s exit or cd stays in its own shell, and a failure stops the rest”
nx#31345run-commands:empty-listfixed-in-item-736packages/vx-migrate/tests/nx.test.ts › “commands: [] is a no-op that succeeds (nx#31345)”
nx#12165run-commands:args-forwardfixed-in-item-736packages/vx-migrate/tests/nx.test.ts › “arguments after vx run … -- reach every command, and an executor target’s options (nx#12165)“<br>packages/vx-migrate/tests/nx-command.test.ts › “forwarded arguments reach EVERY command, and none when forwardAllArgs is off (nx#12165)”
nx#36652run:exec-cwdn/avx/src/util/verbs.ts CORE_VERBS has no exec.
nx#32579run:package-manager-detectn/avx-migrate/README.md: “nx:run-script is the package’s script body with its pre<name> / post<name> hooks folded in (or yarn run <name> when the body calls yarn’s run builtin; …)”.
nx#35302, nx#36863output:lost-on-exitfixed-in-item-740packages/vx/tests/runner.test.ts › “output a backgrounded child writes after the drain bound is cut, and the frame says so”The post-exit drain bound stays; when it cuts output, the frame says so.
nx#27968output:truncated-pipecoveredpackages/vx/tests/bin-stdout.test.ts › “a JSON answer past the pipe buffer parses whole”
nx#31237output:truncated-largecoveredpackages/vx/tests/capture-cap.test.ts › “a hit replays the bounded text with the line, never the whole output”
nx#13540output:partial-linen/avx/docs/execution.md § Output capture and rendering: “Stdin is never the terminal”. A one-shot task “gets 'ignore'”; a persistent task “gets a pipe vx holds and never writes”.
nx#5472output:stderr-lostcoveredpackages/vx/tests/output-flow.test.ts › “failure → full frame with the buffered output”
nx#35292, nx#34387color:force-color-overridefixed-in-item-737packages/vx/tests/ci-output.test.ts › “FORCE_COLOR=0 and =false leave the piped run plain, and reach the task as set”
nx#23259color:forced-without-ttycoveredpackages/vx/tests/terminal.unsafe.test.ts › “vx painting its own output on a terminal sets no FORCE_COLOR for the task”written for this ledger (item 745)
nx#9673, nx#8051, nx#10918color:lost-in-nestedn/apackages/vx/tests/recursive-run.test.ts › “is refused in the task’s own workspace, naming the task”A nested vx run in the task’s own workspace is refused. cli.md § Output format › Colors: “a task gets FORCE_COLOR and NO_COLOR passed through as set, and decides its own colour.”
nx#15116, nx#14891, nx#22259, nx#34742, nx#29101affected:lockfile-allcoveredpackages/vx-lockfile/tests/pnpm.test.ts › “--affected selects the projects the bump reaches”
nx#36929affected:lockfile-transitivecoveredpackages/vx-lockfile/tests/pnpm.test.ts › “a transitive bump moves the importers that reach it and no other”
nx#35524affected:lockfile-catalogn/aA lockfile plugin keys each project on its own closure, but a catalog edit re-keys and selects every project: the catalog lives in a file core fingerprints whole (pnpm-workspace.yaml, .yarnrc.yml; modules/fingerprint.md § Files folded in), and bun() folds bun.lock’s catalogs into every project.
nx#35173affected:lockfile-resolutionscoveredpackages/vx-lockfile/tests/yarn.test.ts › “a transitive bump moves the workspaces that reach it and no other”
nx#36415affected:root-devdep-globalfixed-in-item-733packages/vx-lockfile/tests/pnpm.test.ts › “a root devDependency bump re-keys and selects every project: the root .bin is on every PATH”
nx#18112, nx#20691affected:deleted-projectcoveredpackages/vx/tests/affected.test.ts › “a deleted project directory selects no remaining project”written for this ledger (item 745)
nx#29699affected:deleted-file-allcoveredpackages/vx/tests/affected.test.ts › “selects the project that owned a deleted file”
nx#21763affected:root-scoped-inputcoveredpackages/vx/tests/affected.test.ts › “a glob a plugin gave a config-less package selects it; a sibling without one is not selected”
nx#27182affected:cross-root-inputcoveredpackages/vx/tests/affected-workspace-files.test.ts › “the change re-keys the task AND selects it”
nx#32974affected:interpolated-inputn/avx/docs/parity.md: “namedInputs, targetDefaults, {projectRoot} tokens, .env auto-loading, tags” are ”≠ rejected: TypeScript configs compose by import”.
nx#33330affected:explicit-base-ignoredcoveredpackages/vx/tests/affected-base-notes.test.ts › “an explicit base never asks git for origin/HEAD or main, and no git error is printed”written for this ledger (item 745)
nx#11840, nx#12203, nx#29051affected:missing-base-refcoveredpackages/vx/tests/affected-base-notes.test.ts › “no origin/HEAD and no parent commit: no base at all, said in CI terms, exit 1”
nx#16975affected:large-diff-buffercoveredpackages/vx/tests/affected.test.ts › “six thousand changed files, over a megabyte of paths, select their project and no other”written for this ledger (item 745)
nx#21319affected:files-listn/avx/docs/cli.md documents no --files.
nx#7177, nx#6370, nx#15819affected:deleted-file-enoentcoveredpackages/vx/tests/inputs.test.ts › “deleted-but-tracked files are skipped (existsSync guard)“<br>packages/vx/tests/affected.test.ts › “selects the project on a working-tree delete (uncommitted)”
nx#36576, nx#21991affected:hangn/avx/docs/design/roadmap-1.0.md Milestone 2, row 2.4: “Record the out-of-scope set as final: daemon, JS-function tasks, generators, TUI, …”.
nx#15625discovery:dir-name-patterncoveredpackages/vx/tests/workspace.test.ts › “a directory named __generated__ or _generated is a project like any other”written for this ledger (item 745)
nx#19981discovery:workspace-globs-negationcoveredpackages/vx/tests/workspace.test.ts › “globs that are only negations list no project and do not throw”written for this ledger (item 745)
nx#36290discovery:root-project-depscoveredpackages/vx/tests/package-graph.test.ts › “the workspace root as a project links a member by file:, link: and workspace:*”written for this ledger (item 745)
nx#27368, nx#34626discovery:new-project-invisiblecoveredpackages/vx/tests/watch-loop-members.test.ts › “a package added under a running watch is a cycle that runs it, and its edits are cycles from then on”
nx#28212env:path-bincoveredpackages/vx/tests/tool-not-on-path.test.ts › “the same tool at the root bin runs green with no line”
nx#34955env:dotenv-cross-filen/avx/docs/comparison.md § Gap audit: “.env files loaded into the task env” — “Tasks read their own .env (Vite, Next do); the cache side is cache.inputs.files: ['.env*']. A config-stage plugin can inject. Not core; a docs footnote.”
nx#19437env:dotenv-expand-overwrittenn/aSame as nx#34955.
nx#23221env:dotenv-config-precedencen/aSame as nx#34955.
nx#17128env:dotenv-per-projectn/aSame as nx#34955.
nx#23581env:envfile-per-taskfixed-in-item-736packages/vx-migrate/tests/nx.test.ts › “a run-commands envFile is loaded under them (nx#23581)“<br>packages/vx-migrate/tests/nx-command.test.ts › “envFile is handed on as declared, {projectRoot} expanded (nx#23581)”
nx#20465env:task-env-optionfixed-in-item-736packages/vx-migrate/tests/nx.test.ts › “a run-commands env reaches the command and the key (nx#20465)”
nx#19850env:dotenv-cwdn/aSame as nx#34955.
nx#36446watch:project-globcoveredpackages/vx/tests/watch-loop-members.test.ts › “a —filter glob runs and watches exactly the projects it names”written for this ledger (item 745)
nx#30663watch:env-to-commandn/avx/docs/cli.md: vx watch [OPTIONS] TASK [-- forwarded-args...]: “Run the named task, then re-run it on every filesystem change in the projects in scope.”
nx#22914, nx#14038watch:self-trigger-loopcoveredpackages/vx/tests/watch-loop-uncached.test.ts › “an UNCACHED task that writes into its project costs exactly one extra execution per edit, then quiet”