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 35%
Model-judged precision N/A
F1 N/A
Tier 1 recall 33.3%
Tier 2 recall 14.3%
Tier 3 recall 50%
Tier 4 recall 50%
Security recall 0%
Defect recall 46.2%
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 7
Defects missed 13
Findings 7
Unkeyed findings 0
Intended findings 0
Carried findings Not recorded

Cost, usage, and speed

Total bill $2.27
Review bill $2.27
Judge bill N/A
Tokens 147334
Duration 3m 42s

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-6173376f94cdba42
Build ID
build-c9a20474a6b1695d
Cohort ID
cohort-07363c4dd57b37b6
Harness
bench 1 / d5372b5a9797137af68e35c478f308f58ca4510c
Adapter
afi 1 / sha256:a1a935298956020ee6d767a756847abb4c00694c88c2eb80d454886ebc4acf8c
Exit code
0
Wall time
222
Deadline exceeded
No
Budget
$20.00
Billing limit
$20.00

Usage

Normalized reviewer-tool usage projection

Input tokens
145251
Output tokens
2083
Cached input
0
Reasoning tokens
14221
Requests
4
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)` is not gated on `dry_run` and `gone` is filled even in a dry run (lines 136-137 run unconditionally), so `POST /v1/admin/cache/sweep?dry_run=true` really unlinks the index… forget(&index, &gone)` is not gated on `dry_run` and `gone` is filled even in a dry run (lines 136-137 run unconditionally), so `POST /v1/admin/cache/sweep?dry_run=true` really unlinks the index entries of every blob it merely reported — the blobs it "did not remove" become unreachable cache misses immediately and are deleted as unreferenced on the very next real sweep, the opposite of the documented "reports … without removing anything".

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)` orders candidates youngest first (smallest `now - mtime` first), yet the eviction loop removes from the front, so an over-ceiling sweep deletes the most recently fetched… sort_by_key(|c| c.age)` orders candidates youngest first (smallest `now - mtime` first), yet the eviction loop removes from the front, so an over-ceiling sweep deletes the most recently fetched blobs and keeps the oldest — an inverted LRU that thrashes exactly the packages current builds are using; the sort needs to be descending by age.

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

a blob with no index entry is removed with no `min_age` grace, but on the miss path a blob exists unlinked for the whole window between `writer.commit()` (services/proxy/src/routes/cache.rs:151) and… a blob with no index entry is removed with no `min_age` grace, but on the miss path a blob exists unlinked for the whole window between `writer.commit()` (services/proxy/src/routes/cache.rs:151) and `store.link()` (cache.rs:163), which includes a network round-trip to the registry — a sweep in that window deletes the just-committed blob and the request 500s at cache.rs:90; reading the index snapshot (line 92) *before* walking blobs (line 95) widens the race further.

bug
Category: bug Confidence: Not recorded

services/proxy/src/sweep.rs:119

Evidence quote

Not recorded

Suggested fix

Not recorded

matchedDefect 18 (locality)
Finding f4

bug

clear_partials` unlinks every file in `incoming` with no age or liveness check, but `incoming` is where `BlobWriter` (store.rs:171-180) is actively writing in-flight downloads — a sweep during a… clear_partials` unlinks every file in `incoming` with no age or liveness check, but `incoming` is where `BlobWriter` (store.rs:171-180) is actively writing in-flight downloads — a sweep during a fetch unlinks the live temp file, and `commit`'s `fs::rename` (store.rs:259) then fails with NotFound, failing the request; the doc's claim that "a file in `incoming` is a fetch that is not coming back" is false while any fetch is in flight.

bug
Category: bug Confidence: Not recorded

services/proxy/src/sweep.rs:230

Evidence quote

Not recorded

Suggested fix

Not recorded

matchedDefect 17 (locality)
Finding f5

bug

values()` loads `sweep_bytes_reclaimed` at index 4 and `sweep_blobs_removed` at index 5, but `COUNTERS` (lines 50-57) names index 4 `cairn_proxy_sweep_blobs_removed_total` and index 5… values()` loads `sweep_bytes_reclaimed` at index 4 and `sweep_blobs_removed` at index 5, but `COUNTERS` (lines 50-57) names index 4 `cairn_proxy_sweep_blobs_removed_total` and index 5 `..._bytes_reclaimed_total` — each sweep counter is exported under the other's name, which is precisely the mix-up the comment on `COUNTERS` warns about, and docs/operations.md tells operators to alert on the bytes counter that will actually carry the blob count.

bug
Category: bug Confidence: Not recorded

services/proxy/src/metrics.rs:94

Evidence quote

Not recorded

Suggested fix

Not recorded

matchedDefect 13 (locality)
Finding f6

bug

the admin route calls `app.sweeper.sweep(dry_run)` directly instead of `run()`, skipping the `running` mutex (sweep.rs:83), so an on-demand sweep runs concurrently with the background sweep (or… the admin route calls `app.sweeper.sweep(dry_run)` directly instead of `run()`, skipping the `running` mutex (sweep.rs:83), so an on-demand sweep runs concurrently with the background sweep (or another admin sweep) — the exact two-sweeps-over-one-total situation the module doc (sweep.rs:10-12) says must never happen, each deleting from a total the other is changing.

bug
Category: bug Confidence: Not recorded

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

Evidence quote

Not recorded

Suggested fix

Not recorded

matchedDefect 11 (locality)
Finding f7

performance

sweeper.sweep()` is a fully synchronous filesystem walk (readdir + stat over up to 65k directories, plus reading every index file) executed inline on a tokio worker thread — routes/mod.rs:125 itself… sweeper.sweep()` is a fully synchronous filesystem walk (readdir + stat over up to 65k directories, plus reading every index file) executed inline on a tokio worker thread — routes/mod.rs:125 itself says a sweep "legitimately takes longer than ten seconds" — blocking that runtime thread for the duration; the same applies to `app.sweeper.run().await` in the spawned task at services/proxy/src/main.rs:116; both should go through `spawn_blocking`.

performance
Category: performance Confidence: Not recorded

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

Evidence quote

Not recorded

Suggested fix

Not recorded

matchedDefect 6 (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 ·