CrawlCheck
Proof

Proof an agent can check without trusting us.

An agent that acts on what CrawlCheck measured should not have to take our word for it. Every report is fingerprinted and each day anchored to Bitcoin; every answer an agent acts on is signed; every signed answer is entered in a log that a witness we run on GitHub, outside our servers, re-checks. Each of the three is checked on the reader’s own machine.

Proves

A report with this digest existed in exactly this form by that day, and has not been edited since.

Does not prove

That the measurement was correct. Only the first claim can be settled by mathematics.

91

sealed days

2,154

reports under this root

#972,685

bitcoin block

Three proofs

What each record proves, and how to check it

Each check runs on the reader’s own machine, from files that are published and can be kept.

1 · Reports

Sealed and anchored to Bitcoin

Each report’s measurements are hashed; each day’s hashes become one root, committed to a Bitcoin block through OpenTimestamps.

Proves the report existed in exactly this form by that day.

The latest sealHow it is built

2 · Answers

Signed with Ed25519

Every Resolve answer an agent receives before it reads, cites, connects or transacts carries a signature over its canonical content.

Proves the answer came from CrawlCheck and was not altered in transit or afterwards.

The signing keysThe offline verifierWhat an answer holds

3 · History

Logged, chained and witnessed

Every signed answer names its leaf in an append-only Merkle log. Each signed tree head chains to the one before, and a witness we run on GitHub, outside our servers, re-checks and co-signs it. It is our own workflow: it proves the log was not rewritten on our servers, not that an independent party checked it.

Proves an answer was not rewritten or removed after it was logged.

The log headThe latest witness

Method

How a report becomes a proof

No wallet, no fee, no key held by us. The proof is a file, not a coin.

1Reportmeasurements only2SHA-256one digest3Merkle rootone per day4OpenTimestampstwo calendars5Bitcoin blockpermanent
  1. 1

    Measurements only

    Host, timestamp, section scores, every path and status fetched, every crawler identity and what it received, the citation state. Wording and layout are excluded, so an editorial change never breaks a proof.

  2. 2

    One digest

    Canonicalised with sorted keys and hashed with SHA-256.

  3. 3

    One root a day

    Digests sorted and folded into a Merkle tree: parent = SHA256(left || right), an odd node paired with itself. Arrival order cannot change the root.

  4. 4

    Anchored

    The root goes to the OpenTimestamps calendars, which commit it into a Bitcoin transaction.

The seal

2026-10-22

Confirmed in Bitcoin block #972,685.

Merkle root
769f84e007a3043e0faf74c7d6a4b470edab64a77329cb47489a48c62bd317c5
Reports covered
2154
Sealed
2026-10-23T01:17:38.617Z
Calendars
https://a.pool.opentimestamps.org
https://b.pool.opentimestamps.org
Bitcoin
block #972,685

Download the .ots proofOne report’s receipt as a single file →

Verify it yourself

ots verify -d 769f84e007a3043e0faf74c7d6a4b470edab64a77329cb47489a48c62bd317c5 crawlcheck-2026-10-22.ots

The reference client checks the file against a Bitcoin node or a public calendar. No CrawlCheck server is needed, or trusted. A fresh seal reads pending confirmation until the next Bitcoin transaction confirms; ots upgrade then stores the block attestation in the file for good.

Ledger

Every sealed day

91 days anchored. Each links to its own root and proof file. Days are sealed once and never recomputed.

The 2154 digests sealed under this root

All 2,154 digests as plain text, one per line; the first 20:

00696d35e400ea947eea1c84b4041c997fb7244281e749ae0b770134557eb7c1
007a8e223ebd755a94262c4a961aade317d0946819559cd32c0b1143675bddc6
007b838cd3e7cbde5127ef3270447de2eb0b57a699f80257b8d38c19d88fa44b
009e7565e1447c023467ab035feed1ddbaf5a07f62dee305b224057332110df0
00b9e47f5ed806480a1519acc3799ac862118dd04a059c3aeeb47969c805b7f5
013e447f1a25da2dd292b7d7d8c39061f744b69d8745b33a6bcc371a778dcb01
0148351877ed9e6ace6028fcc310490fe6d131d2383d1da94d664aed7ce3550e
017240bdf09e2dd13ac576085852cf13e572a1c91f77311e87a180c2892f89b4
017fe50685113fa692d45de1fbc2ebdc67cc681ff0b4af2e02bc701c6e74fbb7
01958e60d410d6b9ac9b353c5decbfb6ee4b635333b30a7a4d0953bd217b58f9
01a4ce98e43bf2834e0a5ea3ed7bf2f4ef7edfb3174766a5f8b333cbfb2e4f34
01c67fe1ad76a647fe31113ce9d7d4d19e8c8d2725d8186f6692c795922e6cbb
01c8ec3df2d7a9fd57809d86da3be5b5f462d4b814f8f503e4cad6b0891216fd
02448c8c05fc21b19dfb7c7ab4ca1b86d848e819e3e396a72d4ebc53b84c1d0f
026384a6d8c48dbfab9586b5f4076950fc080d6102b51175c5ae59deb1d4675a
026414af93b8ee069bc0787cc6c8110b496350b567105d02f628596d90b408bf
02939e9c33122d70252de49132bdd1d684d1274b74a7b8a72fbed3d419ef8c23
029bf605249e89b95bc89370ad551797c823123831b02262df67b8061fa95e70
02ac294e62d10a4557bd7c5c2e5ca436c65a508034d658379d5bfb54308255d4
02ac3f9e89f4d2e12551e9edc8ae0a4df26f3a9b5d62f1c9a0c59c6f6db47b49

Questions about this page

QWhat does the Bitcoin anchor prove?
That a report with exactly this digest existed no later than the anchored block, and that it has not been edited since. It is a proof about time and integrity, not about correctness.
QHow do I verify a report myself?
Download the day’s .ots proof from this page, recompute the report digest from its JSON record, and verify the proof with the OpenTimestamps client against a Bitcoin node or public calendar. No CrawlCheck server is needed for the check.
QWhy exclude wording and layout from the hash?
So an editorial change never invalidates a measurement. Only the measured fields are hashed; the words around them can be improved without the proof breaking.
QWhich days are anchored?
Every sealed day is listed on this page with its digest and proof file. Days are sealed once, after they end, and never recomputed. A day sealed within the last day or so reads as pending in the reference client: the calendar holds the commitment, and the Bitcoin block confirming it is usually mined within 24 hours. The proof file here is upgraded to carry that block header once it exists, so a pending file is a proof waiting on a block, not a missing seal.