Daily measurement roots
Every UTC day, Agenstry computes a SHA-256 Merkle root over four classes of measurement we recorded that day. Anyone with read access to the same source rows on the same date can re-compute the same root. If our DB ever diverged from a published root, the discrepancy would surface in seconds.
Algorithm
- For each UTC day, collect rows from four append-only tables:
agents(live-probe snapshot perlast_seen_okin window),agent_card_snapshots(every card change),probe_runs(every probe),agent_revenue_snapshots(every per-window revenue settlement). - Hash each row into a 32-byte leaf using SHA-256 over a NUL-separated, domain-prefixed serialisation of its key columns. The prefix (
agent\0…,snapshot\0…, …) prevents cross-table collision. - Compute a Merkle root per sub-tree using the RFC-6962 odd-leaf-carry variant (no duplication — avoids the second-preimage attack on classic Merkle).
- Concatenate the four sub-roots in fixed order (
agents→snaps→probes→revenue) with their domain separator prefix, then Merkle-fold once more for the day's top-level root. - Persist the root, the row counts, and
computed_atintransparency_roots. The row is never updated; a mismatch on recompute is a flag, not a silent fix. - Coming next: publish the root onchain (Base contract
setRoot(date, root)) so even an attacker with DB write access cannot rewrite history. The schema'sonchain_anchor_*columns are already shaped for that path; today's column values are NULL.
Reproducibility kit
The reference implementation is at app/transparency.py. The JSON API at /api/transparency/daily-root.json returns the latest root + row counts; per-date lookup at /api/transparency/<date>.json (replace <date> with any ISO YYYY-MM-DD).
Published roots · last 30 days
| Date | Merkle root | Agents | Snaps | Probes | Revenue rows | Onchain anchor |
|---|---|---|---|---|---|---|
2026-05-21 |
acbb9d07c41d89eebb99257a… | 288 | 69 | 1,233 | 48 | DB only · onchain pending |
2026-05-20 |
3d9cb9979222aa9bf9a39e2e… | 136 | 77 | 8,553 | 0 | DB only · onchain pending |
Same data, machine-readable: /api/transparency/daily-root.json. Want to verify? Pull the source rows for a date via the federation feed (/api/feed/all.jsonl.gz), run the algorithm in app/transparency.py, compare the root you compute with the row above.