@vzn/vx 0.0.638 → 0.0.639

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (103) hide show
  1. package/docs/caching.md +44 -15
  2. package/docs/cli.md +168 -345
  3. package/docs/execution.md +18 -43
  4. package/docs/features.md +7 -10
  5. package/docs/patterns.md +5 -7
  6. package/docs/schema.md +47 -49
  7. package/package.json +5 -5
  8. package/schemas/last.json +7 -4
  9. package/skills/vx/SKILL.md +6 -4
  10. package/src/cache/cache.ts +40 -10
  11. package/src/cache/git-inputs.ts +6 -0
  12. package/src/cache/index.ts +2 -2
  13. package/src/cache/layer.ts +25 -11
  14. package/src/cache/layered-cache.ts +108 -315
  15. package/src/cache/plugin-cache.ts +2 -10
  16. package/src/cache/remote-lane.ts +383 -0
  17. package/src/cache/run-history.ts +24 -8
  18. package/src/cache/run-store.ts +4 -4
  19. package/src/cache/schema.ts +6 -4
  20. package/src/cache/scoped-cache.ts +7 -0
  21. package/src/cli/completions.ts +2 -2
  22. package/src/cli/foreign-flags.ts +10 -22
  23. package/src/cli/help.ts +6 -31
  24. package/src/cli/info.ts +2 -1
  25. package/src/cli/last.ts +6 -3
  26. package/src/cli/plan-format.ts +5 -58
  27. package/src/cli/plugin-commands.ts +2 -2
  28. package/src/cli/run.ts +23 -185
  29. package/src/cli/show.ts +6 -0
  30. package/src/cli/upgrade.ts +123 -39
  31. package/src/cli/watch-cycle.ts +2 -1
  32. package/src/cli/watch.ts +29 -14
  33. package/src/cli/why.ts +4 -4
  34. package/src/config.ts +0 -6
  35. package/src/exec/executor.ts +1 -1
  36. package/src/exec/sandbox-runtime.ts +1 -1
  37. package/src/exec/sandbox-violations.ts +3 -1
  38. package/src/graph/index.ts +9 -1
  39. package/src/graph/priorities.ts +1 -1
  40. package/src/graph/scheduler.ts +4 -16
  41. package/src/graph/task-graph.ts +87 -17
  42. package/src/graph/task-status.ts +95 -0
  43. package/src/{orchestrator → history}/failure-mode.ts +1 -1
  44. package/src/{orchestrator → history}/history.ts +1 -1
  45. package/src/history/index.ts +48 -0
  46. package/src/{orchestrator → history}/metrics.ts +7 -20
  47. package/src/{orchestrator → history}/miss-reason.ts +1 -1
  48. package/src/index.ts +10 -28
  49. package/src/orchestrator/doctor.ts +1 -1
  50. package/src/orchestrator/execute-args.ts +80 -0
  51. package/src/orchestrator/execute-task.ts +21 -386
  52. package/src/orchestrator/fingerprint-watch.ts +2 -2
  53. package/src/orchestrator/index.ts +1 -73
  54. package/src/orchestrator/miss-save.ts +33 -3
  55. package/src/orchestrator/options.ts +1 -36
  56. package/src/orchestrator/output-host.ts +4 -3
  57. package/src/orchestrator/persistent-task.ts +321 -0
  58. package/src/orchestrator/persistent.ts +130 -3
  59. package/src/orchestrator/placement.ts +3 -3
  60. package/src/orchestrator/plan.ts +18 -5
  61. package/src/orchestrator/plugin-host.ts +67 -47
  62. package/src/orchestrator/plugin.ts +6 -6
  63. package/src/orchestrator/prepare.ts +28 -29
  64. package/src/orchestrator/remote-prefetch.ts +14 -1
  65. package/src/orchestrator/run-artifacts.ts +5 -177
  66. package/src/orchestrator/run-context.ts +55 -0
  67. package/src/orchestrator/run-failures.ts +15 -3
  68. package/src/orchestrator/run-records.ts +35 -3
  69. package/src/orchestrator/run-report.ts +81 -179
  70. package/src/orchestrator/run-settings.ts +1 -16
  71. package/src/orchestrator/run-stop.ts +153 -0
  72. package/src/orchestrator/run.ts +260 -601
  73. package/src/orchestrator/sandbox-fix.ts +0 -16
  74. package/src/orchestrator/signals.ts +14 -6
  75. package/src/orchestrator/stable-keys.ts +107 -3
  76. package/src/orchestrator/steps.ts +50 -0
  77. package/src/orchestrator/task-hash.ts +3 -16
  78. package/src/orchestrator/task-log-buffer.ts +1 -1
  79. package/src/orchestrator/task-process.ts +94 -0
  80. package/src/orchestrator/telemetry-host.ts +1 -1
  81. package/src/orchestrator/telemetry.ts +5 -82
  82. package/src/{orchestrator → report}/events.ts +41 -8
  83. package/src/{orchestrator → report}/forecast.ts +35 -2
  84. package/src/{orchestrator → report}/framed-output.ts +39 -33
  85. package/src/report/index.ts +36 -0
  86. package/src/{orchestrator → report}/logger.ts +158 -20
  87. package/src/{orchestrator → report}/status-line.ts +84 -7
  88. package/src/{orchestrator → report}/summary.ts +126 -35
  89. package/src/report/tally.ts +83 -0
  90. package/src/settings.ts +1 -22
  91. package/src/util/colors.ts +44 -4
  92. package/src/util/git-ignored.ts +143 -0
  93. package/src/util/index.ts +19 -4
  94. package/src/util/report.ts +13 -5
  95. package/src/util/settle.ts +14 -39
  96. package/src/util/tail.ts +1 -1
  97. package/src/util/ui.ts +17 -6
  98. package/schemas/summary.json +0 -133
  99. package/src/cache/chained-cache.ts +0 -280
  100. package/src/orchestrator/tally.ts +0 -112
  101. /package/src/{orchestrator → report}/path-links.ts +0 -0
  102. /package/src/{orchestrator → report}/plain-output.ts +0 -0
  103. /package/src/{orchestrator → report}/terminal-signals.ts +0 -0
