Coverage

feat(proxy): reclaim space from the blob store

20 keyed defects in answer key bd331c0b144e

74 runs 54 compatible groups smykla-skalski/cairn#8

Answer key

Tier describes discovery difficulty; severity describes impact; they are independent

IDDefectLocationTierSeverity
1Sorting ascending by age evicts the newest blobs
services/proxy/src/sweep.rs:102
1issue
2A failed unlink still counts its bytes as reclaimed
services/proxy/src/sweep.rs:125-137
1issue
3The ceiling comparison removes a blob from a store already inside it
services/proxy/src/sweep.rs:120
1suggestion
4`fs::metadata` follows links, so the sweep deletes outside the store
services/proxy/src/sweep.rs:160-169
2blocking
5A future mtime becomes an age of zero, so those blobs are never evicted
services/proxy/src/sweep.rs:185-190
2issue
6The pass is never handed to `spawn_blocking`, so it holds a runtime worker
services/proxy/src/sweep.rs:14-18
services/proxy/src/routes/admin.rs:76
services/proxy/src/main.rs:116
2issue
7`tokio::time::interval` fires immediately, so every restart sweeps
services/proxy/src/main.rs:101
services/proxy/src/main.rs:108
2issue
8`MissedTickBehavior::Delay` leaves no gap after a sweep that overran
services/proxy/src/main.rs:109-112
2suggestion
9Every blob in the store is materialised into one `Vec` before any deletion
services/proxy/src/sweep.rs:94-102
services/proxy/src/sweep.rs:153
2suggestion
10A malformed `dry_run` is rejected before auth and outside the error contract
services/proxy/src/routes/admin.rs:51-56
services/proxy/src/routes/admin.rs:61-66
2suggestion
11The route bypasses the lock that makes a sweep exclusive
services/proxy/src/sweep.rs:65-67
services/proxy/src/sweep.rs:82-90
services/proxy/src/routes/admin.rs:76
3issue
12A dry run leaves the blobs and deletes their index entries
services/proxy/src/sweep.rs:125
services/proxy/src/sweep.rs:140
services/proxy/src/sweep.rs:249
3blocking
13The two new counters are rendered under each other's names
services/proxy/src/metrics.rs:50-57
services/proxy/src/metrics.rs:94-95
3issue
14Age is the write time, so eviction is by insertion order and not by use
services/proxy/src/sweep.rs:186
services/proxy/src/sweep.rs:100-101
services/proxy/src/sweep.rs:10-12
3issue
15The three new variables are absent from `docker-compose.yml`
.env.example:41
.env.example:43-44
docs/operations.md:51
3issue
16The runbook recommends the dry run, which is the one call that corrupts
docs/operations.md:51
3suggestion
17Clearing `incoming` unlinks partials that live fetches and `link` are using
services/proxy/src/sweep.rs:219-236
4blocking
18The unreferenced prune deletes a blob committed but not yet linked
services/proxy/src/sweep.rs:114-120
4blocking
19Two proxies over one blob directory over-reclaim and double-count
services/proxy/src/sweep.rs:10-12
services/proxy/src/sweep.rs:65-67
4issue
20Eviction leaves `versions.cached_at` set, so the dashboard lies
services/proxy/src/sweep.rs:125-137
docs/operations.md:53
4issue

Intended behavior

