Hostile-read repairs across the kernel artifacts: 17 confirmed over-claims fixed to honest

A 6-lens hostile panel with adversarial verification confirmed 17 attacks that
would hold in a public takedown. All repaired: the MI contract now carries the
two base-fee floor-lapse windows (12,978,617-13,087,959 and
13,596,033-13,596,141) as explicit ruleset validation exceptions, so a stranger
implementing the written rules no longer halts where our own follower did; the
honesty boundary now states the full record of reject-on-disagreement including
the windows, and why the fact stays load-bearing; the independence claim is
bounded (upstream skeletons yes, AERE ruleset has one author in both forks, so
a common-author bug passes any differential gate by construction); the harness
verdict claims only what it measures, records engine identity via
web3_clientVersion on every run, refuses same-URL endpoint pairs, and prints
its NOT MEASURED block on every run; stage 4 names the live engine (upstream
parallel processing enabled by default, idling on empty blocks) and its
oracle's model limits; 'governed registry' became 'owner-controlled' with the
single-key fact stated. The panel also confirmed the import-proof doc claimed
a two-month validation history where six days is the truth; fixed.
This commit is contained in:
Aere Network 2026-08-15 23:28:24 +03:00
parent 46c42164de
commit f2ab368c36
5 changed files with 116 additions and 19 deletions

View File

