A filtered log of every request the app made, with bodies, status, timing, automatic credential redaction, and an honest note when evidence has expired.
reticle_network is not advertised. The default surface is the merged nine, so an agent does not see
this name. Call reticle_observe { action: "network" } instead. Everything below describes what that call does;
only the spelling changed. A call to the old name is answered with the new one, but an
allowedTools allowlist or an MCP permission rule naming it refuses before Reticle is asked.
reticle_network returns a filtered log of every request the app made, with request and response bodies, status, timing, and automatic credential redaction. Reach for it to answer “did that call actually fire, and what came back?”, which is the thing a screenshot fundamentally cannot show.
Real response, with the second call’s headers block trimmed off:
{ "calls": [ { "method": "POST", "url": "http://localhost:8787/api/login", "status": 401, "statusText": "Unauthorized", "contentType": "application/json; charset=utf-8", "responseSize": 37, "requestBody": "{\"email\":\"admin@reticle.dev\",\"password\":\"[REDACTED]\"}", "responseBody": "{\"error\":\"invalid email or password\"}", "ms": 23 }, { "method": "POST", "url": "http://localhost:8787/api/login", "status": 200, "statusText": "OK", "contentType": "application/json; charset=utf-8", "responseSize": 67, "requestBody": "{\"email\":\"admin@reticle.dev\",\"password\":\"[REDACTED]\"}", "responseBody": "{\"token\":\"[REDACTED]\",\"user\":{\"email\":\"admin@reticle.dev\"}}", "ms": 4 } ], "buffer": { "held": 535, "dropped": 10, "note": "event buffer evicted older events (age/size cap): a negative result here may be a false negative; the evidence may have expired. Grade sooner or widen the buffer." }, "cost": { "bytes": 1133, "tokens": 284 }}
Two attempts at the same login, the first rejected and the second accepted, with the server’s own error text attached to the failure. That is the whole diagnosis in one read.
Look at requestBody. The password is [REDACTED] and so is the returned token, without anyone configuring anything. Reticle strips credential-shaped values before they leave the page, so neither your agent’s context nor any transcript of it ever holds them.The email is not redacted, because an email is not a credential. The line is drawn at secrets.
"buffer": { "held": 535, "dropped": 10, "note": "…the evidence may have expired…" }
Reticle keeps a bounded event buffer. When it overflows, older events are evicted. And if you then ask “did a POST to /api/orders happen?”, the honest answer is not “no”. It is “not in what I still have.”Most tools would return an empty array and let you draw the wrong conclusion. This one tells you the result may be a false negative and suggests grading sooner or widening the buffer. Take that note seriously: a confident “no requests fired” built on evicted evidence is exactly the kind of false green Reticle exists to prevent.
If calls has two entries with near-identical timestamps, you have found it. Better still, assert it up front so the agent cannot rationalise it afterwards. reticle_act_and_wait accepts an exact count predicate, which turns “roughly one request” into a check that fails at two.
{ "ok": false } keeps only the calls that failed, so an empty result there is a genuinely useful answer: nothing broke. Provided the buffer note says nothing was dropped. Read both.Desktop IPC (ipc://) has no status code, so its 200 and 500 are derived. Filter those on ok rather than status.
Prove it, don't just look at it
reticle_network reads. It does not produce a verdict. Name the expected request in
reticle_act_and_wait instead.