package/docs/caching.md CHANGED
@@ -453,8 +453,17 @@ transitive dependant of one with it (their up-front keys fold a
453
453
  preliminary key); a glob with no literal prefix reaches every project.
454
454
  Before item 584 one such declaration emptied the tier graph-wide.
455
455
  `rules.upfrontKeys` (on by default, X-54) refuses at load a task whose
456
- input globs can match another task's declared outputs, so the clauses
457
- on declared outputs fire only with the rule off; undeclared writes, an
456
+ input globs can match another task's declared outputs, unless git
457
+ ignores those outputs whole, so the clauses on declared outputs fire
458
+ only with the rule off. An output git ignores whole is no reach either:
459
+ a key reads only what git lists, so a `**/*` reader beside a gitignored
460
+ `**/dist/**` producer keys up front, the same key before and after the
461
+ build. The run asks git once, beside its walk and only when a reader
462
+ reaches a same-project output: one `git check-ignore` over each such
463
+ output's directory (`dist/`, and a fresh `__vx_probe__/dist/` for a
464
+ glob that starts with `**`), and the walk's listing must hold no file
465
+ the glob matches (a tracked output, a directory a `!` rule takes back);
466
+ anything git cannot answer keeps the key late. Undeclared writes, an
458
467
  `outputs.workspaceFiles` producer upstream, a rewriter the key does not
459
468
  fold, and runtime probes after a writer still leave a key preliminary.
460
469
  The
@@ -553,7 +562,24 @@ Hard invariants of the remote prefetch:
553
562
  later `get` finds it as a now-local hit — still reports
554
563
  `source: 'remote'`, so the outcome is `cache-hit-remote`.
