The honesty ledger
Receipts, not promises.
House rule since day one: nothing is claimed until it has run, and the worst days get published with the best ones. This page is the ledger — dated, in order, with the exact hashes and the steps to check them. If an entry says measured, there is a log behind it. If something is still a plan, we say "plan."
Clean-slate design — and a live 4-validator BFT chain the same night
Architecture locked in the morning (pure hash-based signatures, shielded-by-default, consensus-enforced mandates, sovereign L1 on vendored Malachite). By night, a 4-validator chain was committing blocks. No months of stealth: the chain existed on day one.
Consensus refused an overspend — and went fully hash-based
The reference storyline ran as real on-chain transactions: an org funded a MandateTree, agents spent within budget, and a rogue agent's overspend came back rejected: mandate: insufficient buffer at depth 1 from leaf — from the state machine, not an app. The same day, every consensus vote switched to LMS/HSS hash signatures under SLH-DSA roots, and a validator rotated its signing key mid-chain with zero downtime.
Shielded pool live: real STARKs, stealth payroll, scoped disclosure
Shield → hidden spend → stealth payment discovered by ML-KEM trial-decapsulation ("BOB DISCOVERED $2") → a one-time disclosure package verified offline, opening exactly one payment and zero others → a block's shielded spends verified by every validator as one constant-size 1.24 MB aggregate proof → and the budget storyline re-run over balances no validator can see.
The whole chain went public
Node, consensus, circuits, join kit — MIT/Apache, with the vendored consensus engine and pinned dependencies. From this point on, every claim on this site is checkable against code anyone can build.
274 tx/s measured — and the staging testnet went live
The storm harness pushed a 4-validator lab chain to 274 tx/s sustained with 1,024-transaction blocks (capacity sheet in the repo). That evening, staging-1 launched on real cloud infrastructure — genesis fingerprint 557f2ea6…62a22, chain ID derived from it, public RPC and explorer from day one.
A validator spent all 32,768 signatures — the chain stopped rather than lie
At height 10,848 a validator's one-time-signature tree ran out — HSS gives ~32.7K signatures, at ~3 per height that's ~10.9K blocks, and it died on schedule. The node refused to reuse a single leaf and the chain halted (2 of 4 votes < ⅔). Six hours later it was back: a rotation certificate signed by the stateless SLH-DSA root swapped in a fresh operational key, publicly visible on the explorer as epoch 2. Exactly what the yellowpaper promises — proven the hard way. Automatic threshold rotation shipped days later.
All three validators rotated their keys overnight — nobody was awake
First night with threshold rotation live: each voter crossed its leaf threshold and issued, committed, and applied its own root-signed rotation certificate, mid-consensus, unattended. The same window shipped the genesis gate: nodes now refuse to peer with anything on a different genesis — an imposter chain cannot even connect.
Exhaustion is now routine: dead validator → root cert → voting again
The same validator has now been revived from full key exhaustion three times — each recovery via the designed path (peers carry the exhausted validator's root-signed certificate), each faster than the last. A liveness blip, never a safety event. The same day, an independent observer node began re-verifying the entire chain from genesis.
Catch-up verification went parallel: 2 → 71 blocks/min
Full re-verification (every hash-based vote envelope, every STARK, every commit certificate) was throughput-bound at ~2 blocks/min. v0.10.8 parallelized it — 35× faster, now outrunning the chain — and v0.10.9 made sync spend zero signer leaves. A killed voter is back at tip in minutes.
A stranger's machine re-verified our entire history — and matched
An observer that joined via the public kit (genesis verified before boot) re-executed and re-verified every block from genesis — ~76,000 of them — through 45+ key-rotation epochs, three validator revivals, and three binary upgrades. At tip, stranger and founding fleet reported the identical full state commitment:
Signer leaves spent syncing: zero. This is the claim that matters — not "trust our fleet," but anyone who replays the chain lands on the same hash.
v0.10.9 released — the whole arc, tagged and reproducible
The full fleet runs v0.10.9; the release notes tell the halt, the rotations, the parallel sync, and the observer receipt in one place. Everything above is now a git checkout away.
Usage sprint → fees are law → testnet-1 launched from a ceremony genesis
In one day: permissionless accounts + a public faucet + a Windows wallet (v0.11), search-anything explorer (v0.11.2), a flat protocol fee that is charged, refunded on refusal, and burned (v0.12) — and then staging-1 was retired at height 107,182 and testnet-1 launched from a genesis ceremony: fresh hash-based keys for all four seats, the fee bound into the genesis from block 1, the faucet treasury allocated at genesis, node memory bounded (history served from disk), and a wallet that pays shielded through the public prover (v0.13.0).
A validator that had burned its tree to zero healed itself
The morning's wedge (a rotation certificate issued but never committed left the guards blocking while the seat burned its fresh tree) reproduced within ten hours on the old binary. The fix (R9: guards hold ten minutes, then re-issue replaces) rolled onto that node one voter at a time; its first tick found the guard clear, pushed an epoch-5 certificate to its peers, and within a minute it was signing again — no human in the loop. Cadence went from a crawl back to ~26 blocks/min the moment its signer lived.
Shield → stealth pay with a memo → unshield → disclose, from a Windows executable
The v0.13.0 wallet drove the whole shielded flow on the live network through the public prover: a shield (block 1,650), a shielded payment to a stealth address with a memo, a partial unshield with change, a one-time disclosure verified offline. Fee-aware from the first click: max = balance − fee, local refusal of what the chain would refuse. Guide with screenshots: /wallet.
All four seats rotated their keys, unattended, within eleven blocks — zero blocks missed
Fresh trees started together with identical budgets, so they crossed the 20% threshold together: rotation certificates landed at heights 11,584, 11,588, 11,594 and 11,595 — one per seat — while the chain kept committing at ~19 blocks a minute. The same evidence is also a finding: correlated rotation means a rotation-path bug would hit every seat in the same minute, so per-seat threshold jitter is now a plan item (R12).
The Android wallet shipped — same Rust core, same files, signed with a persistent key
Two days after the community was asked, HashKinetics Wallet for Android v0.2.0 is a release: the desktop wallet's library cross-compiled for the phone (UniFFI bindings, no hand-written JNI), gated end to end on a local chain — create → faucet → send → shield → scan → unshield → pay shielded with a memo → disclose → seal → lock → unlock — with the byte-compatibility receipt that the CLI opens the phone's sealed files and accepts a payment from them. The APK is built by CI and signed with a release key that lives only in a repository secret; the signer's certificate digest is published beside the file hash, so an upgrade is verifiable and a look-alike is not.
Every consensus signature cost ~450 ms. We had blamed the disk. He measured the CPU.
A seated external validator (Eddy) reproduced on the v0.18.1 sources what his seat had been showing since it joined: 447.7 ms median, 787 ms p95 per hash-based signature — enough to eat the 2 s propose timeout on a modest CPU. Our first diagnosis, storage latency, was wrong and was corrected the same day. Two bugs: the vendored signature crate rejected the node's authentication-path cache on every call (a length bug in its HMAC check), and the expanded key was rebuilt per signature. v0.18.2 fixes both — 179 µs per signature on the release build — with signatures byte-identical to before, the on-disk signer state unchanged, and the one rule a hash-based signer must keep (never reuse a one-time leaf) guarded and tested exactly as before. Unpaced, a lab chain then ran at 9 blocks a second, so the same release paces blocks to a 1 s floor. No consensus rule, no deadline; his name is on the release. Rolled to the four founding seats the same evening (17:57–18:07 UTC, one at a time, chain never paused): their heights measure 1.0 s — the floor, exactly — and Eddy had upgraded his own seat within thirty minutes of the notice.
Height 190,000: the pool stops being single-asset, with a deadline every seat met
v0.19.0 was the first release with a hard activation height: every node had to run it before 190,000, announced ten hours ahead with the hour posted every few hours. All seven seats were on it by 06:57 UTC; the height passed at about 08:47 UTC with the certificate shape unchanged and no seat lost. From there a shield of any registered, pool-eligible asset opens that asset's own pool — own tree, own nullifiers, own conservation total — while the circuit, the proving keys, the note format and the wallets stayed exactly as they were.
20 USDC left Sepolia and arrived as USDC.sep; 5 went back — every hop a public receipt
The first cross-chain loop, on testnets: a vault contract on Ethereum Sepolia locked 20 Circle test USDC naming a testnet-1 account; after Ethereum finalized the block (19 minutes — all of it Ethereum's finality), the bridge service minted 20 USDC.sep to that account. The account then burned 5 with a Sepolia address as the destination, and 90 seconds later the vault released 5 USDC to it under the attestor's signature. Afterwards the vault holds 15 = supply 20 − burned 5, which the service re-checks every ten minutes. Two hours later the other direction: 4 of an HK-issued test asset burned on testnet-1 became 4 wHKT.sep on Sepolia within a minute (a HashKinetics commit is final, so nothing to wait for), and 1 burned back on Sepolia was re-minted on testnet-1 after Ethereum's finality. At 16:42 UTC the first person outside the team — an external seat operator — bridged 5 USDC from the page, unprompted, forty minutes after it went live; and that evening bridged USDC was shielded: 2 USDC.sep into its own pool, 0.5 paid to a stealth address with zero transparent trace, 1 unshielded. Trust label, said first: on this side every balance moves under hash-based keys; on the Ethereum side the vault trusts one ECDSA attestor key today (1-of-1, founder-run) — the bridge is exactly as safe as that key. Deposit ids checked by consensus and a committee of operators are the next two steps, in that order.
Our worst days are load-bearing
Every incident above — the halt, the wedges, the exhaustions — became a shipped, tagged fix within days, and stayed in the public record. A chain that has only ever seen good days is a chain whose recovery story is fiction. Ours is measured.
Demo-gated claims only
Numbers on this site are measured on real runs or are explicit arithmetic on measured constants, and are labeled as such. Roadmap items are labeled plans. Mainnet follows independent audits — not the other way around.
Reproduce THE RECEIPT yourself — on the chain that is running now
One Linux box. You verify everything — every vote, every proof, every certificate — and trust nothing. THE RECEIPT above (457799f2…cb1443) is staging-1's state commitment: an archived chain, reproducible from its retained block log on request. On testnet-1 the same test is simpler — your node's app_hash at any height must equal what the fleet reports at that height.
# join testnet-1 as a verifying observer git clone https://github.com/hashkinetics/hashkinetics && cd hashkinetics # follow networks/testnet-1/README.md — verify the genesis fingerprint first: sha256sum networks/testnet-1/genesis.json # → 4e4ea68d…971c7 # then compare your tip to the fleet's: curl -s -X POST http://127.0.0.1:26000 -d '{"method":"hk_chainInfo"}' # yours curl -s -X POST https://rpc.hashkinetics.org -d '{"method":"hk_chainInfo"}' # theirs — same height ⇒ same app_hash, or you caught us