Session summary

default

scored

afi / afi · cli reviewed proxy at 9b51f95e with Default profile / Anthropic · fable 5 high on afi 0.30.0

Measurements

Unavailable values retain their exported state and reason

Quality

Recall 50%
Model-judged precision N/A
F1 N/A
Tier 1 recall 66.7%
Tier 2 recall 42.9%
Tier 3 recall 50%
Tier 4 recall 50%
Security recall 50%
Defect recall 61.5%
Maintainability recall 0%
Performance recall 33.3%
Median anchor distance 0
Worst anchor distance 0
Refusals a judge overturned Not recorded

Review outcomes

Distinct matched defects 10
Defects missed 10
Findings 10
Unkeyed findings 0
Intended findings 0
Carried findings Not recorded

Cost, usage, and speed

Total bill $1.71
Review bill $1.71
Judge bill N/A
Tokens 108636
Duration 2m 50s

Execution and identity

Lifecycle, reviewer, build, settings, and normalized execution limits

Lifecycle
completed
Lifecycle reason
Not recorded
Started
Finished
Reviewer
afi
Reviewer tool
afi · cli
Configuration
default / 8232536cf248
Configuration ID
config-c7610bea013352e3
Build
afi 0.30.0 / b0f313c0b59a66ecc7612396dc8db0ea5da13a7a
Comparison
comparison-3f421c0960d73d4c
Build ID
build-c9a20474a6b1695d
Cohort ID
cohort-fdab2adfb8a4bd39
Harness
bench 1 / d5372b5a9797137af68e35c478f308f58ca4510c
Adapter
afi 1 / sha256:a1a935298956020ee6d767a756847abb4c00694c88c2eb80d454886ebc4acf8c
Exit code
0
Wall time
170
Deadline exceeded
No
Budget
$20.00
Billing limit
$20.00

Usage

Normalized reviewer-tool usage projection

Input tokens
106515
Output tokens
2121
Cached input
0
Reasoning tokens
10709
Requests
3
Models counted
Not recorded

Judge

Normalized assessment summary

Judge data is N/A for this run

Findings

Review text is escaped; normalized decisions follow each finding

Finding f1

bug

forget(&index, &gone)` runs even when `dry_run` is true, so a "report only" dry run permanently deletes the index entries for every blob it would have removed — the blobs become unreachable cache… forget(&index, &gone)` runs even when `dry_run` is true, so a "report only" dry run permanently deletes the index entries for every blob it would have removed — the blobs become unreachable cache misses and are collected as unreferenced garbage by the next real sweep, making `?dry_run=true` destructive despite the route's promise.

bug
Category: bug Confidence: Not recorded

services/proxy/src/sweep.rs:140

Evidence quote

Not recorded

Suggested fix

Not recorded

matchedDefect 12 (locality)
Finding f2

bug

sort_by_key(|c| c.age)` sorts ascending, putting the *youngest* blobs first, so the eviction loop removes the most recently fetched blobs first — the exact opposite of the "Oldest first" comment and… sort_by_key(|c| c.age)` sorts ascending, putting the *youngest* blobs first, so the eviction loop removes the most recently fetched blobs first — the exact opposite of the "Oldest first" comment and of the documented `CAIRN_CACHE_MAX_BYTES` behaviour; the hot working set is evicted while the stalest blobs survive.

bug
Category: bug Confidence: Not recorded

services/proxy/src/sweep.rs:102

Evidence quote

Not recorded

Suggested fix

Not recorded

matchedDefect 1 (locality)
Finding f3

bug

clear_partials` unlinks every file in `incoming/` with no age check, but `BlobStore::temp_path` (store.rs:201) puts *live* in-flight downloads there; each sweep unlinks the temp files of concurrent… clear_partials` unlinks every file in `incoming/` with no age check, but `BlobStore::temp_path` (store.rs:201) puts *live* in-flight downloads there; each sweep unlinks the temp files of concurrent fetches, whose `commit` rename (store.rs:259) then fails, so every sweep fails all downloads in flight at that moment.

bug
Category: bug Confidence: Not recorded

services/proxy/src/sweep.rs:230

Evidence quote

Not recorded

Suggested fix

Not recorded

matchedDefect 17 (locality)
Finding f4

bug

values()` loads `sweep_bytes_reclaimed` at index 4 and `sweep_blobs_removed` at index 5, but `COUNTERS` puts `..._blobs_removed_total` at index 4 and `..._bytes_reclaimed_total` at index 5, so the… values()` loads `sweep_bytes_reclaimed` at index 4 and `sweep_blobs_removed` at index 5, but `COUNTERS` puts `..._blobs_removed_total` at index 4 and `..._bytes_reclaimed_total` at index 5, so the two new counters are rendered under each other's names — the exact mix-up the comment above `COUNTERS` warns about, and the ops doc tells operators to alert on the misrendered `cairn_proxy_sweep_bytes_reclaimed_total`.

