# Coverage and confidence

Know how much of the chain Roundhouse sees, and which published figures are exact.

Section: The data layer
Source: https://www.roundhouse.studio/docs/data/coverage-and-confidence

---

Two separate questions decide what a figure here is worth: **coverage** (did we see it?) and
**confidence** (is it what we think it is?). Blending them produces numbers that look authoritative
and are not.

This page is what to believe.

## Confidence: is this row really an x402 payment?

`verified_x402` is three-valued, and the three are genuinely different claims:

| Value | Claim | Evidence |
| --- | --- | --- |
| `true` | This was an x402 settlement | An EIP-3009 `AuthorizationUsed` log in the transaction receipt |
| `null` | Unexamined | Matched a catalogued `payTo`; heuristic confidence is low — usually *probably not* |
| `false` | **Disproven** | Examined, and it was a plain transfer, not an authorized payment |

The `true` case is the only one with proof. A USDC transfer to a known service wallet is *evidence*
of a payment; the EIP-3009 marker is *proof* that the transfer went through an authorization rather
than a plain `transfer()` call.

```sql
-- Say what you mean.
select count(*) from settlements
where payee = lower('0x…') and verified_x402
```

> [!WARNING]
> `mv_entity_rollups` — and therefore every lifetime figure on a profile page —
> **sums all three values.** The pages that use it say so. When a number needs to
> mean *proven*, compute it yourself with the filter above. Fixing the rollups
> needs new matview columns, and it is known outstanding work rather than a
> subtlety we are hiding.

[`/stats`](https://www.roundhouse.studio/stats) leads with the verified population and discloses the rest in words. The splits
reconcile exactly against the blended totals, so the view is a decomposition rather than a competing
number.

## Coverage: did we see it?

Capture runs continuously against each supported chain, with a cursor per chain. Three mechanisms keep
it honest, and they check different directions:

**The reorg sweep** asks *"do we hold rows the chain no longer has?"* and deletes them. Base's
finality depth is set to 2 confirmations, which is only safe because the 24 blocks behind the cursor
are re-verified every run. Settlements are immutable and duplicate inserts are ignored, so a row for a
reorged-out block cannot be fixed by re-ingesting — it has to be removed.

**The continuity audit** asks the mirror-image question: *"does the chain have settlements we do not
hold?"* and queues the range for repair. It compares distinct transactions rather than rows, because a
batch relay is one transaction with several settlements and a fee-proxy collapse is two legs folded
into one row. It is deliberately conservative: an empty marker set is treated as *no information*, not
as an empty chain.

**Gap repair** drains the queue through the same path a live settlement takes — marker-verified,
collapsed, attributed. A recovered settlement is not a lower-grade row.

Between them, the chain arbitrates our record in both directions.

## What `/status` tells you

[`/status`](https://www.roundhouse.studio/status) is the honest surface, and its verdict reads the whole page rather than just
reachability:

| Signal | Means |
| --- | --- |
| Capture lag per chain | How far behind the tip we are |
| Open gaps | Ranges the audit found and repair has not yet drained |
| Gap count `null` | **The ledger was unreadable** — never "no gaps" |
| Rollup staleness | How old the pre-computed aggregates are |
| Service freshness | When the catalog was last crawled and enriched |

Open gaps existing is not an incident: the audit finds, repair drains, that is the system working.
What is worth alerting on is a range repair gave up on, or one nothing is draining.

Note the asymmetry: capture can be at the tip with a hole behind it, so **lag does not imply
completeness**. That is exactly why the gap count is published separately.

## Figures that are exact, and figures that are floors

| Figure | Status | Why |
| --- | --- | --- |
| Settlement counts over a bounded range | **Exact** | Counted directly from an index range |
| Settled volume, anywhere | **A floor** | `amount_usd` is `NULL` for unpriced tokens |
| Distinct payers / payees | Exact for what is indexed | Bounded by coverage, not by pricing |
| Per-entity lifetime totals | Blended confidence | Sums `true`, `null` and `false` |
| Service listing counts | Exact matched count | From a counting query, not a fetch window |
| "Nobody has paid this" | **Not assertable** | Absence of a row is not proof of absence |

Two habits behind those rows:

- **A price is never guessed.** A `NULL` `usd_rate` means captured-but-unpriced. So a count and a sum
  are computed over different populations, and `/stats` states the unpriced count.
- **A fetch window is not a dataset.** A list that reads 600 rows must not print "600" as a total —
  the directory shows an exact matched count from a counting query and cites the indexed total
  separately.

## What is not indexed

- **Chains we do not observe.** Coverage is Base and Base Sepolia today. A payment elsewhere is
  invisible here, and its absence says nothing about the counterparty.
- **Off-chain payments.** Invoices, cards, credits. Not our ledger.
- **Testnet as economic activity.** Base Sepolia settlements are indexed but are not real volume.
- **Anything private.** There is no private tier of the dataset; paid tiers buy rate limit, not
  access.

## Reading a number responsibly

Three questions, and the answers are all above:

1. **Is it filtered on confidence?** If not, it blends proven with unexamined.
2. **Is it a count or a sum?** Sums are floors, because unpriced rows are absent from them.
3. **Is the coverage window clean?** Check [`/status`](https://www.roundhouse.studio/status) for open gaps in the range you care
   about.

Answering those three is the difference between a figure you can publish and a figure that is
approximately right.

## Next steps

- [The data model](https://www.roundhouse.studio/docs/data/data-model) — the columns behind these
- [SQL over the index](https://www.roundhouse.studio/docs/data/sql) — computing it yourself
- [Platform status](https://www.roundhouse.studio/status) — live coverage

---

Every page in these docs is available as markdown at its own URL plus `.md`.
Full index: https://www.roundhouse.studio/docs.md