555
564
  - **A remote-read-off policy** (`--no-cache`, `--force`, or
556
- `--cache-policy=remote:`) fires no prefetch.
565
+ `--cache-policy=remote:`) fires no prefetch. With remote writes on
566
+ (`--force`), the same up-front keys go to one `hasMany` per remote
567
+ the run writes but does not read and that can batch, in the
568
+ background: no task waits for it, only each upload does. An upload
569
+ of a key that remote holds is skipped (an entry is immutable) and is
570
+ counted nowhere. A key the probe did not cover, or a remote with no
571
+ `hasMany`, asks `has` for that key inside its upload job; a probe
572
+ that fails uploads, as before.
573
+ - **No `has` before a `put`.** An entry is immutable: a remote's `put`
574
+ of a key it holds keeps the stored bytes, and a wire that would
575
+ overwrite checks inside (`turboCache()` asks HEAD unless a 404 or a
576
+ batch answer this run said the key is absent; `reapi()` looks the
577
+ action up beside its upload and keeps a stored result; Nx servers
578
+ answer 409). `ctx.cache.put` and a run's own entries send the `put`
579
+ alone.
580
+ - **`--dry` batches too.** The plan derives every key first, then asks
581
+ each remote with `hasMany` once; a remote without it is asked `has`
582
+ per key.
557
583
  - **Never fail.** Every remote path (get / put / ingest / prefetch)
558
584
  catches all errors and degrades to a cache miss. A remote 500, a
559
585
  network drop, a corrupt artifact, or a failed integrity check can
@@ -573,16 +599,16 @@ fire-and-forget background upload**. The task's outcome (and its
573
599
  dependents) never wait on upload latency — the uploads race alongside
574
600
  the rest of the run and are drained before `cache.close()`, so a
575
601
  short run still ships every artifact before the process exits. Upload
576
- failures log via `onRemoteError` and are otherwise ignored (the task
602
+ failures are warned once per failure class and are otherwise ignored (the task
577
603
  already succeeded; the only loss is the remote entry).
578
604
 
579
605
  An upload is the outputs as the task wrote them; secret masking does
580
606
  not reach file contents, so a task whose outputs embed a secret is one
581
607
  to leave uncached ([security](./security.md)).
582
608
 
583
- ### Planning probes (`--dry` / `--graph`)
609
+ ### Planning probes (`--dry`)
584
610
 
585
- The planning paths (`vx run --dry`, `--graph`) predict hits without
611
+ The planning path (`vx run --dry`) predicts hits without
586
612
  side effects: against a remote cache they use a **lightweight
587
613
  existence probe** — no artifact download, no local ingest. A predicted
588
614
  `hit-remote` means the artifact exists remotely; the bytes move only
@@ -615,8 +641,8 @@ remote executor's own store.
615
641
  The CLI maps three flags to a policy (precedence: start all-on → apply
616
642
  `--cache-policy` → `--no-cache` forces all off → `--force` forces both reads
617
643
  off): `--no-cache` = everything off (no read, no write, no output
618
- clean); `--force` = reads off / writes on (re-execute and refresh the
619
- cache, outputs cleaned); `--cache-policy=<spec>` = explicit per-layer control.
644
+ clean); `--force` = reads off / writes on (re-execute, outputs cleaned;
645
+ a key already stored, locally or in a remote, is kept as it is); `--cache-policy=<spec>` = explicit per-layer control.
620
646
  Off CI, unless a spec names the remote, `remoteWrite` starts off: a key
621
647
  holds only declared inputs, so a laptop's undeclared tool or file could
622
648
  replay on CI. See `docs/cli.md` § Cache control.
@@ -665,7 +691,10 @@ is on):
665
691
  Until 2026-09-27 (A-3) the rename came first, and a commit refused
666
692
  past the busy timeout left the new bytes beside the old rows: every
667
693
  later hit on the key failed the task as a corrupt artifact.