Correct findings about these trade-offs are classified as intended, not unkeyed

  1. The sweep route sits outside the `TimeoutLayer`. Noticing that a destructive endpoint has no request deadline is correct; the router comment gives the reason, which is that a sweep of a large store legitimately runs longer than ten seconds and a gateway timeout would report failure for a pass that ran.
  2. The pass uses `std::fs` rather than `tokio::fs`. Intended, and the module documentation argues it. The keyed defect is 6, the missing `spawn_blocking` - a review arguing that every call should instead go through `tokio::fs` is arguing against the intended choice.
  3. `sweep.rs` restates the three directory names instead of reaching them through `BlobStore`. Intended, with the reason in the comment above the constants; `store.rs` remains the definition of the layout.
  4. The sweep task is not part of the graceful shutdown. Intended, with the reason in `spawn_sweeps`: a pass is a sequence of independent unlinks, and stopping one part-way leaves the store as consistent as finishing it would.
  5. Nothing cross-validates `CAIRN_CACHE_MAX_BYTES` against `CAIRN_MAX_ARTIFACT_BYTES`. `config.rs` cross-validates no pair of values today - every check is one value against zero or against its parser - so not comparing these two is consistent with the file rather than an oversight here.
  6. There is no test over the new code. A reviewer asking for one is right about this repository's convention, which covers pure logic as a matter of course. The pull request body answers for most of the module - the reclamation loop needs a populated store on a real filesystem, which is why the store paths are untested too - but `age_of`, the ceiling comparison and the ordering are pure and testable, so a review that asks for a test on the eviction order is making a fair point the body does not answer.
  7. Index entries are left behind by `BlobStore::remove`. Pre-existing and documented there; the sweep's own index pruning is new and is covered by defect 12.

Compatible groups

Inspect a group before selecting an individual trial

