Mainnet prep 2026-09-23: network isolation, mining readiness, self-qualifying release artifact - #136
Merged
Merged
Conversation
… changing behavior
…d remaining gates
…of reading mainnet M23-NET, F-M23-02. A malformed UNIVERSE_CHAIN_NETWORKS value or an unsupported network used to be dropped with a warning, and the chain then read mainnet. An explicit setting that is wrong now resolves to a typed unavailable result with a reason; absent or omitted settings still read mainnet. Keys and networks are pinned to the overlay's explorer-context contract (dogecoin, zcash, fractal). Every caller changes together: chain reads are deferred and fail with ChainNetworkUnavailableError before any request, the picker skips the chain and names the setting invalid, the websocket opens no socket, bookmarks and visits are never filed under a substitute network, and the dashboard, mining and chain pages render a recoverable configuration error. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…k Core reading M23-HEALTH, F-M23-03. Mining was reported ready whenever the blocks and pools tables had rows; production published ready with the index at 968172 and Core at 968299. Readiness now compares the highest indexed block with Core's height, requiring the reading to be under 120 s old and from the served network, within MEMPOOL.MINING_MAX_BEHIND_TIP (default 3). A missing, stale or other-network reading is the new unknown state; Core in initial block download is syncing; an index ahead of Core after a reorganization withholds readiness. The report now carries indexedTip, bitcoinCoreTip, lagBlocks and maxLagBlocks. backend-info records Core's chain name so the comparison can be matched to a network. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…nd qualify the packed archive M23-PACK, F-M23-01. The artifact workflow staged docs/ but left it out of the tar member list, and never staged the evidence files the acceptance envelope names, so a candidate qualified in the checkout could not qualify on the host. protocol-contract.mjs --stage-acceptance copies the manifest, envelope and complete evidence closure under docs/, checking every file with the gate's own rules (plain docs/ path, inside the root, not a symlink, recorded SHA-256) before and after the copy. docs is now packed, and qualify-artifact.mjs lists the archive (refusing traversal, absolute names and links in the evidence tree), extracts it into an empty directory and runs the gate the archive carries, before upload. release-artifact.test.mjs proves it on real gzip tar archives: a valid Signet-qualified Mainnet candidate, missing docs, missing nested evidence, tampered bytes, a symlink member, traversal names and stale revisions. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…e changed sources The prepared branch's annotation already left the matrix stale. Still FUNCTIONAL NO-GO with operationDenominatorReconciled false and zero real-network passes; nothing here is an acceptance result. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… verified Fulcrum outage cause Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ne read at a time With an electrum or Core backend, restoring the RBF cache read every unexpired cached transaction sequentially before the HTTP server listened. On 2026-09-23 that was 8,044 reads through the new Core RPC tunnel, and the explorer API stayed down for about half an hour on each restart while the watchdog kept restarting a stalled block loop. Eight concurrent reads, each still caught on its own, well inside the shared RPC budget. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…uest Against Core (electrum or none backends), every block transaction missing from the mempool cost two RPC round trips: the transaction and its block header. Since Core moved behind a 115 ms tunnel on 2026-09-22 that is about 0.5 s per transaction and roughly thirty minutes for a block the mempool no longer holds, which is the main loop watchdog's whole budget. The explorer stalled at 968172 and the watchdog restarted it repeatedly. When more than 50 transactions are missing, $getTransactionsExtended now builds them from one verbose getblock (status from the block, fee from Core's own field, no prevouts, exactly as the per-transaction path did with prevouts off), and falls back to per-transaction reads if that read fails. Stale blocks and esplora keep their existing paths. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Implements the three code work packages from the 2026-09-23 mainnet preparation (
audit/mainnet-prep-20260923-1745, 161b7bd). This is the code half only: it is not functional acceptance and not a release.M23-NET, F-M23-02: explicit invalid network settings never read mainnet
chain-network.tsresolves each chain to a network or a typed unavailable result with a reason. Absent/omitted settings still read mainnet.explorer-context.ts(dogecoin, zcash, fractal).ChainNetworkUnavailableErrorbefore any request. The picker skips the chain and labels it "Network setting invalid". No websocket is opened, and nothing is bookmarked under a substitute network. Dashboard, mining and chain pages show a recoverable configuration error.M23-HEALTH, F-M23-03: mining readiness needs a current index
capabilities.mining.ts: ready only when the highest indexed block is withinMEMPOOL.MINING_MAX_BEHIND_TIP(default 3) of a Core reading that is under 120 s old and from the served network.unknownstate when the reference is missing, stale or from another network.syncingwhile Core is in IBD. Readiness is withheld while the index is ahead of Core (reorg).indexedTip,bitcoinCoreTip,lagBlocksandmaxLagBlocks. The config key is added to the sample, fixture, docker template, start.sh and CONFIGURATION.md.M23-PACK, F-M23-01: the artifact carries and proves its own acceptance
protocol-contract.mjs --stage-acceptancestages the manifest, the envelope and the full evidence closure underdocs/, using the gate's own path and digest rules.docsis now in the tar member list.qualify-artifact.mjsqualifies the packed archive before upload. It refuses traversal, absolute names and links in the evidence tree, then extracts to an empty dir and runs the gate the archive carries.release-artifact.test.mjscovers real gzip tar archives: a valid Signet-qualified Mainnet candidate, missing docs, missing nested evidence, tampered bytes, a symlink member, traversal and stale revisions.Verification (Windows SERVER, Node 24.19.0 / npm 11.17.0)
build:universesucceeds.tscclean; lint 0 errors. New capability tests andconfig.test.tspass. Three untouched intelligence suites (message-signature, payjoin proposal-analysis, simplicity formal-checker) fail on this host because they spawn native verifier binaries it lacks; CI runs them on Linux.--checkholds 39 protocols,acceptance-matrix --checkpasses after regeneration (still NO-GO, denominator unreconciled, 0 real passes),bash -n release.sh, text gate.Operational note (separate from this diff)
The live address outage and stalled ingestion had one verified cause. Fulcrum (127.0.0.1:50001) stopped at 13:05 UTC on 2026-09-22 when Bitcoin Core migrated to the OVH node, and nothing restarted it. It was restarted with its data intact, caught up 175 blocks, and
addressLookupreports ready again.🤖 Generated with Claude Code