Retention
Disk is not free and old dev builds are mostly noise. Retention is per-channel and deliberately boring: dev keeps a count, staging keeps an age, release keeps everything. Nothing is deleted without you asking, and --dry-run is the first thing you should ever type.
Defaults
| Channel | Policy | Meaning |
|---|---|---|
dev | keep 10 | Keep the ten newest versions on dev; older ones are eligible for prune. |
staging | older_than 45d | Anything on staging untouched for 45 days is eligible. |
release | keep 0 (never) | Release is permanent. keep 0 reads as "never prune", which is the one value that means do nothing. |
A pinned artifact is never eligible, regardless of channel or age. Pinning is how you exempt the one dev build a customer is still running.
Shared payloads
Two coordinates can point at the same payload digest - promotion guarantees it. prune counts a payload as reclaimable only when the last coordinate referencing it goes away. Before 2.4.1 the reclaimed-bytes figure double-counted shared payloads; it now reports the bytes actually freed.
Running it
anvil prune --dry-run # lists what WOULD go, frees nothing anvil prune --channel dev # applies dev policy only anvil prune --dry-run --json # machine-readable preview
Rather than trust the prose, rehearse a policy on this site against the demo store snapshot - it runs the same count/age logic in your browser.