ReviewerConfigurationBuildScored / recordedRecallJudged precision
afi
afi · cli
default
Default profile / OpenAI · gpt 5.6 sol high
afi 0.30.03/355%N/A
afi
afi · cli
default
Default profile / xAI · grok 4.5 high
afi 0.30.02/242.5%N/A
afi
afi · cli
default
Default profile / Z.AI · glm 5.2 high
afi 0.30.01/120%N/A
afi
afi · cli
default
Default profile / Meta · llama 4 maverick high
afi 0.30.00/3Not recordedNot recorded
afi
afi · cli
default
Default profile / Z.AI · glm 5.3 flash high
afi 0.30.01/140%N/A
afi
afi · cli
default
Default profile / Mistral AI · devstral 2512 high
afi 0.30.00/1Not recordedNot recorded
afi
afi · cli
default
Default profile / Minimax · m3 high
afi 0.30.01/115%N/A
afi
afi · cli
default
Default profile / Moonshot AI · kimi k2.7 code high
afi 0.30.01/130%N/A
afi
afi · cli
default
Default profile / DeepSeek · v4 flash high
afi 0.30.01/10%N/A
afi
afi · cli
default
Default profile / Z.AI · glm 5.3 high
afi 0.30.01/140%N/A
afi
afi · cli
default
Default profile / DeepSeek · v4 pro high
afi 0.30.01/160%N/A
afi
afi · cli
default
Default profile / xAI · grok 4.5 high
afi 0.30.01/140%N/A
afi
afi · cli
default
Default profile / Z.AI · glm 5.2 high
afi 0.30.01/115%N/A
afi
afi · cli
default
Default profile / Moonshot AI · kimi k3 high
afi 0.30.01/135%N/A
afi
afi · cli
default
Default profile / Z.AI · glm 5.3 high
afi 0.30.01/10%N/A
afi
afi · cli
default
Default profile / DeepSeek · v4 pro high
afi 0.30.01/125%N/A
afi
afi · cli
default
Default profile / OpenAI · gpt 5.6 terra high
afi 0.30.02/230%N/A
afi
afi · cli
default
Default profile / DeepSeek · v4 flash high
afi 0.30.01/10%N/A
afi
afi · cli
default
Default profile / OpenAI · gpt 5.6 luna high
afi 0.30.03/340%N/A
afi
afi · cli
default
Default profile / Anthropic · fable 5 high
afi 0.30.01/150%N/A
afi
afi · cli
default
Default profile / Z.AI · glm 5.3 flash high
afi 0.30.01/140%N/A
afi
afi · cli
default
Default profile / Z.AI · glm 5.3 flash high
afi 0.30.02/235%N/A
afi
afi · cli
default
Default profile / Z.AI · glm 5.3 flash high
afi 0.30.03/345%N/A
afi
afi · cli
default
Default profile / Z.AI · glm 5.3 flash high
afi 0.30.01/130%N/A
afi
afi · cli
default
Default profile / Anthropic · opus 5 high
afi 0.30.01/145%N/A
afi
afi · cli
default
Default profile / Minimax · m3 high
afi 0.30.01/110%N/A
afi
afi · cli
default
Default profile / OpenAI · gpt 5.6 terra high
afi 0.30.01/135%N/A
afi
afi · cli
default
Default profile / Anthropic · fable 5 high
afi 0.30.02/235%N/A
afi
afi · cli
default
Default profile / Z.AI · glm 5.2 high
afi 0.30.01/115%N/A
afi
afi · cli
default
Default profile / OpenAI · gpt oss 120b high
afi 0.30.02/20%N/A
afi
afi · cli
default
Default profile / DeepSeek · v4 flash high
afi 0.30.01/15%N/A
afi
afi · cli
default
Default profile / Mistral AI · devstral 2512 high
afi 0.30.00/2Not recordedNot recorded
afi
afi · cli
default
Default profile / Moonshot AI · kimi k3 high
afi 0.30.01/130%N/A
afi
afi · cli
default
Default profile / Anthropic · opus 5 high
afi 0.30.00/1Not recordedNot recorded
afi
afi · cli
default
Default profile / Z.AI · glm 4.7 flash high
afi 0.30.01/10%N/A
afi
afi · cli
default
Default profile / Qwen · qwen3 coder 30b a3b instruct high
afi 0.30.00/3Not recordedNot recorded
afi
afi · cli
default
Default profile / Moonshot AI · kimi k3 high
afi 0.30.01/140%N/A
afi
afi · cli
default
Default profile / Google · gemini 3.1 pro preview high
afi 0.30.01/145%N/A
afi
afi · cli
default
Default profile / Google · gemini 3.1 pro preview high
afi 0.30.01/120%N/A
afi
afi · cli
default
Default profile / Google · gemini 3.7 flash high
afi 0.30.02/230%N/A
afi
afi · cli
default
Default profile / Google · gemini 3.1 pro preview high
afi 0.30.01/140%N/A
afi
afi · cli
default
Default profile / Anthropic · sonnet 5 high
afi 0.30.02/217.5%N/A
afi
afi · cli
default
Default profile / Moonshot AI · kimi k2.7 code high
afi 0.30.01/130%N/A
afi
afi · cli
default
Default profile / Qwen · qwen3.7 flash high
afi 0.30.00/3Not recordedNot recorded
afi
afi · cli
default
Default profile / OpenAI · gpt oss 120b high
afi 0.30.01/10%N/A
afi
afi · cli
default
Default profile / Anthropic · opus 5 high
afi 0.30.01/150%N/A
afi
afi · cli
default
Default profile / Anthropic · opus 5 high
afi 0.30.00/1Not recordedNot recorded
afi
afi · cli
default
Default profile / Z.AI · glm 4.7 flash high
afi 0.30.01/10%N/A
afi
afi · cli
default
Default profile / Minimax · m3 high
afi 0.30.01/120%N/A
afi
afi · cli
default
Default profile / DeepSeek · v4 pro high
afi 0.30.01/15%N/A
afi
afi · cli
default
Default profile / Moonshot AI · kimi k2.7 code high
afi 0.30.01/145%N/A
afi
afi · cli
default
Default profile / Google · gemini 3.7 flash high
afi 0.30.01/115%N/A
afi
afi · cli
default
Default profile / Z.AI · glm 5.3 flash high
afi 0.30.01/140%N/A
afi
afi · cli
default
Default profile / Z.AI · glm 5.3 high
afi 0.30.01/15%N/A

Subject evidence

Content-addressed answer key and patch artifacts

faults present

Open verified source artifact

Open this path at the exported commit

The artifact is present; its content is available through the verified source link

patch present

Open verified source artifact

Open this path at the exported commit

The artifact is present; its content is available through the verified source link

pull request present

Open verified source artifact

Open this path at the exported commit

The artifact is present; its content is available through the verified source link

benchee benchee-dashboard-1 built from 10f4ec58 Static benchmark evidence ·