Integrity & storage
PartialExact, or not served
Scripture data that can be quietly altered is worse than none. Every verse carries a hash, the whole corpus rolls up to one root, and any agent can check both without trusting this server.
Per-verse hashes
sha256 on every verse object is the hash of the UTF-8 string {source}|{ref}|{text}. Binding the source id and the reference into the hash means a verse cannot be moved to another address, or another edition, without the hash changing.
Merkle root
Verse hashes are ordered canonically (book, chapter, verse), paired and hashed upward to a single root. The root is published in /.well-known/harness.json and /api/v1/sources. It changes only if the text changes, which is the point.
corpus kjv-1611
verses 31,102
leaf sha256(`${bookId}.${chapter}.${verse}\n${text}`)
merkleRoot e33985722301b534baa052a9c9f74db965abbee4deb8b2f70c96cd7bd693f2beLiveVerify locally
Recompute a verse hash yourself; the harness client does this in verify().
v=$(curl -s https://harness.talk/api/v1/verses/jn.3.16)
printf '%s|%s|%s' "$(jq -r .source <<<"$v")" "$(jq -r .ref <<<"$v")" "$(jq -r .text <<<"$v")" | sha256sum
jq -r .sha256 <<<"$v" # must matchTake the corpus with you
/exports/kjv.jsonl.gz is one verse per line — the same objects the API returns, same hashes — so an agent can go fully offline. harnessd serves from this file. Nothing here requires our server to keep existing.
Decentralized distribution
Pinning the export to IPFS and mirroring across dVPN exits makes the corpus reachable when any single host is not. The Merkle root is what makes a mirror trustworthy: fetch from anywhere, check against the root you already hold.
- IPFS CID of each export published alongside the Merkle root.
- Mirror manifest listing known-good origins, signed.
- Client fallback order: local harnessd → configured mirrors → this site.
Audit trail
The ingestion report (data/kjv/BUILD-REPORT.md) lists every line the parser had to resolve — page headers dropped mid-verse, inline verse markers split, caps fragments kept as text — so the path from the published edition to each JSON verse is inspectable. Build fails if the counts (66 / 1,189 / 31,102) or the spot-checked verses do not match.