aere-docs/AERE-CROSS-CLIENT-DETERMINISM.md
Aere Network e4cead319d Initial public release
Aere Network public source. Everything here can be checked against the live
chain (chain id 2800, https://rpc.aere.network).

Scope note, stated up front rather than buried: consensus on chain 2800 is
classical secp256k1 ECDSA QBFT. The post-quantum work in this repository is at
the signature, precompile, account and transport layers. Nothing here makes the
consensus post-quantum, and no document in it should be read as claiming so.
2026-07-20 01:01:36 +03:00

481 lines
27 KiB
Markdown

# Aere Network Cross-Client Determinism
Technical specification. Chain 2800 (Aere Network mainnet).
Grounding and consistency: this document is the reproducible proof behind Aere's
client-diversity claim. It is consistent by construction with section 5.5 of
`aerenew/docs/AERE-ENGINEERING-SECURITY-SPEC.md` (the two clients disagree on state)
and the consensus row of `aerenew/docs/AERE-ARCHITECTURE-MAP.md`. Where those documents
and this one describe the same status, they say the same thing. If they ever diverge,
the engineering spec 5.5 is authoritative and this document is wrong.
Evidence cited here lives in `aerenew/nethermind-pqc/` (the second-client work and its
proof logs), `aerenew/conformance/` (the executable conformance vector suite),
`aerenew/docs/NETHERMIND-2ND-CLIENT-LIVE-2026-07-17.md`,
`aerenew/docs/DECENTRALIZATION-2ND-CLIENT-RUNBOOK.md`, and
`aerenew/docs/AERE-ENGINEERING-SECURITY-SPEC.md`.
---
## 1. Why cross-client determinism matters, and the honest scope
### 1.1 A single producing client is a systemic risk
A blockchain is a deterministic state machine: for one ordered sequence of inputs (the
blocks) there is exactly one correct output (the state). A network that runs a single
client implementation has no independent check on whether that implementation computes
the one correct output. If the sole client has a consensus-relevant bug, the whole
network inherits it, and there is nothing to compare against that would reveal the error
before it is finalized.
The reference case is the September 2025 Reth halt. A chain whose block production
depended on one implementation stopped when that implementation hit a bug. The failure
was not in the protocol; it was in the monoculture. This is the exact risk Aere's
second-client program exists to retire, and it is the reason `AERE-ENGINEERING-SECURITY-SPEC.md`
section 4.2 records "a single producing client is a demonstrated systemic risk" as the
design driver.
Aere's live mainnet today runs one production client: a fork of Hyperledger Besu v26.4.0
(base commit d2032017, JDK 21), the sole producer for all seven QBFT validators. A second,
independent implementation that computes the same state from the same inputs turns "trust
the one client" into "two independent implementations agree", which is a materially
different and stronger assurance.
### 1.2 What this proves, and what it does not
The second client is a patched Nethermind 1.39.0 (.NET), chosen for implementation
diversity: a different codebase in a different language, so a consensus-relevant bug in
one is unlikely to exist in the other. A second Besu instance would not be client
diversity, because it would share every Besu bug.
This document proves one specific property:
> **State-computation determinism across two independent implementations.** For the same
> chain-2800 inputs, the patched Besu producer and the patched Nethermind client compute
> byte-identical block hashes and byte-identical state roots, and agree on seal validity
> and post-quantum precompile outputs.
This document does **not** claim any of the following, and the reader should not infer them:
- It does **not** claim Nethermind is a live producing validator on mainnet. It is not.
Nethermind runs as a non-validating follower and as a cross-check; it takes zero part in
live consensus. Besu remains the sole live producer.
- It does **not** claim client-diverse consensus or a "two-client mainnet". Making
Nethermind a live sealer is a separate, founder-gated, high-risk change documented in
`DECENTRALIZATION-2ND-CLIENT-RUNBOOK.md` Phase B, not started and not authorized here.
- It does **not** claim post-quantum consensus. Consensus is classical secp256k1 ECDSA
QBFT. The post-quantum surface is signatures, accounts, and applications only. This scope
boundary holds throughout every section below.
The value delivered is real and bounded: two independent implementations demonstrably
compute the same state, so a consensus-relevant divergence between them is detectable
rather than silent. The gap between that assurance and a fully automated live fail-safe
gate is stated plainly in section 4.
---
## 2. The determinism protocol
This is the method a third party uses to verify cross-client determinism directly. It has
five parts, each an independent check on the same underlying property. Each part states
what is asserted and what evidence supports it. Reproduction commands are in section 5.
### 2.a Full re-validation to genesis (zero invalid seals)
**Assertion.** The patched Nethermind re-validates chain-2800 blocks from genesis forward
through its own header-import and seal-validation code path, accepting every genuine header
and asserting zero invalid seals, and rejecting any tampered header.
**Method.** Nethermind reproduces the genesis exactly
(`0xd86d57a899cbfa580669f0e1c7cd4ae5f525247c3c823f8f75df176a0c5d7f1a`), then for each block
recomputes the QBFT canonical block hash (extraData re-encoded seal-stripped, round kept),
recovers each 65-byte committed seal to a distinct in-set validator address, and requires
the recovered-signer count to meet the QBFT quorum `ceil(2N/3)` (N=7, quorum 5). This runs
inside Nethermind's production `HeaderValidator` / `ISealValidator` seam, subclassed as
`AereQbftHeaderValidator` and `AereQbftSealValidator`, so it is the client's own validation
logic, not a bespoke script.
**Evidence.**
- `aerenew/nethermind-pqc/QBFT-VALIDATION-2026-07-12.md` and
`aerenew/nethermind-pqc/QBFT-FOLLOWER-2026-07-12.md`: real chain-2800 headers driven
through Nethermind's own `HeaderValidator.Validate()`; genuine headers accepted, four
tamper modes rejected. Vectors in `aerenew/nethermind-pqc/test/AerePqc.Tests/qbft-vectors.json`
(16 real chain-2800 headers).
- Live follower re-validation from genesis forward with zero invalid-seal rejects over the
synced range (section 2.c).
**Honest boundary.** Header and seal re-validation is proven over sampled real headers and
over the contiguous ranges the follower has synced from genesis. A single unbroken
re-validation across the entire history to current head, asserting zero invalid seals over
all of it, completes when the permanent follower finishes its sync to head.
[VERIFY: at-head, full-history re-validation with a zero-invalid-seal count over the complete
0..head range is pending the permanent follower reaching head; per
`NETHERMIND-2ND-CLIENT-LIVE-2026-07-17.md` section 6 this is an explicit open TODO.]
### 2.b Byte-identical re-execution (block hash AND state root at each height)
**Assertion.** Replaying real chain-2800 blocks through both clients yields an identical
block hash **and** an identical state root at each height. State-root identity is the strong
check: it means both implementations executed every transaction, applied every reward and
fee rule, and arrived at the same world state, not merely copied a header.
**Method.** Full-sync mode (`FastSync/SnapSync/FastBlocks = false`) so every block is
executed and its post-state root is recomputed by the node, then compared against the
reference client's state root at the same height.
**Evidence.**
- `aerenew/nethermind-pqc/QBFT-GENESIS-SYNC-FIX-2026-07-13.md`: a real Nethermind node
full-syncs from genesis, re-executes all transactions, and every node-computed state root
matches the real chain exactly. Genesis stateRoot
`0x2d2255d41483c22e8a2d51ca18249157e25a47f949e8a6c54552d0f790b7b127`. Spot-checked
read-only against the live chain:
| height | node-computed stateRoot | live chain-2800 stateRoot | match |
|---|---|---|---|
| 458 | `0xc314d2c3…` | `0xc314d2c3…` | yes |
| 694 | `0xf0a4309e…` | `0xf0a4309e…` | yes |
| 872 | `0xcda2107d…` | `0xcda2107d…` | yes |
| 1661 | `0x44baac17…` | `0x44baac17…` | yes |
| 3000 | `0x44baac178e561fe2…243e8575` | `0x44baac178e561fe2…243e8575` | yes |
This run is bounded to the first 3000 blocks (22 transactions re-executed), genuine
full-state re-derivation over that range, not a header copy.
- `aerenew/docs/NETHERMIND-2ND-CLIENT-LIVE-2026-07-17.md` section 4: the live permanent
follower matches `rpc.aere.network` on block hash AND state root at heights 1, 100, 1,000,
10,000, 11,133, and 11,136 (head at check time).
**Honest boundary.** Byte-identical re-execution is proven over the ranges executed to date
(offline genesis..3000, and the live follower's synced heights). The cross-boundary check at
the AerePQC precompile fork (block 9,189,161) and at current head completes when the
permanent follower crosses that height.
[MEASURE: state-root identity at the fork boundary 9,189,160 and 9,189,161 and at current
head, per `DECENTRALIZATION-2ND-CLIENT-RUNBOOK.md` A.6, is verified once the follower is at
head. A mismatch at or across the boundary would indicate a wrong precompile gate.]
### 2.c Live follower cross-check
**Assertion.** A listen-only Nethermind following the live chain over devp2p matches the
live RPC's block hash and state root at each checked height, with zero invalid-seal rejects.
**Method.** The follower is hardened to be non-validating: no validator key, no `AERE_*`
environment, `eth/68`-only on the wire (the `istanbul/100` QBFT capability is stripped), so
the engine, producer, and importer paths are inert. It peers to nodes under Foundation
control (rpc2 primary, infra secondary), full-syncs from genesis, and its per-height
hash and state root are compared to `rpc.aere.network`.
**Evidence.**
- `aerenew/docs/NETHERMIND-2ND-CLIENT-LIVE-2026-07-17.md`: the permanent second client
`aere-client2` (a dedicated second-client host, Helsinki, dedicated firewall,
JSON-RPC bound to `127.0.0.1` only, durable `systemd` service). Parity table of hash and
state root MATCH at 1 / 100 / 1,000 / 10,000 / 11,133 / 11,136; zero invalid-seal rejects
in range.
- The first live-devp2p run (recorded in the memory note `client_diversity_2026-07-13` and
the live doc) full-executed genesis to block 182,777 and matched hash and state root at
1 / 100 / 1,000 / 10,000 / 100,000 / 111,130 / 182,777, with zero divergence in range.
**Honest boundary.** The follower is a listen-only cross-check, not a validator. As of the
recorded state it is syncing toward head (honest ETA roughly 18 hours from the recorded
start; DB projected near 48 GB at head).
[VERIFY: "at head, tracking within a few blocks of `rpc.aere.network`, zero divergence over a
sustained soak" per runbook A.6/A.7 is the completion criterion and is pending the follower
reaching and holding head.]
### 2.d Generated edge-case corpus
**Assertion.** Adversarial and edge-case inputs, run through both clients, widen coverage
beyond organic blocks. Organic chain-2800 blocks are near-empty, so replaying only real
blocks under-exercises the state-transition surface. A generated corpus of adversarial
transactions and malformed inputs closes that gap.
**Status, split by layer:**
- **Precompile edge-case corpus: EXISTS.** `aerenew/conformance/conformance-vectors.json`
carries the adversarial precompile surface directly: valid, wrong-key, tampered-signature,
tampered-nonce or message, wrong-header-byte, wrong-length, empty, too-short,
below-minimum, and at-minimum-all-zero cases for each verifier, plus the full vendored NIST
ACVP negative test groups (ML-DSA-sigVer-FIPS204 tg8: 15 records, 3 pass / 12 fail;
SLH-DSA-sigVer-FIPS205 tg31: 14 records, 2 pass / 12 fail) and the SHAKE256 output-length
domain including the over-cap truncation edge. These are the "trap for a second client"
cases and they are pinned as vectors (`aerenew/conformance/README.md`).
- **Block-level and transaction-level adversarial corpus: [MEASURE], to build.** A dedicated
corpus of adversarial or edge-case transactions (deep call stacks, storage-collision
patterns, gas-edge and revert-edge transactions, EIP-2935 lookback boundary calls, base-fee
floor boundary blocks) executed through both clients with state-root diff at each step does
not yet exist as a committed artifact. It is the corpus to build to widen coverage beyond
organic blocks. [MEASURE: generate an adversarial block/transaction corpus, replay through
both clients, assert identical state root per step; store under `aerenew/conformance/` next
to the precompile vectors.]
### 2.e PQC precompile parity
**Assertion.** Both clients produce identical outputs for the same NIST vectors through the
0x0AE1..0x0AE5 precompiles (Falcon-512, Falcon-1024, ML-DSA-44, SLH-DSA-SHA2-128s, SHAKE256).
**Method.** The five Aere post-quantum precompiles are compiled into a real Nethermind
1.39.0 process via its own `IPrecompileProvider` extension seam (the same interface Optimism
and Taiko use), gated to activate at the fork boundary. NIST KAT and conformance vectors are
driven through the running Nethermind JSON-RPC by `eth_call` and compared byte-for-byte
against the Besu fork's output for the same input.
**Evidence.**
- `aerenew/nethermind-pqc/REAL-NETHERMIND-PQC-2026-07-12.md`: 27 of 27 NIST-KAT and
conformance vectors pass byte-for-byte via `eth_call` inside a genuine running Nethermind
1.39.0 (commit `14aca2c5`), matching the Besu 26.4.0 fork. Includes the tampered-signature
negative for each of Falcon-512, Falcon-1024, ML-DSA-44, and SLH-DSA-128s (each returns the
32-byte zero word, not-verified).
- `aerenew/conformance/`: the executable conformance suite has since grown to 83 precompile
vectors (Falcon-512 x12, Falcon-1024 x12, ML-DSA-44 x22, SLH-DSA-SHA2-128s x21, SHAKE256
x16), 112 vectors total including QBFT, EIP-2935, and extraData. Last live run: 112/112
passed against the chain-2800 Besu reference (`aerenew/conformance/README.md`). Note the
distinction: the 27/27 figure is the set re-run byte-for-byte inside the actual Nethermind
process; the 112/112 figure is the full suite confirmed against the live Besu reference by
`runner.mjs`.
**Precompile fail-closed semantics (both clients must match).** On malformed input the
signature precompiles (0x0AE1..0x0AE4) return a 32-byte zero word (not-verified) and never
revert; SHAKE256 (0x0AE5) returns empty when input is under 32 bytes or `outLen` is zero, and
truncates an over-cap `outLen` to 65536 rather than reverting. A second client that reverts,
or returns empty where the reference returns a zero word, diverges. These semantics are
observed-live, not assumed, and are pinned as vectors.
**Gate parity (a real divergence trap).** The precompiles must activate at exactly the Aere
fork boundary, block 9,189,161 (the first block with timestamp >= 1783820272), gated by
`chainId == 2800`. An ungated build (active from block 0) would diverge state if any pre-fork
block ever called an `0x0AE*` address as an ordinary account. The permanent follower gates on
the futureEips timestamp in `ReleaseSpec.cs` (`IsAerePqcEnabled`) and
`ChainSpecBasedSpecProvider.CreateReleaseSpec`, verified inactive pre-fork by an `eth_call`
to `0x0AE5` returning `0x` on the pre-fork head versus the SHAKE output on the post-fork head
(`NETHERMIND-2ND-CLIENT-LIVE-2026-07-17.md` section 3).
---
## 3. Existing evidence (byte-identical production and import)
Beyond the follower and precompile parity above, the second client has been shown to produce
QBFT blocks that the reference client accepts byte-for-byte, and to have that acceptance be
non-vacuous (a tampered seal is rejected). This is the production-encoding half of client
diversity. All of it is on an isolated test network; the live chain, the live validators, and
the infra box were never touched.
### 3.1 Byte-for-byte block production, then Besu import
`aerenew/nethermind-pqc/QBFT-PRODUCER-2ND-CLIENT-2026-07-13.md` (with proof log
`proofs/qbft-producer-besu-import-proof-2026-07-13.txt` and
`proofs/qbft-producer-manifest-2026-07-13.json`):
- **Byte-exact calibration.** Given the same key, genesis, and timestamp, the Nethermind-side
producer's full block RLP is byte-for-byte identical to Besu's `debug_getRawBlock(1)`: 1286
hex characters equal, including the ECDSA committed seal and the block hash
`0xa34f5e43…f6c616`.
- **Production interop.** The producer sealed 8 empty QBFT blocks; a fresh stock Besu 24.12.2
node imported all 8 through its real BFT block-validation path (offline `blocks import`,
which runs the same `BftCommitSealsValidationRule` and `MainnetBlockValidator` as live
import). Every imported block hash equals the producer's manifest; miner is the Nethermind
validator address.
### 3.2 Non-vacuity: a one-byte-tampered seal is rejected
Same proof, control C: one byte of block 1's committed seal was flipped
(`0x8d -> 0x72`), leaving the block hash unchanged so the check isolates the seal. Genuine
block imported; tampered block rejected by Besu's own rule
(`BftCommitSealsValidationRule | Invalid block header: Not all committers are in the locally
maintained validator list`, `tampered exit: 1`). The 8-block acceptance is therefore genuine
cryptographic agreement, not a rubber stamp.
### 3.3 Cross-client hash agreement across proposers
`aerenew/nethermind-pqc/proofs/mixed-client/proposer/01-onchain-alternation-hashmatch.txt`: on
a mixed set, proposers strictly alternate Besu and Nethermind, and the on-chain block hash
computed by the Nethermind node equals the Besu node's hash at every one of 20 consecutive
blocks (NM_hash == Besu_hash, YES, blocks 1..20). At N=4 (2 Besu + 2 Nethermind), all four
nodes agree on the head hash (`proofs/mixed-client/follower-sync/REGRESSION-n4.txt`, 4-way head
hash agreement at block `0x2d`).
### 3.4 PQC precompile parity inside a real Nethermind
Section 2.e: 27/27 NIST KAT and conformance vectors byte-for-byte via `eth_call` inside a
running Nethermind, matching the Besu fork
(`aerenew/nethermind-pqc/REAL-NETHERMIND-PQC-2026-07-12.md`); the broader 112/112 conformance
suite against the live Besu reference (`aerenew/conformance/`).
---
## 4. Honest status
This is the load-bearing honesty section. It states, without rounding up, exactly what is
proven and what is remaining operational work. It matches section 5.5 of
`AERE-ENGINEERING-SECURITY-SPEC.md`; the two must stay consistent.
**PROVEN, as a validation cross-check.** The second client demonstrably re-derives state
independently and would detect a state divergence. Concretely, it re-validates chain-2800
headers and seals through its own validation code (accept genuine, reject tampered);
re-executes real blocks to byte-for-byte identical block hashes and state roots (offline over
genesis..3000, and as a live listen-only follower matching the live RPC's hash and state root
at every checked height in range); and produces identical outputs for the five PQC precompiles
on the same NIST vectors. Because there is exactly one definition of correct state and two
independent implementations computing it, a consensus-relevant divergence (a differing state
root, a differing block hash, a differing seal decision) between Besu and Nethermind is
detectable by comparing the two. It does not silently pass. This is real client-diversity
assurance.
**NOT yet a live automated divergence gate.** The cross-check is not yet wired into production
monitoring as an automated, alerting fail-safe that watches Besu and Nethermind continuously
and raises an alarm on the first byte of divergence. Today the comparison is run and
spot-checked; it is not a continuously-armed live gate.
**NOT yet a live producing validator.** Nethermind is a non-validating follower and a
cross-check. It takes zero part in live consensus. Besu is the sole live producer on chain
2800. A Nethermind disagreement flags a discrepancy against the producer; it does not arbitrate
consensus, because Nethermind casts no vote and seals no block on mainnet.
**Behavior on a detected divergence.** This is a fail-safe, not an automatic consensus action.
A detected divergence is a signal to halt and investigate before the divergent block is
trusted, not something that itself forks or halts the live chain. In all adversarial fault
testing to date, zero forks were observed; the chain's failure posture is to halt and later
recover, not to fork.
**The remaining operational work** is turning the proven cross-check into an automated live
fail-safe gate: a supervised process that continuously reads both clients at head, diffs block
hash and state root per block, and alerts (and gates trust) on the first divergence, with the
permanent follower held at head under a sustained soak. Separately and further out, making
Nethermind a live sealing validator is the founder-gated, high-risk Phase B in
`DECENTRALIZATION-2ND-CLIENT-RUNBOOK.md` (extended mixed-client soak at production shape,
independent audit of the Nethermind QBFT engine, a rehearsed one-block rollback vote, and
fault tolerance preserved by construction), not started and not authorized by this document.
Public-copy rule that travels with this status: a second independent client follows and
validates live chain 2800 as a non-validating full node. Do not write "client-diverse
consensus", "two-client mainnet", or anything implying the second client seals live blocks.
The Nakamoto coefficient by operator is still about 1; a follower does not change it. Never
claim mainnet consensus is post-quantum; it is classical secp256k1 ECDSA.
---
## 5. Reproduction
A third party reproduces the differential by building both clients, replaying blocks, and
diffing state roots. Steps that need the fork host or a heavy full-history build are marked
[MEASURE] with the command rather than an asserted fresh number, because the numbers above
were measured on Foundation infrastructure and the point of reproduction is that an independent
party gets the same bytes, not that they trust ours.
### 5.1 Precompile parity and conformance suite (light, no chain build)
The executable spec runs read-only against the live reference and needs only `ethers` v6:
```bash
cd aerenew/conformance
node runner.mjs # validates every vector against the live Besu reference (read-only)
node build-vectors.mjs # regenerates vectors from NIST KATs + real chain-2800 headers
```
Expected: all vectors pass; `runner.mjs` re-confirms the live N=7 validator set and the
`validator_set_root` before asserting the QBFT vectors. This reproduces the precompile-output
half of determinism (section 2.e) against the reference without building a client.
To reproduce the same 27/27 inside a second client rather than against the reference, build
the patched Nethermind (5.2) and drive the vectors through its `eth_call`, per
`aerenew/nethermind-pqc/REAL-NETHERMIND-PQC-2026-07-12.md`.
### 5.2 Build the two clients
- **Reference (Besu fork).** Hyperledger Besu v26.4.0, base commit d2032017, JDK 21, plus the
Aere PQC precompile and EIP-2935 fork rules. [MEASURE: build on a scratch box, not infra;
Aere's live producer is not rebuilt for this. See `ops_no_heavy_compute_on_infra`.]
- **Second client (patched Nethermind).** Nethermind 1.39.0 commit `14aca2c5`, .NET SDK
10.0.30x, with the in-tree `Nethermind.AerePqc` project applied:
```bash
cd aerenew/nethermind-pqc/nethermind-intree
./apply.sh && ./apply2.sh && ./apply3.sh # precompiles + release-spec gate
# for the header/seal follower add through apply9.sh; for the producer path add apply5.sh
dotnet build src/Nethermind/Nethermind.Runner -c Release
```
For the non-validating follower build, exclude the istanbul-dependent QBFT engine and the
producer so the binary is `eth/68`-only, and leave `AERE_PRODUCER_KEY` and `AERE_QBFT_KEY`
unset (this is the invariant that keeps it non-validating). Gate the precompiles on the
futureEips timestamp so they activate at block 9,189,161, not block 0.
### 5.3 Full re-validation to genesis (2.a)
Start the follower in full-sync from genesis against a node under your control and confirm
zero invalid-seal rejects in the logs:
```bash
# config: chainspec with the reproduced genesis 0xd86d57a8…0c5d7f1a,
# --Sync FullSync (FastSync/SnapSync/FastBlocks = false), static peer to a Besu node,
# discovery off, RPC bound to 127.0.0.1
dotnet Nethermind.Runner.dll --config aere-live-config.json
```
[MEASURE: full-history re-validation to head with a zero-invalid-seal count over 0..head
requires the multi-hour full-history sync on the fork host; assert the count once the follower
is at head.]
### 5.4 Byte-identical re-execution, diff the state roots (2.b)
For each checked height, pull the state root from both clients and diff. Read-only, via each
client's own RPC (the follower on `127.0.0.1:8545`, the reference on its node RPC):
```bash
for h in 1 100 1000 10000 3000; do
a=$(cast rpc eth_getBlockByNumber $(printf '0x%x' $h) false --rpc-url http://127.0.0.1:8545 | jq -r .stateRoot)
b=$(cast rpc eth_getBlockByNumber $(printf '0x%x' $h) false --rpc-url <reference-node-rpc> | jq -r .stateRoot)
[ "$a" = "$b" ] && echo "$h stateRoot MATCH" || echo "$h stateRoot DIVERGE a=$a b=$b"
done
```
Do the same for `.hash` (block hash) at each height. Expected: MATCH at every height, per the
tables in section 2.b.
[MEASURE: extend the height list across the fork boundary (9,189,160 and 9,189,161) and to
current head once the follower has executed past 9,189,161. A mismatch at or across the
boundary indicates a wrong precompile gate; stop and fix.]
**baseFee reproduction trap.** Compare state roots and block hashes against a raw Besu node,
not the public `rpc.aere.network`. The public RPC is behind a proxy that overwrites
`baseFeePerGas` with a constant 1 Gwei for display; that shimmed value does not reproduce the
real block hash for blocks whose true base fee differs. A client reading directly from a Besu
node gets the true consensus value and needs no override (`aerenew/conformance/README.md`,
baseFee shim caveat).
### 5.5 Production interop and tamper control (3.1, 3.2)
On an isolated testnet, have the Nethermind-side producer seal a short chain and import it with
a stock Besu, then repeat with one seal byte flipped:
```bash
# produce N blocks -> nm-blocks.rlp (isolated chainId, single validator), then:
besu --data-path <fresh> blocks import --from nm-blocks.rlp # expect exit 0, all hashes match the manifest
# flip one byte of a committed seal, re-import -> expect BftCommitSealsValidationRule rejection, exit 1
```
Expected: genuine chain imports with byte-identical hashes; the tampered chain is rejected by
Besu's own BFT rule. This is the non-vacuity control, reproduced from
`aerenew/nethermind-pqc/QBFT-PRODUCER-2ND-CLIENT-2026-07-13.md`.
### 5.6 Live follower cross-check (2.c)
Run the non-validating follower against the live chain and diff hash and state root against a
raw live node at a spread of heights:
[MEASURE: the live follower cross-check at head requires the follower to be fully synced (honest
ETA roughly 18 hours) and peered to a live node; assert per-height hash and state-root MATCH and
zero divergence over a sustained soak per `DECENTRALIZATION-2ND-CLIENT-RUNBOOK.md` A.6 and A.7.]
---
## 6. Summary
Two independent implementations, in different languages, compute the same chain-2800 state:
identical block hashes, identical state roots, matching seal decisions, and byte-for-byte
identical post-quantum precompile outputs, with a tampered seal provably rejected. That is
proven as a validation cross-check. It is not yet a continuously-armed automated live
divergence gate, and Nethermind is not yet a live producing validator; those are the remaining
operational and founder-gated steps. The claim this document supports is precise and defensible:
Aere's client-diversity assurance is a demonstrated, reproducible cross-check on state
computation, not a marketing line, and its boundaries are stated in the same words as the
engineering spec it is consistent with.