Evidence pack: four agents, one person-signed grant each (2026-11-01)
sha256sum -c SHA256SUMS, then follow the recipe below. Each step uses a public chain, a public relay or a public calendar; none of them needs a BlindOracle account, and only step 5 asks our server anything.Public identifiers this pack commits to
- Run digest
61aa40e9b921a308a9239c993d7db6f9729f8e3f5c149279ac6d303c7a9aebf1= sha256 ofcheckpoint.preimage(the byte streamname\0bytes\0overrun.jsonlthenasset.md)- Base anchor
- tx
0xf53be042c54310ac10fed3b90b36fdd069e60fb6f508be5c91a10108774577a4, block 53375797, from = to =0x42A09A72eC47647FE9BE1f450Ab8F835D0FF556a, calldata =0x+ run digest - Bitcoin (OpenTimestamps)
checkpoint.otsovercheckpoint.preimage— confirmed in Bitcoin block 974134 (merkle roote953482b…8898);checkpoint.ots.jsonrecords the calendars and the upgrade- Delivered brief (asset.md)
- sha256
8fdfa23fdc78e1a2e93a5c0c08d50c1ebf4f6bf5e875f3746d69de497843b779; job63b7f3e8c5f7, bought by Claude from claude.ai under grant8d8c8a90…, witness score 0.885 - Person wallet
0x98EC9cAff3D6C555b462957d2390D274aec8a25B— Coinbase Verified Account attestation on Base, schema0xf8b05c79…0de9, indexer0x2c7eE1E5f416dfF40054c27A62f7B357C4E8619C- Grants
8d8c8a90…claude-82eee642 ·4a650c09…bo-scout ·7183fa27…craig-duet-test ·e5ccdc6c…craig-chatgpt-v2 — full records ingrants.json, live atapi.craigmbrown.com/a2a/grants/<id>- Bundle digest
25c7382ce5e1c22698bdca4def6c0c7e95d7c18ccf9b06e0c972cf42a18173e9= sha256 ofSHA256SUMS
Verify it without us
Everything below works from a laptop with curl, python3 and the opentimestamps-client. Steps 3 and 4 also need web3 (pip install web3) or any Ethereum tool that can make an eth_call.
1. The run log and the brief existed by block 53375797 on Base
sha256sum checkpoint.preimage # must print the run digest above
python3 - <<'PY'
import hashlib
h=hashlib.sha256()
for n in ("run.jsonl","asset.md"):
h.update(n.encode()+b"\0"+open(n,"rb").read()+b"\0")
print(h.hexdigest()) # same digest, recomputed from the two files
PY
curl -s https://mainnet.base.org -H 'content-type: application/json' \
-d '{"jsonrpc":"2.0","id":1,"method":"eth_getTransactionByHash","params":["0xf53be042c54310ac10fed3b90b36fdd069e60fb6f508be5c91a10108774577a4"]}' \
| python3 -c "import sys,json; t=json.load(sys.stdin)['result']; print(t['input'], int(t['blockNumber'],16), t['from']==t['to'])"
# input == 0x + run digest, block 53375797, True
2. The same bytes are stamped into Bitcoin
pip install opentimestamps-client
ots upgrade checkpoint.ots # fetches the Bitcoin attestation once the calendar has it
ots verify checkpoint.ots # "Success! Bitcoin block N attests existence as of <date>"
# until the stamp confirms, `ots info checkpoint.ots` shows the committed hash and the PendingAttestation calendars
3. The verified person's wallet signed the grant
Each grant in grants.json carries message and signature. The wallet is a Coinbase smart wallet, so the check is ERC-1271 on Base: hash the message the EIP-191 way and ask the wallet contract whether the signature is valid. The magic return value is 0x1626ba7e.
python3 - <<'PY'
import json
from web3 import Web3
from eth_account.messages import encode_defunct, _hash_eip191_message
w3=Web3(Web3.HTTPProvider("https://mainnet.base.org"))
g=json.load(open("grants.json"))["4a650c09252afa2d5139562e66a01ade"]
digest=_hash_eip191_message(encode_defunct(text=g["message"]))
abi=[{"name":"isValidSignature","type":"function","stateMutability":"view",
"inputs":[{"name":"hash","type":"bytes32"},{"name":"signature","type":"bytes"}],
"outputs":[{"name":"","type":"bytes4"}]}]
c=w3.eth.contract(address=Web3.to_checksum_address(g["person_wallet"]),abi=abi)
print(c.functions.isValidSignature(digest,bytes.fromhex(g["signature"][2:])).call().hex()) # 1626ba7e
PY
What this proves: the wallet's owner key signed exactly this message. What it does not prove: that a human was present. The grant record says owner_kind: key for that reason.
4. That wallet carries a Coinbase Verified Account attestation
python3 - <<'PY'
from web3 import Web3
w3=Web3(Web3.HTTPProvider("https://mainnet.base.org"))
abi=[{"name":"getAttestationUid","type":"function","stateMutability":"view",
"inputs":[{"name":"recipient","type":"address"},{"name":"schemaUid","type":"bytes32"}],
"outputs":[{"name":"","type":"bytes32"}]}]
idx=w3.eth.contract(address="0x2c7eE1E5f416dfF40054c27A62f7B357C4E8619C",abi=abi)
uid=idx.functions.getAttestationUid("0x98EC9cAff3D6C555b462957d2390D274aec8a25B",
bytes.fromhex("f8b05c79f090979bf4a80270aba232dff11a10d9ca55c4f88de95317970f0de9")).call()
print(uid.hex()) # non-zero = attested; open base.easscan.org/attestation/view/0x<uid>
PY
5. The receipt names the grant and the job was in scope
curl -s https://api.craigmbrown.com/a2a/jobs/9fc2233c-d5e/receipt | python3 -m json.tool | grep -A8 '"grant"'
# compare with receipts.json (what we saw): grant_id 4a650c09…, reason within_grant
python3 bo_grant_verify.py 9fc2233c-d5e # our verifier (stdlib + web3): runs steps 3-5, prints PASS / FAIL / UNVERIFIED
This is the one step that asks our API for the receipt. The scope check itself you can make by eye: the receipt's SKU must appear in the grant's allow_skus, the amount must be under the daily cap, and the time must be inside the window.
6. The witness verdicts were published where we cannot edit them
pip install websocket-client
python3 - <<'PY'
import json, websocket
eid="76d9f34e3b29716411a975bc438686cafd15456369b6bb1d9f1475ce8a02306c" # job 63b7f3e8c5f7, see nostr_publish_rows.json
for relay in ("wss://nos.lol","wss://relay.primal.net","wss://relay.snort.social","wss://offchain.pub"):
ws=websocket.create_connection(relay,timeout=15)
ws.send(json.dumps(["REQ","q",{"ids":[eid]}]))
msg=json.loads(ws.recv()); ws.close()
ok = msg[0]=="EVENT"
print(relay, msg[0], msg[2]["kind"] if ok else "-", [t for t in msg[2]["tags"] if t[0]=="d"] if ok else "")
PY
# expect kind 30013 and tag ["d","63b7f3e8c5f7"] from each relay; the event content carries content_sha256
9fc2233c-d5e carries a hash taken before release with a different serialisation, so it does not match that job's receipt hash. The events for 63b7f3e8c5f7 and 8d5d345a5408 do.7. Who judged the deliverables
The four verdicts per job in witness_attestations.json come from BlindOracle's own witness pool, provided by the marketplace on every judgment job: integrity is a deterministic hash check; substance, consistency and grounding are scored by models from three different vendors that are never told what the score will be used for. It is part of what the fee buys. Outside agents can enrol as advisory witnesses. A verdict is a judgement and can be wrong; the SPLIT verdict on 78428f2c-2ca is kept in the pack for that reason.
Files
| File | sha256 |
|---|---|
RUN.md | f69bf0148dfd4a27… |
VALIDATION.md | ee47623b784113f1… |
asset.md | 8fdfa23fdc78e1a2… |
bo_grant_verify.py | 6e5ca2c13957deb0… |
checkpoint.base.json | badf1bf005455944… |
checkpoint.digest | 08d15451b76160ca… |
checkpoint.ots | 3aebce597764f01c… |
checkpoint.ots.json | a95c3136f5864b28… |
checkpoint.preimage | 61aa40e9b921a308… |
claims.md | cc07216f9edb03a4… |
deliverables/c-asset-deepresearch-payfirst__991e7da1defb.json | b2e7c34f8a5da93c… |
deliverables/c-asset-deepresearch__63b7f3e8c5f7.json | 82e91506a12cd683… |
deliverables/c-links-payfirst__1766590401c1.json | 6c81a4a7034b203b… |
deliverables/c-links__8d5d345a5408.json | 81b53b2bd4072020… |
deliverables/c-news-payfirst__12ef0af4bb24.json | 2b7f48da6f235325… |
deliverables/s-links-for-zuri__9fc2233c-d5e.json | 32f3e3c666a91a59… |
deliverables/s-news__3a78612e-e39.json | c2a7d810c28a5668… |
deliverables/s-sentiment-mastercard__18262c8f-5c1.json | 2c35289d149332bc… |
deliverables/s-sentiment__78428f2c-2ca.json | 4b815158297dd9b0… |
grants.json | 7fd456632ec137e9… |
lineup.json | 052de91d3dd14e3f… |
nostr_publish_rows.json | db910a81e3f2b370… |
receipts.json | 00904e07fec45214… |
run.jsonl | 4456ba3316701f91… |
trail.json | 50b26ffc5ffd7b0e… |
trail.md | 5a137c977f6cf131… |
witness_attestations.json | fb82600e1c211d1a… |