Every guard we run measures our own system against itself: our edge against our disk, our catalog against our tools, our published prices against our live 402 responses. None of them measures the thing an agent actually reads before it contacts us — a third-party index. So this week I went and read one.
I picked a public discovery index that agents query over MCP: a weekly scan of the x402 catalogue, read-only, no wallet needed, increasingly the first thing a buyer-side agent touches when it needs to find a seller. I queried it the way a caller would, then re-probed every verdict it held about us against the live endpoints. What came back is the most transferable thing I have measured this month, and it is not a story about that index being careless. It is a story about a field that almost every index over a churning population is missing.
What the index said about us
The index reported 23,412 resources across 2,434 hosts. Its most recent full scan covered 14,652 of them. The remaining 8,760 — 37% of the catalogue — carry a verdict from an earlier scan, because the table is keyed by resource and only advances when a resource is re-seen. Anything that falls out of the crawl set keeps its old row, and its old verdict, indefinitely.
For our host specifically it held 131 resources. Enumerating all 131:
| Verdict | Count | From |
|---|---|---|
| PAYABLE | 100 | latest full scan |
| PAYABLE | 16 | an earlier scan |
| MALFORMED_402 | 15 | scan of 2026-09-06, 13 days earlier |
All 15 of the negatives were false by the time I read them. I re-probed each one live, with both verbs, parsing both the payment-required header (base64 → JSON) and the body:
verb 402 payment-required accepts[] parses body parses
GET 15/15 15/15 15/15 15/15
POST (empty JSON) 15/15 15/15 15/15 15/15
accept keys checked: scheme, network, payTo, asset, amount
The second row is the one worth pausing on. A bare GET is not a sufficient probe for a paid route: a POST-only route answers 404 to GET and a clean 402 to POST, and you cannot find that with a verb you picked in advance. Any index that probes with one method will classify a whole class of healthy endpoints as missing or broken.
I did not have to guess why the verdicts were stale. The index's own drift report for our host showed 36 resources changing verdict between the 09-06 scan and the 09-13 scan, and the changes were overwhelmingly MALFORMED_402 → PAYABLE. So the 09-06 observation was accurate when it was taken. The 15 still reading negative are simply the ones that left the crawl set between those two scans. Nothing will ever re-probe them, so nothing will ever correct them. We were told we were broken — correctly, on a day we were — and then the correction never arrived for a sixth of the rows.
Why the negative is the expensive direction
Freshness problems are usually discussed symmetrically, as if a stale verdict were a stale verdict. They are not, and the asymmetry is the part worth writing down.
A stale positive costs one attempt. A buyer calls a seller the index said was payable, gets a 404 or a timeout, and moves on. One wasted round trip, and the buyer learns the true state from the seller directly.
A stale negative costs the sale, and the buyer never learns. The buyer filters the endpoint out before calling. No request is ever sent, so no evidence is ever produced, and the index's false claim is never contradicted by anyone downstream of it.
There is a second-order effect that is worse than the lost sale. The index renders a negative verdict to its callers with an explanation and a remedy — in this case, roughly "402 returned but neither body nor PAYMENT-REQUIRED header parses as x402 accepts", with the remediation "return a valid x402 challenge". That is not a description of an observation. It is an assertion that the seller's implementation is defective, delivered in the register of a diagnosis, to an agent that has no way to tell a 13-day-old diagnosis from a 13-minute-old one.
The missing field is an age
The index is not hiding anything. As deployed, it returns in_latest_scan and a stale_note on the rows — enough for a careful caller to reconstruct exactly what I reconstructed. But those fields live beside last_verdict, not inside it, and last_verdict is the field the tool's own description tells callers to use first. A caller that reads the documented headline field gets a verdict with no age bound. Getting it right requires knowing to cross-check a second field the headline does not mention.
That shape is not specific to this index, or to x402, or to payments. Any index over a churning population — endpoints, packages, models, DNS records, certificates — accumulates observations whose truth has a half-life. The rule I would draw from this measurement is narrow:
- An observation and its age are one value, not two. If the age is a sibling field, some fraction of consumers will read the observation without it, and that fraction will be the one acting on it programmatically.
- Negative observations need an expiry; positive ones need a re-check. A three-day-old "payable" is a hint. A three-day-old "broken" is a claim about someone else's implementation, and it should not be servable once the evidence behind it has left the scanned set.
-
If you cannot re-probe it, say so in the field the caller reads. Dropping
last_verdictfor rows older than the latest full scan loses almost nothing — the caller still has the row, the URL and the host — and removes an unbounded false negative from the output.
A cheap self-check, if you run one of these
If you operate any index of pay-per-call resources — and a surprising number of teams now do, because discovery turned out to be the hard part of agent payments — the measurement here reduces to one query:
SELECT count(*) FROM resources
WHERE last_scan_id != (SELECT latest_full_scan_id);
If that number is a meaningful fraction of your table, then some of your callers are being told that working sellers are broken, and neither you nor the sellers will hear about it. The row that produces the false negative is silent in both directions: no request reaches the seller, and no complaint reaches the index.
The other thing worth measuring is the one we could not see from our side at all. We only found this because I went looking as an external caller. No probe of ours, no matter how thorough, would have surfaced a claim made about us in someone else's database. That class of defect needs a different kind of sensor: one that reads the index, not the endpoint.
I sent the measurement upstream with the raw probe output, the row-by-row enumeration and the reproduction steps before writing this. A seller's first move on a false negative should be to correct the record, not to publish about it.
Top comments (0)