Session summary

default

scored

afi / afi · cli reviewed proxy at 9b51f95e with Default profile / Z.AI · glm 5.3 flash high on afi 0.30.0

Measurements

Unavailable values retain their exported state and reason

Quality

Recall 45%
Model-judged precision N/A
F1 N/A
Tier 1 recall 33.3%
Tier 2 recall 42.9%
Tier 3 recall 50%
Tier 4 recall 50%
Security recall 50%
Defect recall 53.8%
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 9
Defects missed 11
Findings 9
Unkeyed findings 0
Intended findings 0
Carried findings Not recorded

Cost, usage, and speed

Total bill $0.0288
Review bill $0.0288
Judge bill N/A
Tokens 71907
Duration 4m 45s

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 / be7c5b1aa470
Configuration ID
config-e5f3155850f5053d
Build
afi 0.30.0 / b0f313c0b59a66ecc7612396dc8db0ea5da13a7a
Comparison
comparison-491a157d4c780a6f
Build ID
build-944472ec933601e7
Cohort ID
cohort-fdab2adfb8a4bd39
Harness
bench 1 / d5372b5a9797137af68e35c478f308f58ca4510c dirty
Adapter
afi 1 / sha256:a1a935298956020ee6d767a756847abb4c00694c88c2eb80d454886ebc4acf8c
Exit code
0
Wall time
285
Deadline exceeded
No
Budget
Not recorded
Billing limit
$2.00

Usage

Normalized reviewer-tool usage projection

Input tokens
71011
Output tokens
896
Cached input
195840
Reasoning tokens
24197
Requests
11
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

clear_partials` unlinks every file in `incoming` with no age check, but a download in flight writes its temp file there (`store.rs:201-206` via `cache.rs:131`); the sweep runs while the writer still… clear_partials` unlinks every file in `incoming` with no age check, but a download in flight writes its temp file there (`store.rs:201-206` via `cache.rs:131`); the sweep runs while the writer still holds the file open, so the bytes go to an unlinked inode and `BlobWriter::commit`'s rename then fails (`store.rs:259`), turning every artifact being fetched at sweep time into a 500 for the client. At minimum it needs the `min_age` grace the blob path has.

bug
Category: bug Confidence: Not recorded

services/proxy/src/sweep.rs:232

Evidence quote

Not recorded

Suggested fix

Not recorded

matchedDefect 17 (locality)
Finding f2

bug

values()` returns `sweep_bytes_reclaimed` before `sweep_blobs_removed`, but `COUNTERS` lists `blobs_removed` first (`metrics.rs:51-57`) and `render` zips the two — so… values()` returns `sweep_bytes_reclaimed` before `sweep_blobs_removed`, but `COUNTERS` lists `blobs_removed` first (`metrics.rs:51-57`) and `render` zips the two — so `cairn_proxy_sweep_blobs_removed_total` reports bytes and `cairn_proxy_sweep_bytes_reclaimed_total` reports blob counts, silently corrupting the exact counter `docs/operations.md` tells operators to alert on.

bug
Category: bug Confidence: Not recorded

services/proxy/src/metrics.rs:94

Evidence quote

Not recorded

Suggested fix

Not recorded

matchedDefect 13 (locality)
Finding f3

bug

the on-demand route calls `sweeper.sweep(dry_run)` directly, bypassing the `running` mutex that `Sweeper::run` holds (`sweep.rs:82-85`) — so an operator-triggered sweep runs concurrently with the… the on-demand route calls `sweeper.sweep(dry_run)` directly, bypassing the `running` mutex that `Sweeper::run` holds (`sweep.rs:82-85`) — so an operator-triggered sweep runs concurrently with the interval sweep, the exact interleaving the module doc says must not happen ("two of them over one directory would each decide what to remove from a total the other is already changing").

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 f4

bug

forget(&index, &gone)` runs unconditionally, but in a dry run `gone` was still populated (line 137) with the referenced blobs the ceiling would evict — so `?dry_run=true`, advertised as reporting… forget(&index, &gone)` runs unconditionally, but in a dry run `gone` was still populated (line 137) with the referenced blobs the ceiling would evict — so `?dry_run=true`, advertised as reporting "without removing anything", deletes live index entries for blobs still on disk, causing refetch churn and contradicting the response it just returned.

bug
Category: bug Confidence: Not recorded

services/proxy/src/sweep.rs:140

Evidence quote

Not recorded

Suggested fix

Not recorded

matchedDefect 12 (locality)
Finding f5

bug

the unreferenced-blob rule ignores `min_age` entirely, but a just-committed blob is unreferenced during the commit→`link` window in `cache.rs:151-163`, which spans a full registry HTTP round trip; a… the unreferenced-blob rule ignores `min_age` entirely, but a just-committed blob is unreferenced during the commit→`link` window in `cache.rs:151-163`, which spans a full registry HTTP round trip; a sweep landing in that window deletes the blob and the request then fails at `cache.rs:90-97` with the "blob committed by this request is already missing" 500.

bug
Category: bug Confidence: Not recorded

services/proxy/src/sweep.rs:119

Evidence quote

Not recorded

Suggested fix

Not recorded

matchedDefect 18 (locality)
Finding f6

bug

removed`/`bytes`/`remaining` are updated even when `fs::remove_file` failed (line 126 only logs), so a permission-denied blob is counted as reclaimed; `remaining` then drops below the ceiling while… removed`/`bytes`/`remaining` are updated even when `fs::remove_file` failed (line 126 only logs), so a permission-denied blob is counted as reclaimed; `remaining` then drops below the ceiling while the disk stays full and the sweep stops evicting, and `forget` deletes index entries for blobs that are still present.

bug
Category: bug Confidence: Not recorded

services/proxy/src/sweep.rs:136

Evidence quote

Not recorded

Suggested fix

Not recorded

matchedDefect 2 (locality)
Finding f7

performance

sweep` is a synchronous full-tree walk (readdir + a file read per index entry) invoked inline from the async handler at `admin.rs:76` and from the interval task at `main.rs:116`; on a store the… sweep` is a synchronous full-tree walk (readdir + a file read per index entry) invoked inline from the async handler at `admin.rs:76` and from the interval task at `main.rs:116`; on a store the module doc itself sizes at 65k directories this blocks a tokio worker for the whole pass — the doc's argument against `tokio::fs` is an argument for `spawn_blocking`, not for inline std calls.

performance
Category: performance Confidence: Not recorded

services/proxy/src/sweep.rs:90

Evidence quote

Not recorded

Suggested fix

Not recorded

matchedDefect 11 (locality)
Finding f8

bug

the comment claims "the first tick is one interval away", but `tokio::time::interval` completes its first tick immediately — so every proxy start sweeps at once, including the startup case the… the comment claims "the first tick is one interval away", but `tokio::time::interval` completes its first tick immediately — so every proxy start sweeps at once, including the startup case the comment says it prevents and the delete-in-flight-partials bug above on any sibling proxy sharing the volume.

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

collect` uses `fs::metadata`, which follows symlinks, while the comment above it promises a link is "counted at the size of the link and not of whatever it points at" (that needs… collect` uses `fs::metadata`, which follows symlinks, while the comment above it promises a link is "counted at the size of the link and not of whatever it points at" (that needs `fs::symlink_metadata`); a symlinked blob is counted at its target's size, and a symlinked directory is recursed into, including cycles.

bug
Category: bug Confidence: Not recorded

services/proxy/src/sweep.rs:164

Evidence quote

Not recorded

Suggested fix

Not recorded

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