{
  "notes": "EPISODE 3 (2026-10-27). Budget: 56 used before, 18 spent now (disprove 15, rerun-evm-reth 1, rerun-hive-reth 1, spec-lag 1) = 74 used, 6 left; episodes 8, this is 3. All 14 earlier batches settled. Two items read nothing (sandbox blocked GitHub and hive: el-evm/reth, hive-failures/reth): re-run now. el-stategas/reth and cl-state/teku line numbers are +/-2-3 (fetch tool). Pins unchanged from episode 2 (reth's EVM is evm2 4a53ec08, patched from DaniPopes/evm2).\n\nCANDIDATE INVENTORY (K=known, NF=not found). EL. Geth: 7928 C1/C2 shared-index netting (K 35776 open, PR 35843 open; needs substituted predeploy code, not canonical); FCU V4 missing targetGasLimit accepted (K intentional PR 35514; Reth same = reth-3 NF; Nethermind rejects). Nethermind: BAL decoder 65,535-change cap (K PR 15276 open; needs >=65,536 txs of one sender); hive 239 fails = wrong error reason in parallel BAL validation, blocks still INVALID (K 15223/15249), consume-rlp 0. Besu: convenience MainnetEVMs.amsterdam uses PragueGasCalculator (K PR 11526; tests/evmtool only), maxUsedGas RPC floor (K 11580), LIGHT body validation skips gas_used (K 11655), EVMExecutor/evmtool burn balance (K 11474), EIP-7843 'affects live code, details withheld' (low confidence, NF). Erigon: 10 MiB BAL byte cap (K intentional PR 24684); txpool reload drops self-transfers (Erigon-1, NF, cosmetic) -> disprove; 7708 DisabledEIPs switch (not L1). Reth: R-1 TX_MAX_TOTAL_GAS_LIMIT not enforced in block executor under 8037 (medium; needs block gas >= 2^32; PRs 27589/27641 closed unmerged) -> disprove; reth-1 missing builder predeploy code does not invalidate block (high; K PR 26695 closed, merge/hive unverified) -> disprove; reth-2 pre-Amsterdam newPayloadV5 gives -32602 not -38005 (NF, cosmetic); evm2 EIP-8246 survivor over pre-existing storage (low, synthetic prestate only). Cross-client D1: negative net state gas at settlement: EELS clamps to 0, Geth+Nethermind reject (K intentional 13178), Erigon clamps with another formula, Reth follows spec; no witness -> disprove. Intrinsic (2780/7976/7981), 7843/7954/8024 and 7708/8246 agree with spec in every client read (Reth el-evm pending re-run; hive 2026-10-26: Geth 2 BAL cross-index fails, Erigon 0, Besu 9/69 unrelated). Spec-text notes: EIP-7981 table stale (2400/1900, 21000) and 'flat surcharge' prose vs both-sides code (equal numbers); EIP-2780 floor prose ambiguous on zero-value calls; EIP-7976 requires-header lacks 3860; EIP-8024 opcodes are 0xe6/0xe7/0xe8 with modular/XOR decoding (brief's old wording wrong); gloas intro pins old EIP revisions; devnet-8 list includes 7610; EIP-7997 has no spec code (must not check factory at fork).\n\nCL. ALL SIX clients implement beta.4 builder onboarding at the fork, not master PR 5736 (merged 2026-10-26): Teku PR 11582 open, Lodestar PR 10428 open, others NF -> spec-lag item checks release/devnet status (is it transient?). Lighthouse (stable): L-1 PTC votes applied before on_block checks (low) -> disprove; L-2 is_head_weak equivocators approximated (K 9593/9831 open); L-3 index-1 attestation: no optimistic IGNORE, no invalid REJECT (K half 10464; Prysm same, PR 17574 open; Lodestar same 10438/9637); L-4/L-5 IGNORE instead of REJECT for invalid block (code TODOs, K 8949 closed); L-6 no gossip REJECT when bid not on parent latest_block_hash (medium NF cosmetic); L-7/8/9 bid gossip prefs key/lookahead/clock disparity (cosmetic); L-10 ByRange pre-Gloas start rejected; L-11 canonical filter by weight (K, spec PR 5608); L-12 no envelope replay after restart (related 10414); L-13 PTC duty needs head at slot (K 9474); min_epochs_for_block_requests fixed 33024 in LH/Prysm/Lodestar/Teku (Lodestar PR 10120 open; cosmetic); 7688 decode-time limits (K intentional 10106); 2 withheld 7732 live-code items. Prysm: P-1 bid seen-cache before later checks (high NF) -> disprove; P-2/P-3 EnvelopesByRange count/start (high NF cosmetic); P-4 REST/gRPC payload attestation without slot check + P-5 queued after slot (NF) -> disprove; P-6 init-sync batch skips PTC votes and marks parent FULL from child bid (medium NF) -> disprove; P-7 restart (K 17735); P-8 previous-slot weight (K 17119 rejected); P-9 proposer reorg parent status (medium-low NF); P-10 optimistic index-1 (K 17574); P-11 verdict order (cosmetic); 8061 weak-subjectivity withheld (live code); 5 withheld 7732 items. Teku: T-2 proposer-boost equivocation suppression missing (K 10608/11020 open, PR 11041 closed); T-3 payload-attestation gossip uses block state not head state (LH same; spec ambiguity) -> disprove; T-4 ByRoot omits non-finalized exception (high NF cosmetic); T-5 envelope poisoning (K 11568/11588 open); transaction-count cap kept in Gloas decoder (medium NF cosmetic); withheld 7732 and 8061 items. Nimbus: N-1 in-block PTC votes write only set bits (medium NF; Lodestar same = lodestar-2) -> disprove; N-2 head-state PTC on stable (K fixed on unstable PR 9341); N-3 bid checks on head state (medium NF; LH-8 similar) -> disprove; N-4 bid verdict order (cosmetic); N-5 is_head_weak node weight incl. boost (low-medium) -> disprove; N-6 quarantined envelope accepted (low); withheld 7688 and 8061 items. Lodestar: JS number precision at 2^53 gwei builder balance (K limitation PR 9835; ~9M ETH in one builder); lodestar-2 -> disprove; lodestar-3 (K); lodestar-4 zero-count ByRange InvalidRequest (low); lodestar-5 weak-head balance fallback (medium NF) -> disprove; 8061 window (K 10120). Grandine: G-1 clock 250 ms early at fork boundary (K PR 989 open; issue 912); G-2 is_head_weak counts slashed as 0 (medium NF) -> disprove; G-3 PTC vote override, IGNORE commented out (high NF) -> disprove; G-4 delayed index-1 block attestations + G-5 async PTC votes (TODOs) -> disprove; G-6 no envelope replay (K 886/887 open); C2 envelope gossip without request-count check, C3 API gossip-only skips body counts, C4 8192 deposit cap in Engine bridge (NF) -> disprove; 8282/7688/8045/8061 other rules agree.\n\nBATCH 'disprove' (15): reth-txcap, reth-builder-code, negative-stategas, lh-ptc-onblock, prysm-bid-seen, prysm-ptc-slot, prysm-batch-sync, ptc-duplicate-seats, grandine-ptc-override, grandine-fc-order, grandine-7688-limits, ptc-gossip-state, bid-gossip-state, headweak-impls, erigon-pool-reload; each ends CONFIRMED / REFUTED / UNDECIDED. Also: rerun-evm-reth, rerun-hive-reth, spec-lag (PR 5736 status).\n\nNEXT EPISODE (4): read the 18 results. If an item read no code because of sandbox blocks, re-run it once with the same vars under a new batch name (6 items left; priority: reth-txcap, reth-builder-code, negative-stategas, prysm-batch-sync, grandine-ptc-override, rerun-hive-reth). Otherwise set finish=true and write the report from the notes plus results. REPORT: (1) EIP list with status, spec files, pins, release tags (episode-2 notes); (2) per layer per client table: candidate, EIP, severity, confidence, known/new, verdict, file#line; (3) cross-client disagreements: D1 negative state gas; targetGasLimit optional (Geth, Reth) vs required (Nethermind); BAL extra caps (Nethermind 65,535 changes, Erigon 10 MiB, none elsewhere); builder onboarding all beta.4; PTC gossip state source (Teku/LH block state, Nimbus-stable head, Prysm dependent root); in-block PTC duplicate seats (Nimbus/Lodestar bits only vs Prysm/Teku all seats); is_head_weak: six different approximations; index-1 optimistic IGNORE missing in LH/Prysm/Lodestar; min_epochs_for_block_requests 33024 everywhere; IGNORE/REJECT verdict orders; (4) withheld live-code entries: Besu 7843; Lighthouse 7732 x2; Prysm 7732 x5 and 8061; Teku 7732 and 8061; Nimbus 7688 and 8061; (5) gaps: nothing executed; hive has no CL data; reth hive failures pending; Reth/Teku line numbers approximate where noted; Geth hive failing-test names unreadable (>10 MB JSON); Besu EVM v2 variants untraced; parallel paths not proven race-free; (6) spec-text issues above. BRIEF RULE: spec-conformance phrasing only, no exploit or reproduction language.",
  "spawn": [
    {
      "name": "disprove",
      "brief": "Public spec-conformance review only: read code, run nothing against any network or node. One CANDIDATE divergence between the {{client}} client and the Glamsterdam spec is given; try to DISPROVE it, then give a verdict. Read code from a shallow clone of https://github.com/{{repo}} at commit {{pin}} (branch {{branch}}) or raw.githubusercontent.com at that commit, not GitHub HTML pages. Spec pins: execution-specs forks/bogota 7f2f4c9b (src/ethereum/forks/amsterdam), consensus-specs master 8a80ffa8 (specs/gloas), EIPs master d4c57552. CANDIDATE: {{candidate}} SPEC: {{spec}} CODE: {{code}} CONDITION: {{condition}} Refutation routes, try all: (1) another check on the same path giving the spec's result; (2) the condition cannot occur on a valid chain (cite the invariant); (3) the spec was misread (quote it); (4) a later commit or merged PR fixes it (api.github.com/repos/{{repo}}/commits?path=<file>); (5) {{checks}} Known: {{known}} Result (markdown): VERDICT CONFIRMED / REFUTED / UNDECIDED with one paragraph why; the strongest refutation attempt; if it survives, the corrected record (spec quote, file#Lstart-Lend at the pin, condition, other client, confidence, severity: consensus split / invalid block accepted / valid block rejected / wrong gas or fee / fork-choice divergence / cosmetic); known-check (issue/PR numbers, states); URLs read. No steps against a live network.",
      "items": [
        {
          "key": "reth-txcap",
          "vars": {
            "client": "Reth",
            "repo": "paradigmxyz/reth",
            "branch": "main",
            "pin": "e0378eb691aa2770bb96fd4ecec2f4445a2a3e7c",
            "candidate": "R-1: under EIP-8037 reth's block executor never rejects a transaction whose gas limit exceeds TX_MAX_TOTAL_GAS_LIMIT (2^32-1); evm2 tx_gas_caps returns (u64::MAX, cap) when EIP8037 is on.",
            "spec": "EIP-8037 'The transaction's gas limit is not higher than TX_MAX_TOTAL_GAS_LIMIT'; transactions.py validate_transaction raises if tx.gas > GasCosts.TX_MAX_TOTAL_GAS_LIMIT (vm/gas.py: 4_294_967_295).",
            "code": "reth crates/ethereum/evm/src/executor.rs validate_transaction_gas_limit (~L270-L300); crates/consensus/common/src/validation.rs; evm2 rev 4a53ec08 (reth Cargo.toml [patch], DaniPopes/evm2) crates/evm2/src/version/mod.rs tx_gas_caps (~L87-L93), crates/evm2/src/ethereum/mod.rs validate_tx_gas_limit; Geth 8817f99f core/state_transition.go preCheck rejects > params.MaxTxTotalGas.",
            "condition": "a block with gas limit above 2^32-1 holding a transaction with gas limit above 2^32-1 that fits the block's execution and state room: spec invalid, reth accepts.",
            "checks": "read crates/engine/tree/src/tree/payload_validator.rs and the txpool validator for any 2^32-1 cap on the block path; find EEST 'cap total transaction gas at 2^32-1' (execution-specs PR 3582) and whether its fixtures use a block gas limit >= 2^32; from hive.ethpandaops.io/glamsterdam-quick/listing.jsonl take the newest reth consume-engine result JSON and report tests named *tx_gas_limit* or *total_gas*; give exact line numbers.",
            "known": "reth PRs 27589, 27641 closed unmerged; 27616 draft closed; revm PR 3957."
          }
        },
        {
          "key": "reth-builder-code",
          "vars": {
            "client": "Reth",
            "repo": "paradigmxyz/reth",
            "branch": "main",
            "pin": "e0378eb691aa2770bb96fd4ecec2f4445a2a3e7c",
            "candidate": "reth-1: with no code at the EIP-8282 builder deposit/exit addresses, reth's system call succeeds with empty output and the block is accepted; the spec makes every block from activation invalid.",
            "spec": "EIP-8282 Deployment: 'If there is no code at either address once the EIP is active, every block from activation onward MUST be invalid'; fork.py#L665-L708 called at #L899-L921.",
            "code": "reth crates/ethereum/evm/src/execution.rs#L390-L451 (no code-existence check); evm2 4a53ec08 crates/evm2/src/system.rs#L139-L188, test #L357-L372 (empty code succeeds); Geth 8817f99f core/state_processor.go#L457-L472 'if evm.StateDB.GetCodeSize(addr) == 0' rejects.",
            "condition": "an Amsterdam block on a state lacking code at 0x0000bff46984e3725691fa540a8c7589300d8282 or 0x000064d678505ad48f8ccb093bc65613800e8282, commitments matching the no-op result: reth accepts, spec and Geth reject.",
            "checks": "read api.github.com/repos/paradigmxyz/reth/pulls/26695 (merged_at?) and whether alloy-evm or evm2 gained the check after the pin; from hive.ethpandaops.io/glamsterdam-quick/listing.jsonl take the newest reth consume-engine result JSON and report tests named *contract_deployment* (EIP-8282, fail_on_empty_code).",
            "known": "reth PR 26695 closed (merge state unverified); Nethermind 15223 fails the same fixtures for another reason."
          }
        },
        {
          "key": "negative-stategas",
          "vars": {
            "client": "Geth, Nethermind, Erigon and Reth (EIP-8037, cross-client)",
            "repo": "ethereum/go-ethereum",
            "branch": "master",
            "pin": "8817f99f92852f8ac53e596de6202dd9e3494065",
            "candidate": "D1: when a transaction's net state gas is negative at settlement, execution-specs clamps it to 0; Geth and Nethermind reject the transaction (block invalid); Erigon clamps with another formula; Reth/evm2 follows the spec. No valid transaction reaching a negative total has been found.",
            "spec": "vm/gas.py#L1211-L1227 settle_transaction_gas: StateGas(Uint(max(0, state_gas_used))), docstring 'refunds can drive it negative'; refills at vm/instructions/storage.py#L141-L158, vm/gas.py#L493-L517, #L594-L647, vm/eoa_delegation.py#L295-L319.",
            "code": "Geth core/state_transition.go#L1046-L1050, core/vm/gascosts.go#L159-L166, #L208-L249; Nethermind d48833af Nethermind.Evm/TransactionProcessing/TransactionProcessor.cs#L1967-L1978; Erigon f32a39d1 execution/protocol/mdgas/md_gas.go#L79-L88, execution/protocol/txn_executor.go#L687-L709; evm2 4a53ec08 crates/evm2/src/ethereum/mod.rs#L792-L806.",
            "condition": "a transaction whose state-gas refills (SSTORE clear refill, failed-create refund, child-frame returns) exceed its state-gas charges, so the top-frame net is negative while all else is valid.",
            "checks": "enumerate every spec site that lowers state_gas_used or returns reservoir and bound each against the charge it reverses in the same transaction (child clearing a parent-created slot, nested REVERT, EIP-7702 set/clear, CREATE collision or OOG); give an opcode sequence in words reaching a negative total, or the invariant forbidding it; quote any spec discussion of the clamp.",
            "known": "Nethermind PR 13178 (intentional reject); execution-specs 3518 closed; none on clamp-vs-reject."
          }
        },
        {
          "key": "lh-ptc-onblock",
          "vars": {
            "client": "Lighthouse",
            "repo": "sigp/lighthouse",
            "branch": "stable",
            "pin": "a376defa30470923556d91bdeb15a802e297f31f",
            "candidate": "lighthouse-1: a block's payload attestations are applied to fork choice (on_payload_attestation, AttestationFromBlock) before the fork-choice on_block checks run; nothing undoes them if on_block then fails.",
            "spec": "specs/gloas/fork-choice.md#L1058-L1061, #L1067-L1076 (is_payload_verified(parent) when the parent is full; finalized-descendant asserts) run before notify_ptc_messages at #L1094-L1095; a failed assert records no PTC vote.",
            "code": "beacon_node/beacon_chain/src/block_verification.rs#L1782-L1805; consensus/fork_choice/src/fork_choice.rs#L828-L879 (ParentPayloadNotVerified, FinalizedSlot, NotFinalizedDescendant at import); gossip checks block_verification.rs#L989-L999; Prysm eb681c1d beacon-chain/blockchain/process_block.go#L79-L91 inserts first.",
            "condition": "a block passes the state transition but fails on_block (finalization advanced meanwhile, or its full parent's payload is unverified): the parent's PTC timeliness/availability votes rise in Lighthouse but not in the spec store, which can flip should_extend_payload or should_build_on_full.",
            "checks": "trace every path into block_verification.rs L1782 (gossip, RPC, range sync, backfill) and whether each already enforced the finalized-descendant and full-parent checks; decide whether a parent payload status can change between those checks and import; check whether on_block failure reverts the write and whether a rejected block's PTC votes can differ from gossip-received ones.",
            "known": "not found in sigp/lighthouse; 9593 (open) is is_head_weak, not this."
          }
        },
        {
          "key": "prysm-bid-seen",
          "vars": {
            "client": "Prysm",
            "repo": "OffchainLabs/prysm",
            "branch": "develop",
            "pin": "eb681c1d13b57c2d0c5da27a63bb41ac9d071e1a",
            "candidate": "prysm-1: validate_execution_payload_bid marks the (slot, parent hash, parent root, builder) tuple seen right after signature verification, before the later IGNORE checks (highest value, can cover, not exiting, parent known, gas limit, head compatibility); a builder's corrected bid for the same tuple is then IGNOREd although the spec accepts it.",
            "spec": "specs/gloas/p2p-interface.md#L968-L983 (first-bid IGNORE on bid_key) and #L1081-L1083 (seen.execution_payload_bids.add after all checks at #L1033-L1090).",
            "code": "beacon-chain/sync/validate_execution_payload_bid.go#L69-L74 (hasSeen; comment 'a hit here implies a valid-sig bid was already seen'), #L120-L123 (setSeen after VerifySignature), #L124-L168 (later checks), #L189-L206 (key); Lighthouse a376defa beacon_node/beacon_chain/src/payload_bid_verification/gossip_verified_bid.rs#L304-L316, observe_bid #L474-L477 agree with the spec.",
            "condition": "an active funded builder's first signed bid for a tuple fails a later IGNORE check for a reason that clears within the slot (parent envelope late, head not moved, balance short, gas-limit target); its corrected bid is dropped for the rest of the slot.",
            "checks": "look for seen-cache removal or expiry on failure, or a second lookup keyed with value or gas limit; search consensus-specs PRs/issues on when seen.execution_payload_bids is written (dedup-before-checks accepted policy?); read Prysm PRs 16832, 16539, 17237, 17405 for intent.",
            "known": "not found as this bug; Prysm 16832 merged, 16539 merged, 17237 closed unmerged, 17405 merged."
          }
        },
        {
          "key": "prysm-ptc-slot",
          "vars": {
            "client": "Prysm",
            "repo": "OffchainLabs/prysm",
            "branch": "develop",
            "pin": "eb681c1d13b57c2d0c5da27a63bb41ac9d071e1a",
            "candidate": "prysm-4/5: payload attestation messages submitted over REST or gRPC are applied to fork choice without the spec's data.slot == block slot check, and messages queued before their block are replayed on arrival without the current-slot check.",
            "spec": "specs/gloas/fork-choice.md#L1153-L1154 'if data.slot != state.slot: return' with state = store.block_states[data.beacon_block_root]; #L1167-L1169 'if not is_from_block: assert data.slot == get_current_slot(store)'.",
            "code": "beacon-chain/blockchain/receive_payload_attestation_message.go#L27-L50 (no slot check; PtcLookupState #L52-L82); forkchoice/doubly-linked-tree/gloas.go#L537-L548; REST beacon-chain/rpc/eth/beacon/handlers_pool.go#L994-L1046; gRPC .../validator/payload_attestation.go#L64-L119; gossip checks it at beacon-chain/sync/validate_payload_attestation.go#L85-L92; replay beacon-chain/sync/pending_payload_attestation.go#L68-L107; Lighthouse a376defa consensus/fork_choice/src/fork_choice.rs#L1426-L1441 enforces both.",
            "condition": "a current-slot PTC member's message names an older block root (REST/gRPC), or a queued message is applied after its slot ended; Prysm sets PTC bits the spec never records.",
            "checks": "check whether SetPTCVote is reached only for nodes at data.slot through an earlier binding (PtcLookupState failing when the block slot differs); whether the pending queue is pruned at slot boundaries elsewhere; whether the REST handler's current-slot check plus PTC membership makes the older-root case impossible; the exact scope of PR 17555.",
            "known": "PR 17555 merged fixed only the in-block path; not found for REST, gRPC or the queue."
          }
        },
        {
          "key": "prysm-batch-sync",
          "vars": {
            "client": "Prysm",
            "repo": "OffchainLabs/prysm",
            "branch": "develop",
            "pin": "eb681c1d13b57c2d0c5da27a63bb41ac9d071e1a",
            "candidate": "prysm-6: the init-sync batch path onBlockBatch never calls handleBlockPayloadAttestations (notify_ptc_messages), and fillInForkChoiceMissingBlocks -> insertFirstPayloadIfNeeded marks a parent FULL from the first block's bid parent_block_hash alone, before batch signature verification and without a verified envelope.",
            "spec": "specs/gloas/fork-choice.md#L1095 notify_ptc_messages in every on_block; #L1059-L1061 'assert is_payload_verified(store, block.parent_root)' when building on the full parent; #L243 anchor store payloads={}.",
            "code": "beacon-chain/blockchain/process_block.go#L89, #L188-L382 onBlockBatch, #L235 before #L330-L341, #L158-L180; beacon-chain/blockchain/process_block_helpers.go#L444-L469; beacon-chain/core/gloas/parent_payload.go#L49-L56; Lighthouse a376defa consensus/fork_choice/src/fork_choice.rs#L829-L839 agrees with the spec.",
            "condition": "during batch sync a batch whose first block claims a full parent creates the parent's FULL node with no verified envelope, and in-block PTC votes are never applied; if the batch is later rejected the FULL mark stays.",
            "checks": "decide whether batch-synced blocks are always older than the previous slot when sync ends (so PTC votes cannot change a decision) and whether envelopes are verified elsewhere (envelopes[0], ParentPayloadReady) before the node is used for head computation; whether MarkFullNode is rolled back on batch failure; search Prysm issues/PRs for initial sync with envelopes under Gloas.",
            "known": "not found; Prysm PR 17735 (restart rebuild, open) is a different path."
          }
        },
        {
          "key": "ptc-duplicate-seats",
          "vars": {
            "client": "Nimbus and Lodestar",
            "repo": "status-im/nimbus-eth2",
            "branch": "stable",
            "pin": "0abc0dd0fc0750a8875c49089d074f7d7197b62c",
            "candidate": "nimbus-1/lodestar-2: applying a block's payload attestations, Nimbus and Lodestar write only the set bit positions; the spec writes every PTC seat the attesting validator holds (duplicates possible).",
            "spec": "specs/gloas/fork-choice.md#L265-L289 notify_ptc_messages dispatches per attesting index; #L1136-L1188 collects every ptc_index whose validator_index matches; beacon-chain.md#L1266-L1269 get_ptc 'with possible duplicates', #L1419-L1424.",
            "code": "Nimbus beacon_chain/fork_choice/fork_choice.nim#L519-L528 (set bits only; wire path fork_choice_epbs.nim#L237-L244 loops every seat); Lodestar e4b4f615 packages/beacon-node/src/chain/blocks/importBlock.ts#L280-L298, packages/fork-choice/src/protoArray/protoArray.ts#L758-L789; Prysm eb681c1d beacon-chain/blockchain/process_block.go#L625-L659 and Teku 2c35574b ForkChoice.java#L1268-L1307 expand every seat.",
            "condition": "a validator holds two or more PTC seats for slot N; a block at N+1 includes a payload attestation setting only some (the aggregate signature over the de-duplicated signer set stays valid); a node that missed the wire message counts fewer votes than the spec near the 256 threshold.",
            "checks": "check whether spec or client block validation requires all of a duplicate validator's bits to be set; how each client's aggregator builds aggregation_bits for duplicate seats; any consensus-spec-tests vector with duplicate PTC seats; both repositories' issues on duplicate PTC positions.",
            "known": "Lodestar PR 9369 merged fixes gossip/pool duplicates only; not found for block import in either client."
          }
        },
        {
          "key": "grandine-ptc-override",
          "vars": {
            "client": "Grandine",
            "repo": "grandinetech/grandine",
            "branch": "develop",
            "pin": "52cd677117b5d93bf477fe4843148070b0303444",
            "candidate": "grandine-3: payload_attestation_message gossip has the 'first valid message from this validator' IGNORE commented out (a TODO asks for implementer consensus) and later messages overwrite earlier PTC votes.",
            "spec": "specs/gloas/p2p-interface.md#L908-L911 ([IGNORE] first valid payload attestation from this validator index, key (data.slot, validator_index)) and #L947-L948 seen.payload_attestation_validators.add.",
            "code": "fork_choice_store/src/store.rs#L4364-L4381 (commented-out IGNORE, returns Accept), #L4787-L4836 apply_payload_attestation_batch overwrites timeliness and availability votes; Nimbus 0abc0dd0 beacon_chain/gossip_processing/gossip_validation.nim#L2005-L2035 errIgnore 'duplicate message from validator' (agrees with spec).",
            "condition": "a PTC member publishes two differently signed messages for the same slot and block (payload_present false, then true); spec nodes keep the first and do not forward the second; Grandine forwards and overwrites, so payload_timeliness counts and the previous-slot FULL/EMPTY tiebreak can differ near 256.",
            "checks": "search consensus-specs issues/PRs for the PTC vote override question the TODO refers to ('payload attestation' override or equivocation); check whether Grandine dedups elsewhere (p2p crate, fork_choice_control tasks, gossipsub message-id); note the spec's handler also overwrites the vote, so say which nodes end up differing.",
            "known": "not found; Grandine 918 and 989 are different."
          }
        },
        {
          "key": "grandine-fc-order",
          "vars": {
            "client": "Grandine",
            "repo": "grandinetech/grandine",
            "branch": "develop",
            "pin": "52cd677117b5d93bf477fe4843148070b0303444",
            "candidate": "grandine-4/5: (a) a block-included index-1 attestation for an unverified payload is queued (DelayUntilPayload) and applied when the envelope arrives, where the spec asserts is_payload_verified and records nothing; (b) a block's payload attestations are applied by a separate task after apply_block has computed the head.",
            "spec": "specs/gloas/fork-choice.md#L942-L944 (index 1: assert is_payload_verified, also for is_from_block); #L1086-L1098 on_block order: store block, reset PTC votes, notify_ptc_messages, record timeliness, proposer boost, before any get_head.",
            "code": "fork_choice_store/src/store.rs#L3206-L3218 (TODO; returns DelayUntilPayload), #L2188-L2196, #L4548-L4685 apply_block; fork_choice_control/src/mutator.rs#L3630, #L5261-L5284; fork_choice_control/src/tasks.rs#L430-L463; Nimbus 0abc0dd0 beacon_chain/fork_choice/fork_choice.nim#L519-L529 tallies before insertion.",
            "condition": "(a) an imported block carries an index-1 attestation for block R whose envelope has not passed on_execution_payload_envelope locally: once it arrives Grandine counts the vote toward R's FULL node, the spec never does; (b) between import of B and task completion, head decisions are made without B's PTC votes.",
            "checks": "for (a) decide whether the delayed attestation is re-validated under the is_from_block rule when applied, and whether the spec's on_block would have rejected the whole block; for (b) whether any duty or head query can run between apply_block and the task result (is it awaited before the head is published?); check Grandine issues for the TODOs.",
            "known": "not found; Grandine 886/887 and 989 are different."
          }
        },
        {
          "key": "grandine-7688-limits",
          "vars": {
            "client": "Grandine",
            "repo": "grandinetech/grandine",
            "branch": "develop",
            "pin": "52cd677117b5d93bf477fe4843148070b0303444",
            "candidate": "C2/C3/C4: (C2) envelope gossip skips verify_execution_requests_limits (builder exits 16, deposits 64); (C3) the Beacon API gossip-only block validation omits body operation-count checks (5 payload attestations, limit 4), publishing it; (C4) the Engine bridge narrows validator deposit requests to 8192 elements although Gloas DepositRequests is uncapped.",
            "spec": "specs/gloas/p2p-interface.md#L509-L528, #L866-L879, #L470-L501, #L597-L603; beacon-chain.md#L272-L280 DepositRequests ProgressiveList, #L1784-L1795 (limits exclude validator deposits); beacon-APIs blocks.v2.yaml#L19-L37.",
            "code": "fork_choice_store/src/store.rs#L4174-L4256; transition_functions/src/gloas/block_processing.rs#L116-L136, #L759-L787, #L920-L960; http_api/src/standard.rs#L5083-L5101, #L5273-L5288; execution_engine/src/types.rs#L1094-L1099, #L1351-L1374, #L1398-L1404; types/src/preset.rs#L411-L433; Nimbus 0abc0dd0 gossip_validation.nim#L909-L917, #L608-L641 agree with spec.",
            "condition": "C2: a signed envelope with 17 builder exits or 65 builder deposits: spec REJECT, Grandine ACCEPT; C3: API publication of a block with 5 payload attestations: Grandine publishes; C4: a legal payload with 8,193 validator deposit logs: Grandine fails Engine encoding and rejects a valid block.",
            "checks": "for C4 compute the minimum gas for 8,193 deposit-contract deposits (deposit call cost, EIP-8037 tx cap 2^24) and at which block gas limit it is reachable; for C2/C3 check whether a later step (state transition, the API's full-validation default) keeps the invalid object from affecting any peer or the head; read Grandine 997, 968, 918.",
            "known": "not found; Grandine 918 open, 997 and 968 merged."
          }
        },
        {
          "key": "ptc-gossip-state",
          "vars": {
            "client": "Teku, Lighthouse and Nimbus",
            "repo": "Consensys-Incorporated/teku",
            "branch": "master",
            "pin": "2c35574b3373cbe8ad121a768d98f066aec05b73",
            "candidate": "teku-3/nimbus-2/Lighthouse: the PTC used to validate payload_attestation_message gossip comes from the referenced block's state (Teku, Lighthouse) or the head state (Nimbus stable); the spec's gossip rule uses the head state, its fork-choice handler the block's state.",
            "spec": "specs/gloas/p2p-interface.md#L926-L945 'state = store.block_states[get_head(store).root]' then get_ptc(state, data.slot); specs/gloas/fork-choice.md#L1139-L1164 uses store.block_states[data.beacon_block_root]; beacon-chain.md#L1266-L1281 get_ptc is state-dependent.",
            "code": "Teku .../statetransition/payloadattestation/PayloadAttestationMessageGossipValidator.java#L156-L198; Lighthouse a376defa beacon_node/beacon_chain/src/payload_attestation_verification/gossip_verified_payload_attestation.rs#L101-L118; Nimbus 0abc0dd0 beacon_chain/gossip_processing/gossip_validation.nim#L2042-L2052, fork_choice_epbs.nim#L234-L248 (headState; unstable PR 9341); Prysm eb681c1d beacon-chain/sync/validate_payload_attestation.go#L98-L113.",
            "condition": "two validated branches with different current-slot PTCs; head on one, the message names a same-slot block on the other: membership and signature verdicts differ between head-state and block-state readers.",
            "checks": "read the gossip rule's history (consensus-specs commits for specs/gloas/p2p-interface.md) and any PR/issue on which state get_ptc should use; decide whether get_ptc for slot S can differ between branches that split after the shuffling dependent root (if not, the candidate is near-unreachable); say which clients follow which.",
            "known": "not found for Teku/Lighthouse; Nimbus PR 9341 merged on unstable."
          }
        },
        {
          "key": "bid-gossip-state",
          "vars": {
            "client": "Nimbus and Lighthouse",
            "repo": "status-im/nimbus-eth2",
            "branch": "stable",
            "pin": "0abc0dd0fc0750a8875c49089d074f7d7197b62c",
            "candidate": "nimbus-3/lighthouse-8: execution_payload_bid gossip checks (builder index valid, active, can cover bid, signature) run on the head state instead of the parent state advanced to bid.slot; Lighthouse also lacks the proposer-lookahead IGNORE.",
            "spec": "specs/gloas/p2p-interface.md#L951-L1085: state = store.block_states[bid.parent_block_root]; process_slots(state, bid.slot); builder checks and signature on that state; #L1013-L1015 lookahead IGNORE; beacon-chain.md#L1054-L1064 is_active_builder depends on finalized_checkpoint.epoch.",
            "code": "Nimbus beacon_chain/gossip_processing/gossip_validation.nim#L1881-L1907 (withState(dag.headState)); Lighthouse a376defa beacon_node/beacon_chain/src/payload_bid_verification/gossip_verified_bid.rs#L130-L155, #L462-L472 (head_state), no lookahead; Prysm eb681c1d beacon-chain/sync/validate_execution_payload_bid.go#L81, #L95-L97 agree with spec.",
            "condition": "(a) a bid for the first slot of a new epoch when epoch processing moves finality or settles exits/pending payments: spec accepts, a head-state reader REJECTs, or the reverse; (b) a bid building on the head's parent: the head state already includes the head block's effect on builders.",
            "checks": "check whether Nimbus or Lighthouse advance the head state to the wall-clock slot before gossip validation so case (a) collapses; whether is_bid_compatible_with_head restricts parents so case (b) cannot differ; whether the later state transition re-validates the bid with the right state so only the gossip verdict differs.",
            "known": "not found in either repository."
          }
        },
        {
          "key": "headweak-impls",
          "vars": {
            "client": "Grandine, Lodestar and Nimbus",
            "repo": "grandinetech/grandine",
            "branch": "develop",
            "pin": "52cd677117b5d93bf477fe4843148070b0303444",
            "candidate": "grandine-2/lodestar-5/nimbus-5: is_head_weak differs: Grandine adds justified_active_balances (0 if slashed or inactive) not effective_balance; Lodestar falls back to head-state balance when the justified cache lacks it; Nimbus stable uses a proto-array node weight that can include proposer boost, omitting FULL.",
            "spec": "specs/gloas/fork-choice.md#L807-L833: head_weight = get_attestation_score(store, PENDING head node, justified_state) + sum(justified_state.validators[i].effective_balance for committee members in store.equivocating_indices); used by should_apply_proposer_boost #L531-L561.",
            "code": "Grandine fork_choice_store/src/store.rs#L1501-L1524, #L6328-L6344, #L1630-L1667; Lodestar e4b4f615 packages/fork-choice/src/forkChoice/forkChoice.ts#L1717-L1754; Nimbus 0abc0dd0 beacon_chain/fork_choice/fork_choice_epbs.nim#L138-L158, proto_array.nim#L282-L319; Teku 2c35574b ForkChoiceUtilGloas.java#L463-L536 agrees.",
            "condition": "an equivocating committee member already slashed or not yet active in the justified state, or a boosted child, moves the parent's weight across REORG_HEAD_WEIGHT_THRESHOLD; with an early equivocating sibling, boost is withheld by one implementation and applied by another.",
            "checks": "for each client bound the difference against the threshold (can the boolean flip?) and check that should_apply_proposer_boost is reached in production; check whether a slashed validator's effective_balance is already zero in the justified state (collapsing the Grandine case); search each repo's issues for is_head_weak.",
            "known": "Lighthouse 9593/9831 open; Lodestar 9232 open, 9654 merged; not found for Grandine or Nimbus."
          }
        },
        {
          "key": "erigon-pool-reload",
          "vars": {
            "client": "Erigon",
            "repo": "erigontech/erigon",
            "branch": "main",
            "pin": "f32a39d1e5f87a9ec3a9ce2858171c74acc3c242",
            "candidate": "Erigon-1: on txpool reload from the database (fromDB) transactions are parsed with withSender=false, so GetSender returns false and IsSelfTransfer is false in validateTx; a persisted self-transfer with gas between the spec intrinsic and the overstated figure is discarded with reason IntrinsicGas (txpool only).",
            "spec": "transactions.py#L736-L747 is_self_transfer = tx.to == sender; self-transfers skip COLD_ACCOUNT_ACCESS and TX_VALUE_COST; EIP-2780 'A self-transfer charges neither the recipient touch nor the value cost'.",
            "code": "txnprovider/txpool/pool.go#L1047-L1056 (IsSelfTransfer: senderOk && ...), #L1081-L1085, #L2794-L2796, #L2808-L2823 (WithSender(false); validateTx after getOrCreateID); txnprovider/txpool/pool_txn_parser.go#L396-L415; execution/types/legacy_tx.go#L87-L92 GetSender; Reth passes the recovered sender.",
            "condition": "an Amsterdam node restarts with a persisted self-transfer whose gas limit is at least the spec intrinsic but below it plus 3000 (zero value) or 9000 (with value): dropped from the pool on every restart although block validation accepts it.",
            "checks": "look for any sender assignment between parse and validateTx in fromDBLocked (SetSender, SenderID to address lookup) or a validateTx path resolving the sender from the senders table; whether the pool re-validates later with the sender set (best, promote); read Erigon 25273, 21942 and commits after the pin touching pool.go fromDB.",
            "known": "not found; Erigon 25273 open (reload blockGasLimit=0), 21942 open."
          }
        }
      ],
      "output": {
        "format": "markdown",
        "maxBytes": 24000
      },
      "merge": {
        "groupSize": 25,
        "brief": "Merge the supplied disproof results into one markdown report. Keep every item's VERDICT, its one-paragraph reason, its corrected candidate record and known-check verbatim, under a heading per item key. Add a summary table at the top: item key, client(s), verdict, severity, known/not found. Add nothing of your own and drop nothing."
      }
    },
    {
      "name": "rerun-evm-reth",
      "brief": "Public-page spec-conformance review only: read code, run nothing against any network or node. Compare the {{client}} execution client's implementation of EIP-7843 (SLOTNUM), EIP-7954 (max contract size) and EIP-8024 (DUPN/SWAPN/EXCHANGE) for Ethereum's Amsterdam fork (Glamsterdam, not live on mainnet) with the specification. Read code from a shallow clone of https://github.com/{{repo}} or raw.githubusercontent.com, not GitHub HTML pages; pin the newest commit on branch {{branch}} via api.github.com/repos/{{repo}}/commits/{{branch}}, or if that host is refused via `git ls-remote` or the clone's HEAD; quote the hash and cite every file as path#Lstart-Lend at it. {{client}}'s EVM lives in the evm2 dependency: read Cargo.toml for the [patch] of alloy-rs/evm2 (last seen DaniPopes/evm2 rev 4a53ec080dfbb904e98e3ca8f0abcc11ab8abae0) and read those files at that rev. Reference: execution-specs branch forks/bogota at 7f2f4c9bf6d73b09ecb8b24eb14d08bf0cf0247b, dir src/ethereum/forks/amsterdam (vm/instructions/block.py slotnum, vm/stack.py decode_single/decode_pair, vm/instructions/stack.py, vm/interpreter.py code-size limits, vm/runtime.py jumpdest analysis, blocks.py header, transactions.py); EIP texts at eips.ethereum.org (current EIP-8024: DUPN 0xe6, SWAPN 0xe7, EXCHANGE 0xe8; decode_single (x+145)%256 with immediates 91-127 invalid; decode_pair k=x^143, q,r=divmod(k,16), (q+1,r+1) if q<r else (r+1,29-q), immediates 82-127 invalid; JUMPDEST analysis unchanged). Check: SLOTNUM 0x4b gas 2 pushes header slot_number as uint64, invalid before Amsterdam, header field last after block_access_list_hash and present iff Amsterdam, payload attributes and newPayloadV5 slot into the header, first-Amsterdam-block slot; MAX_CODE_SIZE 0x10000 and MAX_INITCODE_SIZE 0x20000 with strict > on deposit, CREATE/CREATE2 and create-transaction init code, init-code word gas unchanged, fork switch, EIP-7702 delegation to large code; the three stack opcodes' decoding, underflow, 1024 overflow, missing immediate (reads 0, pc += 2), gas 3, invalid immediate halts, jumpdest scanning. Compare with Geth at master 8817f99f92852f8ac53e596de6202dd9e3494065 on every rule. For every place where {{client}}'s result (gas, state, validity, encoding) differs from the spec give: (1) spec text verbatim, (2) client code verbatim with file#line, (3) the block/transaction/state condition under which the result differs, in words, (4) Geth's behaviour, (5) confidence and what you tried to disprove it, (6) severity (consensus split / invalid block accepted / valid block rejected / wrong gas or fee / cosmetic). Prefer no candidate to a weak one; list rules checked and found correct in a table. Known-check: search api.github.com/search/issues?q=repo:{{repo}}+<term> for 7843, slotnum, 7954, 'contract size', 8024, SWAPN, DUPN, EXCHANGE (issues and PRs, open and closed) and mark each candidate known/not found with numbers and states. List URLs read. Report plainly any source you could not read and the error.",
      "items": [
        {
          "key": "reth",
          "vars": {
            "client": "Reth",
            "repo": "paradigmxyz/reth",
            "branch": "main"
          }
        }
      ],
      "output": {
        "format": "markdown",
        "maxBytes": 40000
      }
    },
    {
      "name": "rerun-hive-reth",
      "brief": "Public-page research only. From https://hive.ethpandaops.io/glamsterdam/listing.jsonl and https://hive.ethpandaops.io/glamsterdam-quick/listing.jsonl (if a direct fetch returns 403, retry with a browser-like User-Agent header and through the sandbox proxy with curl -x \"$HTTP_PROXY\"; another item of this goal read them on 2026-10-27), and the per-run result JSON files they name at https://hive.ethpandaops.io/<listing>/results/<file> (read the JSON directly; the HTML dashboard does not render for readers; for a file over 10 MB stream it and filter testCases with summaryResult.pass == false instead of loading it whole), list every failing test in the newest run of each suite (eels/consume-engine, eels/consume-enginex, eels/consume-rlp, eels/consume-wirex, eels/execute) for the {{client}} execution client. For each failing test: suite, run date, client version string, test name/path, the EIP named by the path, and the failure message from the run's testDetailsLog (use HTTP Range with the byte offsets in summaryResult.log). Then group by EIP with counts, say which failures appeared or disappeared between the two newest runs of each suite, and for each group search api.github.com/search/issues?q=repo:{{repo}}+<term> (issues and PRs, open and closed) with the test name, the EIP number and the error text to find a matching report; give number, title, state. Pay particular attention to: EIP-8282 builder contract deployment tests (test_contract_deployment, fail_on_empty_code; {{client}} PR 26695), EIP-8037 'cap total transaction gas at 2^32-1' tests, and EIP-7928 BAL tests. Known context: on 2026-10-26 {{client}} had 1626 consume-engine and 3094 consume-enginex failures on glamsterdam; quick runs on 2026-10-27 showed 23/23/6/4. Result (markdown): per-suite tables, an EIP summary table with issue matches, and the URLs read. Report plainly if a source could not be read and the HTTP status. Run nothing against any node.",
      "items": [
        {
          "key": "reth",
          "vars": {
            "client": "reth",
            "repo": "paradigmxyz/reth"
          }
        }
      ],
      "output": {
        "format": "markdown",
        "maxBytes": 40000
      }
    },
    {
      "name": "spec-lag",
      "brief": "Public-page research only. Determine the status of consensus-specs PR 5736 ('Separate builder and validator deposits at the Gloas fork', merged 2026-10-26 as 8b374fa8) across the Ethereum consensus clients and test releases, so a final report can say whether the v1.7.0-beta.4-style builder onboarding found in all six clients ({{clients}}) is a live risk or a transient lag. Read: (1) https://api.github.com/repos/ethereum/consensus-specs/releases (is there a v1.7.0-beta.5 or later containing 5736? tag and date) and the consensus-spec-tests release whose gloas/fork vectors reflect the new routing; (2) for each client repository ({{repos}}) search issues and PRs, open and closed, via api.github.com/search/issues?q=repo:<r>+<term> for '5736', 'onboard builders', 'builder deposits fork', 'beta.5'; record any PR implementing the new routing with its state and merge date, and whether the default branch's newest commit (api.github.com/repos/<r>/commits/<branch>) still has the old order (read the onboarding file at that commit via raw.githubusercontent.com and quote the first routing check); (3) https://notes.ethereum.org/@ethpandaops/glamsterdam-devnet-11 and any newer devnet note, and the ethereum/pm ACDC issues from 2026-10-16 onward, for which spec version the devnets and the Sepolia and Hoodi Glamsterdam forks target and whether 5736 is scheduled for a devnet; (4) whether Sepolia (Gloas fork epoch 353024) and Hoodi (132352) already passed the fork with the old routing, which would make fork-time onboarding a past one-time event there; (5) https://blog.ethereum.org/2026/10/22/glamsterdam-hoodi-delay for the current schedule. Result (markdown): a table per client (pin, old or new routing at the newest commit, PR number and state), the spec release status, the devnet and testnet target versions, and a one-paragraph verdict: 'transient lag, fixed before any network forks on master', 'live divergence risk on <network>', or 'undetermined', with every claim cited by URL. Run nothing against any network or node.",
      "items": [
        {
          "key": "pr5736",
          "vars": {
            "clients": "Lighthouse stable a376defa consensus/state_processing/src/upgrade/gloas.rs#L258-L303; Prysm eb681c1d beacon-chain/state/state-native/setters_gloas.go#L808-L843; Teku 2c35574b ethereum/spec/src/main/java/tech/pegasys/teku/spec/logic/versions/gloas/forktransition/GloasStateUpgrade.java#L222-L268; Nimbus 0abc0dd0 beacon_chain/spec/beaconstate.nim#L2360-L2405; Lodestar e4b4f615 packages/state-transition/src/slot/upgradeStateToGloas.ts#L211-L245; Grandine 52cd6771 helper_functions/src/fork.rs#L984-L1059",
            "repos": "sigp/lighthouse (stable and unstable), OffchainLabs/prysm (develop), Consensys-Incorporated/teku (master), status-im/nimbus-eth2 (stable and unstable), ChainSafe/lodestar (unstable), grandinetech/grandine (develop)"
          }
        }
      ],
      "output": {
        "format": "markdown",
        "maxBytes": 24000
      }
    }
  ],
  "read": [],
  "cancel": [],
  "wake": {
    "batches": [
      "disprove",
      "rerun-evm-reth",
      "rerun-hive-reth",
      "spec-lag"
    ],
    "afterMinutes": 240
  },
  "finish": false
}
