74 runs 54 compatible groups smykla-skalski/cairn#8
Answer key
Tier describes discovery difficulty; severity describes impact; they are independent
| ID | Defect | Location | Tier | Severity |
|---|---|---|---|---|
1 | Sorting ascending by age evicts the newest blobs | services/proxy/src/sweep.rs:102 | 1 | issue |
2 | A failed unlink still counts its bytes as reclaimed | services/proxy/src/sweep.rs:125-137 | 1 | issue |
3 | The ceiling comparison removes a blob from a store already inside it | services/proxy/src/sweep.rs:120 | 1 | suggestion |
4 | `fs::metadata` follows links, so the sweep deletes outside the store | services/proxy/src/sweep.rs:160-169 | 2 | blocking |
5 | A future mtime becomes an age of zero, so those blobs are never evicted | services/proxy/src/sweep.rs:185-190 | 2 | issue |
6 | The pass is never handed to `spawn_blocking`, so it holds a runtime worker | services/proxy/src/sweep.rs:14-18services/proxy/src/routes/admin.rs:76services/proxy/src/main.rs:116 | 2 | issue |
7 | `tokio::time::interval` fires immediately, so every restart sweeps | services/proxy/src/main.rs:101services/proxy/src/main.rs:108 | 2 | issue |
8 | `MissedTickBehavior::Delay` leaves no gap after a sweep that overran | services/proxy/src/main.rs:109-112 | 2 | suggestion |
9 | Every blob in the store is materialised into one `Vec` before any deletion | services/proxy/src/sweep.rs:94-102services/proxy/src/sweep.rs:153 | 2 | suggestion |
10 | A malformed `dry_run` is rejected before auth and outside the error contract | services/proxy/src/routes/admin.rs:51-56services/proxy/src/routes/admin.rs:61-66 | 2 | suggestion |
11 | The route bypasses the lock that makes a sweep exclusive | services/proxy/src/sweep.rs:65-67services/proxy/src/sweep.rs:82-90services/proxy/src/routes/admin.rs:76 | 3 | issue |
12 | A dry run leaves the blobs and deletes their index entries | services/proxy/src/sweep.rs:125services/proxy/src/sweep.rs:140services/proxy/src/sweep.rs:249 | 3 | blocking |
13 | The two new counters are rendered under each other's names | services/proxy/src/metrics.rs:50-57services/proxy/src/metrics.rs:94-95 | 3 | issue |
14 | Age is the write time, so eviction is by insertion order and not by use | services/proxy/src/sweep.rs:186services/proxy/src/sweep.rs:100-101services/proxy/src/sweep.rs:10-12 | 3 | issue |
15 | The three new variables are absent from `docker-compose.yml` | .env.example:41.env.example:43-44docs/operations.md:51 | 3 | issue |
16 | The runbook recommends the dry run, which is the one call that corrupts | docs/operations.md:51 | 3 | suggestion |
17 | Clearing `incoming` unlinks partials that live fetches and `link` are using | services/proxy/src/sweep.rs:219-236 | 4 | blocking |
18 | The unreferenced prune deletes a blob committed but not yet linked | services/proxy/src/sweep.rs:114-120 | 4 | blocking |
19 | Two proxies over one blob directory over-reclaim and double-count | services/proxy/src/sweep.rs:10-12services/proxy/src/sweep.rs:65-67 | 4 | issue |
20 | Eviction leaves `versions.cached_at` set, so the dashboard lies | services/proxy/src/sweep.rs:125-137docs/operations.md:53 | 4 | issue |
Intended behavior
Correct findings about these trade-offs are classified as intended, not unkeyed
- 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.
- 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.
- `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.
- 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.
- 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.
- 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.
- 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
| Reviewer | Configuration | Build | Scored / recorded | Recall | Judged precision |
|---|---|---|---|---|---|
| afi afi · cli | default Default profile / OpenAI · gpt 5.6 sol high | afi 0.30.0 | 3/3 | 55% | N/A |
| afi afi · cli | default Default profile / xAI · grok 4.5 high | afi 0.30.0 | 2/2 | 42.5% | N/A |
| afi afi · cli | default Default profile / Z.AI · glm 5.2 high | afi 0.30.0 | 1/1 | 20% | N/A |
| afi afi · cli | default Default profile / Meta · llama 4 maverick high | afi 0.30.0 | 0/3 | Not recorded | Not recorded |
| afi afi · cli | default Default profile / Z.AI · glm 5.3 flash high | afi 0.30.0 | 1/1 | 40% | N/A |
| afi afi · cli | default Default profile / Mistral AI · devstral 2512 high | afi 0.30.0 | 0/1 | Not recorded | Not recorded |
| afi afi · cli | default Default profile / Minimax · m3 high | afi 0.30.0 | 1/1 | 15% | N/A |
| afi afi · cli | default Default profile / Moonshot AI · kimi k2.7 code high | afi 0.30.0 | 1/1 | 30% | N/A |
| afi afi · cli | default Default profile / DeepSeek · v4 flash high | afi 0.30.0 | 1/1 | 0% | N/A |
| afi afi · cli | default Default profile / Z.AI · glm 5.3 high | afi 0.30.0 | 1/1 | 40% | N/A |
| afi afi · cli | default Default profile / DeepSeek · v4 pro high | afi 0.30.0 | 1/1 | 60% | N/A |
| afi afi · cli | default Default profile / xAI · grok 4.5 high | afi 0.30.0 | 1/1 | 40% | N/A |
| afi afi · cli | default Default profile / Z.AI · glm 5.2 high | afi 0.30.0 | 1/1 | 15% | N/A |
| afi afi · cli | default Default profile / Moonshot AI · kimi k3 high | afi 0.30.0 | 1/1 | 35% | N/A |
| afi afi · cli | default Default profile / Z.AI · glm 5.3 high | afi 0.30.0 | 1/1 | 0% | N/A |
| afi afi · cli | default Default profile / DeepSeek · v4 pro high | afi 0.30.0 | 1/1 | 25% | N/A |
| afi afi · cli | default Default profile / OpenAI · gpt 5.6 terra high | afi 0.30.0 | 2/2 | 30% | N/A |
| afi afi · cli | default Default profile / DeepSeek · v4 flash high | afi 0.30.0 | 1/1 | 0% | N/A |
| afi afi · cli | default Default profile / OpenAI · gpt 5.6 luna high | afi 0.30.0 | 3/3 | 40% | N/A |
| afi afi · cli | default Default profile / Anthropic · fable 5 high | afi 0.30.0 | 1/1 | 50% | N/A |
| afi afi · cli | default Default profile / Z.AI · glm 5.3 flash high | afi 0.30.0 | 1/1 | 40% | N/A |
| afi afi · cli | default Default profile / Z.AI · glm 5.3 flash high | afi 0.30.0 | 2/2 | 35% | N/A |
| afi afi · cli | default Default profile / Z.AI · glm 5.3 flash high | afi 0.30.0 | 3/3 | 45% | N/A |
| afi afi · cli | default Default profile / Z.AI · glm 5.3 flash high | afi 0.30.0 | 1/1 | 30% | N/A |
| afi afi · cli | default Default profile / Anthropic · opus 5 high | afi 0.30.0 | 1/1 | 45% | N/A |
| afi afi · cli | default Default profile / Minimax · m3 high | afi 0.30.0 | 1/1 | 10% | N/A |
| afi afi · cli | default Default profile / OpenAI · gpt 5.6 terra high | afi 0.30.0 | 1/1 | 35% | N/A |
| afi afi · cli | default Default profile / Anthropic · fable 5 high | afi 0.30.0 | 2/2 | 35% | N/A |
| afi afi · cli | default Default profile / Z.AI · glm 5.2 high | afi 0.30.0 | 1/1 | 15% | N/A |
| afi afi · cli | default Default profile / OpenAI · gpt oss 120b high | afi 0.30.0 | 2/2 | 0% | N/A |
| afi afi · cli | default Default profile / DeepSeek · v4 flash high | afi 0.30.0 | 1/1 | 5% | N/A |
| afi afi · cli | default Default profile / Mistral AI · devstral 2512 high | afi 0.30.0 | 0/2 | Not recorded | Not recorded |
| afi afi · cli | default Default profile / Moonshot AI · kimi k3 high | afi 0.30.0 | 1/1 | 30% | N/A |
| afi afi · cli | default Default profile / Anthropic · opus 5 high | afi 0.30.0 | 0/1 | Not recorded | Not recorded |
| afi afi · cli | default Default profile / Z.AI · glm 4.7 flash high | afi 0.30.0 | 1/1 | 0% | N/A |
| afi afi · cli | default Default profile / Qwen · qwen3 coder 30b a3b instruct high | afi 0.30.0 | 0/3 | Not recorded | Not recorded |
| afi afi · cli | default Default profile / Moonshot AI · kimi k3 high | afi 0.30.0 | 1/1 | 40% | N/A |
| afi afi · cli | default Default profile / Google · gemini 3.1 pro preview high | afi 0.30.0 | 1/1 | 45% | N/A |
| afi afi · cli | default Default profile / Google · gemini 3.1 pro preview high | afi 0.30.0 | 1/1 | 20% | N/A |
| afi afi · cli | default Default profile / Google · gemini 3.7 flash high | afi 0.30.0 | 2/2 | 30% | N/A |
| afi afi · cli | default Default profile / Google · gemini 3.1 pro preview high | afi 0.30.0 | 1/1 | 40% | N/A |
| afi afi · cli | default Default profile / Anthropic · sonnet 5 high | afi 0.30.0 | 2/2 | 17.5% | N/A |
| afi afi · cli | default Default profile / Moonshot AI · kimi k2.7 code high | afi 0.30.0 | 1/1 | 30% | N/A |
| afi afi · cli | default Default profile / Qwen · qwen3.7 flash high | afi 0.30.0 | 0/3 | Not recorded | Not recorded |
| afi afi · cli | default Default profile / OpenAI · gpt oss 120b high | afi 0.30.0 | 1/1 | 0% | N/A |
| afi afi · cli | default Default profile / Anthropic · opus 5 high | afi 0.30.0 | 1/1 | 50% | N/A |
| afi afi · cli | default Default profile / Anthropic · opus 5 high | afi 0.30.0 | 0/1 | Not recorded | Not recorded |
| afi afi · cli | default Default profile / Z.AI · glm 4.7 flash high | afi 0.30.0 | 1/1 | 0% | N/A |
| afi afi · cli | default Default profile / Minimax · m3 high | afi 0.30.0 | 1/1 | 20% | N/A |
| afi afi · cli | default Default profile / DeepSeek · v4 pro high | afi 0.30.0 | 1/1 | 5% | N/A |
| afi afi · cli | default Default profile / Moonshot AI · kimi k2.7 code high | afi 0.30.0 | 1/1 | 45% | N/A |
| afi afi · cli | default Default profile / Google · gemini 3.7 flash high | afi 0.30.0 | 1/1 | 15% | N/A |
| afi afi · cli | default Default profile / Z.AI · glm 5.3 flash high | afi 0.30.0 | 1/1 | 40% | N/A |
| afi afi · cli | default Default profile / Z.AI · glm 5.3 high | afi 0.30.0 | 1/1 | 5% | N/A |
Subject evidence
Content-addressed answer key and patch artifacts
faults
Open this path at the exported commit
The artifact is present; its content is available through the verified source link
patch
Open this path at the exported commit
The artifact is present; its content is available through the verified source link
pull request
Open this path at the exported commit
The artifact is present; its content is available through the verified source link