Daily measurement roots
Every UTC day, Agenstry computes a SHA-256 Merkle root over 5 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 5 append-only sources:
agent_day_states(an immutable end-of-day capture of each agent's graded columns — v1 and v2 dates read the liveagentstable instead, which is why they are replayed under their own version),agent_card_snapshots(every card change),probe_runs(every probe),agent_revenue_snapshots(every per-window revenue settlement), andagent_passports(every passport issued that day). - 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, which avoids the second-preimage attack on classic Merkle).
- Prefix each sub-root with its own label and a colon —
sha256(label + ":" + sub_root_hex)— then Merkle-fold those 5 hashes, in the fixed orderagents→snaps→probes→revenue→passports, for the day's top-level root. The order is append-only: a new tree kind goes on the end under a new version number, never inserted, or every prior root silently changes meaning. - Persist the root, the row counts,
computed_atand theroot_versionintransparency_roots. The row is never updated; a mismatch on recompute is a flag, not a silent fix. Today's version is3; every date is replayed under the version it was built with, and/api/transparency/<date>.jsonreports that version so you know which recipe to apply. - Anchor the root in Bitcoin with OpenTimestamps, so even an attacker with write access to our database cannot rewrite a published day. The timestamped value is the root itself: its 32 bytes, not a hash of its hex. We submit it to several public calendars, which fold it into a Bitcoin transaction within hours. A day reads pending until its proof carries a Bitcoin block attestation, and anchored in Bitcoin block N only after that attestation has been checked against the block header. A timestamp proves the root existed no later than that block. Roots computed before anchoring began were stamped later, so their block date is the day we stamped them, not the day they were computed.
Reproducibility kit
The reference implementation is the Algorithm section above —
that prose is the specification, which is what /api/transparency/daily-root.json
itself names as the source of truth (algorithm_url). The repository is private,
so a link into it would 404 for every reader.
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).
Verify an anchor yourself. Download a day's .ots proof from the table below and run
ots verify -d <merkle_root> agenstry-root-YYYY-MM-DD.ots with the OpenTimestamps client
(pip install opentimestamps-client), passing that day's full 64-character root as the digest. The client checks the proof against a Bitcoin node, so you rely on neither us nor the calendars.
A pending proof can be completed first with ots upgrade.
Published roots · last 30 days
| Date | Merkle root | Agents | Snaps | Probes | Revenue rows | Bitcoin anchor |
|---|---|---|---|---|---|---|
2026-10-05 |
aa02ebc7a8dac92f5f96c717… | 6,654 | 1,545 | 16,636 | 9,871 | Anchored in Bitcoin block 970104 2026-10-06 .ots proof |
2026-10-04 |
b1ea1129cc0b0f4d92363e74… | 6,796 | 1,163 | 23,805 | 9,795 | Anchored in Bitcoin block 969926 2026-10-05 .ots proof |
2026-10-03 |
8439aa4bd744787bcbe9d359… | 6,626 | 2,120 | 25,673 | 9,573 | Anchored in Bitcoin block 969783 2026-10-04 .ots proof |
2026-10-02 |
4f04e289692b2879f379de01… | 6,130 | 1,438 | 23,347 | 9,427 | Anchored in Bitcoin block 969655 2026-10-03 .ots proof |
2026-10-01 |
295c62faa581a59eae069ce8… | 6,403 | 1,431 | 6,811 | 9,136 | Anchored in Bitcoin block 969508 2026-10-02 .ots proof |
2026-09-30 |
e50845323a1f2bc00e56d22e… | 5,622 | 473 | 3,929 | 8,578 | Anchored in Bitcoin block 969451 2026-10-01 .ots proof |
2026-09-29 |
e059b01fcaf05ccfa3772853… | 5,460 | 751 | 6,017 | 8,500 | Anchored in Bitcoin block 969451 2026-10-01 .ots proof |
2026-09-28 |
34d3a53c64dc3083a3e18b19… | 5,246 | 714 | 5,289 | 8,417 | Anchored in Bitcoin block 969451 2026-10-01 .ots proof |
2026-09-27 |
69bd226d8f7315de38f5c818… | 5,069 | 669 | 4,813 | 8,367 | Anchored in Bitcoin block 969451 2026-10-01 .ots proof |
2026-09-26 |
1596abb96a575a7ef8c16856… | 4,582 | 819 | 6,744 | 8,102 | Anchored in Bitcoin block 969451 2026-10-01 .ots proof |
2026-09-25 |
bf61060bb8dc895c19c736f5… | 5,107 | 596 | 4,258 | 7,680 | Anchored in Bitcoin block 969451 2026-10-01 .ots proof |
2026-09-24 |
15330afbebbc7c3cb1ab2b72… | 5,129 | 835 | 5,444 | 7,327 | Anchored in Bitcoin block 969451 2026-10-01 .ots proof |
2026-09-23 |
b8b15dc684ffb9be2ef53403… | 5,280 | 627 | 5,469 | 6,704 | Anchored in Bitcoin block 969451 2026-10-01 .ots proof |
2026-09-22 |
55ec4b0a2beb106cc4d84406… | 5,068 | 786 | 6,591 | 29 | Anchored in Bitcoin block 969451 2026-10-01 .ots proof |
2026-09-21 |
1eb811eedfd83489dfd9b422… | 2,300 | 815 | 6,525 | 30 | Anchored in Bitcoin block 969451 2026-10-01 .ots proof |
2026-09-20 |
a08a14f5ba5863413e77b380… | 4,935 | 711 | 5,498 | 6,599 | Anchored in Bitcoin block 969451 2026-10-01 .ots proof |
2026-09-19 |
63a687e998e66139277ec965… | 4,933 | 710 | 5,599 | 6,530 | Anchored in Bitcoin block 969451 2026-10-01 .ots proof |
2026-09-18 |
bfe1dc09afa340c64db6550f… | 4,931 | 863 | 6,665 | 6,526 | Anchored in Bitcoin block 969451 2026-10-01 .ots proof |
2026-09-17 |
0a431bac3978f732d93fe324… | 5,115 | 880 | 6,191 | 6,522 | Anchored in Bitcoin block 969451 2026-10-01 .ots proof |
2026-09-16 |
9b606e5d24763ac4a405d6ee… | 5,030 | 445 | 3,891 | 6,522 | Anchored in Bitcoin block 969451 2026-10-01 .ots proof |
2026-09-15 |
7db7cabb9b0dd337eb3770ef… | 1,504 | 795 | 6,330 | 12 | Anchored in Bitcoin block 969451 2026-10-01 .ots proof |
2026-09-14 |
a9b56551de21330919156d5b… | 5,152 | 648 | 5,496 | 6,506 | Anchored in Bitcoin block 969451 2026-10-01 .ots proof |
2026-09-13 |
17572b4eca1ac0b8b485ee3d… | 4,981 | 781 | 6,174 | 6,492 | Anchored in Bitcoin block 969451 2026-10-01 .ots proof |
2026-09-12 |
d6986b54a93ceab86acd1f11… | 5,212 | 864 | 6,694 | 6,488 | Anchored in Bitcoin block 969451 2026-10-01 .ots proof |
2026-09-11 |
85fe6a74fd86004af5b9018f… | 5,158 | 946 | 6,697 | 6,476 | Anchored in Bitcoin block 969451 2026-10-01 .ots proof |
2026-09-10 |
40b49b24ad1c620103c08318… | 4,917 | 728 | 5,131 | 6,476 | Anchored in Bitcoin block 969471 2026-10-01 .ots proof |
2026-09-09 |
453d37920101ae73bbeb5697… | 5,322 | 823 | 5,634 | 6,476 | Anchored in Bitcoin block 969471 2026-10-01 .ots proof |
2026-09-08 |
f05ce6c99a547d2c913bc583… | 4,752 | 535 | 3,910 | 6,468 | Anchored in Bitcoin block 969471 2026-10-01 .ots proof |
2026-09-07 |
9d7cce66b006bfde9e4dfcb6… | 4,812 | 715 | 5,067 | 6,392 | Anchored in Bitcoin block 969471 2026-10-01 .ots proof |
2026-09-06 |
b4a39b3594fd5dcb0ffff261… | 4,819 | 708 | 5,245 | 6,352 | Anchored in Bitcoin block 969471 2026-10-01 .ots proof |
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 specified above, compare the root you compute with the row above.