Publishing rules — every headline stat ships with six things
- 1 · Object definition — mint? funded wallet? paying x402 buyer? live endpoint? Say which.
- 2 · Chain set — “all chains” is a claim, not a default.
- 3 · Time window — 24h, 30d, cumulative. Windows change conclusions.
- 4 · Scrape timestamp — explorers drift; ours are stamped.
- 5 · Exclusions — what is left out (payments before the registration existed, routing hops inside a larger transaction, money that never left the agent's control) is written on the definition, so the excluded part can be read beside the total.
- 6 · Link to raw data — every figure's history as JSON at /api/series and as CSV at /api/series?format=csv; the definition behind it at /def.
Two standing bans: forecasts never appear in live tiles (they are quarantined and labeled), and raw reputation averages are never displayed as trust.
The L0–L9 liveness ladder
“Active agents” means nothing without a definition. Each rung below is one test, written as the code runs it, with what it measures today and what it costs to reach. We rank at L7+: the first rung that money, not a file, has to pass.
| Level | Name | The test, as the code runs it | Measured now | Cheapest way to pass it |
|---|---|---|---|---|
| L0 | Mint | The identity exists in the ERC-8004 Identity registry on Base | 371,059 registrations | One mint transaction |
| L1 | Pointer | Its current URI (never the mint URI) is non-empty | 93.16% of the sample | Any string |
| L2 | Resolve | The registration file is readable: a data: URI that decodes, or an https or IPFS URI that answers 2xx within 8 seconds (redirects included, at most 3) | 80.08% | Any hosted file |
| L3 | Parse | The file is a JSON object with at least one of name, type, description, services or endpoints: an ERC-8004 registration file or an Agentverse card. A parse check, not full schema validation | 79.2% | One JSON field |
| L4 | Declare | services[] or endpoints[] lists at least one entry with an address | 73.54% | One URL string |
| L5 | Reach | A declared web endpoint answers within 8 seconds: a 2xx or a 402 (payment required) to a GET, or the L6 handshake. Up to 8 web endpoints, in any order; ENS names, DIDs and emails are skipped. A shared hosting platform's submit URL is never probed and cannot pass (probe.l5.endpoint_live.v2) | 64.16% | Any web server that answers |
| L6 | Speak | An endpoint completes a protocol handshake. MCP: a POSTed initialize returns a JSON-RPC result with a protocolVersion. A2A: an agent card with a name and a skills array. x402: a 402 carrying payment requirements (scheme, network, payTo) (probe.l6.protocol.v1) | 63.18% | A minimal MCP server or a static card |
| L7 | Paid | A bound wallet made a counted stablecoin payment that left the agent's control: receipt read, after the registration was minted, not a routing hop, nothing inferred, not into a lending or vault position the receipt shows it still holds, not to its own addresses (any wallet ever bound to it, its registration's owner, its minter), not a bridge leg that came back to it (rank.l7plus.v2). L7 does not require L1–L6: a wallet that paid is an economic actor whether or not it publishes an endpoint | 9,984 agents | One payment, any size, to an address nothing links to the agent. That is why L9 exists |
| L8 | Funded | L7, and a bound wallet holds at least $10 in USDC, USDT, EURC or DAI at the latest balance read; ETH does not count (rank.l8plus.v3) | 696 agents | $10 left in the wallet |
| L9 | Economic | L8, and those payments reached at least 3 independent counterparties in the last 30 days. Independent means a contract that is not a bot-like router, or an address that at least one agent outside this agent's operator set also pays; operator sets are registrations tied by the same bound wallet, owner, minter or first funder, each link ignored above 50 (rank.l9.v4, cluster.ratio.v1) | 94 agents | Three payments to shared contracts or services in a month, plus L8; or agents funded from fresh, unlinked addresses paying the same three addresses, the case no chain link closes |
The probe rungs (L1–L6) are rates over a uniform random sample of 1,024 registrations, swept every six hours; the money rungs (L7–L9) are counts over every bound wallet, recomputed every three hours. One file holds the tests, pulse/lib/ladder.mjs: the prober, the rank job and the publish gate all read it, so a tile, an agent page and the API cannot disagree. A rank that loses its evidence falls to the agent's measured probe level, never to a level nobody measured. What each rank costs to reach, in dollars, is published as rank.costtofake.v1.
Ladder v2, in force from 13 October 2026, 12:54 UTC. L5 reads up to 8 endpoints in any order and counts a completed handshake; L6 is measured; L7 needs money that left the agent's control; L9 needs three independent counterparties. Counted on the switch, with no new payments in between: L7+ 7,866 → 7,525, L8+ 562 → 557, L9 118 → 74. The v1 definitions stay served, marked superseded, and history before the switch keeps their ids (cp-2026-10-13-ladder-v2). L9 operator-set aware from 13 October 2026, 21:22 UTC (rank.l9.v4): measured before the switch, 71 of 72 L9 agents kept the level; at the switch, 72 under both rules (cp-2026-10-13-l9-v4).
Reference points for calibration: the reproducible Base crawl (n=1,204 of 63,832 registrations through 2026-08-16) measured L5 = 6.8% (95% CI 5.5–8.4%); the July 2026 ecosystem cut put working services at 2.24% of 385,998 registrations. Both are dated reference points, not the current figure — our own sweep runs continuously and right now reports L5 at 64.16% across a sample of 1,024. Where they disagree, the live number is the one we stand behind; the crawl is kept because anyone can re-run it, and a calibration point you can reproduce is worth more than one you have to take on trust. Full context →
Parameters — documented now, changeable with a dated note
| Parameter | Value | Note |
|---|---|---|
| Funded floor (L8) | $10 | in USDC, USDT, EURC or DAI on the largest bound wallet (rank.l8plus.v3) |
| Minimum payment (L7, L9) | none | a micro-payment for an API call is real spending; what the ranks cost to reach is published instead (rank.costtofake.v1) |
| Economic window (L9) | 30d · 3 independent | contracts that are not bot-like, or addresses an agent outside the payer's operator set also pays, among payments that left the agent's control (rank.l9.v4) |
| Fetch timeout | 8 s | for the whole request, redirects included; at most 3 redirects, each checked again; 256 KB body cap; private and reserved addresses refused; nothing fetched is executed. Status, latency, error class and body hash are stored for every request |
| Endpoints read per registration | up to 8 | web addresses only (http, https, ipfs), in any order |
| Hosted sinks | never probed | agentverse.ai/v1/hosting/submit and /v1/submit: an answer proves the platform is up, not the agent. A registration whose only web endpoints are sinks stays at L4 |
| Probe cadence | every 6 h · 1,024 | a uniform random sample over the whole minted range, so new registrations are not over-weighted |
| Rank cadence | every 3 h | every bound wallet is swept for payments every three hours and every actor's rank recomputed after the sweep; 519 wallets ranked before the 27 September census are also pushed to us in real time by an address-activity webhook |
| Wallet binding | 2 methods | the registration's owner (ERC-721 ownerOf), or the agentWallet the registration file declares; each binding stores its method and evidence and closes when the registration changes hands (binding spec) |
Coverage verification — every publish passes the data checks
checks = 45 rules over payments, ranks, bindings, snapshots and series
block = 24 of them: one failure stops the publish # fail-closed since 9 Oct 2026
warn = published with the failing keys on /data-health
- The rank is checked against its evidence on every run: no agent at L7+ without a counted payment, no L9 without three counterparties, no L6 that no probe measured. The checks read the same ladder file as the rank job.
- The Base registration count is read two ways, day by day: from our own table of the registry's mints and from The Graph's Agent0 subgraph. A gap is a published warning, not a silent pick.
- A payment counts only after its transaction receipt is read: a transfer that is a routing hop inside a larger transaction is left out.
- Probe results are stored as a time series — status, latency, body hash, error class — never overwritten, so “endpoint responds” is auditable after the fact.
Today's results, every check with its failing keys: /data-health and /api/dq.
Reputation & volume hygiene
- Reputation feedback has no weight in the rank (see below). It is published as its own signal, with the share of feedback backed by a payment between the reviewer and the agent.
- Review campaigns (bursts from single-use wallets, one wallet reviewing one agent a hundred times a day) are logged as findings for a person to read, never used to rank.
- Payment value is published three ways, each with its own definition: everything counted (pay.usd.total.v1), what left the agents' control (pay.usd.leftcontrol.v1), and that net of money bridged back to the payer (pay.usd.leftcontrol.netbridge.v1), with what the counted total consists of (pay.composition.v1).
How the roster is ordered
The rank is sorted by exactly two keys, in this order, and there is no third:
- Liveness rung, descending. L9 above L8 above L7. The rung is the frozen ladder above — it is not a score and nothing is averaged into it.
- Observed payment value, descending, as a tie-break inside a rung.
That is the whole rule. It is deliberately dull, and the dullness is the point: a reader can reproduce our ordering from the API without trusting a weighting we chose.
The weighted score we planned, and did not ship
An earlier design blended several signals into one number — payment volume, counterparties, liveness, float, vault position, reputation, minus penalties for an open god-key flag or a sanctions hit. We built the measurements and then declined to build the blend, for two reasons.
The reputation term would have been the largest hole. We now read the ERC-8004 Reputation registry directly, and the shape of that data settles the argument: one vouching programme accounts for 69.6% of every feedback event on the registry, written by a few dozen addresses, and ten addresses account for 44.14% of all feedback from a pool of more than eleven thousand raters. A rank with a reputation weight in it would not have measured agents. It would have measured whoever runs the busiest vouching script — and it would have been trivially purchasable, which is the one property a rank must never have. Reputation is published as its own signal and given no weight here.
The rest of the blend hid its own assumptions. Any set of weights encodes a view about whether a wallet holding money matters more than a wallet spending it. We would rather publish both numbers, name each one, and let a reader form that view — than bury it in coefficients and call the output objective. Every input the blend would have used is already public and separately defined: observed value, counterparties, float, reputation. Anyone who wants a composite can build one from those and say what they weighted.
If a weighted score does ship later it will arrive as its own versioned definition, sitting beside the ladder rather than replacing it, and the ladder will keep meaning what it means today.
The address sets
Several published figures are computed over a set of addresses — which recipients count as an x402 rail, which contracts agent wallets delegate to, which addresses minted the registry. A claim like that is only checkable if you can see the set, so every one of them is published with its provenance and its true size. The wallet-set register →
Crawler ethics
We identify ourselves (AFG-Pulse/1, with a link to this page, so an operator who sees us in their logs can find out who we are and why). Each sampled registration gets one request per listed web endpoint per sweep; where it declares a protocol, at most one MCP initialize or up to three agent-card reads (the declared card, then the two well-known paths); and the ERC-8004 domain-proof file on at most two endpoint hosts. Nothing is retried. We never send a payment, call a tool or follow a link a page asks us to follow. We are calling other people’s agents; we act like a good counterparty — or our own liveness numbers would collapse into noise.
Reproducibility
Methodologies we build on and credit: maxguryanov/agent-registry-research (Base liveness crawl), the indexer-honesty notes of yaojin0609/erc-8004-liveness, and arXiv 2606.26028 (Can Trustless Agents Be Trusted?). Disagree with a threshold? Argue with us — the parameters table above is versioned for exactly that.