@ -150,10 +150,19 @@ input or output. Only the commitments above are.
**Determinism is measured across implementations, not asserted from one.** A single client **Determinism is measured across implementations, not asserted from one.** A single client
agreeing with itself proves nothing about determinism. The measurement that means something is agreeing with itself proves nothing about determinism. The measurement that means something is
two independent engines, built by different teams in different languages, deriving the same two engines built by different teams in different languages deriving the same commitments from
commitments from the same input. Today that is Besu (serial, live producer) versus Nethermind the same input. Today that is Besu (live producer; note that upstream Besu ships with parallel
(independent second client, live at `client2.aere.network`). Tomorrow it is Block-STM through transaction processing enabled by default and the fleet does not disable it, so the live engine
the same seam (treapta 4), measured by the same harness. is the parallel-capable one, idling on empty blocks) versus Nethermind (second client, live at
`client2.aere.network`). **The independence claim has a boundary, stated here rather than found
by a hostile reader:** it holds for the upstream engine skeletons (different teams, different
languages, different codebases), and it does NOT hold for the AERE-specific ruleset. The floor
fork, the lapse windows and the PQ precompiles have a single author, this project, ported into
both forks. A rule bug with a common author passes any differential gate by construction,
because both sides inherit it. Cross-client agreement therefore catches implementation
divergence, not specification error; specification error is what the formal models and hostile
reads are for. Tomorrow Block-STM enters through the same seam (treapta 4), measured by the
same harness.
**Honesty boundary, carried from `cross-client-determinism/`.** A matching header root served **Honesty boundary, carried from `cross-client-determinism/`.** A matching header root served
over RPC proves, on its own, only that both endpoints **serve the same bytes** for a block that over RPC proves, on its own, only that both endpoints **serve the same bytes** for a block that
@ -164,6 +173,19 @@ that sits in the follower's canonical chain below its processed head is therefor
`post_state` the follower's own engine reproduced. The harness states this boundary on every run `post_state` the follower's own engine reproduced. The harness states this boundary on every run
and never claims more than it. and never claims more than it.
The full record of that mechanism, stated before a hostile reader states it for us: every time
reject-on-disagreement fired on the live chain, the resolution was to change the rejecting
follower until it accepted the producer's chain. The two rejections cited above were resolved by
patching the follower (missing predeploys, missing chainspec keys), and the largest episode is
the floor-lapse window of section 6: the follower refused ~109,000 canonical blocks and was
given a hardcoded acceptance window (`AereFloorLapse.cs`). Two things keep the fact
load-bearing anyway. First, the acceptance windows live in header-fee derivation only; state
root, receipts root and gas used stay fully validated inside the windows, so the post-state
inference above survives. Second, the mechanism demonstrably still fires: after the first
window was encoded, the follower stopped again at 13,596,032, which is exactly how the second
lapse window was discovered. A rejection mechanism whose firings keep finding real producer
defects is doing its job; a contract that cited only its flattering firings was not.
--- ---
## 6. Admissible inputs ## 6. Admissible inputs
@ -186,8 +208,22 @@ and never claims more than it.
the live AERE fork. It is a **rule keyed on block number**, not an ambient input: every node the live AERE fork. It is a **rule keyed on block number**, not an ambient input: every node
computes the same base-fee floor for the same height. An engine that lacks it computes a computes the same base-fee floor for the same height. An engine that lacks it computes a
different fee, therefore a different state root, and is a different MI, not the same one with different fee, therefore a different state root, and is a different MI, not the same one with
a different environment. This is exactly the D-150 lesson: a binary missing the floor fork a different environment. A binary missing the floor fork froze a real node at a state-root
froze a real node at a state-root mismatch while every shape check stayed green. mismatch while every shape check stayed green.
- **The two floor-lapse windows, and they are part of the ruleset, not a footnote.** The live
chain contains two dated windows in which the floor was NOT applied by the block producer:
blocks **12,978,617 to 13,087,959** (109,343 blocks; the floor property had been silently
lost from every validator's options and the base fee decayed to single-digit wei), and
blocks **13,596,033 to 13,596,141** (a second, smaller lapse, found when the follower
stopped again exactly at its edge). Inside these windows the base fee of a block is **not a
function of the parent header**; it depends on which validator won the round. The rule an
implementation must carry is therefore: **within these two windows, `baseFeePerGas` is
accepted as given in the header** (validation exception), and outside them the floor rule
applies strictly. An implementer who takes the floor rule without the windows will halt at
block 12,978,617, which is precisely what this project's own second client did until the
exception was encoded (`AereFloorLapse.cs` in the published follower source). A contract
that omits the windows sends every stranger into the same wall, so they are stated here, in
the ruleset, with their exact bounds.
Everything not in this list is inadmissible as an input. In particular: no OS clock, no RNG, no Everything not in this list is inadmissible as an input. In particular: no OS clock, no RNG, no
environment read at execution time, no network, no cross-block mutable cache. environment read at execution time, no network, no cross-block mutable cache.
@ -276,7 +312,9 @@ fork build.
## 10. What this contract does NOT claim ## 10. What this contract does NOT claim
Printed as NOT MEASURED by the harness, never as a pass: The harness prints a NOT MEASURED block naming these on every run, and its JSON report carries
them in the `honesty` field, so the non-claims travel with every result rather than living only
in this document:
- **That consensus is post-quantum.** It is not. Consensus finality is classical secp256k1 ECDSA - **That consensus is post-quantum.** It is not. Consensus finality is classical secp256k1 ECDSA
QBFT plus a Falcon certificate. MI is an execution seam and says nothing about consensus. QBFT plus a Falcon certificate. MI is an execution seam and says nothing about consensus.

View File

@ -31,11 +31,16 @@ planted collision.
state by (address, slot). Any collapse of two distinct logical locations onto one key is a state by (address, slot). Any collapse of two distinct logical locations onto one key is a
correctness bug, not a performance detail, and is named in the contract while it costs nothing, correctness bug, not a performance detail, and is named in the contract while it costs nothing,
not when it bites. not when it bites.
- **One visible consensus change per activation (house rule from the panel).** Turning parallel - **One visible consensus change per activation (house rule from the panel).** Turning the
execution on for mainnet, if it ever changes an observable, is one coordinated activation with a AERE Block-STM engine on for mainnet, if it ever changes an observable, is one coordinated
runbook, exactly the discipline proven at block 14,050,000. Today it is gated off activation with a runbook, exactly the discipline proven at block 14,050,000.
(`AERE_BLOCKSTM` unset reproduces the default builder byte for byte), so it changes nothing - **The live engine, stated plainly (measured):** upstream Besu ships
observable and needs no activation. `DEFAULT_PARALLEL_TX_PROCESSING = true`, the fleet's start script does not disable it, and
`AERE_BLOCKSTM` is unset on all nine validators. So the fleet already runs Besu's own
parallel-capable block processor; on today's empty blocks it executes nothing in parallel, so
no contention path is exercised in production. Setting `AERE_BLOCKSTM=1` would REPLACE that
engine with ours, which is exactly why the determinism oracle and a real-block proof (which
does not exist yet, and this document says so instead of implying it) must come first.
## The proof (Stage 4 gate) ## The proof (Stage 4 gate)
@ -43,12 +48,21 @@ The reference executor `aere-research/parallel-executor` already carries both pa
(`execute_block_sequential` as the oracle, `execute_block_parallel` as Block-STM) and a (`execute_block_sequential` as the oracle, `execute_block_parallel` as Block-STM) and a
from-scratch keccak256 state root. The Stage 4 gate is its A/B mode run as a determinism oracle: from-scratch keccak256 state root. The Stage 4 gate is its A/B mode run as a determinism oracle:
1. **Positive:** for a batch of transactions with real contention, serial and parallel produce the 1. **Positive:** for SYNTHETIC batches with designed contention (not real chain-2800 blocks,
which are empty today), serial and parallel produce the
IDENTICAL state root, across repetitions and thread counts. Same root, or the gate is red. IDENTICAL state root, across repetitions and thread counts. Same root, or the gate is red.
2. **Negative control (mandatory):** plant a divergence, a parallel path that drops one write, or 2. **Negative control (mandatory):** plant a divergence, a parallel path that drops one write, or
a key-aliasing bug, and require the A/B gate to go red. A determinism oracle that has never a key-aliasing bug, and require the A/B gate to go red. A determinism oracle that has never
disagreed is applause, not measurement. disagreed is applause, not measurement.
## What the oracle's model does and does not cover
The reference executor models accounts, storage writes and a keccak state root. It does NOT
model gas accounting, receipts, or the full EVM; those live in the real engines and are covered
by the cross-client checks, not by this oracle. And the oracle runs on synthetic batches: the
proof that parallel execution reproduces REAL chain-2800 blocks does not exist yet and is held
open as a CRITIC finding in the registry (D-184) rather than implied here.
## What Stage 4 does NOT claim ## What Stage 4 does NOT claim
- It does not claim a throughput number. 8-10x is proven CAPACITY on synthetic contended - It does not claim a throughput number. 8-10x is proven CAPACITY on synthetic contended
@ -65,3 +79,15 @@ Contract written 2026-08-15. The determinism oracle runs from the existing Rust
run and its negative control are recorded in `stage4-determinism-run.md` beside this file once the run and its negative control are recorded in `stage4-determinism-run.md` beside this file once the
toolchain build completes. Until that run is recorded, Stage 4 is specified and NOT yet proven, toolchain build completes. Until that run is recorded, Stage 4 is specified and NOT yet proven,
and this sentence says so rather than implying otherwise. and this sentence says so rather than implying otherwise.
---
## Stage 5 note (window narrowing): specified, blocked on a live prover
Stage 5 narrows the proof window as the cost curve from Stage 2 allows. Measured 2026-08-15:
the claim-chain detector's lag is dominated by the safety margin behind the tip (about 8 blocks),
not by proving cost, because there is no SP1 prover producing timed proofs on this machine, and
running MODE=prove is never done on aere-infra. So the cost curve that Stage 5 would narrow
against does not exist yet to be measured. Stage 5 is specified and honestly NOT measurable until
a prover produces windowed proofs with recorded wall-time. Stating this rather than publishing a
lag number that measures the ruler and not the proving cost, which is the D-150 mistake.

View File

@ -6,7 +6,7 @@
* *
* "Post-quantum" is not one algorithm frozen into the protocol. A chain that means to outlast the * "Post-quantum" is not one algorithm frozen into the protocol. A chain that means to outlast the
* cryptography it ships must be able to add a scheme and retire another without a hard fork. AERE * cryptography it ships must be able to add a scheme and retire another without a hard fork. AERE
* puts that in a governed on-chain registry, AereCryptoRegistry at * puts that in an owner-controlled on-chain registry (the owner is a single-key account today, stated plainly rather than dressed as governance), AereCryptoRegistry at
* 0xaE6fC596bb3eCcbf5c5D02D67B0Ef065b3Afbaa5 * 0xaE6fC596bb3eCcbf5c5D02D67B0Ef065b3Afbaa5
* which maps each registered algorithm to the precompile that verifies it, its parameters, and a * which maps each registered algorithm to the precompile that verifies it, its parameters, and a
* status. This tool asks the live chain to prove three things: * status. This tool asks the live chain to prove three things:

View File

@ -103,7 +103,7 @@ const FIELD_BY_NAME = new Map(MI_FIELDS.map((f) => [f.name, f]));
// ---- read-only JSON-RPC over the Node built-ins, no dependencies ------------------------------- // ---- read-only JSON-RPC over the Node built-ins, no dependencies -------------------------------
const ALLOWED_METHODS = new Set(['eth_chainId', 'eth_blockNumber', 'eth_getBlockByNumber']); const ALLOWED_METHODS = new Set(['eth_chainId', 'eth_blockNumber', 'eth_getBlockByNumber', 'web3_clientVersion']);
function rpc(endpoint, method, params, tries = 4) { function rpc(endpoint, method, params, tries = 4) {
if (!ALLOWED_METHODS.has(method)) { if (!ALLOWED_METHODS.has(method)) {
@ -335,7 +335,11 @@ async function main() {
honesty: 'A matching header root served over RPC proves both endpoints serve the same bytes; ' honesty: 'A matching header root served over RPC proves both endpoints serve the same bytes; '
+ 'the load-bearing fact is that Nethermind validates on processing and rejects on ' + 'the load-bearing fact is that Nethermind validates on processing and rejects on '
+ 'disagreement. Consensus is classical secp256k1 ECDSA QBFT plus Falcon; MI is execution ' + 'disagreement. Consensus is classical secp256k1 ECDSA QBFT plus Falcon; MI is execution '
+ 'only and this is not a post-quantum-consensus claim. Not a benchmark.', + 'only and this is not a post-quantum-consensus claim. Not a benchmark. Both endpoints are '
+ 'operated by the same party (the trust root does not move; what is removed is the class '
+ 'of lies needing only one client implementation). State older than the ~512-block RPC '
+ 'state window is not probed. Engine identity of each endpoint is recorded below.',
engines: null,
verdict: null, verdict: null,
}; };
@ -345,6 +349,30 @@ async function main() {
console.log(` Nethermind: ${NETH_RPC}`); console.log(` Nethermind: ${NETH_RPC}`);
console.log(` mode: ${report.mode}${INJECT ? ` (AERE_MI_INJECT=${INJECT})` : ''}`); console.log(` mode: ${report.mode}${INJECT ? ` (AERE_MI_INJECT=${INJECT})` : ''}`);
// endpoint-identity gate: one endpoint agreeing with itself measures nothing
if (BESU_RPC.replace(/\/+$/, '') === NETH_RPC.replace(/\/+$/, '')) {
report.verdict = 'NOT MEASURED: both endpoints are the same URL; agreement of an endpoint with itself is not a measurement';
console.log('RESULT: ' + report.verdict);
return finish(report, 2);
}
// engine identity, recorded so "who answered" travels with every report
try {
const [ebesu, eneth] = await Promise.all([
rpc(BESU_RPC, 'web3_clientVersion', []), rpc(NETH_RPC, 'web3_clientVersion', [])]);
report.engines = { besu: ebesu, nethermind: eneth };
console.log(' engines: ' + ebesu + ' | ' + eneth);
if (String(ebesu).toLowerCase().split('/')[0] === String(eneth).toLowerCase().split('/')[0]) {
console.log(' WARNING: both endpoints report the SAME engine family; the cross-client claim does not hold for this run');
}
} catch (e) { report.engines = { error: String(e.message) }; }
// NOT MEASURED, printed on every run (the contract's non-claims, stated by the tool itself):
console.log(' NOT MEASURED by this harness: post-quantum consensus; independent derivation');
console.log(' (proven only via the follower validate-on-processing behavior); throughput or');
console.log(' latency; who operates the endpoints (same party today); state older than the');
console.log(' ~512-block RPC window; gas accounting beyond the gasUsed commitment.');
// chain-id gate on both endpoints // chain-id gate on both endpoints
const [besuChain, nethChain] = await Promise.all([chainIdOf(BESU_RPC), chainIdOf(NETH_RPC)]); const [besuChain, nethChain] = await Promise.all([chainIdOf(BESU_RPC), chainIdOf(NETH_RPC)]);
report.chainId = { besu: besuChain, nethermind: nethChain }; report.chainId = { besu: besuChain, nethermind: nethChain };
@ -458,7 +486,10 @@ async function main() {
report.verdict = `AGREE: Besu and Nethermind committed identical MI fields ` + report.verdict = `AGREE: Besu and Nethermind committed identical MI fields ` +
`(stateRoot, receiptsRoot, transactionsRoot, logsBloom, gasUsed, hash, parentHash) in BOTH ` + `(stateRoot, receiptsRoot, transactionsRoot, logsBloom, gasUsed, hash, parentHash) in BOTH ` +
`directions for all ${report.blocksCovered} covered blocks, and the pre-state chain links on ` + `directions for all ${report.blocksCovered} covered blocks, and the pre-state chain links on ` +
`both clients. Two independent execution paths derived the same post-state.`; `both clients. What this proves: both endpoints serve identical canonical MI commitments ` +
`(the same bytes) for every covered block. Independent derivation is NOT proven by this ` +
`run alone; it rests on the follower's validate-on-processing behavior, stated in the ` +
`honesty field, and on the recorded engine identities.`;
console.log('RESULT: AGREE across ' + report.blocksCovered + ' blocks (both directions, 0 divergences).'); console.log('RESULT: AGREE across ' + report.blocksCovered + ' blocks (both directions, 0 divergences).');
finish(report, 0); finish(report, 0);
} else { } else {

View File

@ -14,7 +14,9 @@ oracle. Both runs below were executed on this machine (WSL, Rust release build o
Across the harness profiles (mixed-moderate and others), seeds, and thread counts (4, 8, 16), Across the harness profiles (mixed-moderate and others), seeds, and thread counts (4, 8, 16),
the state root produced by optimistic parallel Block-STM is byte-identical to the state root the the state root produced by optimistic parallel Block-STM is byte-identical to the state root the
sequential oracle produces for the same block and pre-state. Zero mismatches. sequential oracle produces for the same synthetic batch and pre-state. Zero mismatches. The
batches are synthetic with designed contention; chain-2800 blocks are empty today, so a
real-block replay under contention does not exist yet for any engine, and that is stated, not hidden.
## Negative control: disable validation, and the oracle goes red ## Negative control: disable validation, and the oracle goes red
@ -39,7 +41,7 @@ the harness catches it on every profile. The source was restored immediately aft
PROVES: the determinism oracle is load-bearing. A green from it means parallel and serial agree, PROVES: the determinism oracle is load-bearing. A green from it means parallel and serial agree,
because the same oracle demonstrably goes red the moment the safety mechanism that guarantees because the same oracle demonstrably goes red the moment the safety mechanism that guarantees
agreement is removed. This is the D-150 discipline applied to parallel execution: the failure agreement is removed. This is the negative-control discipline (a gate that has never failed cannot be believed) applied to parallel execution: the failure
mode of concern (silent state divergence under contention) is exactly the one the negative control mode of concern (silent state divergence under contention) is exactly the one the negative control
plants and the oracle catches. plants and the oracle catches.