# METHOD — ERC-8004 tokenURI resolvability (hop H2), 2026-09-02

Companion to `dataset.csv`, `dataset.jsonld`, `DATA-DICTIONARY.md`, and the
raw JSON at
`https://onchainagentintel.io/data/tokenuri_resolvability.json`. Documents
what was probed, how the eligible population was built, how the sample was
drawn, the pre-pinned usable-card rule, and the fixed bucket set.

## What this measures

For every indexed ERC-8004 agent whose on-chain `tokenURI` resolves to an
HTTP(S) URL, whether that URL answers hop H2 with a parseable
JSON-object body that satisfies a usable-card schema check. Chains:
Base (`chain_id` 8453) and Ethereum mainnet (`chain_id` 1). Per-chain
sample `n=600`, pooled sample `n=1200`.

**This measures schema shape and HTTP resolvability at probe time, not
agent quality, ranking, or score.** No agent is scored, ranked, or
bucketed by this dataset. Readiness / Trust scoring and the published
methodology are unchanged.

## Source

- Raw JSON (publicly served): `https://onchainagentintel.io/data/tokenuri_resolvability.json`.

## Eligible population

Values lifted verbatim from the raw JSON `corpus` block:

| Field | Value |
|---|---|
| `corpus.source_dir` | local working directory of the Ethereum agent-profile store (path not published) |
| `corpus.files_read` | `324` |
| `corpus.raw_lines_with_nonempty_uri` | `25964` |
| `corpus.eligible_after_dedup_per_chain.base` | `22807` |
| `corpus.eligible_after_dedup_per_chain.ethereum` | `2827` |

The eligible population is the set of indexed ERC-8004 agents whose
captured `tokenURI` string is non-empty, after per-chain deduplication.
Agents with empty / missing `tokenURI` are not in the frame; agents with
a `tokenURI` that fails URI parsing are kept in-frame and land in the
`bad_scheme_or_unparseable_uri` bucket at probe time.

## Sampling

- `seed`: `415` (fixed PRNG seed for reproducibility).
- `n_per_chain_target`: `600`.
- `actual_draw_n` / `realized_n`: `600` on both chains → pooled `n=1200`.
- `truncated`: `false` (no cap bite).

A simple random sample without replacement, drawn from each chain's
eligible population independently.

## Probe window and parameters

| Parameter | Value |
|---|---|
| `measured_at` | `2026-09-02T20:06:20Z` |
| `wall_clock_cap_s` | `720` |
| `elapsed_s` | `310.35` |
| `global_rate_per_sec` | `4` |
| `per_host_concurrency` | `1` |
| `timeout_s` | `10` |
| `user_agent` | `AgentZero/0415-h2measure (+https://onchainagentintel.io research probe)` |

This is an **observational, one-shot probe**. One unauthenticated request
per sampled agent at hop H2. No authentication, no payment, no retries,
no state mutation.

## Usable-card definition (pinned before probing)

The `usable_card_definition` was pinned before any probe was issued,
exactly as follows (verbatim from the raw JSON):

```
requires:
  - JSON object at top level
  - non-empty top-level `name` string
  - at least one of: url, endpoint, serviceEndpoint, serviceEndpoints,
    services, capabilities, skills
pinned_before_probing: true
```

A response counts as a **usable card** when it satisfies all three
pre-conditions. A response that returns a parseable JSON object at the
top level but fails one or more pre-conditions is counted as
`json_but_not_a_card` and listed as a near-miss shape example.

## Buckets (9, defined before probing)

Each sampled agent's hop-H2 response is placed into exactly one of these
9 buckets, defined before the probe ran:

| # | Bucket | Short meaning |
|---:|---|---|
| 1 | `ok_json` | HTTP 2xx with a parseable JSON body (card or non-card). |
| 2 | `non_json_body` | HTTP 2xx with a body that failed JSON parse. |
| 3 | `empty_body` | HTTP 2xx with zero-length body. |
| 4 | `http_4xx` | HTTP 4xx response. |
| 5 | `http_5xx` | HTTP 5xx response. |
| 6 | `dns_or_conn_fail` | DNS or TCP connection failure. |
| 7 | `timeout` | Request did not complete within `timeout_s` (10s). |
| 8 | `ipfs_gateway_fail` | IPFS gateway returned a non-2xx or non-JSON. |
| 9 | `bad_scheme_or_unparseable_uri` | `tokenURI` string failed URI parsing or carried an unsupported scheme. |

`resolve_rate` counts `ok_json` as a success (any parseable JSON body);
`usable_card_rate` tightens that to the pinned usable-card rule.

## Confidence intervals

95% Wilson confidence intervals, computed on each per-chain and pooled
rate from the realized sample size. The CI bounds are stored verbatim in
the raw JSON (`resolve_rate.{lo,hi}`, `usable_card_rate.{lo,hi}`); the CSV
mirrors them without rounding.

## Headline table

Lifted verbatim from the raw JSON `per_chain` and `pooled` blocks:

| Scope | Metric | Point | 95% CI (lo–hi) | n |
|---|---|---:|---|---:|
| Base | `resolve_rate` | 0.6817 | 0.6433–0.7177 | 600 |
| Base | `usable_card_rate` | 0.5633 | 0.5234–0.6025 | 600 |
| Ethereum | `resolve_rate` | 0.7483 | 0.7121–0.7814 | 600 |
| Ethereum | `usable_card_rate` | 0.7133 | 0.6759–0.7481 | 600 |
| Pooled | `resolve_rate` | 0.7150 | 0.6888–0.7398 | 1200 |
| Pooled | `usable_card_rate` | 0.6383 | 0.6107–0.6650 | 1200 |

## Near-miss shape examples

The raw JSON lists three near-miss shape examples per chain
(`per_chain.<chain>.near_miss_shape_examples`). Each example is the set
of top-level JSON keys from an `ok_json` response that failed the
usable-card rule — a diagnostic listing of the fields present, nothing
more. No per-agent id, wallet, or ENS name is attached.

## What this is NOT

- **Not an endorsement, score, or ranking.** The agent's `tokenURI` was
  fetched once at the probe instant; nothing more.
- **Not a liveness guarantee.** We did not re-probe for transient
  timeouts, DNS, or TLS edge cases. An endpoint that returned a
  non-usable bucket at `measured_at` may be fine today, and vice versa.
- **Not a payment outcome.** This probe never paid.
- **Not a methodology change.** The usable-card rule is a schema check
  pinned before probing, not a scoring, ranking, or bucket-threshold
  change. No agent is scored by this dataset.
- **Not aggregated into Agent Zero's scoring pipeline.** Scoring and
  the published methodology remain unchanged.

## Reproducing a sampled row

Given the fixed `seed=415`, the eligible-population dedup rule, and the
per-chain sample size `n_per_chain_target=600`, the sample draw is
deterministic. For each drawn `tokenURI`:

1. Issue one unauthenticated HTTP(S) GET with
   `User-Agent: AgentZero/0415-h2measure (+https://onchainagentintel.io research probe)`,
   `timeout_s=10`, no retries.
2. Place the response into exactly one of the 9 buckets.
3. If `ok_json`, apply the pinned `usable_card_definition` and classify
   `usable_card` vs `json_but_not_a_card`.

Everything downstream — the per-chain / pooled aggregates, the Wilson
CIs, and the top-host-by-bucket summaries — is derived from these raw
classifications.

## License

[Creative Commons Attribution 4.0 International (CC BY 4.0)](https://creativecommons.org/licenses/by/4.0/).
Free to reuse, remix, and redistribute — including commercially — with
attribution.

> On-Chain Agent Intel (2026). ERC-8004 tokenURI resolvability (hop H2), 2026-09-02. CC BY 4.0. https://onchainagentintel.io/data/tokenuri-resolvability-2026-09-02/