668
- A re-save (`--force`) first moves the previous artifact aside under
694
+ A `--force` save of a key the index already holds is skipped, so
695
+ `--force` rewrites nothing. A re-save (a key dropped as corrupt, or
696
+ two writers that both found it absent) first moves the previous
697
+ artifact aside under
669
698
  a temp name and unlinks it after the commit: ext4 flushes the
670
699
  incoming file when a rename replaces one, 0.55 ms a save on the main
671
700
  thread against 0.04 (a forced 1,000-task run 4.01 s → 3.46 s,
@@ -1470,7 +1499,7 @@ keep). The artifacts stay: each is indexed again from its own bytes
1470
1499
  when its task next asks for its key (below).
1471
1500
 
1472
1501
  ```sql
1473
- -- src/cache/schema.ts (SCHEMA_VERSION = 'v38', in cache.ts)
1502
+ -- src/cache/schema.ts (SCHEMA_VERSION = 'v40', in cache.ts)
1474
1503
  -- With a shared store, entries, entry_stdout, output_files, entry_inputs,
1475
1504
  -- store_meta, task_durations, task_outcomes, blob_sizes and plugin_blobs live in its store.db, attached as `store`; the rest is
1476
1505
  -- the workspace's cache.db. A named cache dir holds all of them.
@@ -1527,7 +1556,8 @@ CREATE TABLE runs (
1527
1556
  timed_out INTEGER, -- 1 when vx's own timeout killed it
1528
1557
  sandbox_violations INTEGER, -- the sandbox's violation count
1529
1558
  not_ready TEXT, -- 'timeout' | 'exited' | 'spawn' (persistent task)
1530
- restored INTEGER -- v31, on a hit: 1 = outputs restored, 0 = up to date
1559
+ restored INTEGER, -- v31, on a hit: 1 = outputs restored, 0 = up to date
1560
+ remote_error TEXT -- v40: each remote read or write of the key that failed
1531
1561
  );
1532
1562
 
1533
1563
  -- Two indexes, both append-only under a run's inserts: every row of a run
@@ -1628,7 +1658,7 @@ CREATE TABLE output_dirs (
1628
1658
 
1629
1659
  -- v22 (Tier 3): one header row per `vx run` invocation. The `runs`
1630
1660
  -- table is per-task; this is the per-invocation record carrying the
1631
- -- command, git/CI/host context, tags, and run-level counts. Recorded
1661
+ -- command, git/CI/host context, and run-level counts. Recorded
1632
1662
  -- atomically alongside `runs` via recordRunBundle (one transaction).
1633
1663
  CREATE TABLE invocations (
1634
1664
  run_id TEXT PRIMARY KEY, -- UUIDv7, == runs.run_id
@@ -1657,8 +1687,7 @@ CREATE TABLE invocations (
1657
1687
  host TEXT, -- os.hostname()
1658
1688
  os TEXT, -- process.platform
1659
1689
  arch TEXT, -- process.arch
1660
- vx_version TEXT NOT NULL,
1661
- tags TEXT NOT NULL DEFAULT '{}' -- JSON object {k:v} from --tag
1690
+ vx_version TEXT NOT NULL
1662
1691
  );
1663
1692
  CREATE INDEX invocations_started ON invocations(started_at);
1664
1693
  CREATE INDEX invocations_branch ON invocations(branch);
@@ -2141,7 +2170,7 @@ breaking footer).
2141
2170
  migration), so this costs one cold rebuild.
2142
2171
  - **SCHEMA v21 → v22 (no `CACHE_VERSION` bump)**: Tier-3 dashboard
2143
2172
  tables — `invocations` (one header row per `vx run` with command,
2144
- git/CI/host context, tags, and run-level counts, recorded with `runs`
2173
+ git/CI/host context, and run-level counts, recorded with `runs`
2145
2174
  via `Cache.recordRunBundle`) and `entry_inputs` (one row per cache-key
2146
2175
  component, keyed by the cache-ENTRY hash — the input-fingerprint
2147
2176
  moat). `entry_inputs` is written **inside the entry-save transaction,