docs(cache): end-to-end numbers, operator runbook, and a vmrun gotcha

Measured through the real pipeline, not the unit tests: a Rust job goes from
186s to 84s (build phase 150s -> 47s), and 75s with the source modified, which
is the scenario CI actually runs. The entry is 645 MB and costs 8s to restore.

The test that decides whether this ships is row 4: a deliberate type error in
fury-core, built warm. The cache restored 645 MB of dependencies and the build
still went red with E0308, exit 1, publishing nothing. A cache that can turn a
red build green is the worst failure a CI system has because it is silent --
re-run that row whenever the prune rules change.

AGENTS.md #17 records something found while validating: `vmrun list` is
per-user. Run as the wrong user it answers "Total running VMs: 0" while a clone
is very much alive, which makes the "no VMs running" check before a
deploy --force (#14) unreliable. `ps | grep vmware-vmx` is user-independent and
was already the recommended diagnosis.
This commit is contained in:
2026-07-22 22:15:32 +02:00
parent 15b1676375
commit 9f78742111
4 changed files with 117 additions and 4 deletions
@@ -56,6 +56,54 @@ The publish path costs 15.7s but runs only on a miss, i.e. once per
Transfer is not the bottleneck anyone feared: the virtual NIC moves the entry
at 140–180 MiB/s, so 645 MiB crosses in under 4 seconds each way.
## End-to-end, through `ci job` (2026-07-22)
Full pipeline against `LinuxRust2404`, furyrs `b8ea567`, `--skip-artifact`.
"Build" is the build phase alone; "total" includes clone, boot (~35s) and
teardown.
| # | Scenario | Build | Total | Cache line in the log |
|---|---|---:|---:|---|
| 1 | Cold, empty store | 150s | 186s | `miss` → `prune: ok` → `published … (645 MB)` |
| 2 | Warm, same commit | **47s** | **84s** | `hit … — restoring` |
| 3 | Warm, source modified | **38s** | **75s** | `hit … — restoring` |
| 4 | Warm, deliberate compile error | — | — | `hit`, then **build fails, exit 1** |
| 5 | `--no-cargo-cache` | 133s | 170s | none — cache never touched |
**Saving: 103s on the build phase (150 → 47), 102s on the total (186 → 84).**
Row 3 is the real CI scenario and is the fastest of the warm runs, because the
touched crate is small.
Row 2's log names every workspace crate being rebuilt —
```
Compiling fury-core, fury-gui, fury-ipc, fury-backend, furyd, fury-cli
```
— and no dependency. That is the design working: dependencies restored,
workspace recompiled from source, every time.
### Row 4 is the one that decides whether this ships
A deliberate type error was pushed to a scratch branch and built warm:
```
[cache] hit for v1-1311… (645 MB) — restoring
error[E0308]: mismatched types
| --- ^^^^^^^^^^^^^^^^^^^ expected `u32`, found `&str`
error: could not compile `fury-core` (lib) due to 1 previous error
JOB_EXIT=1
```
The cache restored 645 MB of dependencies and the regression still went red. A
cache that can turn a red build green is the worst failure a CI system has,
because it is silent; this is the test that rules it out, and it is worth
re-running whenever the prune rules change.
The failed job also published nothing — the store still held exactly one entry
and `.incoming/` was empty — because publishing sits after the build-failure
check. A broken tree cannot become an entry.
## Notes that changed the implementation
**`zstd` is already in the template.** `/usr/bin/zstd` is present on