bug
Category: bug Confidence: Not recorded

services/proxy/src/metrics.rs:94

Evidence quote

Not recorded

Suggested fix

Not recorded

matchedDefect 13 (locality)
Finding f5

bug

the admin route calls `app.sweeper.sweep(dry_run)` directly, bypassing the `running` mutex that only `Sweeper::run` takes (sweep.rs:83), so an admin-triggered sweep can run concurrently with the… the admin route calls `app.sweeper.sweep(dry_run)` directly, bypassing the `running` mutex that only `Sweeper::run` takes (sweep.rs:83), so an admin-triggered sweep can run concurrently with the background sweep (or with another admin sweep) — the exact double-sweep over-eviction the module doc at sweep.rs:10-12 says the mutex exists to prevent.

bug
Category: bug Confidence: Not recorded

services/proxy/src/routes/admin.rs:76

Evidence quote

Not recorded

Suggested fix

Not recorded

matchedDefect 6 (locality)
Finding f6

bug

an unreferenced blob is removed with no `min_age` grace, but a blob is legitimately unreferenced in the window between `writer.commit()` (cache.rs:151) and `store.link` (cache.rs:163), which spans a… an unreferenced blob is removed with no `min_age` grace, but a blob is legitimately unreferenced in the window between `writer.commit()` (cache.rs:151) and `store.link` (cache.rs:163), which spans a registry round-trip; a sweep in that window deletes the freshly committed blob and the request 500s at cache.rs:90 ("a blob committed by this request is already missing").

bug
Category: bug Confidence: Not recorded

services/proxy/src/sweep.rs:119

Evidence quote

Not recorded

Suggested fix

Not recorded

matchedDefect 18 (locality)
Finding f7

performance

run()` (and the admin handler via admin.rs:76) executes the fully synchronous walk-and-unlink `sweep()` directly on a tokio worker thread instead of `spawn_blocking`; the router comment in… run()` (and the admin handler via admin.rs:76) executes the fully synchronous walk-and-unlink `sweep()` directly on a tokio worker thread instead of `spawn_blocking`; the router comment in routes/mod.rs concedes a sweep "legitimately takes longer than ten seconds", so a large store blocks an async runtime worker for that whole time.

performance
Category: performance Confidence: Not recorded

services/proxy/src/sweep.rs:84

Evidence quote

Not recorded

Suggested fix

Not recorded

matchedDefect 11 (locality)
Finding f8

bug

tokio::time::interval` completes its first tick immediately, so the first sweep runs at startup — the doc comment at lines 101-102 claims the first tick is one interval away precisely to avoid this;… tokio::time::interval` completes its first tick immediately, so the first sweep runs at startup — the doc comment at lines 101-102 claims the first tick is one interval away precisely to avoid this; `interval_at(Instant::now() + period, period)` is what the comment describes.

bug
Category: bug Confidence: Not recorded

services/proxy/src/main.rs:108

Evidence quote

Not recorded

Suggested fix

Not recorded

matchedDefect 7 (locality)
Finding f9

bug

fs::metadata` follows symlinks, so a link is counted at the size of its *target* (and a symlinked directory is recursed into and its contents unlinked), the inverse of the comment's claim that "a… fs::metadata` follows symlinks, so a link is counted at the size of its *target* (and a symlinked directory is recursed into and its contents unlinked), the inverse of the comment's claim that "a link is counted at the size of the link"; `symlink_metadata` is what the comment describes.

bug
Category: bug Confidence: Not recorded

services/proxy/src/sweep.rs:164

Evidence quote

Not recorded

Suggested fix

Not recorded

matchedDefect 4 (locality)
Finding f10

bug

when `fs::remove_file` fails on line 126, the blob is still counted in `removed`/`bytes`/`remaining` and pushed to `gone`, so the reported reclaim overstates reality and `forget` deletes the index… when `fs::remove_file` fails on line 126, the blob is still counted in `removed`/`bytes`/`remaining` and pushed to `gone`, so the reported reclaim overstates reality and `forget` deletes the index entries of a blob that is still on disk, orphaning it until a later sweep.

bug
Category: bug Confidence: Not recorded

services/proxy/src/sweep.rs:134

Evidence quote

Not recorded

Suggested fix

Not recorded

matchedDefect 2 (locality)

Source artifacts

Open a row to inspect or download evidence from this atomically published local run

findings 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

meta 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

record 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

result 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

spend 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

stderr 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

summary 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

traffic 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 ·