From 1cf850c9edec4d1159854263be15852f7409b5b6 Mon Sep 17 00:00:00 2001 From: igneum-josh <337424239+igneum-josh@users.noreply.github.com> Date: Wed, 7 Oct 2026 13:31:00 +0100 Subject: [PATCH 01/19] Counter ASIC 3.0 status: the fifth commit c4459193, the shutdown test green, the kept-datadir carry Co-Authored-By: Claude Fable 5.1 --- docs/plans/counter-asic-3-status.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/plans/counter-asic-3-status.md b/docs/plans/counter-asic-3-status.md index 2efdf2cf8..f8ab87726 100644 --- a/docs/plans/counter-asic-3-status.md +++ b/docs/plans/counter-asic-3-status.md @@ -338,7 +338,7 @@ Josh gave the go in advance for tonight: the shipper runs publish 1 on the 0.3.1 | THE ANALYSIS (the hash lane, ca3-v4-uniform 095f84a7, `docs/analysis/ca3-v4-uniform.md`, the tool on igneum-build-1) | the window model moves the null from 0.115 to 0.160 percent (1.39x, not 4.05x); the rest is a FAULT beyond it: site 15 reads a register last written by `or r6, r4`, so all-ones recurs at (3/4)^32 per read and the era map sends it to F8's hottest item exactly (the popcount model predicts 77,348 all-ones reads against 78,479; the top-0.1-percent share 0.58 against 0.52); it passes the acceptance rule because part (a) takes any write as a fresh source and part (c) counts saturation on final values only. The census of 1,024 chain-shaped v4 programs: 96.6 percent carry a lossy-sourced load (or, mul, mulhi as the last writer), 48.5 percent an or-sourced one (0.30 percent of all reads per site), 4.9 percent an or-of-or chain (4.6 percent of all reads on 0.1 percent of items); F8's 1.2x gate fails 96.6 percent of today's programs. Worth to a chip: 1.07 MB of SRAM ($0.25) serving 0.52 percent of a typical program's reads and 4.6 percent of the worst class's, at most 1.005x and 1.048x in rate; the ceiling under rule (c)'s 120-of-128 floor one site repeating its item in all 8 iterations, 6.25 percent of reads, 1.067x in 64 bytes; the 2x margin stands; the public line says "bounded at 1.067x", not "uniform" (the public text corrected) | | The two options, priced, STOPPED at the coordinator for Josh's word | A: a 0.3.19 class amendment before the flip (the generator draws a load's source from the registers whose last writer injects): a new program stream, new vectors, the seven gate packs re-exported, the six gates again (G1 to G3 and the verifier about an hour on the Mac and PC 2; G4 to G6 the node lane), every node before the flip under the one-box-at-a-time rule; the risk a node that misses the build splits the chain at the flip. B: hold the flip at the floor with v4 as it is; the bound documented; the source rule to class v5: a hot set worth up to 1.005x on about half the hours and 1.05x on 5 percent, 1.067x at the ceiling; no chain risk. The number: 1.067x at the ceiling against the 2x margin. The lane recommends B | | The v5 bound (sent to the v5 lane) | H = W_0.1 (the window term, 0.115 to 0.251 percent) + the sum over load sites of h(last writer) (or 0.30 percent, an or chain 4.5, mul 0.067, mulhi 0.049, an injecting op or a rotate 0), H at or under 1.2 x W_0.1, which is the static rule "every load's source was last written by an injecting op or a rotate"; as a rejection it costs 96.6 percent of candidates (about 30 attempts per seed), as a generator draw nothing; gate F8's 64-seed census with the saturated-source count | -| JOSH'S WORD (15:2x UK, 7 October): OPTION A, "do this but limit the testing, get it pushed" | the class v4 amendment: a load's source drawn only from registers whose last writer injects or is a rotate (the v5 rule applied now), a new program stream and vectors, the seven gate packs re-exported, the amended class with its own generator stamp; rides 0.3.20, the feature node (release-0.3.20-node = dc141409; 0.3.19 is an app-only cut with nothing of ours), on the shipper's line. The rollout arithmetic for the flip clock (the shipper): the standing fleet's one-box-at-a-time rollout took 32 minutes for 14 boxes (04:56 to 05:28Z, 7 October), the hands and the seed about 3 minutes after the miners, the Mac and the PCs within minutes of the publish; every 0.3.20 worker must accept the amended stamp before any flip. Owners: the hash lane (ca3-v4-amend: the generator, the vectors, the packs, the pairing on the box, one G1 run on PC 2, the ledger row), the node lane (release-0.3.20-node: the stamp agreed with the hash lane, the split-protection mechanism and the earliest flip time, the digest test, the mixed-version Devnet 2 gate), the attack-pass lane (the F8 census at 2^24 on the new stream, the gate 1.2x of the window model over 64 seeds), the shipper (the cut, the rollout order that sets the earliest flip). Testing limited to what prevents a split and proves the fix; G2, G3, the ladder re-measure and the rest of G4 to G6 OWED. THE STAMP agreed (the node and hash lanes, 7 October afternoon): generator 4 with sub-version 1 inside igneum-pow's id function, so the amended v4's program id for a seed differs from the old v4's (the old devnet epoch-0 id c120d7963abdcd96 pinned as the must-differ vector in kaspa-pow's test). SPLIT PROTECTION SETTLED (the node lane, plan section 6.6, ca3-v4-node fa5bc9e6; the node side on release-0.3.20-node): a fresh object byte. CLASS_SIGNAL_V4 is 5; the amended binary stamps 5 and the tally counts a block only at byte 5 or above; object 4 was stamped only by the unpublished dc141409 canary, so no published block carries it and a byte-4 block never counts; a node of the 6 October stream that sees byte 5 counts it as v4 (its rule is at least 4), flips to its own stream at the same epoch and forks ALONE (its blocks fail the amended id check, generator 4 sub-version 1 inside every id; the amended blocks fail its own), ours to upgrade in the sweep; object 6 is class v5's; the two holds already in the rule keep the window shut until every node is on 0.3.20 (a node stamps and tallies only with both v4 fields in its file; the fields publish only after the one-sweep rollout); a lagging worker refuses the amended pack at packcheck and mines nothing after the flip, costing that box, never the chain; no extra window hold: seven full day-windows are the hold. THE EARLIEST FLIP (approximate, measured 09:40Z: DAA 270,659, 1.095 DAA/s over 25 hours, 1.165 over 4; epoch 3,600, lead 600; seven windows 604,800 DAA wholly after the sweep's end D_s = T + about 40 minutes; the flip epoch the first e with 3600 e - 600 >= D_s + 604,800): T + 6 days 10 hours to T + 6 days 11 hours UK; for a publish at 12:00 UK on 7 October, 13 October between 22:20 and 23:10 UK (about 13:00 UK if the 4-hour rate holds). The floor as it stands (831,600, about 13 October 09:00 UK) would fire before any seven-window signal from a publish today completes, so it moves by the 0.3.16 rule to the publish DAA + 604,800 rounded up to the epoch boundary (882,000 for a 12:00 UK publish), firing about 30 minutes before the earliest signal flip: either way about 6 days 10 hours after the publish, never before every node has had the sweep plus a week. THE CLOCK (the node lane, 11:3x UK, after a Mac reboot moved its runs to the box): the 0.3.20 node line (dc141409 plus the proof archive aea0ca5c plus the amended v4 at object byte 5, igneum-pow at the hash lane's a0aaca92 beside the fork on the box) tested on the box, committed on release-0.3.20-node, pushed to the mirror and origin, igneumd and igneum-miner built, the tip to the shipper: about 12:00 UK; the mixed-version Devnet 2 gate (node-compat.mjs on the box, the amended node beside the 5899f603 pair for ten minutes) and the digest test (digest-compat.mjs): about 12:45 UK; the object-byte pin 5 unless the v5 lane answers both lanes with another assignment (v5 at 6 proposed). THE HASH SIDE on ca3-v4-amend (tip 8c728ca3, read from the branch 14:0x UK; the hash lane's own report pending): 1748fd1d the PC 2 G1-only playbook; e1f48d63 the fud-ledger entry AP-F8-1 (the fault, Josh's ruling, the amendment, the split protection, the owed tests); d8859522 the G1 line (the eight fingerprints equal on the RTX 5090, self-test PASS) and the node lane's signal byte 5; 4aa0c665 the v4 unit test following the amendment; 965d9e96 igneum-pow taken from release-0.3.20's 3f1652bf (the ladder's chain_program_shadow with the reps argument, never on master) with the amendment re-applied, the seven packs re-exporting byte-identical; 8c728ca3 the source rule keyed on the class with the shadow's pass count set aside, so every ladder rung draws under it (the fork's ladder test). The shipper took this igneum-pow tree into release-0.3.20 (00249643, byte-equal); nothing after 8c728ca3 touches igneum-pow. THE VECTORS AND THE PACKS (read from the branch and its ledger entry, 14:1x UK): the seven amended v4 packs (v4-devnet-epoch0, v4-era-0 to 5) carry generator 4, sub-version 1, one program id 1a4230699a6b9c60 (the 2.0 one-id-per-seed rule across the eras; the old c120d7963abdcd96 pinned as must-differ); the v3 control mx8-devnet-epoch0 untouched (73bcbfe8ccf988f1, fingerprint 90f794dd556f7a3b); the seven 2^24 fingerprints, Metal equal to Apple OpenCL: 867dbc45cfb36b4d, 2146ecacc8c75a8e, fe52602393f6d3d4, 3b206471a13912b4, c3f03c4a5d7333aa, f1dfd7209f15bb97, 8c194da64fadf31d; the zip of the eight packs sha256 889ec99976d2728b4b5035bfa476032e5b6a13b928968fc45236d5f25084aa39; the per-pack vectors.json sha256 prefixes 756301bf (devnet epoch 0), 1b5f4568, d430cadc, 1a1b21d8, 460fff9e, 4a85d49d, f83a1196 (eras 0 to 5). G1 on the RTX 5090 (PC 2 job run-ca3-v4-amend-g1-pc2-20261007, 09:41:07 to 09:41:28Z, exit 0, the installed worker): every fingerprint equal to the Mac's (the seven above and the control), NVRTC 188 to 332 ms per pack, the 1 GiB build 38 to 49 ms. hash-gates.md's older table still lists the pre-amendment fingerprints (f410c731... and the eras), which no longer apply to the amended packs; the ledger entry is the record. THE FIRST GREEN (11:31 UK, the box): the kaspa-pow suite on release-0.3.20-node (dc141409 plus the proof archive aea0ca5c plus the object-5 change) against the hash lane's igneum-pow 8c728ca3: 17 passed, 0 failed; the amended devnet epoch-0 id 1a4230699a6b9c60 pinned equal and c120d7963abdcd96 differing, the ladder's rung test green under the rekeyed rule, the v3 control unchanged; the consensus-core and exec RPC suites follow, then the node line (commit, push, box build, the tip to the shipper), then the digest and mixed-version gates. CLOCK RE-CUT (the node lane, 13:0x UK): the node line now carries, beside the object-5 change and the vector test, the lane's 0.3.20 fixes from the day (isSynced from the hook's stamp, the lazy template snapshot, the weight-table cache, the submit path returning after the block task, the watchdog, the RPC fields), about 13:30 UK if the box suites are green; the shipper's fresh-join canary 60 to 100 minutes after the cut; PC 1 as its first machine about 16:00 UK at the earliest, approximate until the shipper names the cut; the earliest flip about 6 days 10 hours after the publish. BUILD-2 LINES (12:28 to 12:33 UK): consensus-core 123 passed (the 60x file test green with the ladder window and activation pinned), the behind test green, kaspa-pow 17 passed (the amended vectors, earlier on build-1), the exec RPC suite green, the flows and rpc-service checks green with the submit-path change; the 24-requester latency test's first run tripped an unrelated flapping-fork double insert (24 equal forks from one parent; the test now builds on the sink as a real miner does; the double insert owed to a small fork harness before it is called a bug); THE NODE LINE COMMITTED (13:1x UK): release-0.3.20-node = 8097d600 (dc141409 + the proof archive aea0ca5c + one commit) on the mirror, pairing igneum-pow 8c728ca3, the hash with the shipper; in it the amended class v4 as object 5 (CLASS_SIGNAL_V4 = 5, byte 4 never counts, the kaspa-pow vector test pinning 1a4230699a6b9c60 equal and c120d7963abdcd96 differing, the daemon's window line naming object 5 and sub-version 1) beside the day's fixes (isSynced from the hook's stamp, the weight-table cache, the lazy snapshot, the submit path, the 100 ms template wait); the suites green on build-2 (consensus-core 123, the exec RPC suite, the four finality tests including 24 requesters under 200 ms: the worst template 100 ms, the worst submit 102 ms) and kaspa-pow 17 on build-1. Next: igneumd and igneum-miner building from 8097d600 on build-1, then the two gate lines (the mixed-version Devnet 2 gate: the 8097d600 node mining beside the 5899f603 pair for ten minutes on the live file without the v4 fields, the old node accepting every block; the digest test: the thirteen-field file b18ed271 unchanged, the sixteen-field object re-read on the 8097d600 binary), expected about 13:30 UK; the shipper picks the cut point. THE DATE FIXED (the node lane, from the hub's live file, 13:3x UK): publish 2 of 6 October (22:49:45Z, digest eada4bda) already put BOTH v4 fields on the live devnet (floor 831,600, window 86,400), so the 0.3.17 fleet has stamped object byte 4 since 7 October 00:2x UK and the floor is live at about 13 October 09:00 UK, before any seven-window signal completes; a 0.3.17 node left on that file flips to the OLD v4 stream at epoch 231 whatever anyone signals, a 0.3.20 node to the amended stream at the same epoch, and the two never share an id, so each straggler forks alone there. REQUIREMENT for the 0.3.20 publish (with the shipper and main): a new file with the floor at the publish DAA + 604,800 rounded up (about 882,000 for a publish today), the digest moving, the one-sweep rollout replacing every 0.3.17 node before 13 October 09:00 UK; any node that misses the sweep is alone then; the earliest flip after that about 6 days 10 hours past the publish; plan section 6.6 amended today. IN THE 0.3.20 PLAN (the shipper, 13:4x UK): both requirements; the node pin by main's rule is the node lane's second commit (the claim floor, the listener watchdog, the claim RPCs, on top of 8097d600) if its suites, both gates and the fleet's 12 GB prover line are green by 15:30 UK, else 8097d600; igneum-pow 8c728ca3 either way; the digest read on whichever binary pins. THE LINE AT 13:5x UK: three commits on release-0.3.20-node, 8097d600 (the object-5 amended class v4 and the day's fixes), 6b94c823 (test-only: the stale PC 1 test from 500ddd66 inverted by the isSynced ruling; the FALLBACK pin, code byte-identical to 8097d600, so the module reads green whole) and 6a3432a3 (the app lane's key methods, the observer's claims, the settled claim floor, the listener watchdog); suites on build-2 on 6a3432a3's code (the whole finality module 25, the exec suite 29 with the watchdog test, the kaspad, flows and rpc-service checks; consensus-core 123 and kaspa-pow 17 earlier); the cut 6a3432a3 if its gates and the fleet's 12 GB settled-claim line are green by 15:30 UK, else 6b94c823; both binaries building on build-1, the two gates (the digest gate, then the ten-minute mixed-version gate beside the 5899f603 pair) on the 8097d600 build, lines about 14:05 UK. GATE NEWS (13:53 UK): on 6a3432a3's own digest gate the listener watchdog counted a bind failure (the four harness nodes share one exec JSON-RPC port) as a listener death and exited three of four nodes at 20 s, where 0.3.17 and 8097d600 only warn and live without the exec RPC; the digest facts came out first and stand (the thirteen-field file a89be8a7 on both binaries, the compat case; the sixteen-field object db9a85f9 refused with the mismatch line, the refusal case); the ten-minute gate on 6a3432a3 stopped as void for the same cause. The fix: a bind failure is a retry every poll, one line a minute, no death counted and never an exit, with a second watchdog test whose known-failed shape is the old rule's exit on a held port; the third commit and its build about 14:15 UK, its gates about 14:35 UK; the fallback 6b94c823's gates on build-1 on their own binary (no watchdog there), lines about 14:20 UK; ledger row N12 for the bind-failure class. A ROLL BLOCKER on every kept datadir (the node lane, 14:1x UK, ledger N13): the fleet started 6a3432a3 on a kept 0.3.17 datadir (pool-1's copy) and it died at start (virtual_state.rs:250, DeserializationError(UnexpectedEof)); the cause 10db4b61 on the 0.3.16 feature line added `silent: bool` to BlockRewardData under serde(default), which bincode ignores, so every build from 10db4b61 on (dc141409, 8097d600, 6b94c823, 6a3432a3, 09124180) reads a 0.3.17 node's virtual-state row short; no canary saw it because every canary wiped, and a one-box roll keeps datadirs, so it blocks the roll on every standing box, the hands and the hub whatever the pin. The fix on the line: the store reads the current layout first and on a deserialization error decodes the row as a v1 mirror, converts with silent false and rewrites it under the same key, with the known-failed test first; the fourth commit and build about 14:40 UK, the fleet's kept-datadir start on the fixed binary about 14:50 UK, its gates after. THE RULE IT ADDS for every node cut from now: a kept-datadir restart gate on a standing box's datadir copy beside the wiped canary. THE CANDIDATE PIN (14:2x UK): b7cc37e7 (8097d600, 6b94c823, 6a3432a3, 09124180, b7cc37e7; igneum-pow 8c728ca3): the N13 fix with its test green on build-2 at 14:04 UK and the kaspad check green, the build on build-1; the fallback 6b94c823 is no longer a pin for the one-box roll (it dies on a kept datadir like every build since 10db4b61): if b7cc37e7's gates are not green by 15:30 UK the honest fallback is 0.3.17's 5899f603 staying live. In flight on build-1: the earlier commits' gates, then b7cc37e7's own digest and ten-minute mixed-version gates on its binary with the read-back, lines about 15:05 UK; on the fleet the kept-datadir start on b7cc37e7 about 14:50 UK and the 12 GB settled-claim line 14:50 to 15:00 UK. Plan section 6.6 amended with the hard date (ca3-v4-node 9d763edd, merged to master); N12 and N13 on the ledger. THE GATES ON THE FALLBACK'S OWN BINARY (6b94c823, sha b1b7d47b, 13:56 to 14:08 UK; code byte-identical to 8097d600, so the amendment's node side): the digest gate, the thirteen-field file a89be8a7 on both binaries (the compat case, n0 peering n1 and n2) and the sixteen-field object db9a85f9 refused with the mismatch line (the refusal case); the mixed-version gate, ten minutes, one digest b0afb2ee on all five nodes, the 5899f603 hub accepting every block the amended node mined (146 new, 246 old, 0 rejected), plain header version 2 on the thirteen-field file, counts equal on all five through the two clean joins and the restart. Two FAILED checks, both the harness's own and fixed (36d3efdc): a refused peer's count read 1 with the reconnect in flight (now the minimum of five), and six address-in-use panics in the two old nodes because the second gate reused the first's ports the second they were sent SIGTERM (a 20 s gap now). CLOCK CORRECTION (the node lane, 12:12Z = 13:12 BST): every "UK" stamp it sent today was the box's CEST, an hour fast of BST; its lines read UTC from now. Restated: b7cc37e7's build about 12:15Z, its digest and mixed-version gates on that binary with the sha and string about 12:32Z (13:32 BST), the fleet's kept-datadir start on it about 12:25Z, its 12 GB settled-claim line 12:50 to 13:00Z; the shipper's checkpoint 14:30Z (15:30 BST), two hours of room. The 13 October date stands (derived from UTC DAA rates): the floor 831,600 about 08:00Z, 09:00 BST. b7cc37e7'S OWN LINES (binary sha256 bc28331abf21f4d5, the string read back on build-1 and on the fleet's pod): the digest gate 12:14:39Z to 12:16:18Z SUMMARY PASS (thirteen fields a89be8a7 on both binaries with the peers as the gate wants them; the sixteen-field object db9a85f9 refused with the line and no peer; the live file's digest eada4bda on the binary, unmoved); the kept-datadir start on the fleet's copy of pool-1's 0.3.17 datadir: the first start 12:17:12Z reads the v1 row through the mirror and rewrites it ("1 mergeset rewards"), the finality blob converts (1,747 locks), the node comes up on its ports with no panic; the second start 12:18:53Z reads first-try with no rewrite line and no panic; 6a3432a3's death on the same copy is the known-failed shape. The ten-minute mixed-version gate beside the 5899f603 pair runs on the same binary since 12:16:39Z, its line about 12:28Z; then the only line outstanding for the shipper's 14:30Z rule is the fleet's 12 GB settled-claim line, 12:50 to 13:00Z. AP-F8-1 RESIDUAL CLASS ON THE AMENDED STREAM (attack-pass lane 12:18Z on igneum-pow 8c728ca3, sub-version 1). F9 over 1,000,000 seeds: programs flagged (hot share at least 1 percent or 7 constant address bits) 1,871 (0.19 percent) against 11,696 (1.17 percent) unamended; worst hot share 9.66 percent against 17.3; mean 0.011 against 0.063 percent; 84 percent of the flagged programs and the whole or-saturation tail gone. F8 at 30 of 64 seeds: nine over 1.2x of the window model (p31 29.3x, p11 5.5x, p19 3.3x, p6 3.1x, p23 2.0x, the rest 1.3x to 1.6x); the 64-seed 1.2x gate is heading to FAIL on sub-version 1. Mechanism, confirmed on the two worst seeds: an all-ones load source (image 0x0ca59e4c under the era map) delivered through a writer the source rule counts as entropy-keeping, a rotate (rotl and rotr map all-ones to itself) or a load whose own source was saturated, with the saturation made one or more writes upstream by or. The rule looks one writer back; it must look through saturation-preserving writers or test the source's values. The ceiling has not moved: rule (c)'s 120-of-128 floor still caps any program at one saturated site, 6.25 percent of reads, a chip edge of at most 1.067x, and the residual (worst seed two sites at 0.53 and 0.56) sits inside it. THE SENTENCE "no lossy-sourced load by construction" IS HELD: it goes in no plan row and no ledger entry as true; sub-version 1 removes the or-source class and bounds the rest. MAIN'S RULING (13:2x UK): 0.3.20 ships object byte 5 on sub-version 1 as it stands, strictly better than the old stream the live floor flips to on 13 October; the fix is sub-version 2 on ca3-v4-amend (object byte 6 or whatever the v5 alignment leaves free) with both fixes: (F1) the static rule made transitive (rotates do not keep entropy; a load keeps entropy only if its own source did; one draw change, no attempts lost) and (F2) the dynamic source check (saturated load SOURCE values counted per site over the 64 units' 16,384 evaluations, rejected above 163 of 16,384, the same 1 percent the final-value rule uses; costs attempts on about 0.2 percent of seeds; rides with F1 because an or-written source is all-ones only (3/4)^32 of the time). Gate before sub-version 2 is proposed, run by the attack-pass lane and not by the hash lane: the full 64-seed census under 1.2x on every seed and the hot-set census. Hash lane's estimate about an hour its side (implement, re-export seven packs, vectors, crate suite, pairing, one G1 on PC 2) plus the node lane's vector re-pin and the attack-pass re-gate. The flip floor for sub-version 1 is expected to move (Josh's word) so the chain never flips to a stream that fails this gate. Also recorded: the crate suite at 8c728ca3 100 of 100 on the box (rc 0, 77 s); the pairing against the fork at dc141409 compiled and ran 15 of 16, the one failure the fork's own pre-amendment assertion (base equals v3's, igneum.rs:972), which 8097d600 on the release-0.3.20-node line turns into assert_ne; the pairing re-runs at b7cc37e7, its line to follow. CORRECTION (the attack-pass lane's own retraction, 13:3x UK): the F9 hot-set figures above (1,871 of 1,000,000, worst 9.66 percent, 84 percent removed, the two or-then-rotate listings) are WITHDRAWN: F9's harness draws through candidate_class with its own era class, outside candidate_from_words_class where the source rule lives, so it measured the old stream (the 8c728ca3 binary prints the identical program to the sub-version-0 binary for its worst seed). F8's 64-seed census on the chain path (pairing verified on 1a4230699a6b9c60) is the valid re-gate and STANDS: at 30 of 64 seeds, nine over 1.2x of the window model (p31 29.3x, p11 5.5x, p19 3.3x, p6 3.1x, p23 2.0x, p4 1.6x, p10 1.5x, p26 1.3x, p25 1.3x). The residual mechanism on the amended stream: a load-after-load chain (a saturated source reads one fixed word, which is the next load's address), admitted because a load injects; and the rotate-preserves-saturation path (generator.rs sets entropy_kept true for a rotate whatever it rotated), correct in code and a second admitted path if it occurs on the chain stream. Sub-version 2 must close both: dataflow freshness per register (a load fresh only if its source was fresh; add, sub, xor, mad, shfl fresh if either operand was; rotates only if the operand was; or, mul, mulhi never) plus the (c') count of saturated load sources per site as the backstop. The STOP holds on F8's evidence alone; the options and the 1.067x ceiling are unchanged. The sentence "no lossy-sourced load by construction" waits on the sub-version 2 census verdict and stays out of every public text until then. SUB-VERSION 2 IN BUILD (the hash lane, ca3-v4-amend, on the coordinator's direction, 13:4x UK): F1 (dataflow freshness per register, keyed on the class v4 shape on every draw path, era or not, so the candidate_class path and the chain path draw one stream) plus F2 (the (c') count of saturated load source values per site over the 64 units' 16,384 evaluations, rejected above 163, keyed on the same shape so v2 and v3 verdicts do not move); PROGRAM_SUBVERSION_V4 = 2, new ids, the seven packs re-exported, recheck.rs with 1a4230699a6b9c60 and c120d7963abdcd96 as the must-differ pair. Clock (UTC): the commit on the branch by 13:30; the crate suite on box 2 and the pairing against b7cc37e7 by about 13:50 (the pairing's vector test fails on the fork's sub-version-1 pin until the node lane re-pins; the compile and the other 15 are the pairing evidence); the G1 job on PC 2 under --cards-off by about 14:10, lock permitting; then the attack-pass lane's full 64-seed census and hot-set census on the chain path. Two consequences stated in the commit: the rule on every draw path moves the no-era sh256xN ladder packs' stream (packs-ca3-shadow's seven 256-block packs re-export with new fingerprints; the measured rates stand as the old stream's), and the class v5 lane's pinned string-seed packs move when it merges sub-version 2, so it re-exports them then. 0.3.20's sub-version-1 packs, ids and fingerprints untouched. OBJECT BYTES SETTLED (main, 13:5x UK): byte 5 = class v4 sub-version 1 (0.3.20), byte 6 = class v5 (pinned: class-v5 16afd0a0, class-v5-node 699db5a2, the flip case passed on 6,6,6; the v5 lane stopped), byte 7 = class v4 sub-version 2; the node and hash lanes told. b7cc37e7's MIXED-VERSION GATE: FAIL, the binary not the harness (12:16:39Z to 12:27:21Z, sha256 bc28331abf21f4d5, the string read back). Before the restart step everything held: one digest b0afb2ee on all five nodes, 268 new and 392 old blocks accepted, 0 rejected, header versions plain 2, counts equal on all five at 324 and 502 through both clean joins. At the new node's restart (12:24:19Z) it died at once on its own datadir ("IO error: While lock file: .../datadir/meta/LOCK: Resource temporarily unavailable", conn_builder.rs:167): the previous process was still shutting down, because the listener watchdog added on 6a3432a3 sleeps its whole 10 s poll before checking shutdown, so every node on the line since then takes up to 10 s longer to stop than 0.3.17 (the fleet saw the same shape as "a 12-second timeout does not stop the node"). Three of the four failed checks follow from that one death (counts, the restarted node's resync, the node it served frozen at 502). The fix on the line, one rule: the poll in 250 ms steps returning the moment shutdown is set, with a test that a shutdown returns within a second (the 10 s loop the known-failed shape); the exec suite on build-2, the fifth commit and its build about 12:45Z, its digest and ten-minute gates about 12:50 to 13:05Z, inside 14:30Z. b7cc37e7 is NOT the pin. The node-side re-pin for sub-version 2 (byte 7) once the hash lane's commit lands: the beside-the-fork igneum-pow copy archived from the commit, the two pinned ids moved in the kaspa-pow vector test (sub-version-2's epoch-0 id must-equal; sub-version-1's joins c120d7963abdcd96 as must-differ), CLASS_SIGNAL and tests for byte 7, the daemon's window line: about 20 minutes of edits plus one kaspa-pow suite run on build-2 (about 2 minutes). THE INTEROP FACT stands from the void run: the 5899f603 hub accepted 235 object-byte-5 blocks from the 8097d600 node with 0 rejected, one digest on all five nodes on the live sixteen-field file. The gates: the digest test and the kaspa-pow vector test (the amended devnet epoch-0 id 1a4230699a6b9c60 must equal, c120d7963abdcd96 must differ, the v3 control unchanged) on the box; the mixed-version Devnet 2 gate (the amended 0.3.20 node beside a 5899f603 node for ten minutes on the live file without the v4 fields) after the Mac build; the fresh-join canary the 0.3.20 cut's | +| JOSH'S WORD (15:2x UK, 7 October): OPTION A, "do this but limit the testing, get it pushed" | the class v4 amendment: a load's source drawn only from registers whose last writer injects or is a rotate (the v5 rule applied now), a new program stream and vectors, the seven gate packs re-exported, the amended class with its own generator stamp; rides 0.3.20, the feature node (release-0.3.20-node = dc141409; 0.3.19 is an app-only cut with nothing of ours), on the shipper's line. The rollout arithmetic for the flip clock (the shipper): the standing fleet's one-box-at-a-time rollout took 32 minutes for 14 boxes (04:56 to 05:28Z, 7 October), the hands and the seed about 3 minutes after the miners, the Mac and the PCs within minutes of the publish; every 0.3.20 worker must accept the amended stamp before any flip. Owners: the hash lane (ca3-v4-amend: the generator, the vectors, the packs, the pairing on the box, one G1 run on PC 2, the ledger row), the node lane (release-0.3.20-node: the stamp agreed with the hash lane, the split-protection mechanism and the earliest flip time, the digest test, the mixed-version Devnet 2 gate), the attack-pass lane (the F8 census at 2^24 on the new stream, the gate 1.2x of the window model over 64 seeds), the shipper (the cut, the rollout order that sets the earliest flip). Testing limited to what prevents a split and proves the fix; G2, G3, the ladder re-measure and the rest of G4 to G6 OWED. THE STAMP agreed (the node and hash lanes, 7 October afternoon): generator 4 with sub-version 1 inside igneum-pow's id function, so the amended v4's program id for a seed differs from the old v4's (the old devnet epoch-0 id c120d7963abdcd96 pinned as the must-differ vector in kaspa-pow's test). SPLIT PROTECTION SETTLED (the node lane, plan section 6.6, ca3-v4-node fa5bc9e6; the node side on release-0.3.20-node): a fresh object byte. CLASS_SIGNAL_V4 is 5; the amended binary stamps 5 and the tally counts a block only at byte 5 or above; object 4 was stamped only by the unpublished dc141409 canary, so no published block carries it and a byte-4 block never counts; a node of the 6 October stream that sees byte 5 counts it as v4 (its rule is at least 4), flips to its own stream at the same epoch and forks ALONE (its blocks fail the amended id check, generator 4 sub-version 1 inside every id; the amended blocks fail its own), ours to upgrade in the sweep; object 6 is class v5's; the two holds already in the rule keep the window shut until every node is on 0.3.20 (a node stamps and tallies only with both v4 fields in its file; the fields publish only after the one-sweep rollout); a lagging worker refuses the amended pack at packcheck and mines nothing after the flip, costing that box, never the chain; no extra window hold: seven full day-windows are the hold. THE EARLIEST FLIP (approximate, measured 09:40Z: DAA 270,659, 1.095 DAA/s over 25 hours, 1.165 over 4; epoch 3,600, lead 600; seven windows 604,800 DAA wholly after the sweep's end D_s = T + about 40 minutes; the flip epoch the first e with 3600 e - 600 >= D_s + 604,800): T + 6 days 10 hours to T + 6 days 11 hours UK; for a publish at 12:00 UK on 7 October, 13 October between 22:20 and 23:10 UK (about 13:00 UK if the 4-hour rate holds). The floor as it stands (831,600, about 13 October 09:00 UK) would fire before any seven-window signal from a publish today completes, so it moves by the 0.3.16 rule to the publish DAA + 604,800 rounded up to the epoch boundary (882,000 for a 12:00 UK publish), firing about 30 minutes before the earliest signal flip: either way about 6 days 10 hours after the publish, never before every node has had the sweep plus a week. THE CLOCK (the node lane, 11:3x UK, after a Mac reboot moved its runs to the box): the 0.3.20 node line (dc141409 plus the proof archive aea0ca5c plus the amended v4 at object byte 5, igneum-pow at the hash lane's a0aaca92 beside the fork on the box) tested on the box, committed on release-0.3.20-node, pushed to the mirror and origin, igneumd and igneum-miner built, the tip to the shipper: about 12:00 UK; the mixed-version Devnet 2 gate (node-compat.mjs on the box, the amended node beside the 5899f603 pair for ten minutes) and the digest test (digest-compat.mjs): about 12:45 UK; the object-byte pin 5 unless the v5 lane answers both lanes with another assignment (v5 at 6 proposed). THE HASH SIDE on ca3-v4-amend (tip 8c728ca3, read from the branch 14:0x UK; the hash lane's own report pending): 1748fd1d the PC 2 G1-only playbook; e1f48d63 the fud-ledger entry AP-F8-1 (the fault, Josh's ruling, the amendment, the split protection, the owed tests); d8859522 the G1 line (the eight fingerprints equal on the RTX 5090, self-test PASS) and the node lane's signal byte 5; 4aa0c665 the v4 unit test following the amendment; 965d9e96 igneum-pow taken from release-0.3.20's 3f1652bf (the ladder's chain_program_shadow with the reps argument, never on master) with the amendment re-applied, the seven packs re-exporting byte-identical; 8c728ca3 the source rule keyed on the class with the shadow's pass count set aside, so every ladder rung draws under it (the fork's ladder test). The shipper took this igneum-pow tree into release-0.3.20 (00249643, byte-equal); nothing after 8c728ca3 touches igneum-pow. THE VECTORS AND THE PACKS (read from the branch and its ledger entry, 14:1x UK): the seven amended v4 packs (v4-devnet-epoch0, v4-era-0 to 5) carry generator 4, sub-version 1, one program id 1a4230699a6b9c60 (the 2.0 one-id-per-seed rule across the eras; the old c120d7963abdcd96 pinned as must-differ); the v3 control mx8-devnet-epoch0 untouched (73bcbfe8ccf988f1, fingerprint 90f794dd556f7a3b); the seven 2^24 fingerprints, Metal equal to Apple OpenCL: 867dbc45cfb36b4d, 2146ecacc8c75a8e, fe52602393f6d3d4, 3b206471a13912b4, c3f03c4a5d7333aa, f1dfd7209f15bb97, 8c194da64fadf31d; the zip of the eight packs sha256 889ec99976d2728b4b5035bfa476032e5b6a13b928968fc45236d5f25084aa39; the per-pack vectors.json sha256 prefixes 756301bf (devnet epoch 0), 1b5f4568, d430cadc, 1a1b21d8, 460fff9e, 4a85d49d, f83a1196 (eras 0 to 5). G1 on the RTX 5090 (PC 2 job run-ca3-v4-amend-g1-pc2-20261007, 09:41:07 to 09:41:28Z, exit 0, the installed worker): every fingerprint equal to the Mac's (the seven above and the control), NVRTC 188 to 332 ms per pack, the 1 GiB build 38 to 49 ms. hash-gates.md's older table still lists the pre-amendment fingerprints (f410c731... and the eras), which no longer apply to the amended packs; the ledger entry is the record. THE FIRST GREEN (11:31 UK, the box): the kaspa-pow suite on release-0.3.20-node (dc141409 plus the proof archive aea0ca5c plus the object-5 change) against the hash lane's igneum-pow 8c728ca3: 17 passed, 0 failed; the amended devnet epoch-0 id 1a4230699a6b9c60 pinned equal and c120d7963abdcd96 differing, the ladder's rung test green under the rekeyed rule, the v3 control unchanged; the consensus-core and exec RPC suites follow, then the node line (commit, push, box build, the tip to the shipper), then the digest and mixed-version gates. CLOCK RE-CUT (the node lane, 13:0x UK): the node line now carries, beside the object-5 change and the vector test, the lane's 0.3.20 fixes from the day (isSynced from the hook's stamp, the lazy template snapshot, the weight-table cache, the submit path returning after the block task, the watchdog, the RPC fields), about 13:30 UK if the box suites are green; the shipper's fresh-join canary 60 to 100 minutes after the cut; PC 1 as its first machine about 16:00 UK at the earliest, approximate until the shipper names the cut; the earliest flip about 6 days 10 hours after the publish. BUILD-2 LINES (12:28 to 12:33 UK): consensus-core 123 passed (the 60x file test green with the ladder window and activation pinned), the behind test green, kaspa-pow 17 passed (the amended vectors, earlier on build-1), the exec RPC suite green, the flows and rpc-service checks green with the submit-path change; the 24-requester latency test's first run tripped an unrelated flapping-fork double insert (24 equal forks from one parent; the test now builds on the sink as a real miner does; the double insert owed to a small fork harness before it is called a bug); THE NODE LINE COMMITTED (13:1x UK): release-0.3.20-node = 8097d600 (dc141409 + the proof archive aea0ca5c + one commit) on the mirror, pairing igneum-pow 8c728ca3, the hash with the shipper; in it the amended class v4 as object 5 (CLASS_SIGNAL_V4 = 5, byte 4 never counts, the kaspa-pow vector test pinning 1a4230699a6b9c60 equal and c120d7963abdcd96 differing, the daemon's window line naming object 5 and sub-version 1) beside the day's fixes (isSynced from the hook's stamp, the weight-table cache, the lazy snapshot, the submit path, the 100 ms template wait); the suites green on build-2 (consensus-core 123, the exec RPC suite, the four finality tests including 24 requesters under 200 ms: the worst template 100 ms, the worst submit 102 ms) and kaspa-pow 17 on build-1. Next: igneumd and igneum-miner building from 8097d600 on build-1, then the two gate lines (the mixed-version Devnet 2 gate: the 8097d600 node mining beside the 5899f603 pair for ten minutes on the live file without the v4 fields, the old node accepting every block; the digest test: the thirteen-field file b18ed271 unchanged, the sixteen-field object re-read on the 8097d600 binary), expected about 13:30 UK; the shipper picks the cut point. THE DATE FIXED (the node lane, from the hub's live file, 13:3x UK): publish 2 of 6 October (22:49:45Z, digest eada4bda) already put BOTH v4 fields on the live devnet (floor 831,600, window 86,400), so the 0.3.17 fleet has stamped object byte 4 since 7 October 00:2x UK and the floor is live at about 13 October 09:00 UK, before any seven-window signal completes; a 0.3.17 node left on that file flips to the OLD v4 stream at epoch 231 whatever anyone signals, a 0.3.20 node to the amended stream at the same epoch, and the two never share an id, so each straggler forks alone there. REQUIREMENT for the 0.3.20 publish (with the shipper and main): a new file with the floor at the publish DAA + 604,800 rounded up (about 882,000 for a publish today), the digest moving, the one-sweep rollout replacing every 0.3.17 node before 13 October 09:00 UK; any node that misses the sweep is alone then; the earliest flip after that about 6 days 10 hours past the publish; plan section 6.6 amended today. IN THE 0.3.20 PLAN (the shipper, 13:4x UK): both requirements; the node pin by main's rule is the node lane's second commit (the claim floor, the listener watchdog, the claim RPCs, on top of 8097d600) if its suites, both gates and the fleet's 12 GB prover line are green by 15:30 UK, else 8097d600; igneum-pow 8c728ca3 either way; the digest read on whichever binary pins. THE LINE AT 13:5x UK: three commits on release-0.3.20-node, 8097d600 (the object-5 amended class v4 and the day's fixes), 6b94c823 (test-only: the stale PC 1 test from 500ddd66 inverted by the isSynced ruling; the FALLBACK pin, code byte-identical to 8097d600, so the module reads green whole) and 6a3432a3 (the app lane's key methods, the observer's claims, the settled claim floor, the listener watchdog); suites on build-2 on 6a3432a3's code (the whole finality module 25, the exec suite 29 with the watchdog test, the kaspad, flows and rpc-service checks; consensus-core 123 and kaspa-pow 17 earlier); the cut 6a3432a3 if its gates and the fleet's 12 GB settled-claim line are green by 15:30 UK, else 6b94c823; both binaries building on build-1, the two gates (the digest gate, then the ten-minute mixed-version gate beside the 5899f603 pair) on the 8097d600 build, lines about 14:05 UK. GATE NEWS (13:53 UK): on 6a3432a3's own digest gate the listener watchdog counted a bind failure (the four harness nodes share one exec JSON-RPC port) as a listener death and exited three of four nodes at 20 s, where 0.3.17 and 8097d600 only warn and live without the exec RPC; the digest facts came out first and stand (the thirteen-field file a89be8a7 on both binaries, the compat case; the sixteen-field object db9a85f9 refused with the mismatch line, the refusal case); the ten-minute gate on 6a3432a3 stopped as void for the same cause. The fix: a bind failure is a retry every poll, one line a minute, no death counted and never an exit, with a second watchdog test whose known-failed shape is the old rule's exit on a held port; the third commit and its build about 14:15 UK, its gates about 14:35 UK; the fallback 6b94c823's gates on build-1 on their own binary (no watchdog there), lines about 14:20 UK; ledger row N12 for the bind-failure class. A ROLL BLOCKER on every kept datadir (the node lane, 14:1x UK, ledger N13): the fleet started 6a3432a3 on a kept 0.3.17 datadir (pool-1's copy) and it died at start (virtual_state.rs:250, DeserializationError(UnexpectedEof)); the cause 10db4b61 on the 0.3.16 feature line added `silent: bool` to BlockRewardData under serde(default), which bincode ignores, so every build from 10db4b61 on (dc141409, 8097d600, 6b94c823, 6a3432a3, 09124180) reads a 0.3.17 node's virtual-state row short; no canary saw it because every canary wiped, and a one-box roll keeps datadirs, so it blocks the roll on every standing box, the hands and the hub whatever the pin. The fix on the line: the store reads the current layout first and on a deserialization error decodes the row as a v1 mirror, converts with silent false and rewrites it under the same key, with the known-failed test first; the fourth commit and build about 14:40 UK, the fleet's kept-datadir start on the fixed binary about 14:50 UK, its gates after. THE RULE IT ADDS for every node cut from now: a kept-datadir restart gate on a standing box's datadir copy beside the wiped canary. THE CANDIDATE PIN (14:2x UK): b7cc37e7 (8097d600, 6b94c823, 6a3432a3, 09124180, b7cc37e7; igneum-pow 8c728ca3): the N13 fix with its test green on build-2 at 14:04 UK and the kaspad check green, the build on build-1; the fallback 6b94c823 is no longer a pin for the one-box roll (it dies on a kept datadir like every build since 10db4b61): if b7cc37e7's gates are not green by 15:30 UK the honest fallback is 0.3.17's 5899f603 staying live. In flight on build-1: the earlier commits' gates, then b7cc37e7's own digest and ten-minute mixed-version gates on its binary with the read-back, lines about 15:05 UK; on the fleet the kept-datadir start on b7cc37e7 about 14:50 UK and the 12 GB settled-claim line 14:50 to 15:00 UK. Plan section 6.6 amended with the hard date (ca3-v4-node 9d763edd, merged to master); N12 and N13 on the ledger. THE GATES ON THE FALLBACK'S OWN BINARY (6b94c823, sha b1b7d47b, 13:56 to 14:08 UK; code byte-identical to 8097d600, so the amendment's node side): the digest gate, the thirteen-field file a89be8a7 on both binaries (the compat case, n0 peering n1 and n2) and the sixteen-field object db9a85f9 refused with the mismatch line (the refusal case); the mixed-version gate, ten minutes, one digest b0afb2ee on all five nodes, the 5899f603 hub accepting every block the amended node mined (146 new, 246 old, 0 rejected), plain header version 2 on the thirteen-field file, counts equal on all five through the two clean joins and the restart. Two FAILED checks, both the harness's own and fixed (36d3efdc): a refused peer's count read 1 with the reconnect in flight (now the minimum of five), and six address-in-use panics in the two old nodes because the second gate reused the first's ports the second they were sent SIGTERM (a 20 s gap now). CLOCK CORRECTION (the node lane, 12:12Z = 13:12 BST): every "UK" stamp it sent today was the box's CEST, an hour fast of BST; its lines read UTC from now. Restated: b7cc37e7's build about 12:15Z, its digest and mixed-version gates on that binary with the sha and string about 12:32Z (13:32 BST), the fleet's kept-datadir start on it about 12:25Z, its 12 GB settled-claim line 12:50 to 13:00Z; the shipper's checkpoint 14:30Z (15:30 BST), two hours of room. The 13 October date stands (derived from UTC DAA rates): the floor 831,600 about 08:00Z, 09:00 BST. b7cc37e7'S OWN LINES (binary sha256 bc28331abf21f4d5, the string read back on build-1 and on the fleet's pod): the digest gate 12:14:39Z to 12:16:18Z SUMMARY PASS (thirteen fields a89be8a7 on both binaries with the peers as the gate wants them; the sixteen-field object db9a85f9 refused with the line and no peer; the live file's digest eada4bda on the binary, unmoved); the kept-datadir start on the fleet's copy of pool-1's 0.3.17 datadir: the first start 12:17:12Z reads the v1 row through the mirror and rewrites it ("1 mergeset rewards"), the finality blob converts (1,747 locks), the node comes up on its ports with no panic; the second start 12:18:53Z reads first-try with no rewrite line and no panic; 6a3432a3's death on the same copy is the known-failed shape. The ten-minute mixed-version gate beside the 5899f603 pair runs on the same binary since 12:16:39Z, its line about 12:28Z; then the only line outstanding for the shipper's 14:30Z rule is the fleet's 12 GB settled-claim line, 12:50 to 13:00Z. AP-F8-1 RESIDUAL CLASS ON THE AMENDED STREAM (attack-pass lane 12:18Z on igneum-pow 8c728ca3, sub-version 1). F9 over 1,000,000 seeds: programs flagged (hot share at least 1 percent or 7 constant address bits) 1,871 (0.19 percent) against 11,696 (1.17 percent) unamended; worst hot share 9.66 percent against 17.3; mean 0.011 against 0.063 percent; 84 percent of the flagged programs and the whole or-saturation tail gone. F8 at 30 of 64 seeds: nine over 1.2x of the window model (p31 29.3x, p11 5.5x, p19 3.3x, p6 3.1x, p23 2.0x, the rest 1.3x to 1.6x); the 64-seed 1.2x gate is heading to FAIL on sub-version 1. Mechanism, confirmed on the two worst seeds: an all-ones load source (image 0x0ca59e4c under the era map) delivered through a writer the source rule counts as entropy-keeping, a rotate (rotl and rotr map all-ones to itself) or a load whose own source was saturated, with the saturation made one or more writes upstream by or. The rule looks one writer back; it must look through saturation-preserving writers or test the source's values. The ceiling has not moved: rule (c)'s 120-of-128 floor still caps any program at one saturated site, 6.25 percent of reads, a chip edge of at most 1.067x, and the residual (worst seed two sites at 0.53 and 0.56) sits inside it. THE SENTENCE "no lossy-sourced load by construction" IS HELD: it goes in no plan row and no ledger entry as true; sub-version 1 removes the or-source class and bounds the rest. MAIN'S RULING (13:2x UK): 0.3.20 ships object byte 5 on sub-version 1 as it stands, strictly better than the old stream the live floor flips to on 13 October; the fix is sub-version 2 on ca3-v4-amend (object byte 6 or whatever the v5 alignment leaves free) with both fixes: (F1) the static rule made transitive (rotates do not keep entropy; a load keeps entropy only if its own source did; one draw change, no attempts lost) and (F2) the dynamic source check (saturated load SOURCE values counted per site over the 64 units' 16,384 evaluations, rejected above 163 of 16,384, the same 1 percent the final-value rule uses; costs attempts on about 0.2 percent of seeds; rides with F1 because an or-written source is all-ones only (3/4)^32 of the time). Gate before sub-version 2 is proposed, run by the attack-pass lane and not by the hash lane: the full 64-seed census under 1.2x on every seed and the hot-set census. Hash lane's estimate about an hour its side (implement, re-export seven packs, vectors, crate suite, pairing, one G1 on PC 2) plus the node lane's vector re-pin and the attack-pass re-gate. The flip floor for sub-version 1 is expected to move (Josh's word) so the chain never flips to a stream that fails this gate. Also recorded: the crate suite at 8c728ca3 100 of 100 on the box (rc 0, 77 s); the pairing against the fork at dc141409 compiled and ran 15 of 16, the one failure the fork's own pre-amendment assertion (base equals v3's, igneum.rs:972), which 8097d600 on the release-0.3.20-node line turns into assert_ne; the pairing re-runs at b7cc37e7, its line to follow. CORRECTION (the attack-pass lane's own retraction, 13:3x UK): the F9 hot-set figures above (1,871 of 1,000,000, worst 9.66 percent, 84 percent removed, the two or-then-rotate listings) are WITHDRAWN: F9's harness draws through candidate_class with its own era class, outside candidate_from_words_class where the source rule lives, so it measured the old stream (the 8c728ca3 binary prints the identical program to the sub-version-0 binary for its worst seed). F8's 64-seed census on the chain path (pairing verified on 1a4230699a6b9c60) is the valid re-gate and STANDS: at 30 of 64 seeds, nine over 1.2x of the window model (p31 29.3x, p11 5.5x, p19 3.3x, p6 3.1x, p23 2.0x, p4 1.6x, p10 1.5x, p26 1.3x, p25 1.3x). The residual mechanism on the amended stream: a load-after-load chain (a saturated source reads one fixed word, which is the next load's address), admitted because a load injects; and the rotate-preserves-saturation path (generator.rs sets entropy_kept true for a rotate whatever it rotated), correct in code and a second admitted path if it occurs on the chain stream. Sub-version 2 must close both: dataflow freshness per register (a load fresh only if its source was fresh; add, sub, xor, mad, shfl fresh if either operand was; rotates only if the operand was; or, mul, mulhi never) plus the (c') count of saturated load sources per site as the backstop. The STOP holds on F8's evidence alone; the options and the 1.067x ceiling are unchanged. The sentence "no lossy-sourced load by construction" waits on the sub-version 2 census verdict and stays out of every public text until then. SUB-VERSION 2 IN BUILD (the hash lane, ca3-v4-amend, on the coordinator's direction, 13:4x UK): F1 (dataflow freshness per register, keyed on the class v4 shape on every draw path, era or not, so the candidate_class path and the chain path draw one stream) plus F2 (the (c') count of saturated load source values per site over the 64 units' 16,384 evaluations, rejected above 163, keyed on the same shape so v2 and v3 verdicts do not move); PROGRAM_SUBVERSION_V4 = 2, new ids, the seven packs re-exported, recheck.rs with 1a4230699a6b9c60 and c120d7963abdcd96 as the must-differ pair. Clock (UTC): the commit on the branch by 13:30; the crate suite on box 2 and the pairing against b7cc37e7 by about 13:50 (the pairing's vector test fails on the fork's sub-version-1 pin until the node lane re-pins; the compile and the other 15 are the pairing evidence); the G1 job on PC 2 under --cards-off by about 14:10, lock permitting; then the attack-pass lane's full 64-seed census and hot-set census on the chain path. Two consequences stated in the commit: the rule on every draw path moves the no-era sh256xN ladder packs' stream (packs-ca3-shadow's seven 256-block packs re-export with new fingerprints; the measured rates stand as the old stream's), and the class v5 lane's pinned string-seed packs move when it merges sub-version 2, so it re-exports them then. 0.3.20's sub-version-1 packs, ids and fingerprints untouched. OBJECT BYTES SETTLED (main, 13:5x UK): byte 5 = class v4 sub-version 1 (0.3.20), byte 6 = class v5 (pinned: class-v5 16afd0a0, class-v5-node 699db5a2, the flip case passed on 6,6,6; the v5 lane stopped), byte 7 = class v4 sub-version 2; the node and hash lanes told. b7cc37e7's MIXED-VERSION GATE: FAIL, the binary not the harness (12:16:39Z to 12:27:21Z, sha256 bc28331abf21f4d5, the string read back). Before the restart step everything held: one digest b0afb2ee on all five nodes, 268 new and 392 old blocks accepted, 0 rejected, header versions plain 2, counts equal on all five at 324 and 502 through both clean joins. At the new node's restart (12:24:19Z) it died at once on its own datadir ("IO error: While lock file: .../datadir/meta/LOCK: Resource temporarily unavailable", conn_builder.rs:167): the previous process was still shutting down, because the listener watchdog added on 6a3432a3 sleeps its whole 10 s poll before checking shutdown, so every node on the line since then takes up to 10 s longer to stop than 0.3.17 (the fleet saw the same shape as "a 12-second timeout does not stop the node"). Three of the four failed checks follow from that one death (counts, the restarted node's resync, the node it served frozen at 502). The fix on the line, one rule: the poll in 250 ms steps returning the moment shutdown is set, with a test that a shutdown returns within a second (the 10 s loop the known-failed shape); the exec suite on build-2, the fifth commit and its build about 12:45Z, its digest and ten-minute gates about 12:50 to 13:05Z, inside 14:30Z. b7cc37e7 is NOT the pin. The node-side re-pin for sub-version 2 (byte 7) once the hash lane's commit lands: the beside-the-fork igneum-pow copy archived from the commit, the two pinned ids moved in the kaspa-pow vector test (sub-version-2's epoch-0 id must-equal; sub-version-1's joins c120d7963abdcd96 as must-differ), CLASS_SIGNAL and tests for byte 7, the daemon's window line: about 20 minutes of edits plus one kaspa-pow suite run on build-2 (about 2 minutes). THE FIFTH COMMIT c4459193 on release-0.3.20-node (b7cc37e7's child, the watchdog poll returning on shutdown; the diff is the poll loop in rpc.rs alone), pairing igneum-pow 8c728ca3; its build on build-1 started 12:30:13Z, sha256 and string to follow. Line A, the shutdown test: rpc::watchdog_tests::a_shutdown_returns_within_a_second_whatever_the_poll green on build-2 at 12:29Z in the exec suite's 31 passed, beside the two other watchdog tests; its known-failed shape the old loop's 10 s stop. Line B, the kept-datadir start: b7cc37e7's fleet read carries to c4459193 since the store code is byte-identical between the two commits; the fleet re-reads on the c4459193 binary only if the shipper's rule wants the string on that line too. The digest gate and the ten-minute mixed-version gate on c4459193's own binary follow its build. THE INTEROP FACT stands from the void run: the 5899f603 hub accepted 235 object-byte-5 blocks from the 8097d600 node with 0 rejected, one digest on all five nodes on the live sixteen-field file. The gates: the digest test and the kaspa-pow vector test (the amended devnet epoch-0 id 1a4230699a6b9c60 must equal, c120d7963abdcd96 must differ, the v3 control unchanged) on the box; the mixed-version Devnet 2 gate (the amended 0.3.20 node beside a 5899f603 node for ten minutes on the live file without the v4 fields) after the Mac build; the fresh-join canary the 0.3.20 cut's | | Main's rulings (7 October, morning) | no generator change to v4 on the live devnet; the record's null is the window model with numbers, sent by the hash lane to the attack-pass lane so AP-F8-1 re-gates against it; a fault beyond the model (a low-entropy source at site 15) stops at the coordinator with the two options priced (a 0.3.19 class amendment before the flip, or the flip held at the floor), nothing shipping without Josh's word; the tighter tail, an acceptance bound on the hot-set share, is a CLASS V5 item (sent to the v5 lane a6410f3b8abefb762 with the 64-seed census as its gate; the bound's number follows from the model) | ### AP-F4-1, the weak-day MUL draw (the attack-pass lane, 7 October, morning): PASS against v4, a class v5 rule From 7d7f5683685448102559718ef9e2a1c91ecb2019 Mon Sep 17 00:00:00 2001 From: igneum-josh <337424239+igneum-josh@users.noreply.github.com> Date: Wed, 7 Oct 2026 13:32:58 +0100 Subject: [PATCH 02/19] Counter ASIC 3.0 status: the shipper's carry ruling, the pin c4459193, sub-version 2 is 0.3.21's, the floor move recommended Co-Authored-By: Claude Fable 5.1 --- docs/plans/counter-asic-3-status.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/plans/counter-asic-3-status.md b/docs/plans/counter-asic-3-status.md index f8ab87726..e433e91d8 100644 --- a/docs/plans/counter-asic-3-status.md +++ b/docs/plans/counter-asic-3-status.md @@ -338,7 +338,7 @@ Josh gave the go in advance for tonight: the shipper runs publish 1 on the 0.3.1 | THE ANALYSIS (the hash lane, ca3-v4-uniform 095f84a7, `docs/analysis/ca3-v4-uniform.md`, the tool on igneum-build-1) | the window model moves the null from 0.115 to 0.160 percent (1.39x, not 4.05x); the rest is a FAULT beyond it: site 15 reads a register last written by `or r6, r4`, so all-ones recurs at (3/4)^32 per read and the era map sends it to F8's hottest item exactly (the popcount model predicts 77,348 all-ones reads against 78,479; the top-0.1-percent share 0.58 against 0.52); it passes the acceptance rule because part (a) takes any write as a fresh source and part (c) counts saturation on final values only. The census of 1,024 chain-shaped v4 programs: 96.6 percent carry a lossy-sourced load (or, mul, mulhi as the last writer), 48.5 percent an or-sourced one (0.30 percent of all reads per site), 4.9 percent an or-of-or chain (4.6 percent of all reads on 0.1 percent of items); F8's 1.2x gate fails 96.6 percent of today's programs. Worth to a chip: 1.07 MB of SRAM ($0.25) serving 0.52 percent of a typical program's reads and 4.6 percent of the worst class's, at most 1.005x and 1.048x in rate; the ceiling under rule (c)'s 120-of-128 floor one site repeating its item in all 8 iterations, 6.25 percent of reads, 1.067x in 64 bytes; the 2x margin stands; the public line says "bounded at 1.067x", not "uniform" (the public text corrected) | | The two options, priced, STOPPED at the coordinator for Josh's word | A: a 0.3.19 class amendment before the flip (the generator draws a load's source from the registers whose last writer injects): a new program stream, new vectors, the seven gate packs re-exported, the six gates again (G1 to G3 and the verifier about an hour on the Mac and PC 2; G4 to G6 the node lane), every node before the flip under the one-box-at-a-time rule; the risk a node that misses the build splits the chain at the flip. B: hold the flip at the floor with v4 as it is; the bound documented; the source rule to class v5: a hot set worth up to 1.005x on about half the hours and 1.05x on 5 percent, 1.067x at the ceiling; no chain risk. The number: 1.067x at the ceiling against the 2x margin. The lane recommends B | | The v5 bound (sent to the v5 lane) | H = W_0.1 (the window term, 0.115 to 0.251 percent) + the sum over load sites of h(last writer) (or 0.30 percent, an or chain 4.5, mul 0.067, mulhi 0.049, an injecting op or a rotate 0), H at or under 1.2 x W_0.1, which is the static rule "every load's source was last written by an injecting op or a rotate"; as a rejection it costs 96.6 percent of candidates (about 30 attempts per seed), as a generator draw nothing; gate F8's 64-seed census with the saturated-source count | -| JOSH'S WORD (15:2x UK, 7 October): OPTION A, "do this but limit the testing, get it pushed" | the class v4 amendment: a load's source drawn only from registers whose last writer injects or is a rotate (the v5 rule applied now), a new program stream and vectors, the seven gate packs re-exported, the amended class with its own generator stamp; rides 0.3.20, the feature node (release-0.3.20-node = dc141409; 0.3.19 is an app-only cut with nothing of ours), on the shipper's line. The rollout arithmetic for the flip clock (the shipper): the standing fleet's one-box-at-a-time rollout took 32 minutes for 14 boxes (04:56 to 05:28Z, 7 October), the hands and the seed about 3 minutes after the miners, the Mac and the PCs within minutes of the publish; every 0.3.20 worker must accept the amended stamp before any flip. Owners: the hash lane (ca3-v4-amend: the generator, the vectors, the packs, the pairing on the box, one G1 run on PC 2, the ledger row), the node lane (release-0.3.20-node: the stamp agreed with the hash lane, the split-protection mechanism and the earliest flip time, the digest test, the mixed-version Devnet 2 gate), the attack-pass lane (the F8 census at 2^24 on the new stream, the gate 1.2x of the window model over 64 seeds), the shipper (the cut, the rollout order that sets the earliest flip). Testing limited to what prevents a split and proves the fix; G2, G3, the ladder re-measure and the rest of G4 to G6 OWED. THE STAMP agreed (the node and hash lanes, 7 October afternoon): generator 4 with sub-version 1 inside igneum-pow's id function, so the amended v4's program id for a seed differs from the old v4's (the old devnet epoch-0 id c120d7963abdcd96 pinned as the must-differ vector in kaspa-pow's test). SPLIT PROTECTION SETTLED (the node lane, plan section 6.6, ca3-v4-node fa5bc9e6; the node side on release-0.3.20-node): a fresh object byte. CLASS_SIGNAL_V4 is 5; the amended binary stamps 5 and the tally counts a block only at byte 5 or above; object 4 was stamped only by the unpublished dc141409 canary, so no published block carries it and a byte-4 block never counts; a node of the 6 October stream that sees byte 5 counts it as v4 (its rule is at least 4), flips to its own stream at the same epoch and forks ALONE (its blocks fail the amended id check, generator 4 sub-version 1 inside every id; the amended blocks fail its own), ours to upgrade in the sweep; object 6 is class v5's; the two holds already in the rule keep the window shut until every node is on 0.3.20 (a node stamps and tallies only with both v4 fields in its file; the fields publish only after the one-sweep rollout); a lagging worker refuses the amended pack at packcheck and mines nothing after the flip, costing that box, never the chain; no extra window hold: seven full day-windows are the hold. THE EARLIEST FLIP (approximate, measured 09:40Z: DAA 270,659, 1.095 DAA/s over 25 hours, 1.165 over 4; epoch 3,600, lead 600; seven windows 604,800 DAA wholly after the sweep's end D_s = T + about 40 minutes; the flip epoch the first e with 3600 e - 600 >= D_s + 604,800): T + 6 days 10 hours to T + 6 days 11 hours UK; for a publish at 12:00 UK on 7 October, 13 October between 22:20 and 23:10 UK (about 13:00 UK if the 4-hour rate holds). The floor as it stands (831,600, about 13 October 09:00 UK) would fire before any seven-window signal from a publish today completes, so it moves by the 0.3.16 rule to the publish DAA + 604,800 rounded up to the epoch boundary (882,000 for a 12:00 UK publish), firing about 30 minutes before the earliest signal flip: either way about 6 days 10 hours after the publish, never before every node has had the sweep plus a week. THE CLOCK (the node lane, 11:3x UK, after a Mac reboot moved its runs to the box): the 0.3.20 node line (dc141409 plus the proof archive aea0ca5c plus the amended v4 at object byte 5, igneum-pow at the hash lane's a0aaca92 beside the fork on the box) tested on the box, committed on release-0.3.20-node, pushed to the mirror and origin, igneumd and igneum-miner built, the tip to the shipper: about 12:00 UK; the mixed-version Devnet 2 gate (node-compat.mjs on the box, the amended node beside the 5899f603 pair for ten minutes) and the digest test (digest-compat.mjs): about 12:45 UK; the object-byte pin 5 unless the v5 lane answers both lanes with another assignment (v5 at 6 proposed). THE HASH SIDE on ca3-v4-amend (tip 8c728ca3, read from the branch 14:0x UK; the hash lane's own report pending): 1748fd1d the PC 2 G1-only playbook; e1f48d63 the fud-ledger entry AP-F8-1 (the fault, Josh's ruling, the amendment, the split protection, the owed tests); d8859522 the G1 line (the eight fingerprints equal on the RTX 5090, self-test PASS) and the node lane's signal byte 5; 4aa0c665 the v4 unit test following the amendment; 965d9e96 igneum-pow taken from release-0.3.20's 3f1652bf (the ladder's chain_program_shadow with the reps argument, never on master) with the amendment re-applied, the seven packs re-exporting byte-identical; 8c728ca3 the source rule keyed on the class with the shadow's pass count set aside, so every ladder rung draws under it (the fork's ladder test). The shipper took this igneum-pow tree into release-0.3.20 (00249643, byte-equal); nothing after 8c728ca3 touches igneum-pow. THE VECTORS AND THE PACKS (read from the branch and its ledger entry, 14:1x UK): the seven amended v4 packs (v4-devnet-epoch0, v4-era-0 to 5) carry generator 4, sub-version 1, one program id 1a4230699a6b9c60 (the 2.0 one-id-per-seed rule across the eras; the old c120d7963abdcd96 pinned as must-differ); the v3 control mx8-devnet-epoch0 untouched (73bcbfe8ccf988f1, fingerprint 90f794dd556f7a3b); the seven 2^24 fingerprints, Metal equal to Apple OpenCL: 867dbc45cfb36b4d, 2146ecacc8c75a8e, fe52602393f6d3d4, 3b206471a13912b4, c3f03c4a5d7333aa, f1dfd7209f15bb97, 8c194da64fadf31d; the zip of the eight packs sha256 889ec99976d2728b4b5035bfa476032e5b6a13b928968fc45236d5f25084aa39; the per-pack vectors.json sha256 prefixes 756301bf (devnet epoch 0), 1b5f4568, d430cadc, 1a1b21d8, 460fff9e, 4a85d49d, f83a1196 (eras 0 to 5). G1 on the RTX 5090 (PC 2 job run-ca3-v4-amend-g1-pc2-20261007, 09:41:07 to 09:41:28Z, exit 0, the installed worker): every fingerprint equal to the Mac's (the seven above and the control), NVRTC 188 to 332 ms per pack, the 1 GiB build 38 to 49 ms. hash-gates.md's older table still lists the pre-amendment fingerprints (f410c731... and the eras), which no longer apply to the amended packs; the ledger entry is the record. THE FIRST GREEN (11:31 UK, the box): the kaspa-pow suite on release-0.3.20-node (dc141409 plus the proof archive aea0ca5c plus the object-5 change) against the hash lane's igneum-pow 8c728ca3: 17 passed, 0 failed; the amended devnet epoch-0 id 1a4230699a6b9c60 pinned equal and c120d7963abdcd96 differing, the ladder's rung test green under the rekeyed rule, the v3 control unchanged; the consensus-core and exec RPC suites follow, then the node line (commit, push, box build, the tip to the shipper), then the digest and mixed-version gates. CLOCK RE-CUT (the node lane, 13:0x UK): the node line now carries, beside the object-5 change and the vector test, the lane's 0.3.20 fixes from the day (isSynced from the hook's stamp, the lazy template snapshot, the weight-table cache, the submit path returning after the block task, the watchdog, the RPC fields), about 13:30 UK if the box suites are green; the shipper's fresh-join canary 60 to 100 minutes after the cut; PC 1 as its first machine about 16:00 UK at the earliest, approximate until the shipper names the cut; the earliest flip about 6 days 10 hours after the publish. BUILD-2 LINES (12:28 to 12:33 UK): consensus-core 123 passed (the 60x file test green with the ladder window and activation pinned), the behind test green, kaspa-pow 17 passed (the amended vectors, earlier on build-1), the exec RPC suite green, the flows and rpc-service checks green with the submit-path change; the 24-requester latency test's first run tripped an unrelated flapping-fork double insert (24 equal forks from one parent; the test now builds on the sink as a real miner does; the double insert owed to a small fork harness before it is called a bug); THE NODE LINE COMMITTED (13:1x UK): release-0.3.20-node = 8097d600 (dc141409 + the proof archive aea0ca5c + one commit) on the mirror, pairing igneum-pow 8c728ca3, the hash with the shipper; in it the amended class v4 as object 5 (CLASS_SIGNAL_V4 = 5, byte 4 never counts, the kaspa-pow vector test pinning 1a4230699a6b9c60 equal and c120d7963abdcd96 differing, the daemon's window line naming object 5 and sub-version 1) beside the day's fixes (isSynced from the hook's stamp, the weight-table cache, the lazy snapshot, the submit path, the 100 ms template wait); the suites green on build-2 (consensus-core 123, the exec RPC suite, the four finality tests including 24 requesters under 200 ms: the worst template 100 ms, the worst submit 102 ms) and kaspa-pow 17 on build-1. Next: igneumd and igneum-miner building from 8097d600 on build-1, then the two gate lines (the mixed-version Devnet 2 gate: the 8097d600 node mining beside the 5899f603 pair for ten minutes on the live file without the v4 fields, the old node accepting every block; the digest test: the thirteen-field file b18ed271 unchanged, the sixteen-field object re-read on the 8097d600 binary), expected about 13:30 UK; the shipper picks the cut point. THE DATE FIXED (the node lane, from the hub's live file, 13:3x UK): publish 2 of 6 October (22:49:45Z, digest eada4bda) already put BOTH v4 fields on the live devnet (floor 831,600, window 86,400), so the 0.3.17 fleet has stamped object byte 4 since 7 October 00:2x UK and the floor is live at about 13 October 09:00 UK, before any seven-window signal completes; a 0.3.17 node left on that file flips to the OLD v4 stream at epoch 231 whatever anyone signals, a 0.3.20 node to the amended stream at the same epoch, and the two never share an id, so each straggler forks alone there. REQUIREMENT for the 0.3.20 publish (with the shipper and main): a new file with the floor at the publish DAA + 604,800 rounded up (about 882,000 for a publish today), the digest moving, the one-sweep rollout replacing every 0.3.17 node before 13 October 09:00 UK; any node that misses the sweep is alone then; the earliest flip after that about 6 days 10 hours past the publish; plan section 6.6 amended today. IN THE 0.3.20 PLAN (the shipper, 13:4x UK): both requirements; the node pin by main's rule is the node lane's second commit (the claim floor, the listener watchdog, the claim RPCs, on top of 8097d600) if its suites, both gates and the fleet's 12 GB prover line are green by 15:30 UK, else 8097d600; igneum-pow 8c728ca3 either way; the digest read on whichever binary pins. THE LINE AT 13:5x UK: three commits on release-0.3.20-node, 8097d600 (the object-5 amended class v4 and the day's fixes), 6b94c823 (test-only: the stale PC 1 test from 500ddd66 inverted by the isSynced ruling; the FALLBACK pin, code byte-identical to 8097d600, so the module reads green whole) and 6a3432a3 (the app lane's key methods, the observer's claims, the settled claim floor, the listener watchdog); suites on build-2 on 6a3432a3's code (the whole finality module 25, the exec suite 29 with the watchdog test, the kaspad, flows and rpc-service checks; consensus-core 123 and kaspa-pow 17 earlier); the cut 6a3432a3 if its gates and the fleet's 12 GB settled-claim line are green by 15:30 UK, else 6b94c823; both binaries building on build-1, the two gates (the digest gate, then the ten-minute mixed-version gate beside the 5899f603 pair) on the 8097d600 build, lines about 14:05 UK. GATE NEWS (13:53 UK): on 6a3432a3's own digest gate the listener watchdog counted a bind failure (the four harness nodes share one exec JSON-RPC port) as a listener death and exited three of four nodes at 20 s, where 0.3.17 and 8097d600 only warn and live without the exec RPC; the digest facts came out first and stand (the thirteen-field file a89be8a7 on both binaries, the compat case; the sixteen-field object db9a85f9 refused with the mismatch line, the refusal case); the ten-minute gate on 6a3432a3 stopped as void for the same cause. The fix: a bind failure is a retry every poll, one line a minute, no death counted and never an exit, with a second watchdog test whose known-failed shape is the old rule's exit on a held port; the third commit and its build about 14:15 UK, its gates about 14:35 UK; the fallback 6b94c823's gates on build-1 on their own binary (no watchdog there), lines about 14:20 UK; ledger row N12 for the bind-failure class. A ROLL BLOCKER on every kept datadir (the node lane, 14:1x UK, ledger N13): the fleet started 6a3432a3 on a kept 0.3.17 datadir (pool-1's copy) and it died at start (virtual_state.rs:250, DeserializationError(UnexpectedEof)); the cause 10db4b61 on the 0.3.16 feature line added `silent: bool` to BlockRewardData under serde(default), which bincode ignores, so every build from 10db4b61 on (dc141409, 8097d600, 6b94c823, 6a3432a3, 09124180) reads a 0.3.17 node's virtual-state row short; no canary saw it because every canary wiped, and a one-box roll keeps datadirs, so it blocks the roll on every standing box, the hands and the hub whatever the pin. The fix on the line: the store reads the current layout first and on a deserialization error decodes the row as a v1 mirror, converts with silent false and rewrites it under the same key, with the known-failed test first; the fourth commit and build about 14:40 UK, the fleet's kept-datadir start on the fixed binary about 14:50 UK, its gates after. THE RULE IT ADDS for every node cut from now: a kept-datadir restart gate on a standing box's datadir copy beside the wiped canary. THE CANDIDATE PIN (14:2x UK): b7cc37e7 (8097d600, 6b94c823, 6a3432a3, 09124180, b7cc37e7; igneum-pow 8c728ca3): the N13 fix with its test green on build-2 at 14:04 UK and the kaspad check green, the build on build-1; the fallback 6b94c823 is no longer a pin for the one-box roll (it dies on a kept datadir like every build since 10db4b61): if b7cc37e7's gates are not green by 15:30 UK the honest fallback is 0.3.17's 5899f603 staying live. In flight on build-1: the earlier commits' gates, then b7cc37e7's own digest and ten-minute mixed-version gates on its binary with the read-back, lines about 15:05 UK; on the fleet the kept-datadir start on b7cc37e7 about 14:50 UK and the 12 GB settled-claim line 14:50 to 15:00 UK. Plan section 6.6 amended with the hard date (ca3-v4-node 9d763edd, merged to master); N12 and N13 on the ledger. THE GATES ON THE FALLBACK'S OWN BINARY (6b94c823, sha b1b7d47b, 13:56 to 14:08 UK; code byte-identical to 8097d600, so the amendment's node side): the digest gate, the thirteen-field file a89be8a7 on both binaries (the compat case, n0 peering n1 and n2) and the sixteen-field object db9a85f9 refused with the mismatch line (the refusal case); the mixed-version gate, ten minutes, one digest b0afb2ee on all five nodes, the 5899f603 hub accepting every block the amended node mined (146 new, 246 old, 0 rejected), plain header version 2 on the thirteen-field file, counts equal on all five through the two clean joins and the restart. Two FAILED checks, both the harness's own and fixed (36d3efdc): a refused peer's count read 1 with the reconnect in flight (now the minimum of five), and six address-in-use panics in the two old nodes because the second gate reused the first's ports the second they were sent SIGTERM (a 20 s gap now). CLOCK CORRECTION (the node lane, 12:12Z = 13:12 BST): every "UK" stamp it sent today was the box's CEST, an hour fast of BST; its lines read UTC from now. Restated: b7cc37e7's build about 12:15Z, its digest and mixed-version gates on that binary with the sha and string about 12:32Z (13:32 BST), the fleet's kept-datadir start on it about 12:25Z, its 12 GB settled-claim line 12:50 to 13:00Z; the shipper's checkpoint 14:30Z (15:30 BST), two hours of room. The 13 October date stands (derived from UTC DAA rates): the floor 831,600 about 08:00Z, 09:00 BST. b7cc37e7'S OWN LINES (binary sha256 bc28331abf21f4d5, the string read back on build-1 and on the fleet's pod): the digest gate 12:14:39Z to 12:16:18Z SUMMARY PASS (thirteen fields a89be8a7 on both binaries with the peers as the gate wants them; the sixteen-field object db9a85f9 refused with the line and no peer; the live file's digest eada4bda on the binary, unmoved); the kept-datadir start on the fleet's copy of pool-1's 0.3.17 datadir: the first start 12:17:12Z reads the v1 row through the mirror and rewrites it ("1 mergeset rewards"), the finality blob converts (1,747 locks), the node comes up on its ports with no panic; the second start 12:18:53Z reads first-try with no rewrite line and no panic; 6a3432a3's death on the same copy is the known-failed shape. The ten-minute mixed-version gate beside the 5899f603 pair runs on the same binary since 12:16:39Z, its line about 12:28Z; then the only line outstanding for the shipper's 14:30Z rule is the fleet's 12 GB settled-claim line, 12:50 to 13:00Z. AP-F8-1 RESIDUAL CLASS ON THE AMENDED STREAM (attack-pass lane 12:18Z on igneum-pow 8c728ca3, sub-version 1). F9 over 1,000,000 seeds: programs flagged (hot share at least 1 percent or 7 constant address bits) 1,871 (0.19 percent) against 11,696 (1.17 percent) unamended; worst hot share 9.66 percent against 17.3; mean 0.011 against 0.063 percent; 84 percent of the flagged programs and the whole or-saturation tail gone. F8 at 30 of 64 seeds: nine over 1.2x of the window model (p31 29.3x, p11 5.5x, p19 3.3x, p6 3.1x, p23 2.0x, the rest 1.3x to 1.6x); the 64-seed 1.2x gate is heading to FAIL on sub-version 1. Mechanism, confirmed on the two worst seeds: an all-ones load source (image 0x0ca59e4c under the era map) delivered through a writer the source rule counts as entropy-keeping, a rotate (rotl and rotr map all-ones to itself) or a load whose own source was saturated, with the saturation made one or more writes upstream by or. The rule looks one writer back; it must look through saturation-preserving writers or test the source's values. The ceiling has not moved: rule (c)'s 120-of-128 floor still caps any program at one saturated site, 6.25 percent of reads, a chip edge of at most 1.067x, and the residual (worst seed two sites at 0.53 and 0.56) sits inside it. THE SENTENCE "no lossy-sourced load by construction" IS HELD: it goes in no plan row and no ledger entry as true; sub-version 1 removes the or-source class and bounds the rest. MAIN'S RULING (13:2x UK): 0.3.20 ships object byte 5 on sub-version 1 as it stands, strictly better than the old stream the live floor flips to on 13 October; the fix is sub-version 2 on ca3-v4-amend (object byte 6 or whatever the v5 alignment leaves free) with both fixes: (F1) the static rule made transitive (rotates do not keep entropy; a load keeps entropy only if its own source did; one draw change, no attempts lost) and (F2) the dynamic source check (saturated load SOURCE values counted per site over the 64 units' 16,384 evaluations, rejected above 163 of 16,384, the same 1 percent the final-value rule uses; costs attempts on about 0.2 percent of seeds; rides with F1 because an or-written source is all-ones only (3/4)^32 of the time). Gate before sub-version 2 is proposed, run by the attack-pass lane and not by the hash lane: the full 64-seed census under 1.2x on every seed and the hot-set census. Hash lane's estimate about an hour its side (implement, re-export seven packs, vectors, crate suite, pairing, one G1 on PC 2) plus the node lane's vector re-pin and the attack-pass re-gate. The flip floor for sub-version 1 is expected to move (Josh's word) so the chain never flips to a stream that fails this gate. Also recorded: the crate suite at 8c728ca3 100 of 100 on the box (rc 0, 77 s); the pairing against the fork at dc141409 compiled and ran 15 of 16, the one failure the fork's own pre-amendment assertion (base equals v3's, igneum.rs:972), which 8097d600 on the release-0.3.20-node line turns into assert_ne; the pairing re-runs at b7cc37e7, its line to follow. CORRECTION (the attack-pass lane's own retraction, 13:3x UK): the F9 hot-set figures above (1,871 of 1,000,000, worst 9.66 percent, 84 percent removed, the two or-then-rotate listings) are WITHDRAWN: F9's harness draws through candidate_class with its own era class, outside candidate_from_words_class where the source rule lives, so it measured the old stream (the 8c728ca3 binary prints the identical program to the sub-version-0 binary for its worst seed). F8's 64-seed census on the chain path (pairing verified on 1a4230699a6b9c60) is the valid re-gate and STANDS: at 30 of 64 seeds, nine over 1.2x of the window model (p31 29.3x, p11 5.5x, p19 3.3x, p6 3.1x, p23 2.0x, p4 1.6x, p10 1.5x, p26 1.3x, p25 1.3x). The residual mechanism on the amended stream: a load-after-load chain (a saturated source reads one fixed word, which is the next load's address), admitted because a load injects; and the rotate-preserves-saturation path (generator.rs sets entropy_kept true for a rotate whatever it rotated), correct in code and a second admitted path if it occurs on the chain stream. Sub-version 2 must close both: dataflow freshness per register (a load fresh only if its source was fresh; add, sub, xor, mad, shfl fresh if either operand was; rotates only if the operand was; or, mul, mulhi never) plus the (c') count of saturated load sources per site as the backstop. The STOP holds on F8's evidence alone; the options and the 1.067x ceiling are unchanged. The sentence "no lossy-sourced load by construction" waits on the sub-version 2 census verdict and stays out of every public text until then. SUB-VERSION 2 IN BUILD (the hash lane, ca3-v4-amend, on the coordinator's direction, 13:4x UK): F1 (dataflow freshness per register, keyed on the class v4 shape on every draw path, era or not, so the candidate_class path and the chain path draw one stream) plus F2 (the (c') count of saturated load source values per site over the 64 units' 16,384 evaluations, rejected above 163, keyed on the same shape so v2 and v3 verdicts do not move); PROGRAM_SUBVERSION_V4 = 2, new ids, the seven packs re-exported, recheck.rs with 1a4230699a6b9c60 and c120d7963abdcd96 as the must-differ pair. Clock (UTC): the commit on the branch by 13:30; the crate suite on box 2 and the pairing against b7cc37e7 by about 13:50 (the pairing's vector test fails on the fork's sub-version-1 pin until the node lane re-pins; the compile and the other 15 are the pairing evidence); the G1 job on PC 2 under --cards-off by about 14:10, lock permitting; then the attack-pass lane's full 64-seed census and hot-set census on the chain path. Two consequences stated in the commit: the rule on every draw path moves the no-era sh256xN ladder packs' stream (packs-ca3-shadow's seven 256-block packs re-export with new fingerprints; the measured rates stand as the old stream's), and the class v5 lane's pinned string-seed packs move when it merges sub-version 2, so it re-exports them then. 0.3.20's sub-version-1 packs, ids and fingerprints untouched. OBJECT BYTES SETTLED (main, 13:5x UK): byte 5 = class v4 sub-version 1 (0.3.20), byte 6 = class v5 (pinned: class-v5 16afd0a0, class-v5-node 699db5a2, the flip case passed on 6,6,6; the v5 lane stopped), byte 7 = class v4 sub-version 2; the node and hash lanes told. b7cc37e7's MIXED-VERSION GATE: FAIL, the binary not the harness (12:16:39Z to 12:27:21Z, sha256 bc28331abf21f4d5, the string read back). Before the restart step everything held: one digest b0afb2ee on all five nodes, 268 new and 392 old blocks accepted, 0 rejected, header versions plain 2, counts equal on all five at 324 and 502 through both clean joins. At the new node's restart (12:24:19Z) it died at once on its own datadir ("IO error: While lock file: .../datadir/meta/LOCK: Resource temporarily unavailable", conn_builder.rs:167): the previous process was still shutting down, because the listener watchdog added on 6a3432a3 sleeps its whole 10 s poll before checking shutdown, so every node on the line since then takes up to 10 s longer to stop than 0.3.17 (the fleet saw the same shape as "a 12-second timeout does not stop the node"). Three of the four failed checks follow from that one death (counts, the restarted node's resync, the node it served frozen at 502). The fix on the line, one rule: the poll in 250 ms steps returning the moment shutdown is set, with a test that a shutdown returns within a second (the 10 s loop the known-failed shape); the exec suite on build-2, the fifth commit and its build about 12:45Z, its digest and ten-minute gates about 12:50 to 13:05Z, inside 14:30Z. b7cc37e7 is NOT the pin. The node-side re-pin for sub-version 2 (byte 7) once the hash lane's commit lands: the beside-the-fork igneum-pow copy archived from the commit, the two pinned ids moved in the kaspa-pow vector test (sub-version-2's epoch-0 id must-equal; sub-version-1's joins c120d7963abdcd96 as must-differ), CLASS_SIGNAL and tests for byte 7, the daemon's window line: about 20 minutes of edits plus one kaspa-pow suite run on build-2 (about 2 minutes). THE FIFTH COMMIT c4459193 on release-0.3.20-node (b7cc37e7's child, the watchdog poll returning on shutdown; the diff is the poll loop in rpc.rs alone), pairing igneum-pow 8c728ca3; its build on build-1 started 12:30:13Z, sha256 and string to follow. Line A, the shutdown test: rpc::watchdog_tests::a_shutdown_returns_within_a_second_whatever_the_poll green on build-2 at 12:29Z in the exec suite's 31 passed, beside the two other watchdog tests; its known-failed shape the old loop's 10 s stop. Line B, the kept-datadir start: b7cc37e7's fleet read carries to c4459193 since the store code is byte-identical between the two commits; the fleet re-reads on the c4459193 binary only if the shipper's rule wants the string on that line too. The digest gate and the ten-minute mixed-version gate on c4459193's own binary follow its build. THE INTEROP FACT stands from the void run: the 5899f603 hub accepted 235 object-byte-5 blocks from the 8097d600 node with 0 rejected, one digest on all five nodes on the live sixteen-field file. The gates: the digest test and the kaspa-pow vector test (the amended devnet epoch-0 id 1a4230699a6b9c60 must equal, c120d7963abdcd96 must differ, the v3 control unchanged) on the box; the mixed-version Devnet 2 gate (the amended 0.3.20 node beside a 5899f603 node for ten minutes on the live file without the v4 fields) after the Mac build; the fresh-join canary the 0.3.20 cut's | +| JOSH'S WORD (15:2x UK, 7 October): OPTION A, "do this but limit the testing, get it pushed" | the class v4 amendment: a load's source drawn only from registers whose last writer injects or is a rotate (the v5 rule applied now), a new program stream and vectors, the seven gate packs re-exported, the amended class with its own generator stamp; rides 0.3.20, the feature node (release-0.3.20-node = dc141409; 0.3.19 is an app-only cut with nothing of ours), on the shipper's line. The rollout arithmetic for the flip clock (the shipper): the standing fleet's one-box-at-a-time rollout took 32 minutes for 14 boxes (04:56 to 05:28Z, 7 October), the hands and the seed about 3 minutes after the miners, the Mac and the PCs within minutes of the publish; every 0.3.20 worker must accept the amended stamp before any flip. Owners: the hash lane (ca3-v4-amend: the generator, the vectors, the packs, the pairing on the box, one G1 run on PC 2, the ledger row), the node lane (release-0.3.20-node: the stamp agreed with the hash lane, the split-protection mechanism and the earliest flip time, the digest test, the mixed-version Devnet 2 gate), the attack-pass lane (the F8 census at 2^24 on the new stream, the gate 1.2x of the window model over 64 seeds), the shipper (the cut, the rollout order that sets the earliest flip). Testing limited to what prevents a split and proves the fix; G2, G3, the ladder re-measure and the rest of G4 to G6 OWED. THE STAMP agreed (the node and hash lanes, 7 October afternoon): generator 4 with sub-version 1 inside igneum-pow's id function, so the amended v4's program id for a seed differs from the old v4's (the old devnet epoch-0 id c120d7963abdcd96 pinned as the must-differ vector in kaspa-pow's test). SPLIT PROTECTION SETTLED (the node lane, plan section 6.6, ca3-v4-node fa5bc9e6; the node side on release-0.3.20-node): a fresh object byte. CLASS_SIGNAL_V4 is 5; the amended binary stamps 5 and the tally counts a block only at byte 5 or above; object 4 was stamped only by the unpublished dc141409 canary, so no published block carries it and a byte-4 block never counts; a node of the 6 October stream that sees byte 5 counts it as v4 (its rule is at least 4), flips to its own stream at the same epoch and forks ALONE (its blocks fail the amended id check, generator 4 sub-version 1 inside every id; the amended blocks fail its own), ours to upgrade in the sweep; object 6 is class v5's; the two holds already in the rule keep the window shut until every node is on 0.3.20 (a node stamps and tallies only with both v4 fields in its file; the fields publish only after the one-sweep rollout); a lagging worker refuses the amended pack at packcheck and mines nothing after the flip, costing that box, never the chain; no extra window hold: seven full day-windows are the hold. THE EARLIEST FLIP (approximate, measured 09:40Z: DAA 270,659, 1.095 DAA/s over 25 hours, 1.165 over 4; epoch 3,600, lead 600; seven windows 604,800 DAA wholly after the sweep's end D_s = T + about 40 minutes; the flip epoch the first e with 3600 e - 600 >= D_s + 604,800): T + 6 days 10 hours to T + 6 days 11 hours UK; for a publish at 12:00 UK on 7 October, 13 October between 22:20 and 23:10 UK (about 13:00 UK if the 4-hour rate holds). The floor as it stands (831,600, about 13 October 09:00 UK) would fire before any seven-window signal from a publish today completes, so it moves by the 0.3.16 rule to the publish DAA + 604,800 rounded up to the epoch boundary (882,000 for a 12:00 UK publish), firing about 30 minutes before the earliest signal flip: either way about 6 days 10 hours after the publish, never before every node has had the sweep plus a week. THE CLOCK (the node lane, 11:3x UK, after a Mac reboot moved its runs to the box): the 0.3.20 node line (dc141409 plus the proof archive aea0ca5c plus the amended v4 at object byte 5, igneum-pow at the hash lane's a0aaca92 beside the fork on the box) tested on the box, committed on release-0.3.20-node, pushed to the mirror and origin, igneumd and igneum-miner built, the tip to the shipper: about 12:00 UK; the mixed-version Devnet 2 gate (node-compat.mjs on the box, the amended node beside the 5899f603 pair for ten minutes) and the digest test (digest-compat.mjs): about 12:45 UK; the object-byte pin 5 unless the v5 lane answers both lanes with another assignment (v5 at 6 proposed). THE HASH SIDE on ca3-v4-amend (tip 8c728ca3, read from the branch 14:0x UK; the hash lane's own report pending): 1748fd1d the PC 2 G1-only playbook; e1f48d63 the fud-ledger entry AP-F8-1 (the fault, Josh's ruling, the amendment, the split protection, the owed tests); d8859522 the G1 line (the eight fingerprints equal on the RTX 5090, self-test PASS) and the node lane's signal byte 5; 4aa0c665 the v4 unit test following the amendment; 965d9e96 igneum-pow taken from release-0.3.20's 3f1652bf (the ladder's chain_program_shadow with the reps argument, never on master) with the amendment re-applied, the seven packs re-exporting byte-identical; 8c728ca3 the source rule keyed on the class with the shadow's pass count set aside, so every ladder rung draws under it (the fork's ladder test). The shipper took this igneum-pow tree into release-0.3.20 (00249643, byte-equal); nothing after 8c728ca3 touches igneum-pow. THE VECTORS AND THE PACKS (read from the branch and its ledger entry, 14:1x UK): the seven amended v4 packs (v4-devnet-epoch0, v4-era-0 to 5) carry generator 4, sub-version 1, one program id 1a4230699a6b9c60 (the 2.0 one-id-per-seed rule across the eras; the old c120d7963abdcd96 pinned as must-differ); the v3 control mx8-devnet-epoch0 untouched (73bcbfe8ccf988f1, fingerprint 90f794dd556f7a3b); the seven 2^24 fingerprints, Metal equal to Apple OpenCL: 867dbc45cfb36b4d, 2146ecacc8c75a8e, fe52602393f6d3d4, 3b206471a13912b4, c3f03c4a5d7333aa, f1dfd7209f15bb97, 8c194da64fadf31d; the zip of the eight packs sha256 889ec99976d2728b4b5035bfa476032e5b6a13b928968fc45236d5f25084aa39; the per-pack vectors.json sha256 prefixes 756301bf (devnet epoch 0), 1b5f4568, d430cadc, 1a1b21d8, 460fff9e, 4a85d49d, f83a1196 (eras 0 to 5). G1 on the RTX 5090 (PC 2 job run-ca3-v4-amend-g1-pc2-20261007, 09:41:07 to 09:41:28Z, exit 0, the installed worker): every fingerprint equal to the Mac's (the seven above and the control), NVRTC 188 to 332 ms per pack, the 1 GiB build 38 to 49 ms. hash-gates.md's older table still lists the pre-amendment fingerprints (f410c731... and the eras), which no longer apply to the amended packs; the ledger entry is the record. THE FIRST GREEN (11:31 UK, the box): the kaspa-pow suite on release-0.3.20-node (dc141409 plus the proof archive aea0ca5c plus the object-5 change) against the hash lane's igneum-pow 8c728ca3: 17 passed, 0 failed; the amended devnet epoch-0 id 1a4230699a6b9c60 pinned equal and c120d7963abdcd96 differing, the ladder's rung test green under the rekeyed rule, the v3 control unchanged; the consensus-core and exec RPC suites follow, then the node line (commit, push, box build, the tip to the shipper), then the digest and mixed-version gates. CLOCK RE-CUT (the node lane, 13:0x UK): the node line now carries, beside the object-5 change and the vector test, the lane's 0.3.20 fixes from the day (isSynced from the hook's stamp, the lazy template snapshot, the weight-table cache, the submit path returning after the block task, the watchdog, the RPC fields), about 13:30 UK if the box suites are green; the shipper's fresh-join canary 60 to 100 minutes after the cut; PC 1 as its first machine about 16:00 UK at the earliest, approximate until the shipper names the cut; the earliest flip about 6 days 10 hours after the publish. BUILD-2 LINES (12:28 to 12:33 UK): consensus-core 123 passed (the 60x file test green with the ladder window and activation pinned), the behind test green, kaspa-pow 17 passed (the amended vectors, earlier on build-1), the exec RPC suite green, the flows and rpc-service checks green with the submit-path change; the 24-requester latency test's first run tripped an unrelated flapping-fork double insert (24 equal forks from one parent; the test now builds on the sink as a real miner does; the double insert owed to a small fork harness before it is called a bug); THE NODE LINE COMMITTED (13:1x UK): release-0.3.20-node = 8097d600 (dc141409 + the proof archive aea0ca5c + one commit) on the mirror, pairing igneum-pow 8c728ca3, the hash with the shipper; in it the amended class v4 as object 5 (CLASS_SIGNAL_V4 = 5, byte 4 never counts, the kaspa-pow vector test pinning 1a4230699a6b9c60 equal and c120d7963abdcd96 differing, the daemon's window line naming object 5 and sub-version 1) beside the day's fixes (isSynced from the hook's stamp, the weight-table cache, the lazy snapshot, the submit path, the 100 ms template wait); the suites green on build-2 (consensus-core 123, the exec RPC suite, the four finality tests including 24 requesters under 200 ms: the worst template 100 ms, the worst submit 102 ms) and kaspa-pow 17 on build-1. Next: igneumd and igneum-miner building from 8097d600 on build-1, then the two gate lines (the mixed-version Devnet 2 gate: the 8097d600 node mining beside the 5899f603 pair for ten minutes on the live file without the v4 fields, the old node accepting every block; the digest test: the thirteen-field file b18ed271 unchanged, the sixteen-field object re-read on the 8097d600 binary), expected about 13:30 UK; the shipper picks the cut point. THE DATE FIXED (the node lane, from the hub's live file, 13:3x UK): publish 2 of 6 October (22:49:45Z, digest eada4bda) already put BOTH v4 fields on the live devnet (floor 831,600, window 86,400), so the 0.3.17 fleet has stamped object byte 4 since 7 October 00:2x UK and the floor is live at about 13 October 09:00 UK, before any seven-window signal completes; a 0.3.17 node left on that file flips to the OLD v4 stream at epoch 231 whatever anyone signals, a 0.3.20 node to the amended stream at the same epoch, and the two never share an id, so each straggler forks alone there. REQUIREMENT for the 0.3.20 publish (with the shipper and main): a new file with the floor at the publish DAA + 604,800 rounded up (about 882,000 for a publish today), the digest moving, the one-sweep rollout replacing every 0.3.17 node before 13 October 09:00 UK; any node that misses the sweep is alone then; the earliest flip after that about 6 days 10 hours past the publish; plan section 6.6 amended today. IN THE 0.3.20 PLAN (the shipper, 13:4x UK): both requirements; the node pin by main's rule is the node lane's second commit (the claim floor, the listener watchdog, the claim RPCs, on top of 8097d600) if its suites, both gates and the fleet's 12 GB prover line are green by 15:30 UK, else 8097d600; igneum-pow 8c728ca3 either way; the digest read on whichever binary pins. THE LINE AT 13:5x UK: three commits on release-0.3.20-node, 8097d600 (the object-5 amended class v4 and the day's fixes), 6b94c823 (test-only: the stale PC 1 test from 500ddd66 inverted by the isSynced ruling; the FALLBACK pin, code byte-identical to 8097d600, so the module reads green whole) and 6a3432a3 (the app lane's key methods, the observer's claims, the settled claim floor, the listener watchdog); suites on build-2 on 6a3432a3's code (the whole finality module 25, the exec suite 29 with the watchdog test, the kaspad, flows and rpc-service checks; consensus-core 123 and kaspa-pow 17 earlier); the cut 6a3432a3 if its gates and the fleet's 12 GB settled-claim line are green by 15:30 UK, else 6b94c823; both binaries building on build-1, the two gates (the digest gate, then the ten-minute mixed-version gate beside the 5899f603 pair) on the 8097d600 build, lines about 14:05 UK. GATE NEWS (13:53 UK): on 6a3432a3's own digest gate the listener watchdog counted a bind failure (the four harness nodes share one exec JSON-RPC port) as a listener death and exited three of four nodes at 20 s, where 0.3.17 and 8097d600 only warn and live without the exec RPC; the digest facts came out first and stand (the thirteen-field file a89be8a7 on both binaries, the compat case; the sixteen-field object db9a85f9 refused with the mismatch line, the refusal case); the ten-minute gate on 6a3432a3 stopped as void for the same cause. The fix: a bind failure is a retry every poll, one line a minute, no death counted and never an exit, with a second watchdog test whose known-failed shape is the old rule's exit on a held port; the third commit and its build about 14:15 UK, its gates about 14:35 UK; the fallback 6b94c823's gates on build-1 on their own binary (no watchdog there), lines about 14:20 UK; ledger row N12 for the bind-failure class. A ROLL BLOCKER on every kept datadir (the node lane, 14:1x UK, ledger N13): the fleet started 6a3432a3 on a kept 0.3.17 datadir (pool-1's copy) and it died at start (virtual_state.rs:250, DeserializationError(UnexpectedEof)); the cause 10db4b61 on the 0.3.16 feature line added `silent: bool` to BlockRewardData under serde(default), which bincode ignores, so every build from 10db4b61 on (dc141409, 8097d600, 6b94c823, 6a3432a3, 09124180) reads a 0.3.17 node's virtual-state row short; no canary saw it because every canary wiped, and a one-box roll keeps datadirs, so it blocks the roll on every standing box, the hands and the hub whatever the pin. The fix on the line: the store reads the current layout first and on a deserialization error decodes the row as a v1 mirror, converts with silent false and rewrites it under the same key, with the known-failed test first; the fourth commit and build about 14:40 UK, the fleet's kept-datadir start on the fixed binary about 14:50 UK, its gates after. THE RULE IT ADDS for every node cut from now: a kept-datadir restart gate on a standing box's datadir copy beside the wiped canary. THE CANDIDATE PIN (14:2x UK): b7cc37e7 (8097d600, 6b94c823, 6a3432a3, 09124180, b7cc37e7; igneum-pow 8c728ca3): the N13 fix with its test green on build-2 at 14:04 UK and the kaspad check green, the build on build-1; the fallback 6b94c823 is no longer a pin for the one-box roll (it dies on a kept datadir like every build since 10db4b61): if b7cc37e7's gates are not green by 15:30 UK the honest fallback is 0.3.17's 5899f603 staying live. In flight on build-1: the earlier commits' gates, then b7cc37e7's own digest and ten-minute mixed-version gates on its binary with the read-back, lines about 15:05 UK; on the fleet the kept-datadir start on b7cc37e7 about 14:50 UK and the 12 GB settled-claim line 14:50 to 15:00 UK. Plan section 6.6 amended with the hard date (ca3-v4-node 9d763edd, merged to master); N12 and N13 on the ledger. THE GATES ON THE FALLBACK'S OWN BINARY (6b94c823, sha b1b7d47b, 13:56 to 14:08 UK; code byte-identical to 8097d600, so the amendment's node side): the digest gate, the thirteen-field file a89be8a7 on both binaries (the compat case, n0 peering n1 and n2) and the sixteen-field object db9a85f9 refused with the mismatch line (the refusal case); the mixed-version gate, ten minutes, one digest b0afb2ee on all five nodes, the 5899f603 hub accepting every block the amended node mined (146 new, 246 old, 0 rejected), plain header version 2 on the thirteen-field file, counts equal on all five through the two clean joins and the restart. Two FAILED checks, both the harness's own and fixed (36d3efdc): a refused peer's count read 1 with the reconnect in flight (now the minimum of five), and six address-in-use panics in the two old nodes because the second gate reused the first's ports the second they were sent SIGTERM (a 20 s gap now). CLOCK CORRECTION (the node lane, 12:12Z = 13:12 BST): every "UK" stamp it sent today was the box's CEST, an hour fast of BST; its lines read UTC from now. Restated: b7cc37e7's build about 12:15Z, its digest and mixed-version gates on that binary with the sha and string about 12:32Z (13:32 BST), the fleet's kept-datadir start on it about 12:25Z, its 12 GB settled-claim line 12:50 to 13:00Z; the shipper's checkpoint 14:30Z (15:30 BST), two hours of room. The 13 October date stands (derived from UTC DAA rates): the floor 831,600 about 08:00Z, 09:00 BST. b7cc37e7'S OWN LINES (binary sha256 bc28331abf21f4d5, the string read back on build-1 and on the fleet's pod): the digest gate 12:14:39Z to 12:16:18Z SUMMARY PASS (thirteen fields a89be8a7 on both binaries with the peers as the gate wants them; the sixteen-field object db9a85f9 refused with the line and no peer; the live file's digest eada4bda on the binary, unmoved); the kept-datadir start on the fleet's copy of pool-1's 0.3.17 datadir: the first start 12:17:12Z reads the v1 row through the mirror and rewrites it ("1 mergeset rewards"), the finality blob converts (1,747 locks), the node comes up on its ports with no panic; the second start 12:18:53Z reads first-try with no rewrite line and no panic; 6a3432a3's death on the same copy is the known-failed shape. The ten-minute mixed-version gate beside the 5899f603 pair runs on the same binary since 12:16:39Z, its line about 12:28Z; then the only line outstanding for the shipper's 14:30Z rule is the fleet's 12 GB settled-claim line, 12:50 to 13:00Z. AP-F8-1 RESIDUAL CLASS ON THE AMENDED STREAM (attack-pass lane 12:18Z on igneum-pow 8c728ca3, sub-version 1). F9 over 1,000,000 seeds: programs flagged (hot share at least 1 percent or 7 constant address bits) 1,871 (0.19 percent) against 11,696 (1.17 percent) unamended; worst hot share 9.66 percent against 17.3; mean 0.011 against 0.063 percent; 84 percent of the flagged programs and the whole or-saturation tail gone. F8 at 30 of 64 seeds: nine over 1.2x of the window model (p31 29.3x, p11 5.5x, p19 3.3x, p6 3.1x, p23 2.0x, the rest 1.3x to 1.6x); the 64-seed 1.2x gate is heading to FAIL on sub-version 1. Mechanism, confirmed on the two worst seeds: an all-ones load source (image 0x0ca59e4c under the era map) delivered through a writer the source rule counts as entropy-keeping, a rotate (rotl and rotr map all-ones to itself) or a load whose own source was saturated, with the saturation made one or more writes upstream by or. The rule looks one writer back; it must look through saturation-preserving writers or test the source's values. The ceiling has not moved: rule (c)'s 120-of-128 floor still caps any program at one saturated site, 6.25 percent of reads, a chip edge of at most 1.067x, and the residual (worst seed two sites at 0.53 and 0.56) sits inside it. THE SENTENCE "no lossy-sourced load by construction" IS HELD: it goes in no plan row and no ledger entry as true; sub-version 1 removes the or-source class and bounds the rest. MAIN'S RULING (13:2x UK): 0.3.20 ships object byte 5 on sub-version 1 as it stands, strictly better than the old stream the live floor flips to on 13 October; the fix is sub-version 2 on ca3-v4-amend (object byte 6 or whatever the v5 alignment leaves free) with both fixes: (F1) the static rule made transitive (rotates do not keep entropy; a load keeps entropy only if its own source did; one draw change, no attempts lost) and (F2) the dynamic source check (saturated load SOURCE values counted per site over the 64 units' 16,384 evaluations, rejected above 163 of 16,384, the same 1 percent the final-value rule uses; costs attempts on about 0.2 percent of seeds; rides with F1 because an or-written source is all-ones only (3/4)^32 of the time). Gate before sub-version 2 is proposed, run by the attack-pass lane and not by the hash lane: the full 64-seed census under 1.2x on every seed and the hot-set census. Hash lane's estimate about an hour its side (implement, re-export seven packs, vectors, crate suite, pairing, one G1 on PC 2) plus the node lane's vector re-pin and the attack-pass re-gate. The flip floor for sub-version 1 is expected to move (Josh's word) so the chain never flips to a stream that fails this gate. Also recorded: the crate suite at 8c728ca3 100 of 100 on the box (rc 0, 77 s); the pairing against the fork at dc141409 compiled and ran 15 of 16, the one failure the fork's own pre-amendment assertion (base equals v3's, igneum.rs:972), which 8097d600 on the release-0.3.20-node line turns into assert_ne; the pairing re-runs at b7cc37e7, its line to follow. CORRECTION (the attack-pass lane's own retraction, 13:3x UK): the F9 hot-set figures above (1,871 of 1,000,000, worst 9.66 percent, 84 percent removed, the two or-then-rotate listings) are WITHDRAWN: F9's harness draws through candidate_class with its own era class, outside candidate_from_words_class where the source rule lives, so it measured the old stream (the 8c728ca3 binary prints the identical program to the sub-version-0 binary for its worst seed). F8's 64-seed census on the chain path (pairing verified on 1a4230699a6b9c60) is the valid re-gate and STANDS: at 30 of 64 seeds, nine over 1.2x of the window model (p31 29.3x, p11 5.5x, p19 3.3x, p6 3.1x, p23 2.0x, p4 1.6x, p10 1.5x, p26 1.3x, p25 1.3x). The residual mechanism on the amended stream: a load-after-load chain (a saturated source reads one fixed word, which is the next load's address), admitted because a load injects; and the rotate-preserves-saturation path (generator.rs sets entropy_kept true for a rotate whatever it rotated), correct in code and a second admitted path if it occurs on the chain stream. Sub-version 2 must close both: dataflow freshness per register (a load fresh only if its source was fresh; add, sub, xor, mad, shfl fresh if either operand was; rotates only if the operand was; or, mul, mulhi never) plus the (c') count of saturated load sources per site as the backstop. The STOP holds on F8's evidence alone; the options and the 1.067x ceiling are unchanged. The sentence "no lossy-sourced load by construction" waits on the sub-version 2 census verdict and stays out of every public text until then. SUB-VERSION 2 IN BUILD (the hash lane, ca3-v4-amend, on the coordinator's direction, 13:4x UK): F1 (dataflow freshness per register, keyed on the class v4 shape on every draw path, era or not, so the candidate_class path and the chain path draw one stream) plus F2 (the (c') count of saturated load source values per site over the 64 units' 16,384 evaluations, rejected above 163, keyed on the same shape so v2 and v3 verdicts do not move); PROGRAM_SUBVERSION_V4 = 2, new ids, the seven packs re-exported, recheck.rs with 1a4230699a6b9c60 and c120d7963abdcd96 as the must-differ pair. Clock (UTC): the commit on the branch by 13:30; the crate suite on box 2 and the pairing against b7cc37e7 by about 13:50 (the pairing's vector test fails on the fork's sub-version-1 pin until the node lane re-pins; the compile and the other 15 are the pairing evidence); the G1 job on PC 2 under --cards-off by about 14:10, lock permitting; then the attack-pass lane's full 64-seed census and hot-set census on the chain path. Two consequences stated in the commit: the rule on every draw path moves the no-era sh256xN ladder packs' stream (packs-ca3-shadow's seven 256-block packs re-export with new fingerprints; the measured rates stand as the old stream's), and the class v5 lane's pinned string-seed packs move when it merges sub-version 2, so it re-exports them then. 0.3.20's sub-version-1 packs, ids and fingerprints untouched. OBJECT BYTES SETTLED (main, 13:5x UK): byte 5 = class v4 sub-version 1 (0.3.20), byte 6 = class v5 (pinned: class-v5 16afd0a0, class-v5-node 699db5a2, the flip case passed on 6,6,6; the v5 lane stopped), byte 7 = class v4 sub-version 2; the node and hash lanes told. b7cc37e7's MIXED-VERSION GATE: FAIL, the binary not the harness (12:16:39Z to 12:27:21Z, sha256 bc28331abf21f4d5, the string read back). Before the restart step everything held: one digest b0afb2ee on all five nodes, 268 new and 392 old blocks accepted, 0 rejected, header versions plain 2, counts equal on all five at 324 and 502 through both clean joins. At the new node's restart (12:24:19Z) it died at once on its own datadir ("IO error: While lock file: .../datadir/meta/LOCK: Resource temporarily unavailable", conn_builder.rs:167): the previous process was still shutting down, because the listener watchdog added on 6a3432a3 sleeps its whole 10 s poll before checking shutdown, so every node on the line since then takes up to 10 s longer to stop than 0.3.17 (the fleet saw the same shape as "a 12-second timeout does not stop the node"). Three of the four failed checks follow from that one death (counts, the restarted node's resync, the node it served frozen at 502). The fix on the line, one rule: the poll in 250 ms steps returning the moment shutdown is set, with a test that a shutdown returns within a second (the 10 s loop the known-failed shape); the exec suite on build-2, the fifth commit and its build about 12:45Z, its digest and ten-minute gates about 12:50 to 13:05Z, inside 14:30Z. b7cc37e7 is NOT the pin. The node-side re-pin for sub-version 2 (byte 7) once the hash lane's commit lands: the beside-the-fork igneum-pow copy archived from the commit, the two pinned ids moved in the kaspa-pow vector test (sub-version-2's epoch-0 id must-equal; sub-version-1's joins c120d7963abdcd96 as must-differ), CLASS_SIGNAL and tests for byte 7, the daemon's window line: about 20 minutes of edits plus one kaspa-pow suite run on build-2 (about 2 minutes). THE FIFTH COMMIT c4459193 on release-0.3.20-node (b7cc37e7's child, the watchdog poll returning on shutdown; the diff is the poll loop in rpc.rs alone), pairing igneum-pow 8c728ca3; its build on build-1 started 12:30:13Z, sha256 and string to follow. Line A, the shutdown test: rpc::watchdog_tests::a_shutdown_returns_within_a_second_whatever_the_poll green on build-2 at 12:29Z in the exec suite's 31 passed, beside the two other watchdog tests; its known-failed shape the old loop's 10 s stop. Line B, the kept-datadir start: b7cc37e7's fleet read carries to c4459193 since the store code is byte-identical between the two commits; the fleet re-reads on the c4459193 binary only if the shipper's rule wants the string on that line too. The digest gate and the ten-minute mixed-version gate on c4459193's own binary follow its build. THE SHIPPER'S CARRY RULING (14:1x UK): b7cc37e7's kept-datadir read stands as evidence that the store fix is right (the store code byte-identical) but is not the gate line for the pin, because the rule reads the binary, not the diff, and the binary changed (rpc.rs); the gate line is the kept read on c4459193's own binary with its string, which the fleet's canary already runs on c18-1 (wipe, then the kept read, then the restart) before the canary's restart step, at no extra cost; no re-read on p12-vast. THE PIN IS c4459193 pairing 8c728ca3 (object byte 5, sub-version 1); sub-version 2 (byte 7) is 0.3.21's, not 0.3.20's. The shipper's reading of main's F8 ruling: 0.3.20 ships object 5 as it stands because the live floor otherwise flips every node to the OLD stream on 13 October, and the 16:00 BST report tells Josh the floor move is now RECOMMENDED rather than optional, so the chain never flips to a stream that fails the 1.2x gate before sub-version 2 lands. THE INTEROP FACT stands from the void run: the 5899f603 hub accepted 235 object-byte-5 blocks from the 8097d600 node with 0 rejected, one digest on all five nodes on the live sixteen-field file. The gates: the digest test and the kaspa-pow vector test (the amended devnet epoch-0 id 1a4230699a6b9c60 must equal, c120d7963abdcd96 must differ, the v3 control unchanged) on the box; the mixed-version Devnet 2 gate (the amended 0.3.20 node beside a 5899f603 node for ten minutes on the live file without the v4 fields) after the Mac build; the fresh-join canary the 0.3.20 cut's | | Main's rulings (7 October, morning) | no generator change to v4 on the live devnet; the record's null is the window model with numbers, sent by the hash lane to the attack-pass lane so AP-F8-1 re-gates against it; a fault beyond the model (a low-entropy source at site 15) stops at the coordinator with the two options priced (a 0.3.19 class amendment before the flip, or the flip held at the floor), nothing shipping without Josh's word; the tighter tail, an acceptance bound on the hot-set share, is a CLASS V5 item (sent to the v5 lane a6410f3b8abefb762 with the 64-seed census as its gate; the bound's number follows from the model) | ### AP-F4-1, the weak-day MUL draw (the attack-pass lane, 7 October, morning): PASS against v4, a class v5 rule From d971e3656b5007502c2319645b01af449320e7b0 Mon Sep 17 00:00:00 2001 From: igneum-josh <337424239+igneum-josh@users.noreply.github.com> Date: Wed, 7 Oct 2026 13:35:10 +0100 Subject: [PATCH 03/19] Counter ASIC 3.0 status: the fleet's clock on c4459193 (wipe line about 14:40Z, past the checkpoint) Co-Authored-By: Claude Fable 5.1 --- docs/plans/counter-asic-3-status.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/plans/counter-asic-3-status.md b/docs/plans/counter-asic-3-status.md index e433e91d8..659bf2256 100644 --- a/docs/plans/counter-asic-3-status.md +++ b/docs/plans/counter-asic-3-status.md @@ -338,7 +338,7 @@ Josh gave the go in advance for tonight: the shipper runs publish 1 on the 0.3.1 | THE ANALYSIS (the hash lane, ca3-v4-uniform 095f84a7, `docs/analysis/ca3-v4-uniform.md`, the tool on igneum-build-1) | the window model moves the null from 0.115 to 0.160 percent (1.39x, not 4.05x); the rest is a FAULT beyond it: site 15 reads a register last written by `or r6, r4`, so all-ones recurs at (3/4)^32 per read and the era map sends it to F8's hottest item exactly (the popcount model predicts 77,348 all-ones reads against 78,479; the top-0.1-percent share 0.58 against 0.52); it passes the acceptance rule because part (a) takes any write as a fresh source and part (c) counts saturation on final values only. The census of 1,024 chain-shaped v4 programs: 96.6 percent carry a lossy-sourced load (or, mul, mulhi as the last writer), 48.5 percent an or-sourced one (0.30 percent of all reads per site), 4.9 percent an or-of-or chain (4.6 percent of all reads on 0.1 percent of items); F8's 1.2x gate fails 96.6 percent of today's programs. Worth to a chip: 1.07 MB of SRAM ($0.25) serving 0.52 percent of a typical program's reads and 4.6 percent of the worst class's, at most 1.005x and 1.048x in rate; the ceiling under rule (c)'s 120-of-128 floor one site repeating its item in all 8 iterations, 6.25 percent of reads, 1.067x in 64 bytes; the 2x margin stands; the public line says "bounded at 1.067x", not "uniform" (the public text corrected) | | The two options, priced, STOPPED at the coordinator for Josh's word | A: a 0.3.19 class amendment before the flip (the generator draws a load's source from the registers whose last writer injects): a new program stream, new vectors, the seven gate packs re-exported, the six gates again (G1 to G3 and the verifier about an hour on the Mac and PC 2; G4 to G6 the node lane), every node before the flip under the one-box-at-a-time rule; the risk a node that misses the build splits the chain at the flip. B: hold the flip at the floor with v4 as it is; the bound documented; the source rule to class v5: a hot set worth up to 1.005x on about half the hours and 1.05x on 5 percent, 1.067x at the ceiling; no chain risk. The number: 1.067x at the ceiling against the 2x margin. The lane recommends B | | The v5 bound (sent to the v5 lane) | H = W_0.1 (the window term, 0.115 to 0.251 percent) + the sum over load sites of h(last writer) (or 0.30 percent, an or chain 4.5, mul 0.067, mulhi 0.049, an injecting op or a rotate 0), H at or under 1.2 x W_0.1, which is the static rule "every load's source was last written by an injecting op or a rotate"; as a rejection it costs 96.6 percent of candidates (about 30 attempts per seed), as a generator draw nothing; gate F8's 64-seed census with the saturated-source count | -| JOSH'S WORD (15:2x UK, 7 October): OPTION A, "do this but limit the testing, get it pushed" | the class v4 amendment: a load's source drawn only from registers whose last writer injects or is a rotate (the v5 rule applied now), a new program stream and vectors, the seven gate packs re-exported, the amended class with its own generator stamp; rides 0.3.20, the feature node (release-0.3.20-node = dc141409; 0.3.19 is an app-only cut with nothing of ours), on the shipper's line. The rollout arithmetic for the flip clock (the shipper): the standing fleet's one-box-at-a-time rollout took 32 minutes for 14 boxes (04:56 to 05:28Z, 7 October), the hands and the seed about 3 minutes after the miners, the Mac and the PCs within minutes of the publish; every 0.3.20 worker must accept the amended stamp before any flip. Owners: the hash lane (ca3-v4-amend: the generator, the vectors, the packs, the pairing on the box, one G1 run on PC 2, the ledger row), the node lane (release-0.3.20-node: the stamp agreed with the hash lane, the split-protection mechanism and the earliest flip time, the digest test, the mixed-version Devnet 2 gate), the attack-pass lane (the F8 census at 2^24 on the new stream, the gate 1.2x of the window model over 64 seeds), the shipper (the cut, the rollout order that sets the earliest flip). Testing limited to what prevents a split and proves the fix; G2, G3, the ladder re-measure and the rest of G4 to G6 OWED. THE STAMP agreed (the node and hash lanes, 7 October afternoon): generator 4 with sub-version 1 inside igneum-pow's id function, so the amended v4's program id for a seed differs from the old v4's (the old devnet epoch-0 id c120d7963abdcd96 pinned as the must-differ vector in kaspa-pow's test). SPLIT PROTECTION SETTLED (the node lane, plan section 6.6, ca3-v4-node fa5bc9e6; the node side on release-0.3.20-node): a fresh object byte. CLASS_SIGNAL_V4 is 5; the amended binary stamps 5 and the tally counts a block only at byte 5 or above; object 4 was stamped only by the unpublished dc141409 canary, so no published block carries it and a byte-4 block never counts; a node of the 6 October stream that sees byte 5 counts it as v4 (its rule is at least 4), flips to its own stream at the same epoch and forks ALONE (its blocks fail the amended id check, generator 4 sub-version 1 inside every id; the amended blocks fail its own), ours to upgrade in the sweep; object 6 is class v5's; the two holds already in the rule keep the window shut until every node is on 0.3.20 (a node stamps and tallies only with both v4 fields in its file; the fields publish only after the one-sweep rollout); a lagging worker refuses the amended pack at packcheck and mines nothing after the flip, costing that box, never the chain; no extra window hold: seven full day-windows are the hold. THE EARLIEST FLIP (approximate, measured 09:40Z: DAA 270,659, 1.095 DAA/s over 25 hours, 1.165 over 4; epoch 3,600, lead 600; seven windows 604,800 DAA wholly after the sweep's end D_s = T + about 40 minutes; the flip epoch the first e with 3600 e - 600 >= D_s + 604,800): T + 6 days 10 hours to T + 6 days 11 hours UK; for a publish at 12:00 UK on 7 October, 13 October between 22:20 and 23:10 UK (about 13:00 UK if the 4-hour rate holds). The floor as it stands (831,600, about 13 October 09:00 UK) would fire before any seven-window signal from a publish today completes, so it moves by the 0.3.16 rule to the publish DAA + 604,800 rounded up to the epoch boundary (882,000 for a 12:00 UK publish), firing about 30 minutes before the earliest signal flip: either way about 6 days 10 hours after the publish, never before every node has had the sweep plus a week. THE CLOCK (the node lane, 11:3x UK, after a Mac reboot moved its runs to the box): the 0.3.20 node line (dc141409 plus the proof archive aea0ca5c plus the amended v4 at object byte 5, igneum-pow at the hash lane's a0aaca92 beside the fork on the box) tested on the box, committed on release-0.3.20-node, pushed to the mirror and origin, igneumd and igneum-miner built, the tip to the shipper: about 12:00 UK; the mixed-version Devnet 2 gate (node-compat.mjs on the box, the amended node beside the 5899f603 pair for ten minutes) and the digest test (digest-compat.mjs): about 12:45 UK; the object-byte pin 5 unless the v5 lane answers both lanes with another assignment (v5 at 6 proposed). THE HASH SIDE on ca3-v4-amend (tip 8c728ca3, read from the branch 14:0x UK; the hash lane's own report pending): 1748fd1d the PC 2 G1-only playbook; e1f48d63 the fud-ledger entry AP-F8-1 (the fault, Josh's ruling, the amendment, the split protection, the owed tests); d8859522 the G1 line (the eight fingerprints equal on the RTX 5090, self-test PASS) and the node lane's signal byte 5; 4aa0c665 the v4 unit test following the amendment; 965d9e96 igneum-pow taken from release-0.3.20's 3f1652bf (the ladder's chain_program_shadow with the reps argument, never on master) with the amendment re-applied, the seven packs re-exporting byte-identical; 8c728ca3 the source rule keyed on the class with the shadow's pass count set aside, so every ladder rung draws under it (the fork's ladder test). The shipper took this igneum-pow tree into release-0.3.20 (00249643, byte-equal); nothing after 8c728ca3 touches igneum-pow. THE VECTORS AND THE PACKS (read from the branch and its ledger entry, 14:1x UK): the seven amended v4 packs (v4-devnet-epoch0, v4-era-0 to 5) carry generator 4, sub-version 1, one program id 1a4230699a6b9c60 (the 2.0 one-id-per-seed rule across the eras; the old c120d7963abdcd96 pinned as must-differ); the v3 control mx8-devnet-epoch0 untouched (73bcbfe8ccf988f1, fingerprint 90f794dd556f7a3b); the seven 2^24 fingerprints, Metal equal to Apple OpenCL: 867dbc45cfb36b4d, 2146ecacc8c75a8e, fe52602393f6d3d4, 3b206471a13912b4, c3f03c4a5d7333aa, f1dfd7209f15bb97, 8c194da64fadf31d; the zip of the eight packs sha256 889ec99976d2728b4b5035bfa476032e5b6a13b928968fc45236d5f25084aa39; the per-pack vectors.json sha256 prefixes 756301bf (devnet epoch 0), 1b5f4568, d430cadc, 1a1b21d8, 460fff9e, 4a85d49d, f83a1196 (eras 0 to 5). G1 on the RTX 5090 (PC 2 job run-ca3-v4-amend-g1-pc2-20261007, 09:41:07 to 09:41:28Z, exit 0, the installed worker): every fingerprint equal to the Mac's (the seven above and the control), NVRTC 188 to 332 ms per pack, the 1 GiB build 38 to 49 ms. hash-gates.md's older table still lists the pre-amendment fingerprints (f410c731... and the eras), which no longer apply to the amended packs; the ledger entry is the record. THE FIRST GREEN (11:31 UK, the box): the kaspa-pow suite on release-0.3.20-node (dc141409 plus the proof archive aea0ca5c plus the object-5 change) against the hash lane's igneum-pow 8c728ca3: 17 passed, 0 failed; the amended devnet epoch-0 id 1a4230699a6b9c60 pinned equal and c120d7963abdcd96 differing, the ladder's rung test green under the rekeyed rule, the v3 control unchanged; the consensus-core and exec RPC suites follow, then the node line (commit, push, box build, the tip to the shipper), then the digest and mixed-version gates. CLOCK RE-CUT (the node lane, 13:0x UK): the node line now carries, beside the object-5 change and the vector test, the lane's 0.3.20 fixes from the day (isSynced from the hook's stamp, the lazy template snapshot, the weight-table cache, the submit path returning after the block task, the watchdog, the RPC fields), about 13:30 UK if the box suites are green; the shipper's fresh-join canary 60 to 100 minutes after the cut; PC 1 as its first machine about 16:00 UK at the earliest, approximate until the shipper names the cut; the earliest flip about 6 days 10 hours after the publish. BUILD-2 LINES (12:28 to 12:33 UK): consensus-core 123 passed (the 60x file test green with the ladder window and activation pinned), the behind test green, kaspa-pow 17 passed (the amended vectors, earlier on build-1), the exec RPC suite green, the flows and rpc-service checks green with the submit-path change; the 24-requester latency test's first run tripped an unrelated flapping-fork double insert (24 equal forks from one parent; the test now builds on the sink as a real miner does; the double insert owed to a small fork harness before it is called a bug); THE NODE LINE COMMITTED (13:1x UK): release-0.3.20-node = 8097d600 (dc141409 + the proof archive aea0ca5c + one commit) on the mirror, pairing igneum-pow 8c728ca3, the hash with the shipper; in it the amended class v4 as object 5 (CLASS_SIGNAL_V4 = 5, byte 4 never counts, the kaspa-pow vector test pinning 1a4230699a6b9c60 equal and c120d7963abdcd96 differing, the daemon's window line naming object 5 and sub-version 1) beside the day's fixes (isSynced from the hook's stamp, the weight-table cache, the lazy snapshot, the submit path, the 100 ms template wait); the suites green on build-2 (consensus-core 123, the exec RPC suite, the four finality tests including 24 requesters under 200 ms: the worst template 100 ms, the worst submit 102 ms) and kaspa-pow 17 on build-1. Next: igneumd and igneum-miner building from 8097d600 on build-1, then the two gate lines (the mixed-version Devnet 2 gate: the 8097d600 node mining beside the 5899f603 pair for ten minutes on the live file without the v4 fields, the old node accepting every block; the digest test: the thirteen-field file b18ed271 unchanged, the sixteen-field object re-read on the 8097d600 binary), expected about 13:30 UK; the shipper picks the cut point. THE DATE FIXED (the node lane, from the hub's live file, 13:3x UK): publish 2 of 6 October (22:49:45Z, digest eada4bda) already put BOTH v4 fields on the live devnet (floor 831,600, window 86,400), so the 0.3.17 fleet has stamped object byte 4 since 7 October 00:2x UK and the floor is live at about 13 October 09:00 UK, before any seven-window signal completes; a 0.3.17 node left on that file flips to the OLD v4 stream at epoch 231 whatever anyone signals, a 0.3.20 node to the amended stream at the same epoch, and the two never share an id, so each straggler forks alone there. REQUIREMENT for the 0.3.20 publish (with the shipper and main): a new file with the floor at the publish DAA + 604,800 rounded up (about 882,000 for a publish today), the digest moving, the one-sweep rollout replacing every 0.3.17 node before 13 October 09:00 UK; any node that misses the sweep is alone then; the earliest flip after that about 6 days 10 hours past the publish; plan section 6.6 amended today. IN THE 0.3.20 PLAN (the shipper, 13:4x UK): both requirements; the node pin by main's rule is the node lane's second commit (the claim floor, the listener watchdog, the claim RPCs, on top of 8097d600) if its suites, both gates and the fleet's 12 GB prover line are green by 15:30 UK, else 8097d600; igneum-pow 8c728ca3 either way; the digest read on whichever binary pins. THE LINE AT 13:5x UK: three commits on release-0.3.20-node, 8097d600 (the object-5 amended class v4 and the day's fixes), 6b94c823 (test-only: the stale PC 1 test from 500ddd66 inverted by the isSynced ruling; the FALLBACK pin, code byte-identical to 8097d600, so the module reads green whole) and 6a3432a3 (the app lane's key methods, the observer's claims, the settled claim floor, the listener watchdog); suites on build-2 on 6a3432a3's code (the whole finality module 25, the exec suite 29 with the watchdog test, the kaspad, flows and rpc-service checks; consensus-core 123 and kaspa-pow 17 earlier); the cut 6a3432a3 if its gates and the fleet's 12 GB settled-claim line are green by 15:30 UK, else 6b94c823; both binaries building on build-1, the two gates (the digest gate, then the ten-minute mixed-version gate beside the 5899f603 pair) on the 8097d600 build, lines about 14:05 UK. GATE NEWS (13:53 UK): on 6a3432a3's own digest gate the listener watchdog counted a bind failure (the four harness nodes share one exec JSON-RPC port) as a listener death and exited three of four nodes at 20 s, where 0.3.17 and 8097d600 only warn and live without the exec RPC; the digest facts came out first and stand (the thirteen-field file a89be8a7 on both binaries, the compat case; the sixteen-field object db9a85f9 refused with the mismatch line, the refusal case); the ten-minute gate on 6a3432a3 stopped as void for the same cause. The fix: a bind failure is a retry every poll, one line a minute, no death counted and never an exit, with a second watchdog test whose known-failed shape is the old rule's exit on a held port; the third commit and its build about 14:15 UK, its gates about 14:35 UK; the fallback 6b94c823's gates on build-1 on their own binary (no watchdog there), lines about 14:20 UK; ledger row N12 for the bind-failure class. A ROLL BLOCKER on every kept datadir (the node lane, 14:1x UK, ledger N13): the fleet started 6a3432a3 on a kept 0.3.17 datadir (pool-1's copy) and it died at start (virtual_state.rs:250, DeserializationError(UnexpectedEof)); the cause 10db4b61 on the 0.3.16 feature line added `silent: bool` to BlockRewardData under serde(default), which bincode ignores, so every build from 10db4b61 on (dc141409, 8097d600, 6b94c823, 6a3432a3, 09124180) reads a 0.3.17 node's virtual-state row short; no canary saw it because every canary wiped, and a one-box roll keeps datadirs, so it blocks the roll on every standing box, the hands and the hub whatever the pin. The fix on the line: the store reads the current layout first and on a deserialization error decodes the row as a v1 mirror, converts with silent false and rewrites it under the same key, with the known-failed test first; the fourth commit and build about 14:40 UK, the fleet's kept-datadir start on the fixed binary about 14:50 UK, its gates after. THE RULE IT ADDS for every node cut from now: a kept-datadir restart gate on a standing box's datadir copy beside the wiped canary. THE CANDIDATE PIN (14:2x UK): b7cc37e7 (8097d600, 6b94c823, 6a3432a3, 09124180, b7cc37e7; igneum-pow 8c728ca3): the N13 fix with its test green on build-2 at 14:04 UK and the kaspad check green, the build on build-1; the fallback 6b94c823 is no longer a pin for the one-box roll (it dies on a kept datadir like every build since 10db4b61): if b7cc37e7's gates are not green by 15:30 UK the honest fallback is 0.3.17's 5899f603 staying live. In flight on build-1: the earlier commits' gates, then b7cc37e7's own digest and ten-minute mixed-version gates on its binary with the read-back, lines about 15:05 UK; on the fleet the kept-datadir start on b7cc37e7 about 14:50 UK and the 12 GB settled-claim line 14:50 to 15:00 UK. Plan section 6.6 amended with the hard date (ca3-v4-node 9d763edd, merged to master); N12 and N13 on the ledger. THE GATES ON THE FALLBACK'S OWN BINARY (6b94c823, sha b1b7d47b, 13:56 to 14:08 UK; code byte-identical to 8097d600, so the amendment's node side): the digest gate, the thirteen-field file a89be8a7 on both binaries (the compat case, n0 peering n1 and n2) and the sixteen-field object db9a85f9 refused with the mismatch line (the refusal case); the mixed-version gate, ten minutes, one digest b0afb2ee on all five nodes, the 5899f603 hub accepting every block the amended node mined (146 new, 246 old, 0 rejected), plain header version 2 on the thirteen-field file, counts equal on all five through the two clean joins and the restart. Two FAILED checks, both the harness's own and fixed (36d3efdc): a refused peer's count read 1 with the reconnect in flight (now the minimum of five), and six address-in-use panics in the two old nodes because the second gate reused the first's ports the second they were sent SIGTERM (a 20 s gap now). CLOCK CORRECTION (the node lane, 12:12Z = 13:12 BST): every "UK" stamp it sent today was the box's CEST, an hour fast of BST; its lines read UTC from now. Restated: b7cc37e7's build about 12:15Z, its digest and mixed-version gates on that binary with the sha and string about 12:32Z (13:32 BST), the fleet's kept-datadir start on it about 12:25Z, its 12 GB settled-claim line 12:50 to 13:00Z; the shipper's checkpoint 14:30Z (15:30 BST), two hours of room. The 13 October date stands (derived from UTC DAA rates): the floor 831,600 about 08:00Z, 09:00 BST. b7cc37e7'S OWN LINES (binary sha256 bc28331abf21f4d5, the string read back on build-1 and on the fleet's pod): the digest gate 12:14:39Z to 12:16:18Z SUMMARY PASS (thirteen fields a89be8a7 on both binaries with the peers as the gate wants them; the sixteen-field object db9a85f9 refused with the line and no peer; the live file's digest eada4bda on the binary, unmoved); the kept-datadir start on the fleet's copy of pool-1's 0.3.17 datadir: the first start 12:17:12Z reads the v1 row through the mirror and rewrites it ("1 mergeset rewards"), the finality blob converts (1,747 locks), the node comes up on its ports with no panic; the second start 12:18:53Z reads first-try with no rewrite line and no panic; 6a3432a3's death on the same copy is the known-failed shape. The ten-minute mixed-version gate beside the 5899f603 pair runs on the same binary since 12:16:39Z, its line about 12:28Z; then the only line outstanding for the shipper's 14:30Z rule is the fleet's 12 GB settled-claim line, 12:50 to 13:00Z. AP-F8-1 RESIDUAL CLASS ON THE AMENDED STREAM (attack-pass lane 12:18Z on igneum-pow 8c728ca3, sub-version 1). F9 over 1,000,000 seeds: programs flagged (hot share at least 1 percent or 7 constant address bits) 1,871 (0.19 percent) against 11,696 (1.17 percent) unamended; worst hot share 9.66 percent against 17.3; mean 0.011 against 0.063 percent; 84 percent of the flagged programs and the whole or-saturation tail gone. F8 at 30 of 64 seeds: nine over 1.2x of the window model (p31 29.3x, p11 5.5x, p19 3.3x, p6 3.1x, p23 2.0x, the rest 1.3x to 1.6x); the 64-seed 1.2x gate is heading to FAIL on sub-version 1. Mechanism, confirmed on the two worst seeds: an all-ones load source (image 0x0ca59e4c under the era map) delivered through a writer the source rule counts as entropy-keeping, a rotate (rotl and rotr map all-ones to itself) or a load whose own source was saturated, with the saturation made one or more writes upstream by or. The rule looks one writer back; it must look through saturation-preserving writers or test the source's values. The ceiling has not moved: rule (c)'s 120-of-128 floor still caps any program at one saturated site, 6.25 percent of reads, a chip edge of at most 1.067x, and the residual (worst seed two sites at 0.53 and 0.56) sits inside it. THE SENTENCE "no lossy-sourced load by construction" IS HELD: it goes in no plan row and no ledger entry as true; sub-version 1 removes the or-source class and bounds the rest. MAIN'S RULING (13:2x UK): 0.3.20 ships object byte 5 on sub-version 1 as it stands, strictly better than the old stream the live floor flips to on 13 October; the fix is sub-version 2 on ca3-v4-amend (object byte 6 or whatever the v5 alignment leaves free) with both fixes: (F1) the static rule made transitive (rotates do not keep entropy; a load keeps entropy only if its own source did; one draw change, no attempts lost) and (F2) the dynamic source check (saturated load SOURCE values counted per site over the 64 units' 16,384 evaluations, rejected above 163 of 16,384, the same 1 percent the final-value rule uses; costs attempts on about 0.2 percent of seeds; rides with F1 because an or-written source is all-ones only (3/4)^32 of the time). Gate before sub-version 2 is proposed, run by the attack-pass lane and not by the hash lane: the full 64-seed census under 1.2x on every seed and the hot-set census. Hash lane's estimate about an hour its side (implement, re-export seven packs, vectors, crate suite, pairing, one G1 on PC 2) plus the node lane's vector re-pin and the attack-pass re-gate. The flip floor for sub-version 1 is expected to move (Josh's word) so the chain never flips to a stream that fails this gate. Also recorded: the crate suite at 8c728ca3 100 of 100 on the box (rc 0, 77 s); the pairing against the fork at dc141409 compiled and ran 15 of 16, the one failure the fork's own pre-amendment assertion (base equals v3's, igneum.rs:972), which 8097d600 on the release-0.3.20-node line turns into assert_ne; the pairing re-runs at b7cc37e7, its line to follow. CORRECTION (the attack-pass lane's own retraction, 13:3x UK): the F9 hot-set figures above (1,871 of 1,000,000, worst 9.66 percent, 84 percent removed, the two or-then-rotate listings) are WITHDRAWN: F9's harness draws through candidate_class with its own era class, outside candidate_from_words_class where the source rule lives, so it measured the old stream (the 8c728ca3 binary prints the identical program to the sub-version-0 binary for its worst seed). F8's 64-seed census on the chain path (pairing verified on 1a4230699a6b9c60) is the valid re-gate and STANDS: at 30 of 64 seeds, nine over 1.2x of the window model (p31 29.3x, p11 5.5x, p19 3.3x, p6 3.1x, p23 2.0x, p4 1.6x, p10 1.5x, p26 1.3x, p25 1.3x). The residual mechanism on the amended stream: a load-after-load chain (a saturated source reads one fixed word, which is the next load's address), admitted because a load injects; and the rotate-preserves-saturation path (generator.rs sets entropy_kept true for a rotate whatever it rotated), correct in code and a second admitted path if it occurs on the chain stream. Sub-version 2 must close both: dataflow freshness per register (a load fresh only if its source was fresh; add, sub, xor, mad, shfl fresh if either operand was; rotates only if the operand was; or, mul, mulhi never) plus the (c') count of saturated load sources per site as the backstop. The STOP holds on F8's evidence alone; the options and the 1.067x ceiling are unchanged. The sentence "no lossy-sourced load by construction" waits on the sub-version 2 census verdict and stays out of every public text until then. SUB-VERSION 2 IN BUILD (the hash lane, ca3-v4-amend, on the coordinator's direction, 13:4x UK): F1 (dataflow freshness per register, keyed on the class v4 shape on every draw path, era or not, so the candidate_class path and the chain path draw one stream) plus F2 (the (c') count of saturated load source values per site over the 64 units' 16,384 evaluations, rejected above 163, keyed on the same shape so v2 and v3 verdicts do not move); PROGRAM_SUBVERSION_V4 = 2, new ids, the seven packs re-exported, recheck.rs with 1a4230699a6b9c60 and c120d7963abdcd96 as the must-differ pair. Clock (UTC): the commit on the branch by 13:30; the crate suite on box 2 and the pairing against b7cc37e7 by about 13:50 (the pairing's vector test fails on the fork's sub-version-1 pin until the node lane re-pins; the compile and the other 15 are the pairing evidence); the G1 job on PC 2 under --cards-off by about 14:10, lock permitting; then the attack-pass lane's full 64-seed census and hot-set census on the chain path. Two consequences stated in the commit: the rule on every draw path moves the no-era sh256xN ladder packs' stream (packs-ca3-shadow's seven 256-block packs re-export with new fingerprints; the measured rates stand as the old stream's), and the class v5 lane's pinned string-seed packs move when it merges sub-version 2, so it re-exports them then. 0.3.20's sub-version-1 packs, ids and fingerprints untouched. OBJECT BYTES SETTLED (main, 13:5x UK): byte 5 = class v4 sub-version 1 (0.3.20), byte 6 = class v5 (pinned: class-v5 16afd0a0, class-v5-node 699db5a2, the flip case passed on 6,6,6; the v5 lane stopped), byte 7 = class v4 sub-version 2; the node and hash lanes told. b7cc37e7's MIXED-VERSION GATE: FAIL, the binary not the harness (12:16:39Z to 12:27:21Z, sha256 bc28331abf21f4d5, the string read back). Before the restart step everything held: one digest b0afb2ee on all five nodes, 268 new and 392 old blocks accepted, 0 rejected, header versions plain 2, counts equal on all five at 324 and 502 through both clean joins. At the new node's restart (12:24:19Z) it died at once on its own datadir ("IO error: While lock file: .../datadir/meta/LOCK: Resource temporarily unavailable", conn_builder.rs:167): the previous process was still shutting down, because the listener watchdog added on 6a3432a3 sleeps its whole 10 s poll before checking shutdown, so every node on the line since then takes up to 10 s longer to stop than 0.3.17 (the fleet saw the same shape as "a 12-second timeout does not stop the node"). Three of the four failed checks follow from that one death (counts, the restarted node's resync, the node it served frozen at 502). The fix on the line, one rule: the poll in 250 ms steps returning the moment shutdown is set, with a test that a shutdown returns within a second (the 10 s loop the known-failed shape); the exec suite on build-2, the fifth commit and its build about 12:45Z, its digest and ten-minute gates about 12:50 to 13:05Z, inside 14:30Z. b7cc37e7 is NOT the pin. The node-side re-pin for sub-version 2 (byte 7) once the hash lane's commit lands: the beside-the-fork igneum-pow copy archived from the commit, the two pinned ids moved in the kaspa-pow vector test (sub-version-2's epoch-0 id must-equal; sub-version-1's joins c120d7963abdcd96 as must-differ), CLASS_SIGNAL and tests for byte 7, the daemon's window line: about 20 minutes of edits plus one kaspa-pow suite run on build-2 (about 2 minutes). THE FIFTH COMMIT c4459193 on release-0.3.20-node (b7cc37e7's child, the watchdog poll returning on shutdown; the diff is the poll loop in rpc.rs alone), pairing igneum-pow 8c728ca3; its build on build-1 started 12:30:13Z, sha256 and string to follow. Line A, the shutdown test: rpc::watchdog_tests::a_shutdown_returns_within_a_second_whatever_the_poll green on build-2 at 12:29Z in the exec suite's 31 passed, beside the two other watchdog tests; its known-failed shape the old loop's 10 s stop. Line B, the kept-datadir start: b7cc37e7's fleet read carries to c4459193 since the store code is byte-identical between the two commits; the fleet re-reads on the c4459193 binary only if the shipper's rule wants the string on that line too. The digest gate and the ten-minute mixed-version gate on c4459193's own binary follow its build. THE SHIPPER'S CARRY RULING (14:1x UK): b7cc37e7's kept-datadir read stands as evidence that the store fix is right (the store code byte-identical) but is not the gate line for the pin, because the rule reads the binary, not the diff, and the binary changed (rpc.rs); the gate line is the kept read on c4459193's own binary with its string, which the fleet's canary already runs on c18-1 (wipe, then the kept read, then the restart) before the canary's restart step, at no extra cost; no re-read on p12-vast. THE PIN IS c4459193 pairing 8c728ca3 (object byte 5, sub-version 1); sub-version 2 (byte 7) is 0.3.21's, not 0.3.20's. The shipper's reading of main's F8 ruling: 0.3.20 ships object 5 as it stands because the live floor otherwise flips every node to the OLD stream on 13 October, and the 16:00 BST report tells Josh the floor move is now RECOMMENDED rather than optional, so the chain never flips to a stream that fails the 1.2x gate before sub-version 2 lands. THE INTEROP FACT stands from the void run: the 5899f603 hub accepted 235 object-byte-5 blocks from the 8097d600 node with 0 rejected, one digest on all five nodes on the live sixteen-field file. The gates: the digest test and the kaspa-pow vector test (the amended devnet epoch-0 id 1a4230699a6b9c60 must equal, c120d7963abdcd96 must differ, the v3 control unchanged) on the box; the mixed-version Devnet 2 gate (the amended 0.3.20 node beside a 5899f603 node for ten minutes on the live file without the v4 fields) after the Mac build; the fresh-join canary the 0.3.20 cut's | +| JOSH'S WORD (15:2x UK, 7 October): OPTION A, "do this but limit the testing, get it pushed" | the class v4 amendment: a load's source drawn only from registers whose last writer injects or is a rotate (the v5 rule applied now), a new program stream and vectors, the seven gate packs re-exported, the amended class with its own generator stamp; rides 0.3.20, the feature node (release-0.3.20-node = dc141409; 0.3.19 is an app-only cut with nothing of ours), on the shipper's line. The rollout arithmetic for the flip clock (the shipper): the standing fleet's one-box-at-a-time rollout took 32 minutes for 14 boxes (04:56 to 05:28Z, 7 October), the hands and the seed about 3 minutes after the miners, the Mac and the PCs within minutes of the publish; every 0.3.20 worker must accept the amended stamp before any flip. Owners: the hash lane (ca3-v4-amend: the generator, the vectors, the packs, the pairing on the box, one G1 run on PC 2, the ledger row), the node lane (release-0.3.20-node: the stamp agreed with the hash lane, the split-protection mechanism and the earliest flip time, the digest test, the mixed-version Devnet 2 gate), the attack-pass lane (the F8 census at 2^24 on the new stream, the gate 1.2x of the window model over 64 seeds), the shipper (the cut, the rollout order that sets the earliest flip). Testing limited to what prevents a split and proves the fix; G2, G3, the ladder re-measure and the rest of G4 to G6 OWED. THE STAMP agreed (the node and hash lanes, 7 October afternoon): generator 4 with sub-version 1 inside igneum-pow's id function, so the amended v4's program id for a seed differs from the old v4's (the old devnet epoch-0 id c120d7963abdcd96 pinned as the must-differ vector in kaspa-pow's test). SPLIT PROTECTION SETTLED (the node lane, plan section 6.6, ca3-v4-node fa5bc9e6; the node side on release-0.3.20-node): a fresh object byte. CLASS_SIGNAL_V4 is 5; the amended binary stamps 5 and the tally counts a block only at byte 5 or above; object 4 was stamped only by the unpublished dc141409 canary, so no published block carries it and a byte-4 block never counts; a node of the 6 October stream that sees byte 5 counts it as v4 (its rule is at least 4), flips to its own stream at the same epoch and forks ALONE (its blocks fail the amended id check, generator 4 sub-version 1 inside every id; the amended blocks fail its own), ours to upgrade in the sweep; object 6 is class v5's; the two holds already in the rule keep the window shut until every node is on 0.3.20 (a node stamps and tallies only with both v4 fields in its file; the fields publish only after the one-sweep rollout); a lagging worker refuses the amended pack at packcheck and mines nothing after the flip, costing that box, never the chain; no extra window hold: seven full day-windows are the hold. THE EARLIEST FLIP (approximate, measured 09:40Z: DAA 270,659, 1.095 DAA/s over 25 hours, 1.165 over 4; epoch 3,600, lead 600; seven windows 604,800 DAA wholly after the sweep's end D_s = T + about 40 minutes; the flip epoch the first e with 3600 e - 600 >= D_s + 604,800): T + 6 days 10 hours to T + 6 days 11 hours UK; for a publish at 12:00 UK on 7 October, 13 October between 22:20 and 23:10 UK (about 13:00 UK if the 4-hour rate holds). The floor as it stands (831,600, about 13 October 09:00 UK) would fire before any seven-window signal from a publish today completes, so it moves by the 0.3.16 rule to the publish DAA + 604,800 rounded up to the epoch boundary (882,000 for a 12:00 UK publish), firing about 30 minutes before the earliest signal flip: either way about 6 days 10 hours after the publish, never before every node has had the sweep plus a week. THE CLOCK (the node lane, 11:3x UK, after a Mac reboot moved its runs to the box): the 0.3.20 node line (dc141409 plus the proof archive aea0ca5c plus the amended v4 at object byte 5, igneum-pow at the hash lane's a0aaca92 beside the fork on the box) tested on the box, committed on release-0.3.20-node, pushed to the mirror and origin, igneumd and igneum-miner built, the tip to the shipper: about 12:00 UK; the mixed-version Devnet 2 gate (node-compat.mjs on the box, the amended node beside the 5899f603 pair for ten minutes) and the digest test (digest-compat.mjs): about 12:45 UK; the object-byte pin 5 unless the v5 lane answers both lanes with another assignment (v5 at 6 proposed). THE HASH SIDE on ca3-v4-amend (tip 8c728ca3, read from the branch 14:0x UK; the hash lane's own report pending): 1748fd1d the PC 2 G1-only playbook; e1f48d63 the fud-ledger entry AP-F8-1 (the fault, Josh's ruling, the amendment, the split protection, the owed tests); d8859522 the G1 line (the eight fingerprints equal on the RTX 5090, self-test PASS) and the node lane's signal byte 5; 4aa0c665 the v4 unit test following the amendment; 965d9e96 igneum-pow taken from release-0.3.20's 3f1652bf (the ladder's chain_program_shadow with the reps argument, never on master) with the amendment re-applied, the seven packs re-exporting byte-identical; 8c728ca3 the source rule keyed on the class with the shadow's pass count set aside, so every ladder rung draws under it (the fork's ladder test). The shipper took this igneum-pow tree into release-0.3.20 (00249643, byte-equal); nothing after 8c728ca3 touches igneum-pow. THE VECTORS AND THE PACKS (read from the branch and its ledger entry, 14:1x UK): the seven amended v4 packs (v4-devnet-epoch0, v4-era-0 to 5) carry generator 4, sub-version 1, one program id 1a4230699a6b9c60 (the 2.0 one-id-per-seed rule across the eras; the old c120d7963abdcd96 pinned as must-differ); the v3 control mx8-devnet-epoch0 untouched (73bcbfe8ccf988f1, fingerprint 90f794dd556f7a3b); the seven 2^24 fingerprints, Metal equal to Apple OpenCL: 867dbc45cfb36b4d, 2146ecacc8c75a8e, fe52602393f6d3d4, 3b206471a13912b4, c3f03c4a5d7333aa, f1dfd7209f15bb97, 8c194da64fadf31d; the zip of the eight packs sha256 889ec99976d2728b4b5035bfa476032e5b6a13b928968fc45236d5f25084aa39; the per-pack vectors.json sha256 prefixes 756301bf (devnet epoch 0), 1b5f4568, d430cadc, 1a1b21d8, 460fff9e, 4a85d49d, f83a1196 (eras 0 to 5). G1 on the RTX 5090 (PC 2 job run-ca3-v4-amend-g1-pc2-20261007, 09:41:07 to 09:41:28Z, exit 0, the installed worker): every fingerprint equal to the Mac's (the seven above and the control), NVRTC 188 to 332 ms per pack, the 1 GiB build 38 to 49 ms. hash-gates.md's older table still lists the pre-amendment fingerprints (f410c731... and the eras), which no longer apply to the amended packs; the ledger entry is the record. THE FIRST GREEN (11:31 UK, the box): the kaspa-pow suite on release-0.3.20-node (dc141409 plus the proof archive aea0ca5c plus the object-5 change) against the hash lane's igneum-pow 8c728ca3: 17 passed, 0 failed; the amended devnet epoch-0 id 1a4230699a6b9c60 pinned equal and c120d7963abdcd96 differing, the ladder's rung test green under the rekeyed rule, the v3 control unchanged; the consensus-core and exec RPC suites follow, then the node line (commit, push, box build, the tip to the shipper), then the digest and mixed-version gates. CLOCK RE-CUT (the node lane, 13:0x UK): the node line now carries, beside the object-5 change and the vector test, the lane's 0.3.20 fixes from the day (isSynced from the hook's stamp, the lazy template snapshot, the weight-table cache, the submit path returning after the block task, the watchdog, the RPC fields), about 13:30 UK if the box suites are green; the shipper's fresh-join canary 60 to 100 minutes after the cut; PC 1 as its first machine about 16:00 UK at the earliest, approximate until the shipper names the cut; the earliest flip about 6 days 10 hours after the publish. BUILD-2 LINES (12:28 to 12:33 UK): consensus-core 123 passed (the 60x file test green with the ladder window and activation pinned), the behind test green, kaspa-pow 17 passed (the amended vectors, earlier on build-1), the exec RPC suite green, the flows and rpc-service checks green with the submit-path change; the 24-requester latency test's first run tripped an unrelated flapping-fork double insert (24 equal forks from one parent; the test now builds on the sink as a real miner does; the double insert owed to a small fork harness before it is called a bug); THE NODE LINE COMMITTED (13:1x UK): release-0.3.20-node = 8097d600 (dc141409 + the proof archive aea0ca5c + one commit) on the mirror, pairing igneum-pow 8c728ca3, the hash with the shipper; in it the amended class v4 as object 5 (CLASS_SIGNAL_V4 = 5, byte 4 never counts, the kaspa-pow vector test pinning 1a4230699a6b9c60 equal and c120d7963abdcd96 differing, the daemon's window line naming object 5 and sub-version 1) beside the day's fixes (isSynced from the hook's stamp, the weight-table cache, the lazy snapshot, the submit path, the 100 ms template wait); the suites green on build-2 (consensus-core 123, the exec RPC suite, the four finality tests including 24 requesters under 200 ms: the worst template 100 ms, the worst submit 102 ms) and kaspa-pow 17 on build-1. Next: igneumd and igneum-miner building from 8097d600 on build-1, then the two gate lines (the mixed-version Devnet 2 gate: the 8097d600 node mining beside the 5899f603 pair for ten minutes on the live file without the v4 fields, the old node accepting every block; the digest test: the thirteen-field file b18ed271 unchanged, the sixteen-field object re-read on the 8097d600 binary), expected about 13:30 UK; the shipper picks the cut point. THE DATE FIXED (the node lane, from the hub's live file, 13:3x UK): publish 2 of 6 October (22:49:45Z, digest eada4bda) already put BOTH v4 fields on the live devnet (floor 831,600, window 86,400), so the 0.3.17 fleet has stamped object byte 4 since 7 October 00:2x UK and the floor is live at about 13 October 09:00 UK, before any seven-window signal completes; a 0.3.17 node left on that file flips to the OLD v4 stream at epoch 231 whatever anyone signals, a 0.3.20 node to the amended stream at the same epoch, and the two never share an id, so each straggler forks alone there. REQUIREMENT for the 0.3.20 publish (with the shipper and main): a new file with the floor at the publish DAA + 604,800 rounded up (about 882,000 for a publish today), the digest moving, the one-sweep rollout replacing every 0.3.17 node before 13 October 09:00 UK; any node that misses the sweep is alone then; the earliest flip after that about 6 days 10 hours past the publish; plan section 6.6 amended today. IN THE 0.3.20 PLAN (the shipper, 13:4x UK): both requirements; the node pin by main's rule is the node lane's second commit (the claim floor, the listener watchdog, the claim RPCs, on top of 8097d600) if its suites, both gates and the fleet's 12 GB prover line are green by 15:30 UK, else 8097d600; igneum-pow 8c728ca3 either way; the digest read on whichever binary pins. THE LINE AT 13:5x UK: three commits on release-0.3.20-node, 8097d600 (the object-5 amended class v4 and the day's fixes), 6b94c823 (test-only: the stale PC 1 test from 500ddd66 inverted by the isSynced ruling; the FALLBACK pin, code byte-identical to 8097d600, so the module reads green whole) and 6a3432a3 (the app lane's key methods, the observer's claims, the settled claim floor, the listener watchdog); suites on build-2 on 6a3432a3's code (the whole finality module 25, the exec suite 29 with the watchdog test, the kaspad, flows and rpc-service checks; consensus-core 123 and kaspa-pow 17 earlier); the cut 6a3432a3 if its gates and the fleet's 12 GB settled-claim line are green by 15:30 UK, else 6b94c823; both binaries building on build-1, the two gates (the digest gate, then the ten-minute mixed-version gate beside the 5899f603 pair) on the 8097d600 build, lines about 14:05 UK. GATE NEWS (13:53 UK): on 6a3432a3's own digest gate the listener watchdog counted a bind failure (the four harness nodes share one exec JSON-RPC port) as a listener death and exited three of four nodes at 20 s, where 0.3.17 and 8097d600 only warn and live without the exec RPC; the digest facts came out first and stand (the thirteen-field file a89be8a7 on both binaries, the compat case; the sixteen-field object db9a85f9 refused with the mismatch line, the refusal case); the ten-minute gate on 6a3432a3 stopped as void for the same cause. The fix: a bind failure is a retry every poll, one line a minute, no death counted and never an exit, with a second watchdog test whose known-failed shape is the old rule's exit on a held port; the third commit and its build about 14:15 UK, its gates about 14:35 UK; the fallback 6b94c823's gates on build-1 on their own binary (no watchdog there), lines about 14:20 UK; ledger row N12 for the bind-failure class. A ROLL BLOCKER on every kept datadir (the node lane, 14:1x UK, ledger N13): the fleet started 6a3432a3 on a kept 0.3.17 datadir (pool-1's copy) and it died at start (virtual_state.rs:250, DeserializationError(UnexpectedEof)); the cause 10db4b61 on the 0.3.16 feature line added `silent: bool` to BlockRewardData under serde(default), which bincode ignores, so every build from 10db4b61 on (dc141409, 8097d600, 6b94c823, 6a3432a3, 09124180) reads a 0.3.17 node's virtual-state row short; no canary saw it because every canary wiped, and a one-box roll keeps datadirs, so it blocks the roll on every standing box, the hands and the hub whatever the pin. The fix on the line: the store reads the current layout first and on a deserialization error decodes the row as a v1 mirror, converts with silent false and rewrites it under the same key, with the known-failed test first; the fourth commit and build about 14:40 UK, the fleet's kept-datadir start on the fixed binary about 14:50 UK, its gates after. THE RULE IT ADDS for every node cut from now: a kept-datadir restart gate on a standing box's datadir copy beside the wiped canary. THE CANDIDATE PIN (14:2x UK): b7cc37e7 (8097d600, 6b94c823, 6a3432a3, 09124180, b7cc37e7; igneum-pow 8c728ca3): the N13 fix with its test green on build-2 at 14:04 UK and the kaspad check green, the build on build-1; the fallback 6b94c823 is no longer a pin for the one-box roll (it dies on a kept datadir like every build since 10db4b61): if b7cc37e7's gates are not green by 15:30 UK the honest fallback is 0.3.17's 5899f603 staying live. In flight on build-1: the earlier commits' gates, then b7cc37e7's own digest and ten-minute mixed-version gates on its binary with the read-back, lines about 15:05 UK; on the fleet the kept-datadir start on b7cc37e7 about 14:50 UK and the 12 GB settled-claim line 14:50 to 15:00 UK. Plan section 6.6 amended with the hard date (ca3-v4-node 9d763edd, merged to master); N12 and N13 on the ledger. THE GATES ON THE FALLBACK'S OWN BINARY (6b94c823, sha b1b7d47b, 13:56 to 14:08 UK; code byte-identical to 8097d600, so the amendment's node side): the digest gate, the thirteen-field file a89be8a7 on both binaries (the compat case, n0 peering n1 and n2) and the sixteen-field object db9a85f9 refused with the mismatch line (the refusal case); the mixed-version gate, ten minutes, one digest b0afb2ee on all five nodes, the 5899f603 hub accepting every block the amended node mined (146 new, 246 old, 0 rejected), plain header version 2 on the thirteen-field file, counts equal on all five through the two clean joins and the restart. Two FAILED checks, both the harness's own and fixed (36d3efdc): a refused peer's count read 1 with the reconnect in flight (now the minimum of five), and six address-in-use panics in the two old nodes because the second gate reused the first's ports the second they were sent SIGTERM (a 20 s gap now). CLOCK CORRECTION (the node lane, 12:12Z = 13:12 BST): every "UK" stamp it sent today was the box's CEST, an hour fast of BST; its lines read UTC from now. Restated: b7cc37e7's build about 12:15Z, its digest and mixed-version gates on that binary with the sha and string about 12:32Z (13:32 BST), the fleet's kept-datadir start on it about 12:25Z, its 12 GB settled-claim line 12:50 to 13:00Z; the shipper's checkpoint 14:30Z (15:30 BST), two hours of room. The 13 October date stands (derived from UTC DAA rates): the floor 831,600 about 08:00Z, 09:00 BST. b7cc37e7'S OWN LINES (binary sha256 bc28331abf21f4d5, the string read back on build-1 and on the fleet's pod): the digest gate 12:14:39Z to 12:16:18Z SUMMARY PASS (thirteen fields a89be8a7 on both binaries with the peers as the gate wants them; the sixteen-field object db9a85f9 refused with the line and no peer; the live file's digest eada4bda on the binary, unmoved); the kept-datadir start on the fleet's copy of pool-1's 0.3.17 datadir: the first start 12:17:12Z reads the v1 row through the mirror and rewrites it ("1 mergeset rewards"), the finality blob converts (1,747 locks), the node comes up on its ports with no panic; the second start 12:18:53Z reads first-try with no rewrite line and no panic; 6a3432a3's death on the same copy is the known-failed shape. The ten-minute mixed-version gate beside the 5899f603 pair runs on the same binary since 12:16:39Z, its line about 12:28Z; then the only line outstanding for the shipper's 14:30Z rule is the fleet's 12 GB settled-claim line, 12:50 to 13:00Z. AP-F8-1 RESIDUAL CLASS ON THE AMENDED STREAM (attack-pass lane 12:18Z on igneum-pow 8c728ca3, sub-version 1). F9 over 1,000,000 seeds: programs flagged (hot share at least 1 percent or 7 constant address bits) 1,871 (0.19 percent) against 11,696 (1.17 percent) unamended; worst hot share 9.66 percent against 17.3; mean 0.011 against 0.063 percent; 84 percent of the flagged programs and the whole or-saturation tail gone. F8 at 30 of 64 seeds: nine over 1.2x of the window model (p31 29.3x, p11 5.5x, p19 3.3x, p6 3.1x, p23 2.0x, the rest 1.3x to 1.6x); the 64-seed 1.2x gate is heading to FAIL on sub-version 1. Mechanism, confirmed on the two worst seeds: an all-ones load source (image 0x0ca59e4c under the era map) delivered through a writer the source rule counts as entropy-keeping, a rotate (rotl and rotr map all-ones to itself) or a load whose own source was saturated, with the saturation made one or more writes upstream by or. The rule looks one writer back; it must look through saturation-preserving writers or test the source's values. The ceiling has not moved: rule (c)'s 120-of-128 floor still caps any program at one saturated site, 6.25 percent of reads, a chip edge of at most 1.067x, and the residual (worst seed two sites at 0.53 and 0.56) sits inside it. THE SENTENCE "no lossy-sourced load by construction" IS HELD: it goes in no plan row and no ledger entry as true; sub-version 1 removes the or-source class and bounds the rest. MAIN'S RULING (13:2x UK): 0.3.20 ships object byte 5 on sub-version 1 as it stands, strictly better than the old stream the live floor flips to on 13 October; the fix is sub-version 2 on ca3-v4-amend (object byte 6 or whatever the v5 alignment leaves free) with both fixes: (F1) the static rule made transitive (rotates do not keep entropy; a load keeps entropy only if its own source did; one draw change, no attempts lost) and (F2) the dynamic source check (saturated load SOURCE values counted per site over the 64 units' 16,384 evaluations, rejected above 163 of 16,384, the same 1 percent the final-value rule uses; costs attempts on about 0.2 percent of seeds; rides with F1 because an or-written source is all-ones only (3/4)^32 of the time). Gate before sub-version 2 is proposed, run by the attack-pass lane and not by the hash lane: the full 64-seed census under 1.2x on every seed and the hot-set census. Hash lane's estimate about an hour its side (implement, re-export seven packs, vectors, crate suite, pairing, one G1 on PC 2) plus the node lane's vector re-pin and the attack-pass re-gate. The flip floor for sub-version 1 is expected to move (Josh's word) so the chain never flips to a stream that fails this gate. Also recorded: the crate suite at 8c728ca3 100 of 100 on the box (rc 0, 77 s); the pairing against the fork at dc141409 compiled and ran 15 of 16, the one failure the fork's own pre-amendment assertion (base equals v3's, igneum.rs:972), which 8097d600 on the release-0.3.20-node line turns into assert_ne; the pairing re-runs at b7cc37e7, its line to follow. CORRECTION (the attack-pass lane's own retraction, 13:3x UK): the F9 hot-set figures above (1,871 of 1,000,000, worst 9.66 percent, 84 percent removed, the two or-then-rotate listings) are WITHDRAWN: F9's harness draws through candidate_class with its own era class, outside candidate_from_words_class where the source rule lives, so it measured the old stream (the 8c728ca3 binary prints the identical program to the sub-version-0 binary for its worst seed). F8's 64-seed census on the chain path (pairing verified on 1a4230699a6b9c60) is the valid re-gate and STANDS: at 30 of 64 seeds, nine over 1.2x of the window model (p31 29.3x, p11 5.5x, p19 3.3x, p6 3.1x, p23 2.0x, p4 1.6x, p10 1.5x, p26 1.3x, p25 1.3x). The residual mechanism on the amended stream: a load-after-load chain (a saturated source reads one fixed word, which is the next load's address), admitted because a load injects; and the rotate-preserves-saturation path (generator.rs sets entropy_kept true for a rotate whatever it rotated), correct in code and a second admitted path if it occurs on the chain stream. Sub-version 2 must close both: dataflow freshness per register (a load fresh only if its source was fresh; add, sub, xor, mad, shfl fresh if either operand was; rotates only if the operand was; or, mul, mulhi never) plus the (c') count of saturated load sources per site as the backstop. The STOP holds on F8's evidence alone; the options and the 1.067x ceiling are unchanged. The sentence "no lossy-sourced load by construction" waits on the sub-version 2 census verdict and stays out of every public text until then. SUB-VERSION 2 IN BUILD (the hash lane, ca3-v4-amend, on the coordinator's direction, 13:4x UK): F1 (dataflow freshness per register, keyed on the class v4 shape on every draw path, era or not, so the candidate_class path and the chain path draw one stream) plus F2 (the (c') count of saturated load source values per site over the 64 units' 16,384 evaluations, rejected above 163, keyed on the same shape so v2 and v3 verdicts do not move); PROGRAM_SUBVERSION_V4 = 2, new ids, the seven packs re-exported, recheck.rs with 1a4230699a6b9c60 and c120d7963abdcd96 as the must-differ pair. Clock (UTC): the commit on the branch by 13:30; the crate suite on box 2 and the pairing against b7cc37e7 by about 13:50 (the pairing's vector test fails on the fork's sub-version-1 pin until the node lane re-pins; the compile and the other 15 are the pairing evidence); the G1 job on PC 2 under --cards-off by about 14:10, lock permitting; then the attack-pass lane's full 64-seed census and hot-set census on the chain path. Two consequences stated in the commit: the rule on every draw path moves the no-era sh256xN ladder packs' stream (packs-ca3-shadow's seven 256-block packs re-export with new fingerprints; the measured rates stand as the old stream's), and the class v5 lane's pinned string-seed packs move when it merges sub-version 2, so it re-exports them then. 0.3.20's sub-version-1 packs, ids and fingerprints untouched. OBJECT BYTES SETTLED (main, 13:5x UK): byte 5 = class v4 sub-version 1 (0.3.20), byte 6 = class v5 (pinned: class-v5 16afd0a0, class-v5-node 699db5a2, the flip case passed on 6,6,6; the v5 lane stopped), byte 7 = class v4 sub-version 2; the node and hash lanes told. b7cc37e7's MIXED-VERSION GATE: FAIL, the binary not the harness (12:16:39Z to 12:27:21Z, sha256 bc28331abf21f4d5, the string read back). Before the restart step everything held: one digest b0afb2ee on all five nodes, 268 new and 392 old blocks accepted, 0 rejected, header versions plain 2, counts equal on all five at 324 and 502 through both clean joins. At the new node's restart (12:24:19Z) it died at once on its own datadir ("IO error: While lock file: .../datadir/meta/LOCK: Resource temporarily unavailable", conn_builder.rs:167): the previous process was still shutting down, because the listener watchdog added on 6a3432a3 sleeps its whole 10 s poll before checking shutdown, so every node on the line since then takes up to 10 s longer to stop than 0.3.17 (the fleet saw the same shape as "a 12-second timeout does not stop the node"). Three of the four failed checks follow from that one death (counts, the restarted node's resync, the node it served frozen at 502). The fix on the line, one rule: the poll in 250 ms steps returning the moment shutdown is set, with a test that a shutdown returns within a second (the 10 s loop the known-failed shape); the exec suite on build-2, the fifth commit and its build about 12:45Z, its digest and ten-minute gates about 12:50 to 13:05Z, inside 14:30Z. b7cc37e7 is NOT the pin. The node-side re-pin for sub-version 2 (byte 7) once the hash lane's commit lands: the beside-the-fork igneum-pow copy archived from the commit, the two pinned ids moved in the kaspa-pow vector test (sub-version-2's epoch-0 id must-equal; sub-version-1's joins c120d7963abdcd96 as must-differ), CLASS_SIGNAL and tests for byte 7, the daemon's window line: about 20 minutes of edits plus one kaspa-pow suite run on build-2 (about 2 minutes). THE FIFTH COMMIT c4459193 on release-0.3.20-node (b7cc37e7's child, the watchdog poll returning on shutdown; the diff is the poll loop in rpc.rs alone), pairing igneum-pow 8c728ca3; its build on build-1 started 12:30:13Z, sha256 and string to follow. Line A, the shutdown test: rpc::watchdog_tests::a_shutdown_returns_within_a_second_whatever_the_poll green on build-2 at 12:29Z in the exec suite's 31 passed, beside the two other watchdog tests; its known-failed shape the old loop's 10 s stop. Line B, the kept-datadir start: b7cc37e7's fleet read carries to c4459193 since the store code is byte-identical between the two commits; the fleet re-reads on the c4459193 binary only if the shipper's rule wants the string on that line too. The digest gate and the ten-minute mixed-version gate on c4459193's own binary follow its build. THE SHIPPER'S CARRY RULING (14:1x UK): b7cc37e7's kept-datadir read stands as evidence that the store fix is right (the store code byte-identical) but is not the gate line for the pin, because the rule reads the binary, not the diff, and the binary changed (rpc.rs); the gate line is the kept read on c4459193's own binary with its string, which the fleet's canary already runs on c18-1 (wipe, then the kept read, then the restart) before the canary's restart step, at no extra cost; no re-read on p12-vast. THE PIN IS c4459193 pairing 8c728ca3 (object byte 5, sub-version 1); sub-version 2 (byte 7) is 0.3.21's, not 0.3.20's. The shipper's reading of main's F8 ruling: 0.3.20 ships object 5 as it stands because the live floor otherwise flips every node to the OLD stream on 13 October, and the 16:00 BST report tells Josh the floor move is now RECOMMENDED rather than optional, so the chain never flips to a stream that fails the 1.2x gate before sub-version 2 lands. THE FLEET'S CLOCK ON c4459193 (the fleet lane, 12:5x UTC): the kept read on pool-1's 0.3.17 datadir copy and the restart (the old process's stop time on the line) run on c18-1 before the wipe, a few minutes each, so both lines land before 14:30Z; the wipe canary (IBD from the pruning-point proof, 98 minutes on this pod class) starts when c18-1 is free of the 0.3.20 cases (about 13:00Z) and the binary is in hand, so its synced line lands about 14:40Z at the earliest, PAST the 14:30Z checkpoint; the 12 GB settled-claim line: c4459193 starts on p12-vast's kept copy of pool-1's datadir beside the 6a3432a3 IBD node on alternate ports the moment the binary lands, catches up from 129,398 blocks (15 to 20 minutes) and the 12 GB prover claims against it, the line on c4459193 itself. The binary not yet in the fleet's hand (build-1 building since 12:30:13Z); a wait armed on the sha and string, a report by 13:10Z if nothing. THE INTEROP FACT stands from the void run: the 5899f603 hub accepted 235 object-byte-5 blocks from the 8097d600 node with 0 rejected, one digest on all five nodes on the live sixteen-field file. The gates: the digest test and the kaspa-pow vector test (the amended devnet epoch-0 id 1a4230699a6b9c60 must equal, c120d7963abdcd96 must differ, the v3 control unchanged) on the box; the mixed-version Devnet 2 gate (the amended 0.3.20 node beside a 5899f603 node for ten minutes on the live file without the v4 fields) after the Mac build; the fresh-join canary the 0.3.20 cut's | | Main's rulings (7 October, morning) | no generator change to v4 on the live devnet; the record's null is the window model with numbers, sent by the hash lane to the attack-pass lane so AP-F8-1 re-gates against it; a fault beyond the model (a low-entropy source at site 15) stops at the coordinator with the two options priced (a 0.3.19 class amendment before the flip, or the flip held at the floor), nothing shipping without Josh's word; the tighter tail, an acceptance bound on the hot-set share, is a CLASS V5 item (sent to the v5 lane a6410f3b8abefb762 with the 64-seed census as its gate; the bound's number follows from the model) | ### AP-F4-1, the weak-day MUL draw (the attack-pass lane, 7 October, morning): PASS against v4, a class v5 rule From 454d9e2fc6bfb976ae7643f8d78805e3bf8f5747 Mon Sep 17 00:00:00 2001 From: igneum-josh <337424239+igneum-josh@users.noreply.github.com> Date: Wed, 7 Oct 2026 13:36:29 +0100 Subject: [PATCH 04/19] Counter ASIC 3.0 status: the shipper's clock call (a second one-shot pod for the wipe canary, line about 14:15Z) Co-Authored-By: Claude Fable 5.1 --- docs/plans/counter-asic-3-status.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/plans/counter-asic-3-status.md b/docs/plans/counter-asic-3-status.md index 659bf2256..9768dc1f0 100644 --- a/docs/plans/counter-asic-3-status.md +++ b/docs/plans/counter-asic-3-status.md @@ -338,7 +338,7 @@ Josh gave the go in advance for tonight: the shipper runs publish 1 on the 0.3.1 | THE ANALYSIS (the hash lane, ca3-v4-uniform 095f84a7, `docs/analysis/ca3-v4-uniform.md`, the tool on igneum-build-1) | the window model moves the null from 0.115 to 0.160 percent (1.39x, not 4.05x); the rest is a FAULT beyond it: site 15 reads a register last written by `or r6, r4`, so all-ones recurs at (3/4)^32 per read and the era map sends it to F8's hottest item exactly (the popcount model predicts 77,348 all-ones reads against 78,479; the top-0.1-percent share 0.58 against 0.52); it passes the acceptance rule because part (a) takes any write as a fresh source and part (c) counts saturation on final values only. The census of 1,024 chain-shaped v4 programs: 96.6 percent carry a lossy-sourced load (or, mul, mulhi as the last writer), 48.5 percent an or-sourced one (0.30 percent of all reads per site), 4.9 percent an or-of-or chain (4.6 percent of all reads on 0.1 percent of items); F8's 1.2x gate fails 96.6 percent of today's programs. Worth to a chip: 1.07 MB of SRAM ($0.25) serving 0.52 percent of a typical program's reads and 4.6 percent of the worst class's, at most 1.005x and 1.048x in rate; the ceiling under rule (c)'s 120-of-128 floor one site repeating its item in all 8 iterations, 6.25 percent of reads, 1.067x in 64 bytes; the 2x margin stands; the public line says "bounded at 1.067x", not "uniform" (the public text corrected) | | The two options, priced, STOPPED at the coordinator for Josh's word | A: a 0.3.19 class amendment before the flip (the generator draws a load's source from the registers whose last writer injects): a new program stream, new vectors, the seven gate packs re-exported, the six gates again (G1 to G3 and the verifier about an hour on the Mac and PC 2; G4 to G6 the node lane), every node before the flip under the one-box-at-a-time rule; the risk a node that misses the build splits the chain at the flip. B: hold the flip at the floor with v4 as it is; the bound documented; the source rule to class v5: a hot set worth up to 1.005x on about half the hours and 1.05x on 5 percent, 1.067x at the ceiling; no chain risk. The number: 1.067x at the ceiling against the 2x margin. The lane recommends B | | The v5 bound (sent to the v5 lane) | H = W_0.1 (the window term, 0.115 to 0.251 percent) + the sum over load sites of h(last writer) (or 0.30 percent, an or chain 4.5, mul 0.067, mulhi 0.049, an injecting op or a rotate 0), H at or under 1.2 x W_0.1, which is the static rule "every load's source was last written by an injecting op or a rotate"; as a rejection it costs 96.6 percent of candidates (about 30 attempts per seed), as a generator draw nothing; gate F8's 64-seed census with the saturated-source count | -| JOSH'S WORD (15:2x UK, 7 October): OPTION A, "do this but limit the testing, get it pushed" | the class v4 amendment: a load's source drawn only from registers whose last writer injects or is a rotate (the v5 rule applied now), a new program stream and vectors, the seven gate packs re-exported, the amended class with its own generator stamp; rides 0.3.20, the feature node (release-0.3.20-node = dc141409; 0.3.19 is an app-only cut with nothing of ours), on the shipper's line. The rollout arithmetic for the flip clock (the shipper): the standing fleet's one-box-at-a-time rollout took 32 minutes for 14 boxes (04:56 to 05:28Z, 7 October), the hands and the seed about 3 minutes after the miners, the Mac and the PCs within minutes of the publish; every 0.3.20 worker must accept the amended stamp before any flip. Owners: the hash lane (ca3-v4-amend: the generator, the vectors, the packs, the pairing on the box, one G1 run on PC 2, the ledger row), the node lane (release-0.3.20-node: the stamp agreed with the hash lane, the split-protection mechanism and the earliest flip time, the digest test, the mixed-version Devnet 2 gate), the attack-pass lane (the F8 census at 2^24 on the new stream, the gate 1.2x of the window model over 64 seeds), the shipper (the cut, the rollout order that sets the earliest flip). Testing limited to what prevents a split and proves the fix; G2, G3, the ladder re-measure and the rest of G4 to G6 OWED. THE STAMP agreed (the node and hash lanes, 7 October afternoon): generator 4 with sub-version 1 inside igneum-pow's id function, so the amended v4's program id for a seed differs from the old v4's (the old devnet epoch-0 id c120d7963abdcd96 pinned as the must-differ vector in kaspa-pow's test). SPLIT PROTECTION SETTLED (the node lane, plan section 6.6, ca3-v4-node fa5bc9e6; the node side on release-0.3.20-node): a fresh object byte. CLASS_SIGNAL_V4 is 5; the amended binary stamps 5 and the tally counts a block only at byte 5 or above; object 4 was stamped only by the unpublished dc141409 canary, so no published block carries it and a byte-4 block never counts; a node of the 6 October stream that sees byte 5 counts it as v4 (its rule is at least 4), flips to its own stream at the same epoch and forks ALONE (its blocks fail the amended id check, generator 4 sub-version 1 inside every id; the amended blocks fail its own), ours to upgrade in the sweep; object 6 is class v5's; the two holds already in the rule keep the window shut until every node is on 0.3.20 (a node stamps and tallies only with both v4 fields in its file; the fields publish only after the one-sweep rollout); a lagging worker refuses the amended pack at packcheck and mines nothing after the flip, costing that box, never the chain; no extra window hold: seven full day-windows are the hold. THE EARLIEST FLIP (approximate, measured 09:40Z: DAA 270,659, 1.095 DAA/s over 25 hours, 1.165 over 4; epoch 3,600, lead 600; seven windows 604,800 DAA wholly after the sweep's end D_s = T + about 40 minutes; the flip epoch the first e with 3600 e - 600 >= D_s + 604,800): T + 6 days 10 hours to T + 6 days 11 hours UK; for a publish at 12:00 UK on 7 October, 13 October between 22:20 and 23:10 UK (about 13:00 UK if the 4-hour rate holds). The floor as it stands (831,600, about 13 October 09:00 UK) would fire before any seven-window signal from a publish today completes, so it moves by the 0.3.16 rule to the publish DAA + 604,800 rounded up to the epoch boundary (882,000 for a 12:00 UK publish), firing about 30 minutes before the earliest signal flip: either way about 6 days 10 hours after the publish, never before every node has had the sweep plus a week. THE CLOCK (the node lane, 11:3x UK, after a Mac reboot moved its runs to the box): the 0.3.20 node line (dc141409 plus the proof archive aea0ca5c plus the amended v4 at object byte 5, igneum-pow at the hash lane's a0aaca92 beside the fork on the box) tested on the box, committed on release-0.3.20-node, pushed to the mirror and origin, igneumd and igneum-miner built, the tip to the shipper: about 12:00 UK; the mixed-version Devnet 2 gate (node-compat.mjs on the box, the amended node beside the 5899f603 pair for ten minutes) and the digest test (digest-compat.mjs): about 12:45 UK; the object-byte pin 5 unless the v5 lane answers both lanes with another assignment (v5 at 6 proposed). THE HASH SIDE on ca3-v4-amend (tip 8c728ca3, read from the branch 14:0x UK; the hash lane's own report pending): 1748fd1d the PC 2 G1-only playbook; e1f48d63 the fud-ledger entry AP-F8-1 (the fault, Josh's ruling, the amendment, the split protection, the owed tests); d8859522 the G1 line (the eight fingerprints equal on the RTX 5090, self-test PASS) and the node lane's signal byte 5; 4aa0c665 the v4 unit test following the amendment; 965d9e96 igneum-pow taken from release-0.3.20's 3f1652bf (the ladder's chain_program_shadow with the reps argument, never on master) with the amendment re-applied, the seven packs re-exporting byte-identical; 8c728ca3 the source rule keyed on the class with the shadow's pass count set aside, so every ladder rung draws under it (the fork's ladder test). The shipper took this igneum-pow tree into release-0.3.20 (00249643, byte-equal); nothing after 8c728ca3 touches igneum-pow. THE VECTORS AND THE PACKS (read from the branch and its ledger entry, 14:1x UK): the seven amended v4 packs (v4-devnet-epoch0, v4-era-0 to 5) carry generator 4, sub-version 1, one program id 1a4230699a6b9c60 (the 2.0 one-id-per-seed rule across the eras; the old c120d7963abdcd96 pinned as must-differ); the v3 control mx8-devnet-epoch0 untouched (73bcbfe8ccf988f1, fingerprint 90f794dd556f7a3b); the seven 2^24 fingerprints, Metal equal to Apple OpenCL: 867dbc45cfb36b4d, 2146ecacc8c75a8e, fe52602393f6d3d4, 3b206471a13912b4, c3f03c4a5d7333aa, f1dfd7209f15bb97, 8c194da64fadf31d; the zip of the eight packs sha256 889ec99976d2728b4b5035bfa476032e5b6a13b928968fc45236d5f25084aa39; the per-pack vectors.json sha256 prefixes 756301bf (devnet epoch 0), 1b5f4568, d430cadc, 1a1b21d8, 460fff9e, 4a85d49d, f83a1196 (eras 0 to 5). G1 on the RTX 5090 (PC 2 job run-ca3-v4-amend-g1-pc2-20261007, 09:41:07 to 09:41:28Z, exit 0, the installed worker): every fingerprint equal to the Mac's (the seven above and the control), NVRTC 188 to 332 ms per pack, the 1 GiB build 38 to 49 ms. hash-gates.md's older table still lists the pre-amendment fingerprints (f410c731... and the eras), which no longer apply to the amended packs; the ledger entry is the record. THE FIRST GREEN (11:31 UK, the box): the kaspa-pow suite on release-0.3.20-node (dc141409 plus the proof archive aea0ca5c plus the object-5 change) against the hash lane's igneum-pow 8c728ca3: 17 passed, 0 failed; the amended devnet epoch-0 id 1a4230699a6b9c60 pinned equal and c120d7963abdcd96 differing, the ladder's rung test green under the rekeyed rule, the v3 control unchanged; the consensus-core and exec RPC suites follow, then the node line (commit, push, box build, the tip to the shipper), then the digest and mixed-version gates. CLOCK RE-CUT (the node lane, 13:0x UK): the node line now carries, beside the object-5 change and the vector test, the lane's 0.3.20 fixes from the day (isSynced from the hook's stamp, the lazy template snapshot, the weight-table cache, the submit path returning after the block task, the watchdog, the RPC fields), about 13:30 UK if the box suites are green; the shipper's fresh-join canary 60 to 100 minutes after the cut; PC 1 as its first machine about 16:00 UK at the earliest, approximate until the shipper names the cut; the earliest flip about 6 days 10 hours after the publish. BUILD-2 LINES (12:28 to 12:33 UK): consensus-core 123 passed (the 60x file test green with the ladder window and activation pinned), the behind test green, kaspa-pow 17 passed (the amended vectors, earlier on build-1), the exec RPC suite green, the flows and rpc-service checks green with the submit-path change; the 24-requester latency test's first run tripped an unrelated flapping-fork double insert (24 equal forks from one parent; the test now builds on the sink as a real miner does; the double insert owed to a small fork harness before it is called a bug); THE NODE LINE COMMITTED (13:1x UK): release-0.3.20-node = 8097d600 (dc141409 + the proof archive aea0ca5c + one commit) on the mirror, pairing igneum-pow 8c728ca3, the hash with the shipper; in it the amended class v4 as object 5 (CLASS_SIGNAL_V4 = 5, byte 4 never counts, the kaspa-pow vector test pinning 1a4230699a6b9c60 equal and c120d7963abdcd96 differing, the daemon's window line naming object 5 and sub-version 1) beside the day's fixes (isSynced from the hook's stamp, the weight-table cache, the lazy snapshot, the submit path, the 100 ms template wait); the suites green on build-2 (consensus-core 123, the exec RPC suite, the four finality tests including 24 requesters under 200 ms: the worst template 100 ms, the worst submit 102 ms) and kaspa-pow 17 on build-1. Next: igneumd and igneum-miner building from 8097d600 on build-1, then the two gate lines (the mixed-version Devnet 2 gate: the 8097d600 node mining beside the 5899f603 pair for ten minutes on the live file without the v4 fields, the old node accepting every block; the digest test: the thirteen-field file b18ed271 unchanged, the sixteen-field object re-read on the 8097d600 binary), expected about 13:30 UK; the shipper picks the cut point. THE DATE FIXED (the node lane, from the hub's live file, 13:3x UK): publish 2 of 6 October (22:49:45Z, digest eada4bda) already put BOTH v4 fields on the live devnet (floor 831,600, window 86,400), so the 0.3.17 fleet has stamped object byte 4 since 7 October 00:2x UK and the floor is live at about 13 October 09:00 UK, before any seven-window signal completes; a 0.3.17 node left on that file flips to the OLD v4 stream at epoch 231 whatever anyone signals, a 0.3.20 node to the amended stream at the same epoch, and the two never share an id, so each straggler forks alone there. REQUIREMENT for the 0.3.20 publish (with the shipper and main): a new file with the floor at the publish DAA + 604,800 rounded up (about 882,000 for a publish today), the digest moving, the one-sweep rollout replacing every 0.3.17 node before 13 October 09:00 UK; any node that misses the sweep is alone then; the earliest flip after that about 6 days 10 hours past the publish; plan section 6.6 amended today. IN THE 0.3.20 PLAN (the shipper, 13:4x UK): both requirements; the node pin by main's rule is the node lane's second commit (the claim floor, the listener watchdog, the claim RPCs, on top of 8097d600) if its suites, both gates and the fleet's 12 GB prover line are green by 15:30 UK, else 8097d600; igneum-pow 8c728ca3 either way; the digest read on whichever binary pins. THE LINE AT 13:5x UK: three commits on release-0.3.20-node, 8097d600 (the object-5 amended class v4 and the day's fixes), 6b94c823 (test-only: the stale PC 1 test from 500ddd66 inverted by the isSynced ruling; the FALLBACK pin, code byte-identical to 8097d600, so the module reads green whole) and 6a3432a3 (the app lane's key methods, the observer's claims, the settled claim floor, the listener watchdog); suites on build-2 on 6a3432a3's code (the whole finality module 25, the exec suite 29 with the watchdog test, the kaspad, flows and rpc-service checks; consensus-core 123 and kaspa-pow 17 earlier); the cut 6a3432a3 if its gates and the fleet's 12 GB settled-claim line are green by 15:30 UK, else 6b94c823; both binaries building on build-1, the two gates (the digest gate, then the ten-minute mixed-version gate beside the 5899f603 pair) on the 8097d600 build, lines about 14:05 UK. GATE NEWS (13:53 UK): on 6a3432a3's own digest gate the listener watchdog counted a bind failure (the four harness nodes share one exec JSON-RPC port) as a listener death and exited three of four nodes at 20 s, where 0.3.17 and 8097d600 only warn and live without the exec RPC; the digest facts came out first and stand (the thirteen-field file a89be8a7 on both binaries, the compat case; the sixteen-field object db9a85f9 refused with the mismatch line, the refusal case); the ten-minute gate on 6a3432a3 stopped as void for the same cause. The fix: a bind failure is a retry every poll, one line a minute, no death counted and never an exit, with a second watchdog test whose known-failed shape is the old rule's exit on a held port; the third commit and its build about 14:15 UK, its gates about 14:35 UK; the fallback 6b94c823's gates on build-1 on their own binary (no watchdog there), lines about 14:20 UK; ledger row N12 for the bind-failure class. A ROLL BLOCKER on every kept datadir (the node lane, 14:1x UK, ledger N13): the fleet started 6a3432a3 on a kept 0.3.17 datadir (pool-1's copy) and it died at start (virtual_state.rs:250, DeserializationError(UnexpectedEof)); the cause 10db4b61 on the 0.3.16 feature line added `silent: bool` to BlockRewardData under serde(default), which bincode ignores, so every build from 10db4b61 on (dc141409, 8097d600, 6b94c823, 6a3432a3, 09124180) reads a 0.3.17 node's virtual-state row short; no canary saw it because every canary wiped, and a one-box roll keeps datadirs, so it blocks the roll on every standing box, the hands and the hub whatever the pin. The fix on the line: the store reads the current layout first and on a deserialization error decodes the row as a v1 mirror, converts with silent false and rewrites it under the same key, with the known-failed test first; the fourth commit and build about 14:40 UK, the fleet's kept-datadir start on the fixed binary about 14:50 UK, its gates after. THE RULE IT ADDS for every node cut from now: a kept-datadir restart gate on a standing box's datadir copy beside the wiped canary. THE CANDIDATE PIN (14:2x UK): b7cc37e7 (8097d600, 6b94c823, 6a3432a3, 09124180, b7cc37e7; igneum-pow 8c728ca3): the N13 fix with its test green on build-2 at 14:04 UK and the kaspad check green, the build on build-1; the fallback 6b94c823 is no longer a pin for the one-box roll (it dies on a kept datadir like every build since 10db4b61): if b7cc37e7's gates are not green by 15:30 UK the honest fallback is 0.3.17's 5899f603 staying live. In flight on build-1: the earlier commits' gates, then b7cc37e7's own digest and ten-minute mixed-version gates on its binary with the read-back, lines about 15:05 UK; on the fleet the kept-datadir start on b7cc37e7 about 14:50 UK and the 12 GB settled-claim line 14:50 to 15:00 UK. Plan section 6.6 amended with the hard date (ca3-v4-node 9d763edd, merged to master); N12 and N13 on the ledger. THE GATES ON THE FALLBACK'S OWN BINARY (6b94c823, sha b1b7d47b, 13:56 to 14:08 UK; code byte-identical to 8097d600, so the amendment's node side): the digest gate, the thirteen-field file a89be8a7 on both binaries (the compat case, n0 peering n1 and n2) and the sixteen-field object db9a85f9 refused with the mismatch line (the refusal case); the mixed-version gate, ten minutes, one digest b0afb2ee on all five nodes, the 5899f603 hub accepting every block the amended node mined (146 new, 246 old, 0 rejected), plain header version 2 on the thirteen-field file, counts equal on all five through the two clean joins and the restart. Two FAILED checks, both the harness's own and fixed (36d3efdc): a refused peer's count read 1 with the reconnect in flight (now the minimum of five), and six address-in-use panics in the two old nodes because the second gate reused the first's ports the second they were sent SIGTERM (a 20 s gap now). CLOCK CORRECTION (the node lane, 12:12Z = 13:12 BST): every "UK" stamp it sent today was the box's CEST, an hour fast of BST; its lines read UTC from now. Restated: b7cc37e7's build about 12:15Z, its digest and mixed-version gates on that binary with the sha and string about 12:32Z (13:32 BST), the fleet's kept-datadir start on it about 12:25Z, its 12 GB settled-claim line 12:50 to 13:00Z; the shipper's checkpoint 14:30Z (15:30 BST), two hours of room. The 13 October date stands (derived from UTC DAA rates): the floor 831,600 about 08:00Z, 09:00 BST. b7cc37e7'S OWN LINES (binary sha256 bc28331abf21f4d5, the string read back on build-1 and on the fleet's pod): the digest gate 12:14:39Z to 12:16:18Z SUMMARY PASS (thirteen fields a89be8a7 on both binaries with the peers as the gate wants them; the sixteen-field object db9a85f9 refused with the line and no peer; the live file's digest eada4bda on the binary, unmoved); the kept-datadir start on the fleet's copy of pool-1's 0.3.17 datadir: the first start 12:17:12Z reads the v1 row through the mirror and rewrites it ("1 mergeset rewards"), the finality blob converts (1,747 locks), the node comes up on its ports with no panic; the second start 12:18:53Z reads first-try with no rewrite line and no panic; 6a3432a3's death on the same copy is the known-failed shape. The ten-minute mixed-version gate beside the 5899f603 pair runs on the same binary since 12:16:39Z, its line about 12:28Z; then the only line outstanding for the shipper's 14:30Z rule is the fleet's 12 GB settled-claim line, 12:50 to 13:00Z. AP-F8-1 RESIDUAL CLASS ON THE AMENDED STREAM (attack-pass lane 12:18Z on igneum-pow 8c728ca3, sub-version 1). F9 over 1,000,000 seeds: programs flagged (hot share at least 1 percent or 7 constant address bits) 1,871 (0.19 percent) against 11,696 (1.17 percent) unamended; worst hot share 9.66 percent against 17.3; mean 0.011 against 0.063 percent; 84 percent of the flagged programs and the whole or-saturation tail gone. F8 at 30 of 64 seeds: nine over 1.2x of the window model (p31 29.3x, p11 5.5x, p19 3.3x, p6 3.1x, p23 2.0x, the rest 1.3x to 1.6x); the 64-seed 1.2x gate is heading to FAIL on sub-version 1. Mechanism, confirmed on the two worst seeds: an all-ones load source (image 0x0ca59e4c under the era map) delivered through a writer the source rule counts as entropy-keeping, a rotate (rotl and rotr map all-ones to itself) or a load whose own source was saturated, with the saturation made one or more writes upstream by or. The rule looks one writer back; it must look through saturation-preserving writers or test the source's values. The ceiling has not moved: rule (c)'s 120-of-128 floor still caps any program at one saturated site, 6.25 percent of reads, a chip edge of at most 1.067x, and the residual (worst seed two sites at 0.53 and 0.56) sits inside it. THE SENTENCE "no lossy-sourced load by construction" IS HELD: it goes in no plan row and no ledger entry as true; sub-version 1 removes the or-source class and bounds the rest. MAIN'S RULING (13:2x UK): 0.3.20 ships object byte 5 on sub-version 1 as it stands, strictly better than the old stream the live floor flips to on 13 October; the fix is sub-version 2 on ca3-v4-amend (object byte 6 or whatever the v5 alignment leaves free) with both fixes: (F1) the static rule made transitive (rotates do not keep entropy; a load keeps entropy only if its own source did; one draw change, no attempts lost) and (F2) the dynamic source check (saturated load SOURCE values counted per site over the 64 units' 16,384 evaluations, rejected above 163 of 16,384, the same 1 percent the final-value rule uses; costs attempts on about 0.2 percent of seeds; rides with F1 because an or-written source is all-ones only (3/4)^32 of the time). Gate before sub-version 2 is proposed, run by the attack-pass lane and not by the hash lane: the full 64-seed census under 1.2x on every seed and the hot-set census. Hash lane's estimate about an hour its side (implement, re-export seven packs, vectors, crate suite, pairing, one G1 on PC 2) plus the node lane's vector re-pin and the attack-pass re-gate. The flip floor for sub-version 1 is expected to move (Josh's word) so the chain never flips to a stream that fails this gate. Also recorded: the crate suite at 8c728ca3 100 of 100 on the box (rc 0, 77 s); the pairing against the fork at dc141409 compiled and ran 15 of 16, the one failure the fork's own pre-amendment assertion (base equals v3's, igneum.rs:972), which 8097d600 on the release-0.3.20-node line turns into assert_ne; the pairing re-runs at b7cc37e7, its line to follow. CORRECTION (the attack-pass lane's own retraction, 13:3x UK): the F9 hot-set figures above (1,871 of 1,000,000, worst 9.66 percent, 84 percent removed, the two or-then-rotate listings) are WITHDRAWN: F9's harness draws through candidate_class with its own era class, outside candidate_from_words_class where the source rule lives, so it measured the old stream (the 8c728ca3 binary prints the identical program to the sub-version-0 binary for its worst seed). F8's 64-seed census on the chain path (pairing verified on 1a4230699a6b9c60) is the valid re-gate and STANDS: at 30 of 64 seeds, nine over 1.2x of the window model (p31 29.3x, p11 5.5x, p19 3.3x, p6 3.1x, p23 2.0x, p4 1.6x, p10 1.5x, p26 1.3x, p25 1.3x). The residual mechanism on the amended stream: a load-after-load chain (a saturated source reads one fixed word, which is the next load's address), admitted because a load injects; and the rotate-preserves-saturation path (generator.rs sets entropy_kept true for a rotate whatever it rotated), correct in code and a second admitted path if it occurs on the chain stream. Sub-version 2 must close both: dataflow freshness per register (a load fresh only if its source was fresh; add, sub, xor, mad, shfl fresh if either operand was; rotates only if the operand was; or, mul, mulhi never) plus the (c') count of saturated load sources per site as the backstop. The STOP holds on F8's evidence alone; the options and the 1.067x ceiling are unchanged. The sentence "no lossy-sourced load by construction" waits on the sub-version 2 census verdict and stays out of every public text until then. SUB-VERSION 2 IN BUILD (the hash lane, ca3-v4-amend, on the coordinator's direction, 13:4x UK): F1 (dataflow freshness per register, keyed on the class v4 shape on every draw path, era or not, so the candidate_class path and the chain path draw one stream) plus F2 (the (c') count of saturated load source values per site over the 64 units' 16,384 evaluations, rejected above 163, keyed on the same shape so v2 and v3 verdicts do not move); PROGRAM_SUBVERSION_V4 = 2, new ids, the seven packs re-exported, recheck.rs with 1a4230699a6b9c60 and c120d7963abdcd96 as the must-differ pair. Clock (UTC): the commit on the branch by 13:30; the crate suite on box 2 and the pairing against b7cc37e7 by about 13:50 (the pairing's vector test fails on the fork's sub-version-1 pin until the node lane re-pins; the compile and the other 15 are the pairing evidence); the G1 job on PC 2 under --cards-off by about 14:10, lock permitting; then the attack-pass lane's full 64-seed census and hot-set census on the chain path. Two consequences stated in the commit: the rule on every draw path moves the no-era sh256xN ladder packs' stream (packs-ca3-shadow's seven 256-block packs re-export with new fingerprints; the measured rates stand as the old stream's), and the class v5 lane's pinned string-seed packs move when it merges sub-version 2, so it re-exports them then. 0.3.20's sub-version-1 packs, ids and fingerprints untouched. OBJECT BYTES SETTLED (main, 13:5x UK): byte 5 = class v4 sub-version 1 (0.3.20), byte 6 = class v5 (pinned: class-v5 16afd0a0, class-v5-node 699db5a2, the flip case passed on 6,6,6; the v5 lane stopped), byte 7 = class v4 sub-version 2; the node and hash lanes told. b7cc37e7's MIXED-VERSION GATE: FAIL, the binary not the harness (12:16:39Z to 12:27:21Z, sha256 bc28331abf21f4d5, the string read back). Before the restart step everything held: one digest b0afb2ee on all five nodes, 268 new and 392 old blocks accepted, 0 rejected, header versions plain 2, counts equal on all five at 324 and 502 through both clean joins. At the new node's restart (12:24:19Z) it died at once on its own datadir ("IO error: While lock file: .../datadir/meta/LOCK: Resource temporarily unavailable", conn_builder.rs:167): the previous process was still shutting down, because the listener watchdog added on 6a3432a3 sleeps its whole 10 s poll before checking shutdown, so every node on the line since then takes up to 10 s longer to stop than 0.3.17 (the fleet saw the same shape as "a 12-second timeout does not stop the node"). Three of the four failed checks follow from that one death (counts, the restarted node's resync, the node it served frozen at 502). The fix on the line, one rule: the poll in 250 ms steps returning the moment shutdown is set, with a test that a shutdown returns within a second (the 10 s loop the known-failed shape); the exec suite on build-2, the fifth commit and its build about 12:45Z, its digest and ten-minute gates about 12:50 to 13:05Z, inside 14:30Z. b7cc37e7 is NOT the pin. The node-side re-pin for sub-version 2 (byte 7) once the hash lane's commit lands: the beside-the-fork igneum-pow copy archived from the commit, the two pinned ids moved in the kaspa-pow vector test (sub-version-2's epoch-0 id must-equal; sub-version-1's joins c120d7963abdcd96 as must-differ), CLASS_SIGNAL and tests for byte 7, the daemon's window line: about 20 minutes of edits plus one kaspa-pow suite run on build-2 (about 2 minutes). THE FIFTH COMMIT c4459193 on release-0.3.20-node (b7cc37e7's child, the watchdog poll returning on shutdown; the diff is the poll loop in rpc.rs alone), pairing igneum-pow 8c728ca3; its build on build-1 started 12:30:13Z, sha256 and string to follow. Line A, the shutdown test: rpc::watchdog_tests::a_shutdown_returns_within_a_second_whatever_the_poll green on build-2 at 12:29Z in the exec suite's 31 passed, beside the two other watchdog tests; its known-failed shape the old loop's 10 s stop. Line B, the kept-datadir start: b7cc37e7's fleet read carries to c4459193 since the store code is byte-identical between the two commits; the fleet re-reads on the c4459193 binary only if the shipper's rule wants the string on that line too. The digest gate and the ten-minute mixed-version gate on c4459193's own binary follow its build. THE SHIPPER'S CARRY RULING (14:1x UK): b7cc37e7's kept-datadir read stands as evidence that the store fix is right (the store code byte-identical) but is not the gate line for the pin, because the rule reads the binary, not the diff, and the binary changed (rpc.rs); the gate line is the kept read on c4459193's own binary with its string, which the fleet's canary already runs on c18-1 (wipe, then the kept read, then the restart) before the canary's restart step, at no extra cost; no re-read on p12-vast. THE PIN IS c4459193 pairing 8c728ca3 (object byte 5, sub-version 1); sub-version 2 (byte 7) is 0.3.21's, not 0.3.20's. The shipper's reading of main's F8 ruling: 0.3.20 ships object 5 as it stands because the live floor otherwise flips every node to the OLD stream on 13 October, and the 16:00 BST report tells Josh the floor move is now RECOMMENDED rather than optional, so the chain never flips to a stream that fails the 1.2x gate before sub-version 2 lands. THE FLEET'S CLOCK ON c4459193 (the fleet lane, 12:5x UTC): the kept read on pool-1's 0.3.17 datadir copy and the restart (the old process's stop time on the line) run on c18-1 before the wipe, a few minutes each, so both lines land before 14:30Z; the wipe canary (IBD from the pruning-point proof, 98 minutes on this pod class) starts when c18-1 is free of the 0.3.20 cases (about 13:00Z) and the binary is in hand, so its synced line lands about 14:40Z at the earliest, PAST the 14:30Z checkpoint; the 12 GB settled-claim line: c4459193 starts on p12-vast's kept copy of pool-1's datadir beside the 6a3432a3 IBD node on alternate ports the moment the binary lands, catches up from 129,398 blocks (15 to 20 minutes) and the 12 GB prover claims against it, the line on c4459193 itself. The binary not yet in the fleet's hand (build-1 building since 12:30:13Z); a wait armed on the sha and string, a report by 13:10Z if nothing. THE INTEROP FACT stands from the void run: the 5899f603 hub accepted 235 object-byte-5 blocks from the 8097d600 node with 0 rejected, one digest on all five nodes on the live sixteen-field file. The gates: the digest test and the kaspa-pow vector test (the amended devnet epoch-0 id 1a4230699a6b9c60 must equal, c120d7963abdcd96 must differ, the v3 control unchanged) on the box; the mixed-version Devnet 2 gate (the amended 0.3.20 node beside a 5899f603 node for ten minutes on the live file without the v4 fields) after the Mac build; the fresh-join canary the 0.3.20 cut's | +| JOSH'S WORD (15:2x UK, 7 October): OPTION A, "do this but limit the testing, get it pushed" | the class v4 amendment: a load's source drawn only from registers whose last writer injects or is a rotate (the v5 rule applied now), a new program stream and vectors, the seven gate packs re-exported, the amended class with its own generator stamp; rides 0.3.20, the feature node (release-0.3.20-node = dc141409; 0.3.19 is an app-only cut with nothing of ours), on the shipper's line. The rollout arithmetic for the flip clock (the shipper): the standing fleet's one-box-at-a-time rollout took 32 minutes for 14 boxes (04:56 to 05:28Z, 7 October), the hands and the seed about 3 minutes after the miners, the Mac and the PCs within minutes of the publish; every 0.3.20 worker must accept the amended stamp before any flip. Owners: the hash lane (ca3-v4-amend: the generator, the vectors, the packs, the pairing on the box, one G1 run on PC 2, the ledger row), the node lane (release-0.3.20-node: the stamp agreed with the hash lane, the split-protection mechanism and the earliest flip time, the digest test, the mixed-version Devnet 2 gate), the attack-pass lane (the F8 census at 2^24 on the new stream, the gate 1.2x of the window model over 64 seeds), the shipper (the cut, the rollout order that sets the earliest flip). Testing limited to what prevents a split and proves the fix; G2, G3, the ladder re-measure and the rest of G4 to G6 OWED. THE STAMP agreed (the node and hash lanes, 7 October afternoon): generator 4 with sub-version 1 inside igneum-pow's id function, so the amended v4's program id for a seed differs from the old v4's (the old devnet epoch-0 id c120d7963abdcd96 pinned as the must-differ vector in kaspa-pow's test). SPLIT PROTECTION SETTLED (the node lane, plan section 6.6, ca3-v4-node fa5bc9e6; the node side on release-0.3.20-node): a fresh object byte. CLASS_SIGNAL_V4 is 5; the amended binary stamps 5 and the tally counts a block only at byte 5 or above; object 4 was stamped only by the unpublished dc141409 canary, so no published block carries it and a byte-4 block never counts; a node of the 6 October stream that sees byte 5 counts it as v4 (its rule is at least 4), flips to its own stream at the same epoch and forks ALONE (its blocks fail the amended id check, generator 4 sub-version 1 inside every id; the amended blocks fail its own), ours to upgrade in the sweep; object 6 is class v5's; the two holds already in the rule keep the window shut until every node is on 0.3.20 (a node stamps and tallies only with both v4 fields in its file; the fields publish only after the one-sweep rollout); a lagging worker refuses the amended pack at packcheck and mines nothing after the flip, costing that box, never the chain; no extra window hold: seven full day-windows are the hold. THE EARLIEST FLIP (approximate, measured 09:40Z: DAA 270,659, 1.095 DAA/s over 25 hours, 1.165 over 4; epoch 3,600, lead 600; seven windows 604,800 DAA wholly after the sweep's end D_s = T + about 40 minutes; the flip epoch the first e with 3600 e - 600 >= D_s + 604,800): T + 6 days 10 hours to T + 6 days 11 hours UK; for a publish at 12:00 UK on 7 October, 13 October between 22:20 and 23:10 UK (about 13:00 UK if the 4-hour rate holds). The floor as it stands (831,600, about 13 October 09:00 UK) would fire before any seven-window signal from a publish today completes, so it moves by the 0.3.16 rule to the publish DAA + 604,800 rounded up to the epoch boundary (882,000 for a 12:00 UK publish), firing about 30 minutes before the earliest signal flip: either way about 6 days 10 hours after the publish, never before every node has had the sweep plus a week. THE CLOCK (the node lane, 11:3x UK, after a Mac reboot moved its runs to the box): the 0.3.20 node line (dc141409 plus the proof archive aea0ca5c plus the amended v4 at object byte 5, igneum-pow at the hash lane's a0aaca92 beside the fork on the box) tested on the box, committed on release-0.3.20-node, pushed to the mirror and origin, igneumd and igneum-miner built, the tip to the shipper: about 12:00 UK; the mixed-version Devnet 2 gate (node-compat.mjs on the box, the amended node beside the 5899f603 pair for ten minutes) and the digest test (digest-compat.mjs): about 12:45 UK; the object-byte pin 5 unless the v5 lane answers both lanes with another assignment (v5 at 6 proposed). THE HASH SIDE on ca3-v4-amend (tip 8c728ca3, read from the branch 14:0x UK; the hash lane's own report pending): 1748fd1d the PC 2 G1-only playbook; e1f48d63 the fud-ledger entry AP-F8-1 (the fault, Josh's ruling, the amendment, the split protection, the owed tests); d8859522 the G1 line (the eight fingerprints equal on the RTX 5090, self-test PASS) and the node lane's signal byte 5; 4aa0c665 the v4 unit test following the amendment; 965d9e96 igneum-pow taken from release-0.3.20's 3f1652bf (the ladder's chain_program_shadow with the reps argument, never on master) with the amendment re-applied, the seven packs re-exporting byte-identical; 8c728ca3 the source rule keyed on the class with the shadow's pass count set aside, so every ladder rung draws under it (the fork's ladder test). The shipper took this igneum-pow tree into release-0.3.20 (00249643, byte-equal); nothing after 8c728ca3 touches igneum-pow. THE VECTORS AND THE PACKS (read from the branch and its ledger entry, 14:1x UK): the seven amended v4 packs (v4-devnet-epoch0, v4-era-0 to 5) carry generator 4, sub-version 1, one program id 1a4230699a6b9c60 (the 2.0 one-id-per-seed rule across the eras; the old c120d7963abdcd96 pinned as must-differ); the v3 control mx8-devnet-epoch0 untouched (73bcbfe8ccf988f1, fingerprint 90f794dd556f7a3b); the seven 2^24 fingerprints, Metal equal to Apple OpenCL: 867dbc45cfb36b4d, 2146ecacc8c75a8e, fe52602393f6d3d4, 3b206471a13912b4, c3f03c4a5d7333aa, f1dfd7209f15bb97, 8c194da64fadf31d; the zip of the eight packs sha256 889ec99976d2728b4b5035bfa476032e5b6a13b928968fc45236d5f25084aa39; the per-pack vectors.json sha256 prefixes 756301bf (devnet epoch 0), 1b5f4568, d430cadc, 1a1b21d8, 460fff9e, 4a85d49d, f83a1196 (eras 0 to 5). G1 on the RTX 5090 (PC 2 job run-ca3-v4-amend-g1-pc2-20261007, 09:41:07 to 09:41:28Z, exit 0, the installed worker): every fingerprint equal to the Mac's (the seven above and the control), NVRTC 188 to 332 ms per pack, the 1 GiB build 38 to 49 ms. hash-gates.md's older table still lists the pre-amendment fingerprints (f410c731... and the eras), which no longer apply to the amended packs; the ledger entry is the record. THE FIRST GREEN (11:31 UK, the box): the kaspa-pow suite on release-0.3.20-node (dc141409 plus the proof archive aea0ca5c plus the object-5 change) against the hash lane's igneum-pow 8c728ca3: 17 passed, 0 failed; the amended devnet epoch-0 id 1a4230699a6b9c60 pinned equal and c120d7963abdcd96 differing, the ladder's rung test green under the rekeyed rule, the v3 control unchanged; the consensus-core and exec RPC suites follow, then the node line (commit, push, box build, the tip to the shipper), then the digest and mixed-version gates. CLOCK RE-CUT (the node lane, 13:0x UK): the node line now carries, beside the object-5 change and the vector test, the lane's 0.3.20 fixes from the day (isSynced from the hook's stamp, the lazy template snapshot, the weight-table cache, the submit path returning after the block task, the watchdog, the RPC fields), about 13:30 UK if the box suites are green; the shipper's fresh-join canary 60 to 100 minutes after the cut; PC 1 as its first machine about 16:00 UK at the earliest, approximate until the shipper names the cut; the earliest flip about 6 days 10 hours after the publish. BUILD-2 LINES (12:28 to 12:33 UK): consensus-core 123 passed (the 60x file test green with the ladder window and activation pinned), the behind test green, kaspa-pow 17 passed (the amended vectors, earlier on build-1), the exec RPC suite green, the flows and rpc-service checks green with the submit-path change; the 24-requester latency test's first run tripped an unrelated flapping-fork double insert (24 equal forks from one parent; the test now builds on the sink as a real miner does; the double insert owed to a small fork harness before it is called a bug); THE NODE LINE COMMITTED (13:1x UK): release-0.3.20-node = 8097d600 (dc141409 + the proof archive aea0ca5c + one commit) on the mirror, pairing igneum-pow 8c728ca3, the hash with the shipper; in it the amended class v4 as object 5 (CLASS_SIGNAL_V4 = 5, byte 4 never counts, the kaspa-pow vector test pinning 1a4230699a6b9c60 equal and c120d7963abdcd96 differing, the daemon's window line naming object 5 and sub-version 1) beside the day's fixes (isSynced from the hook's stamp, the weight-table cache, the lazy snapshot, the submit path, the 100 ms template wait); the suites green on build-2 (consensus-core 123, the exec RPC suite, the four finality tests including 24 requesters under 200 ms: the worst template 100 ms, the worst submit 102 ms) and kaspa-pow 17 on build-1. Next: igneumd and igneum-miner building from 8097d600 on build-1, then the two gate lines (the mixed-version Devnet 2 gate: the 8097d600 node mining beside the 5899f603 pair for ten minutes on the live file without the v4 fields, the old node accepting every block; the digest test: the thirteen-field file b18ed271 unchanged, the sixteen-field object re-read on the 8097d600 binary), expected about 13:30 UK; the shipper picks the cut point. THE DATE FIXED (the node lane, from the hub's live file, 13:3x UK): publish 2 of 6 October (22:49:45Z, digest eada4bda) already put BOTH v4 fields on the live devnet (floor 831,600, window 86,400), so the 0.3.17 fleet has stamped object byte 4 since 7 October 00:2x UK and the floor is live at about 13 October 09:00 UK, before any seven-window signal completes; a 0.3.17 node left on that file flips to the OLD v4 stream at epoch 231 whatever anyone signals, a 0.3.20 node to the amended stream at the same epoch, and the two never share an id, so each straggler forks alone there. REQUIREMENT for the 0.3.20 publish (with the shipper and main): a new file with the floor at the publish DAA + 604,800 rounded up (about 882,000 for a publish today), the digest moving, the one-sweep rollout replacing every 0.3.17 node before 13 October 09:00 UK; any node that misses the sweep is alone then; the earliest flip after that about 6 days 10 hours past the publish; plan section 6.6 amended today. IN THE 0.3.20 PLAN (the shipper, 13:4x UK): both requirements; the node pin by main's rule is the node lane's second commit (the claim floor, the listener watchdog, the claim RPCs, on top of 8097d600) if its suites, both gates and the fleet's 12 GB prover line are green by 15:30 UK, else 8097d600; igneum-pow 8c728ca3 either way; the digest read on whichever binary pins. THE LINE AT 13:5x UK: three commits on release-0.3.20-node, 8097d600 (the object-5 amended class v4 and the day's fixes), 6b94c823 (test-only: the stale PC 1 test from 500ddd66 inverted by the isSynced ruling; the FALLBACK pin, code byte-identical to 8097d600, so the module reads green whole) and 6a3432a3 (the app lane's key methods, the observer's claims, the settled claim floor, the listener watchdog); suites on build-2 on 6a3432a3's code (the whole finality module 25, the exec suite 29 with the watchdog test, the kaspad, flows and rpc-service checks; consensus-core 123 and kaspa-pow 17 earlier); the cut 6a3432a3 if its gates and the fleet's 12 GB settled-claim line are green by 15:30 UK, else 6b94c823; both binaries building on build-1, the two gates (the digest gate, then the ten-minute mixed-version gate beside the 5899f603 pair) on the 8097d600 build, lines about 14:05 UK. GATE NEWS (13:53 UK): on 6a3432a3's own digest gate the listener watchdog counted a bind failure (the four harness nodes share one exec JSON-RPC port) as a listener death and exited three of four nodes at 20 s, where 0.3.17 and 8097d600 only warn and live without the exec RPC; the digest facts came out first and stand (the thirteen-field file a89be8a7 on both binaries, the compat case; the sixteen-field object db9a85f9 refused with the mismatch line, the refusal case); the ten-minute gate on 6a3432a3 stopped as void for the same cause. The fix: a bind failure is a retry every poll, one line a minute, no death counted and never an exit, with a second watchdog test whose known-failed shape is the old rule's exit on a held port; the third commit and its build about 14:15 UK, its gates about 14:35 UK; the fallback 6b94c823's gates on build-1 on their own binary (no watchdog there), lines about 14:20 UK; ledger row N12 for the bind-failure class. A ROLL BLOCKER on every kept datadir (the node lane, 14:1x UK, ledger N13): the fleet started 6a3432a3 on a kept 0.3.17 datadir (pool-1's copy) and it died at start (virtual_state.rs:250, DeserializationError(UnexpectedEof)); the cause 10db4b61 on the 0.3.16 feature line added `silent: bool` to BlockRewardData under serde(default), which bincode ignores, so every build from 10db4b61 on (dc141409, 8097d600, 6b94c823, 6a3432a3, 09124180) reads a 0.3.17 node's virtual-state row short; no canary saw it because every canary wiped, and a one-box roll keeps datadirs, so it blocks the roll on every standing box, the hands and the hub whatever the pin. The fix on the line: the store reads the current layout first and on a deserialization error decodes the row as a v1 mirror, converts with silent false and rewrites it under the same key, with the known-failed test first; the fourth commit and build about 14:40 UK, the fleet's kept-datadir start on the fixed binary about 14:50 UK, its gates after. THE RULE IT ADDS for every node cut from now: a kept-datadir restart gate on a standing box's datadir copy beside the wiped canary. THE CANDIDATE PIN (14:2x UK): b7cc37e7 (8097d600, 6b94c823, 6a3432a3, 09124180, b7cc37e7; igneum-pow 8c728ca3): the N13 fix with its test green on build-2 at 14:04 UK and the kaspad check green, the build on build-1; the fallback 6b94c823 is no longer a pin for the one-box roll (it dies on a kept datadir like every build since 10db4b61): if b7cc37e7's gates are not green by 15:30 UK the honest fallback is 0.3.17's 5899f603 staying live. In flight on build-1: the earlier commits' gates, then b7cc37e7's own digest and ten-minute mixed-version gates on its binary with the read-back, lines about 15:05 UK; on the fleet the kept-datadir start on b7cc37e7 about 14:50 UK and the 12 GB settled-claim line 14:50 to 15:00 UK. Plan section 6.6 amended with the hard date (ca3-v4-node 9d763edd, merged to master); N12 and N13 on the ledger. THE GATES ON THE FALLBACK'S OWN BINARY (6b94c823, sha b1b7d47b, 13:56 to 14:08 UK; code byte-identical to 8097d600, so the amendment's node side): the digest gate, the thirteen-field file a89be8a7 on both binaries (the compat case, n0 peering n1 and n2) and the sixteen-field object db9a85f9 refused with the mismatch line (the refusal case); the mixed-version gate, ten minutes, one digest b0afb2ee on all five nodes, the 5899f603 hub accepting every block the amended node mined (146 new, 246 old, 0 rejected), plain header version 2 on the thirteen-field file, counts equal on all five through the two clean joins and the restart. Two FAILED checks, both the harness's own and fixed (36d3efdc): a refused peer's count read 1 with the reconnect in flight (now the minimum of five), and six address-in-use panics in the two old nodes because the second gate reused the first's ports the second they were sent SIGTERM (a 20 s gap now). CLOCK CORRECTION (the node lane, 12:12Z = 13:12 BST): every "UK" stamp it sent today was the box's CEST, an hour fast of BST; its lines read UTC from now. Restated: b7cc37e7's build about 12:15Z, its digest and mixed-version gates on that binary with the sha and string about 12:32Z (13:32 BST), the fleet's kept-datadir start on it about 12:25Z, its 12 GB settled-claim line 12:50 to 13:00Z; the shipper's checkpoint 14:30Z (15:30 BST), two hours of room. The 13 October date stands (derived from UTC DAA rates): the floor 831,600 about 08:00Z, 09:00 BST. b7cc37e7'S OWN LINES (binary sha256 bc28331abf21f4d5, the string read back on build-1 and on the fleet's pod): the digest gate 12:14:39Z to 12:16:18Z SUMMARY PASS (thirteen fields a89be8a7 on both binaries with the peers as the gate wants them; the sixteen-field object db9a85f9 refused with the line and no peer; the live file's digest eada4bda on the binary, unmoved); the kept-datadir start on the fleet's copy of pool-1's 0.3.17 datadir: the first start 12:17:12Z reads the v1 row through the mirror and rewrites it ("1 mergeset rewards"), the finality blob converts (1,747 locks), the node comes up on its ports with no panic; the second start 12:18:53Z reads first-try with no rewrite line and no panic; 6a3432a3's death on the same copy is the known-failed shape. The ten-minute mixed-version gate beside the 5899f603 pair runs on the same binary since 12:16:39Z, its line about 12:28Z; then the only line outstanding for the shipper's 14:30Z rule is the fleet's 12 GB settled-claim line, 12:50 to 13:00Z. AP-F8-1 RESIDUAL CLASS ON THE AMENDED STREAM (attack-pass lane 12:18Z on igneum-pow 8c728ca3, sub-version 1). F9 over 1,000,000 seeds: programs flagged (hot share at least 1 percent or 7 constant address bits) 1,871 (0.19 percent) against 11,696 (1.17 percent) unamended; worst hot share 9.66 percent against 17.3; mean 0.011 against 0.063 percent; 84 percent of the flagged programs and the whole or-saturation tail gone. F8 at 30 of 64 seeds: nine over 1.2x of the window model (p31 29.3x, p11 5.5x, p19 3.3x, p6 3.1x, p23 2.0x, the rest 1.3x to 1.6x); the 64-seed 1.2x gate is heading to FAIL on sub-version 1. Mechanism, confirmed on the two worst seeds: an all-ones load source (image 0x0ca59e4c under the era map) delivered through a writer the source rule counts as entropy-keeping, a rotate (rotl and rotr map all-ones to itself) or a load whose own source was saturated, with the saturation made one or more writes upstream by or. The rule looks one writer back; it must look through saturation-preserving writers or test the source's values. The ceiling has not moved: rule (c)'s 120-of-128 floor still caps any program at one saturated site, 6.25 percent of reads, a chip edge of at most 1.067x, and the residual (worst seed two sites at 0.53 and 0.56) sits inside it. THE SENTENCE "no lossy-sourced load by construction" IS HELD: it goes in no plan row and no ledger entry as true; sub-version 1 removes the or-source class and bounds the rest. MAIN'S RULING (13:2x UK): 0.3.20 ships object byte 5 on sub-version 1 as it stands, strictly better than the old stream the live floor flips to on 13 October; the fix is sub-version 2 on ca3-v4-amend (object byte 6 or whatever the v5 alignment leaves free) with both fixes: (F1) the static rule made transitive (rotates do not keep entropy; a load keeps entropy only if its own source did; one draw change, no attempts lost) and (F2) the dynamic source check (saturated load SOURCE values counted per site over the 64 units' 16,384 evaluations, rejected above 163 of 16,384, the same 1 percent the final-value rule uses; costs attempts on about 0.2 percent of seeds; rides with F1 because an or-written source is all-ones only (3/4)^32 of the time). Gate before sub-version 2 is proposed, run by the attack-pass lane and not by the hash lane: the full 64-seed census under 1.2x on every seed and the hot-set census. Hash lane's estimate about an hour its side (implement, re-export seven packs, vectors, crate suite, pairing, one G1 on PC 2) plus the node lane's vector re-pin and the attack-pass re-gate. The flip floor for sub-version 1 is expected to move (Josh's word) so the chain never flips to a stream that fails this gate. Also recorded: the crate suite at 8c728ca3 100 of 100 on the box (rc 0, 77 s); the pairing against the fork at dc141409 compiled and ran 15 of 16, the one failure the fork's own pre-amendment assertion (base equals v3's, igneum.rs:972), which 8097d600 on the release-0.3.20-node line turns into assert_ne; the pairing re-runs at b7cc37e7, its line to follow. CORRECTION (the attack-pass lane's own retraction, 13:3x UK): the F9 hot-set figures above (1,871 of 1,000,000, worst 9.66 percent, 84 percent removed, the two or-then-rotate listings) are WITHDRAWN: F9's harness draws through candidate_class with its own era class, outside candidate_from_words_class where the source rule lives, so it measured the old stream (the 8c728ca3 binary prints the identical program to the sub-version-0 binary for its worst seed). F8's 64-seed census on the chain path (pairing verified on 1a4230699a6b9c60) is the valid re-gate and STANDS: at 30 of 64 seeds, nine over 1.2x of the window model (p31 29.3x, p11 5.5x, p19 3.3x, p6 3.1x, p23 2.0x, p4 1.6x, p10 1.5x, p26 1.3x, p25 1.3x). The residual mechanism on the amended stream: a load-after-load chain (a saturated source reads one fixed word, which is the next load's address), admitted because a load injects; and the rotate-preserves-saturation path (generator.rs sets entropy_kept true for a rotate whatever it rotated), correct in code and a second admitted path if it occurs on the chain stream. Sub-version 2 must close both: dataflow freshness per register (a load fresh only if its source was fresh; add, sub, xor, mad, shfl fresh if either operand was; rotates only if the operand was; or, mul, mulhi never) plus the (c') count of saturated load sources per site as the backstop. The STOP holds on F8's evidence alone; the options and the 1.067x ceiling are unchanged. The sentence "no lossy-sourced load by construction" waits on the sub-version 2 census verdict and stays out of every public text until then. SUB-VERSION 2 IN BUILD (the hash lane, ca3-v4-amend, on the coordinator's direction, 13:4x UK): F1 (dataflow freshness per register, keyed on the class v4 shape on every draw path, era or not, so the candidate_class path and the chain path draw one stream) plus F2 (the (c') count of saturated load source values per site over the 64 units' 16,384 evaluations, rejected above 163, keyed on the same shape so v2 and v3 verdicts do not move); PROGRAM_SUBVERSION_V4 = 2, new ids, the seven packs re-exported, recheck.rs with 1a4230699a6b9c60 and c120d7963abdcd96 as the must-differ pair. Clock (UTC): the commit on the branch by 13:30; the crate suite on box 2 and the pairing against b7cc37e7 by about 13:50 (the pairing's vector test fails on the fork's sub-version-1 pin until the node lane re-pins; the compile and the other 15 are the pairing evidence); the G1 job on PC 2 under --cards-off by about 14:10, lock permitting; then the attack-pass lane's full 64-seed census and hot-set census on the chain path. Two consequences stated in the commit: the rule on every draw path moves the no-era sh256xN ladder packs' stream (packs-ca3-shadow's seven 256-block packs re-export with new fingerprints; the measured rates stand as the old stream's), and the class v5 lane's pinned string-seed packs move when it merges sub-version 2, so it re-exports them then. 0.3.20's sub-version-1 packs, ids and fingerprints untouched. OBJECT BYTES SETTLED (main, 13:5x UK): byte 5 = class v4 sub-version 1 (0.3.20), byte 6 = class v5 (pinned: class-v5 16afd0a0, class-v5-node 699db5a2, the flip case passed on 6,6,6; the v5 lane stopped), byte 7 = class v4 sub-version 2; the node and hash lanes told. b7cc37e7's MIXED-VERSION GATE: FAIL, the binary not the harness (12:16:39Z to 12:27:21Z, sha256 bc28331abf21f4d5, the string read back). Before the restart step everything held: one digest b0afb2ee on all five nodes, 268 new and 392 old blocks accepted, 0 rejected, header versions plain 2, counts equal on all five at 324 and 502 through both clean joins. At the new node's restart (12:24:19Z) it died at once on its own datadir ("IO error: While lock file: .../datadir/meta/LOCK: Resource temporarily unavailable", conn_builder.rs:167): the previous process was still shutting down, because the listener watchdog added on 6a3432a3 sleeps its whole 10 s poll before checking shutdown, so every node on the line since then takes up to 10 s longer to stop than 0.3.17 (the fleet saw the same shape as "a 12-second timeout does not stop the node"). Three of the four failed checks follow from that one death (counts, the restarted node's resync, the node it served frozen at 502). The fix on the line, one rule: the poll in 250 ms steps returning the moment shutdown is set, with a test that a shutdown returns within a second (the 10 s loop the known-failed shape); the exec suite on build-2, the fifth commit and its build about 12:45Z, its digest and ten-minute gates about 12:50 to 13:05Z, inside 14:30Z. b7cc37e7 is NOT the pin. The node-side re-pin for sub-version 2 (byte 7) once the hash lane's commit lands: the beside-the-fork igneum-pow copy archived from the commit, the two pinned ids moved in the kaspa-pow vector test (sub-version-2's epoch-0 id must-equal; sub-version-1's joins c120d7963abdcd96 as must-differ), CLASS_SIGNAL and tests for byte 7, the daemon's window line: about 20 minutes of edits plus one kaspa-pow suite run on build-2 (about 2 minutes). THE FIFTH COMMIT c4459193 on release-0.3.20-node (b7cc37e7's child, the watchdog poll returning on shutdown; the diff is the poll loop in rpc.rs alone), pairing igneum-pow 8c728ca3; its build on build-1 started 12:30:13Z, sha256 and string to follow. Line A, the shutdown test: rpc::watchdog_tests::a_shutdown_returns_within_a_second_whatever_the_poll green on build-2 at 12:29Z in the exec suite's 31 passed, beside the two other watchdog tests; its known-failed shape the old loop's 10 s stop. Line B, the kept-datadir start: b7cc37e7's fleet read carries to c4459193 since the store code is byte-identical between the two commits; the fleet re-reads on the c4459193 binary only if the shipper's rule wants the string on that line too. The digest gate and the ten-minute mixed-version gate on c4459193's own binary follow its build. THE SHIPPER'S CARRY RULING (14:1x UK): b7cc37e7's kept-datadir read stands as evidence that the store fix is right (the store code byte-identical) but is not the gate line for the pin, because the rule reads the binary, not the diff, and the binary changed (rpc.rs); the gate line is the kept read on c4459193's own binary with its string, which the fleet's canary already runs on c18-1 (wipe, then the kept read, then the restart) before the canary's restart step, at no extra cost; no re-read on p12-vast. THE PIN IS c4459193 pairing 8c728ca3 (object byte 5, sub-version 1); sub-version 2 (byte 7) is 0.3.21's, not 0.3.20's. The shipper's reading of main's F8 ruling: 0.3.20 ships object 5 as it stands because the live floor otherwise flips every node to the OLD stream on 13 October, and the 16:00 BST report tells Josh the floor move is now RECOMMENDED rather than optional, so the chain never flips to a stream that fails the 1.2x gate before sub-version 2 lands. THE FLEET'S CLOCK ON c4459193 (the fleet lane, 12:5x UTC): the kept read on pool-1's 0.3.17 datadir copy and the restart (the old process's stop time on the line) run on c18-1 before the wipe, a few minutes each, so both lines land before 14:30Z; the wipe canary (IBD from the pruning-point proof, 98 minutes on this pod class) starts when c18-1 is free of the 0.3.20 cases (about 13:00Z) and the binary is in hand, so its synced line lands about 14:40Z at the earliest, PAST the 14:30Z checkpoint; the 12 GB settled-claim line: c4459193 starts on p12-vast's kept copy of pool-1's datadir beside the 6a3432a3 IBD node on alternate ports the moment the binary lands, catches up from 129,398 blocks (15 to 20 minutes) and the 12 GB prover claims against it, the line on c4459193 itself. The binary not yet in the fleet's hand (build-1 building since 12:30:13Z); a wait armed on the sha and string, a report by 13:10Z if nothing. THE SHIPPER'S CALL ON THE CLOCK (14:2x UK): the wipe canary is the decisive read by the deploy rule; the pin never cuts without it and b7cc37e7's lineage does not stand in (the binary changed). The fleet rents a second one-shot pod of c18-1's class now and starts the wipe canary on c4459193's binary the moment the build lands, synced line about 14:15Z (15:15 BST), inside the checkpoint; c18-1 keeps the 0.3.20 cases and the pool window. If the wipe line slips past 15:30 BST the pin holds to it and main hears the clock (a slip is a report, not a cut). The set: the node lane's digest and mixed-version gates (12:50 to 13:05Z), the kept read and restart on the new pod, the wipe line on the new pod, the 12 GB settled-claim line on p12-vast. THE INTEROP FACT stands from the void run: the 5899f603 hub accepted 235 object-byte-5 blocks from the 8097d600 node with 0 rejected, one digest on all five nodes on the live sixteen-field file. The gates: the digest test and the kaspa-pow vector test (the amended devnet epoch-0 id 1a4230699a6b9c60 must equal, c120d7963abdcd96 must differ, the v3 control unchanged) on the box; the mixed-version Devnet 2 gate (the amended 0.3.20 node beside a 5899f603 node for ten minutes on the live file without the v4 fields) after the Mac build; the fresh-join canary the 0.3.20 cut's | | Main's rulings (7 October, morning) | no generator change to v4 on the live devnet; the record's null is the window model with numbers, sent by the hash lane to the attack-pass lane so AP-F8-1 re-gates against it; a fault beyond the model (a low-entropy source at site 15) stops at the coordinator with the two options priced (a 0.3.19 class amendment before the flip, or the flip held at the floor), nothing shipping without Josh's word; the tighter tail, an acceptance bound on the hot-set share, is a CLASS V5 item (sent to the v5 lane a6410f3b8abefb762 with the 64-seed census as its gate; the bound's number follows from the model) | ### AP-F4-1, the weak-day MUL draw (the attack-pass lane, 7 October, morning): PASS against v4, a class v5 rule From f9e05fc0b7f704163dd2665e8b887e299d56ea1a Mon Sep 17 00:00:00 2001 From: igneum-josh <337424239+igneum-josh@users.noreply.github.com> Date: Wed, 7 Oct 2026 13:39:00 +0100 Subject: [PATCH 05/19] Counter ASIC 3.0 status: c4459193's binary sha256 in the fleet's hand, the wipe pod c19-1, synced line about 14:20Z Co-Authored-By: Claude Fable 5.1 --- docs/plans/counter-asic-3-status.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/plans/counter-asic-3-status.md b/docs/plans/counter-asic-3-status.md index 9768dc1f0..0bb524425 100644 --- a/docs/plans/counter-asic-3-status.md +++ b/docs/plans/counter-asic-3-status.md @@ -338,7 +338,7 @@ Josh gave the go in advance for tonight: the shipper runs publish 1 on the 0.3.1 | THE ANALYSIS (the hash lane, ca3-v4-uniform 095f84a7, `docs/analysis/ca3-v4-uniform.md`, the tool on igneum-build-1) | the window model moves the null from 0.115 to 0.160 percent (1.39x, not 4.05x); the rest is a FAULT beyond it: site 15 reads a register last written by `or r6, r4`, so all-ones recurs at (3/4)^32 per read and the era map sends it to F8's hottest item exactly (the popcount model predicts 77,348 all-ones reads against 78,479; the top-0.1-percent share 0.58 against 0.52); it passes the acceptance rule because part (a) takes any write as a fresh source and part (c) counts saturation on final values only. The census of 1,024 chain-shaped v4 programs: 96.6 percent carry a lossy-sourced load (or, mul, mulhi as the last writer), 48.5 percent an or-sourced one (0.30 percent of all reads per site), 4.9 percent an or-of-or chain (4.6 percent of all reads on 0.1 percent of items); F8's 1.2x gate fails 96.6 percent of today's programs. Worth to a chip: 1.07 MB of SRAM ($0.25) serving 0.52 percent of a typical program's reads and 4.6 percent of the worst class's, at most 1.005x and 1.048x in rate; the ceiling under rule (c)'s 120-of-128 floor one site repeating its item in all 8 iterations, 6.25 percent of reads, 1.067x in 64 bytes; the 2x margin stands; the public line says "bounded at 1.067x", not "uniform" (the public text corrected) | | The two options, priced, STOPPED at the coordinator for Josh's word | A: a 0.3.19 class amendment before the flip (the generator draws a load's source from the registers whose last writer injects): a new program stream, new vectors, the seven gate packs re-exported, the six gates again (G1 to G3 and the verifier about an hour on the Mac and PC 2; G4 to G6 the node lane), every node before the flip under the one-box-at-a-time rule; the risk a node that misses the build splits the chain at the flip. B: hold the flip at the floor with v4 as it is; the bound documented; the source rule to class v5: a hot set worth up to 1.005x on about half the hours and 1.05x on 5 percent, 1.067x at the ceiling; no chain risk. The number: 1.067x at the ceiling against the 2x margin. The lane recommends B | | The v5 bound (sent to the v5 lane) | H = W_0.1 (the window term, 0.115 to 0.251 percent) + the sum over load sites of h(last writer) (or 0.30 percent, an or chain 4.5, mul 0.067, mulhi 0.049, an injecting op or a rotate 0), H at or under 1.2 x W_0.1, which is the static rule "every load's source was last written by an injecting op or a rotate"; as a rejection it costs 96.6 percent of candidates (about 30 attempts per seed), as a generator draw nothing; gate F8's 64-seed census with the saturated-source count | -| JOSH'S WORD (15:2x UK, 7 October): OPTION A, "do this but limit the testing, get it pushed" | the class v4 amendment: a load's source drawn only from registers whose last writer injects or is a rotate (the v5 rule applied now), a new program stream and vectors, the seven gate packs re-exported, the amended class with its own generator stamp; rides 0.3.20, the feature node (release-0.3.20-node = dc141409; 0.3.19 is an app-only cut with nothing of ours), on the shipper's line. The rollout arithmetic for the flip clock (the shipper): the standing fleet's one-box-at-a-time rollout took 32 minutes for 14 boxes (04:56 to 05:28Z, 7 October), the hands and the seed about 3 minutes after the miners, the Mac and the PCs within minutes of the publish; every 0.3.20 worker must accept the amended stamp before any flip. Owners: the hash lane (ca3-v4-amend: the generator, the vectors, the packs, the pairing on the box, one G1 run on PC 2, the ledger row), the node lane (release-0.3.20-node: the stamp agreed with the hash lane, the split-protection mechanism and the earliest flip time, the digest test, the mixed-version Devnet 2 gate), the attack-pass lane (the F8 census at 2^24 on the new stream, the gate 1.2x of the window model over 64 seeds), the shipper (the cut, the rollout order that sets the earliest flip). Testing limited to what prevents a split and proves the fix; G2, G3, the ladder re-measure and the rest of G4 to G6 OWED. THE STAMP agreed (the node and hash lanes, 7 October afternoon): generator 4 with sub-version 1 inside igneum-pow's id function, so the amended v4's program id for a seed differs from the old v4's (the old devnet epoch-0 id c120d7963abdcd96 pinned as the must-differ vector in kaspa-pow's test). SPLIT PROTECTION SETTLED (the node lane, plan section 6.6, ca3-v4-node fa5bc9e6; the node side on release-0.3.20-node): a fresh object byte. CLASS_SIGNAL_V4 is 5; the amended binary stamps 5 and the tally counts a block only at byte 5 or above; object 4 was stamped only by the unpublished dc141409 canary, so no published block carries it and a byte-4 block never counts; a node of the 6 October stream that sees byte 5 counts it as v4 (its rule is at least 4), flips to its own stream at the same epoch and forks ALONE (its blocks fail the amended id check, generator 4 sub-version 1 inside every id; the amended blocks fail its own), ours to upgrade in the sweep; object 6 is class v5's; the two holds already in the rule keep the window shut until every node is on 0.3.20 (a node stamps and tallies only with both v4 fields in its file; the fields publish only after the one-sweep rollout); a lagging worker refuses the amended pack at packcheck and mines nothing after the flip, costing that box, never the chain; no extra window hold: seven full day-windows are the hold. THE EARLIEST FLIP (approximate, measured 09:40Z: DAA 270,659, 1.095 DAA/s over 25 hours, 1.165 over 4; epoch 3,600, lead 600; seven windows 604,800 DAA wholly after the sweep's end D_s = T + about 40 minutes; the flip epoch the first e with 3600 e - 600 >= D_s + 604,800): T + 6 days 10 hours to T + 6 days 11 hours UK; for a publish at 12:00 UK on 7 October, 13 October between 22:20 and 23:10 UK (about 13:00 UK if the 4-hour rate holds). The floor as it stands (831,600, about 13 October 09:00 UK) would fire before any seven-window signal from a publish today completes, so it moves by the 0.3.16 rule to the publish DAA + 604,800 rounded up to the epoch boundary (882,000 for a 12:00 UK publish), firing about 30 minutes before the earliest signal flip: either way about 6 days 10 hours after the publish, never before every node has had the sweep plus a week. THE CLOCK (the node lane, 11:3x UK, after a Mac reboot moved its runs to the box): the 0.3.20 node line (dc141409 plus the proof archive aea0ca5c plus the amended v4 at object byte 5, igneum-pow at the hash lane's a0aaca92 beside the fork on the box) tested on the box, committed on release-0.3.20-node, pushed to the mirror and origin, igneumd and igneum-miner built, the tip to the shipper: about 12:00 UK; the mixed-version Devnet 2 gate (node-compat.mjs on the box, the amended node beside the 5899f603 pair for ten minutes) and the digest test (digest-compat.mjs): about 12:45 UK; the object-byte pin 5 unless the v5 lane answers both lanes with another assignment (v5 at 6 proposed). THE HASH SIDE on ca3-v4-amend (tip 8c728ca3, read from the branch 14:0x UK; the hash lane's own report pending): 1748fd1d the PC 2 G1-only playbook; e1f48d63 the fud-ledger entry AP-F8-1 (the fault, Josh's ruling, the amendment, the split protection, the owed tests); d8859522 the G1 line (the eight fingerprints equal on the RTX 5090, self-test PASS) and the node lane's signal byte 5; 4aa0c665 the v4 unit test following the amendment; 965d9e96 igneum-pow taken from release-0.3.20's 3f1652bf (the ladder's chain_program_shadow with the reps argument, never on master) with the amendment re-applied, the seven packs re-exporting byte-identical; 8c728ca3 the source rule keyed on the class with the shadow's pass count set aside, so every ladder rung draws under it (the fork's ladder test). The shipper took this igneum-pow tree into release-0.3.20 (00249643, byte-equal); nothing after 8c728ca3 touches igneum-pow. THE VECTORS AND THE PACKS (read from the branch and its ledger entry, 14:1x UK): the seven amended v4 packs (v4-devnet-epoch0, v4-era-0 to 5) carry generator 4, sub-version 1, one program id 1a4230699a6b9c60 (the 2.0 one-id-per-seed rule across the eras; the old c120d7963abdcd96 pinned as must-differ); the v3 control mx8-devnet-epoch0 untouched (73bcbfe8ccf988f1, fingerprint 90f794dd556f7a3b); the seven 2^24 fingerprints, Metal equal to Apple OpenCL: 867dbc45cfb36b4d, 2146ecacc8c75a8e, fe52602393f6d3d4, 3b206471a13912b4, c3f03c4a5d7333aa, f1dfd7209f15bb97, 8c194da64fadf31d; the zip of the eight packs sha256 889ec99976d2728b4b5035bfa476032e5b6a13b928968fc45236d5f25084aa39; the per-pack vectors.json sha256 prefixes 756301bf (devnet epoch 0), 1b5f4568, d430cadc, 1a1b21d8, 460fff9e, 4a85d49d, f83a1196 (eras 0 to 5). G1 on the RTX 5090 (PC 2 job run-ca3-v4-amend-g1-pc2-20261007, 09:41:07 to 09:41:28Z, exit 0, the installed worker): every fingerprint equal to the Mac's (the seven above and the control), NVRTC 188 to 332 ms per pack, the 1 GiB build 38 to 49 ms. hash-gates.md's older table still lists the pre-amendment fingerprints (f410c731... and the eras), which no longer apply to the amended packs; the ledger entry is the record. THE FIRST GREEN (11:31 UK, the box): the kaspa-pow suite on release-0.3.20-node (dc141409 plus the proof archive aea0ca5c plus the object-5 change) against the hash lane's igneum-pow 8c728ca3: 17 passed, 0 failed; the amended devnet epoch-0 id 1a4230699a6b9c60 pinned equal and c120d7963abdcd96 differing, the ladder's rung test green under the rekeyed rule, the v3 control unchanged; the consensus-core and exec RPC suites follow, then the node line (commit, push, box build, the tip to the shipper), then the digest and mixed-version gates. CLOCK RE-CUT (the node lane, 13:0x UK): the node line now carries, beside the object-5 change and the vector test, the lane's 0.3.20 fixes from the day (isSynced from the hook's stamp, the lazy template snapshot, the weight-table cache, the submit path returning after the block task, the watchdog, the RPC fields), about 13:30 UK if the box suites are green; the shipper's fresh-join canary 60 to 100 minutes after the cut; PC 1 as its first machine about 16:00 UK at the earliest, approximate until the shipper names the cut; the earliest flip about 6 days 10 hours after the publish. BUILD-2 LINES (12:28 to 12:33 UK): consensus-core 123 passed (the 60x file test green with the ladder window and activation pinned), the behind test green, kaspa-pow 17 passed (the amended vectors, earlier on build-1), the exec RPC suite green, the flows and rpc-service checks green with the submit-path change; the 24-requester latency test's first run tripped an unrelated flapping-fork double insert (24 equal forks from one parent; the test now builds on the sink as a real miner does; the double insert owed to a small fork harness before it is called a bug); THE NODE LINE COMMITTED (13:1x UK): release-0.3.20-node = 8097d600 (dc141409 + the proof archive aea0ca5c + one commit) on the mirror, pairing igneum-pow 8c728ca3, the hash with the shipper; in it the amended class v4 as object 5 (CLASS_SIGNAL_V4 = 5, byte 4 never counts, the kaspa-pow vector test pinning 1a4230699a6b9c60 equal and c120d7963abdcd96 differing, the daemon's window line naming object 5 and sub-version 1) beside the day's fixes (isSynced from the hook's stamp, the weight-table cache, the lazy snapshot, the submit path, the 100 ms template wait); the suites green on build-2 (consensus-core 123, the exec RPC suite, the four finality tests including 24 requesters under 200 ms: the worst template 100 ms, the worst submit 102 ms) and kaspa-pow 17 on build-1. Next: igneumd and igneum-miner building from 8097d600 on build-1, then the two gate lines (the mixed-version Devnet 2 gate: the 8097d600 node mining beside the 5899f603 pair for ten minutes on the live file without the v4 fields, the old node accepting every block; the digest test: the thirteen-field file b18ed271 unchanged, the sixteen-field object re-read on the 8097d600 binary), expected about 13:30 UK; the shipper picks the cut point. THE DATE FIXED (the node lane, from the hub's live file, 13:3x UK): publish 2 of 6 October (22:49:45Z, digest eada4bda) already put BOTH v4 fields on the live devnet (floor 831,600, window 86,400), so the 0.3.17 fleet has stamped object byte 4 since 7 October 00:2x UK and the floor is live at about 13 October 09:00 UK, before any seven-window signal completes; a 0.3.17 node left on that file flips to the OLD v4 stream at epoch 231 whatever anyone signals, a 0.3.20 node to the amended stream at the same epoch, and the two never share an id, so each straggler forks alone there. REQUIREMENT for the 0.3.20 publish (with the shipper and main): a new file with the floor at the publish DAA + 604,800 rounded up (about 882,000 for a publish today), the digest moving, the one-sweep rollout replacing every 0.3.17 node before 13 October 09:00 UK; any node that misses the sweep is alone then; the earliest flip after that about 6 days 10 hours past the publish; plan section 6.6 amended today. IN THE 0.3.20 PLAN (the shipper, 13:4x UK): both requirements; the node pin by main's rule is the node lane's second commit (the claim floor, the listener watchdog, the claim RPCs, on top of 8097d600) if its suites, both gates and the fleet's 12 GB prover line are green by 15:30 UK, else 8097d600; igneum-pow 8c728ca3 either way; the digest read on whichever binary pins. THE LINE AT 13:5x UK: three commits on release-0.3.20-node, 8097d600 (the object-5 amended class v4 and the day's fixes), 6b94c823 (test-only: the stale PC 1 test from 500ddd66 inverted by the isSynced ruling; the FALLBACK pin, code byte-identical to 8097d600, so the module reads green whole) and 6a3432a3 (the app lane's key methods, the observer's claims, the settled claim floor, the listener watchdog); suites on build-2 on 6a3432a3's code (the whole finality module 25, the exec suite 29 with the watchdog test, the kaspad, flows and rpc-service checks; consensus-core 123 and kaspa-pow 17 earlier); the cut 6a3432a3 if its gates and the fleet's 12 GB settled-claim line are green by 15:30 UK, else 6b94c823; both binaries building on build-1, the two gates (the digest gate, then the ten-minute mixed-version gate beside the 5899f603 pair) on the 8097d600 build, lines about 14:05 UK. GATE NEWS (13:53 UK): on 6a3432a3's own digest gate the listener watchdog counted a bind failure (the four harness nodes share one exec JSON-RPC port) as a listener death and exited three of four nodes at 20 s, where 0.3.17 and 8097d600 only warn and live without the exec RPC; the digest facts came out first and stand (the thirteen-field file a89be8a7 on both binaries, the compat case; the sixteen-field object db9a85f9 refused with the mismatch line, the refusal case); the ten-minute gate on 6a3432a3 stopped as void for the same cause. The fix: a bind failure is a retry every poll, one line a minute, no death counted and never an exit, with a second watchdog test whose known-failed shape is the old rule's exit on a held port; the third commit and its build about 14:15 UK, its gates about 14:35 UK; the fallback 6b94c823's gates on build-1 on their own binary (no watchdog there), lines about 14:20 UK; ledger row N12 for the bind-failure class. A ROLL BLOCKER on every kept datadir (the node lane, 14:1x UK, ledger N13): the fleet started 6a3432a3 on a kept 0.3.17 datadir (pool-1's copy) and it died at start (virtual_state.rs:250, DeserializationError(UnexpectedEof)); the cause 10db4b61 on the 0.3.16 feature line added `silent: bool` to BlockRewardData under serde(default), which bincode ignores, so every build from 10db4b61 on (dc141409, 8097d600, 6b94c823, 6a3432a3, 09124180) reads a 0.3.17 node's virtual-state row short; no canary saw it because every canary wiped, and a one-box roll keeps datadirs, so it blocks the roll on every standing box, the hands and the hub whatever the pin. The fix on the line: the store reads the current layout first and on a deserialization error decodes the row as a v1 mirror, converts with silent false and rewrites it under the same key, with the known-failed test first; the fourth commit and build about 14:40 UK, the fleet's kept-datadir start on the fixed binary about 14:50 UK, its gates after. THE RULE IT ADDS for every node cut from now: a kept-datadir restart gate on a standing box's datadir copy beside the wiped canary. THE CANDIDATE PIN (14:2x UK): b7cc37e7 (8097d600, 6b94c823, 6a3432a3, 09124180, b7cc37e7; igneum-pow 8c728ca3): the N13 fix with its test green on build-2 at 14:04 UK and the kaspad check green, the build on build-1; the fallback 6b94c823 is no longer a pin for the one-box roll (it dies on a kept datadir like every build since 10db4b61): if b7cc37e7's gates are not green by 15:30 UK the honest fallback is 0.3.17's 5899f603 staying live. In flight on build-1: the earlier commits' gates, then b7cc37e7's own digest and ten-minute mixed-version gates on its binary with the read-back, lines about 15:05 UK; on the fleet the kept-datadir start on b7cc37e7 about 14:50 UK and the 12 GB settled-claim line 14:50 to 15:00 UK. Plan section 6.6 amended with the hard date (ca3-v4-node 9d763edd, merged to master); N12 and N13 on the ledger. THE GATES ON THE FALLBACK'S OWN BINARY (6b94c823, sha b1b7d47b, 13:56 to 14:08 UK; code byte-identical to 8097d600, so the amendment's node side): the digest gate, the thirteen-field file a89be8a7 on both binaries (the compat case, n0 peering n1 and n2) and the sixteen-field object db9a85f9 refused with the mismatch line (the refusal case); the mixed-version gate, ten minutes, one digest b0afb2ee on all five nodes, the 5899f603 hub accepting every block the amended node mined (146 new, 246 old, 0 rejected), plain header version 2 on the thirteen-field file, counts equal on all five through the two clean joins and the restart. Two FAILED checks, both the harness's own and fixed (36d3efdc): a refused peer's count read 1 with the reconnect in flight (now the minimum of five), and six address-in-use panics in the two old nodes because the second gate reused the first's ports the second they were sent SIGTERM (a 20 s gap now). CLOCK CORRECTION (the node lane, 12:12Z = 13:12 BST): every "UK" stamp it sent today was the box's CEST, an hour fast of BST; its lines read UTC from now. Restated: b7cc37e7's build about 12:15Z, its digest and mixed-version gates on that binary with the sha and string about 12:32Z (13:32 BST), the fleet's kept-datadir start on it about 12:25Z, its 12 GB settled-claim line 12:50 to 13:00Z; the shipper's checkpoint 14:30Z (15:30 BST), two hours of room. The 13 October date stands (derived from UTC DAA rates): the floor 831,600 about 08:00Z, 09:00 BST. b7cc37e7'S OWN LINES (binary sha256 bc28331abf21f4d5, the string read back on build-1 and on the fleet's pod): the digest gate 12:14:39Z to 12:16:18Z SUMMARY PASS (thirteen fields a89be8a7 on both binaries with the peers as the gate wants them; the sixteen-field object db9a85f9 refused with the line and no peer; the live file's digest eada4bda on the binary, unmoved); the kept-datadir start on the fleet's copy of pool-1's 0.3.17 datadir: the first start 12:17:12Z reads the v1 row through the mirror and rewrites it ("1 mergeset rewards"), the finality blob converts (1,747 locks), the node comes up on its ports with no panic; the second start 12:18:53Z reads first-try with no rewrite line and no panic; 6a3432a3's death on the same copy is the known-failed shape. The ten-minute mixed-version gate beside the 5899f603 pair runs on the same binary since 12:16:39Z, its line about 12:28Z; then the only line outstanding for the shipper's 14:30Z rule is the fleet's 12 GB settled-claim line, 12:50 to 13:00Z. AP-F8-1 RESIDUAL CLASS ON THE AMENDED STREAM (attack-pass lane 12:18Z on igneum-pow 8c728ca3, sub-version 1). F9 over 1,000,000 seeds: programs flagged (hot share at least 1 percent or 7 constant address bits) 1,871 (0.19 percent) against 11,696 (1.17 percent) unamended; worst hot share 9.66 percent against 17.3; mean 0.011 against 0.063 percent; 84 percent of the flagged programs and the whole or-saturation tail gone. F8 at 30 of 64 seeds: nine over 1.2x of the window model (p31 29.3x, p11 5.5x, p19 3.3x, p6 3.1x, p23 2.0x, the rest 1.3x to 1.6x); the 64-seed 1.2x gate is heading to FAIL on sub-version 1. Mechanism, confirmed on the two worst seeds: an all-ones load source (image 0x0ca59e4c under the era map) delivered through a writer the source rule counts as entropy-keeping, a rotate (rotl and rotr map all-ones to itself) or a load whose own source was saturated, with the saturation made one or more writes upstream by or. The rule looks one writer back; it must look through saturation-preserving writers or test the source's values. The ceiling has not moved: rule (c)'s 120-of-128 floor still caps any program at one saturated site, 6.25 percent of reads, a chip edge of at most 1.067x, and the residual (worst seed two sites at 0.53 and 0.56) sits inside it. THE SENTENCE "no lossy-sourced load by construction" IS HELD: it goes in no plan row and no ledger entry as true; sub-version 1 removes the or-source class and bounds the rest. MAIN'S RULING (13:2x UK): 0.3.20 ships object byte 5 on sub-version 1 as it stands, strictly better than the old stream the live floor flips to on 13 October; the fix is sub-version 2 on ca3-v4-amend (object byte 6 or whatever the v5 alignment leaves free) with both fixes: (F1) the static rule made transitive (rotates do not keep entropy; a load keeps entropy only if its own source did; one draw change, no attempts lost) and (F2) the dynamic source check (saturated load SOURCE values counted per site over the 64 units' 16,384 evaluations, rejected above 163 of 16,384, the same 1 percent the final-value rule uses; costs attempts on about 0.2 percent of seeds; rides with F1 because an or-written source is all-ones only (3/4)^32 of the time). Gate before sub-version 2 is proposed, run by the attack-pass lane and not by the hash lane: the full 64-seed census under 1.2x on every seed and the hot-set census. Hash lane's estimate about an hour its side (implement, re-export seven packs, vectors, crate suite, pairing, one G1 on PC 2) plus the node lane's vector re-pin and the attack-pass re-gate. The flip floor for sub-version 1 is expected to move (Josh's word) so the chain never flips to a stream that fails this gate. Also recorded: the crate suite at 8c728ca3 100 of 100 on the box (rc 0, 77 s); the pairing against the fork at dc141409 compiled and ran 15 of 16, the one failure the fork's own pre-amendment assertion (base equals v3's, igneum.rs:972), which 8097d600 on the release-0.3.20-node line turns into assert_ne; the pairing re-runs at b7cc37e7, its line to follow. CORRECTION (the attack-pass lane's own retraction, 13:3x UK): the F9 hot-set figures above (1,871 of 1,000,000, worst 9.66 percent, 84 percent removed, the two or-then-rotate listings) are WITHDRAWN: F9's harness draws through candidate_class with its own era class, outside candidate_from_words_class where the source rule lives, so it measured the old stream (the 8c728ca3 binary prints the identical program to the sub-version-0 binary for its worst seed). F8's 64-seed census on the chain path (pairing verified on 1a4230699a6b9c60) is the valid re-gate and STANDS: at 30 of 64 seeds, nine over 1.2x of the window model (p31 29.3x, p11 5.5x, p19 3.3x, p6 3.1x, p23 2.0x, p4 1.6x, p10 1.5x, p26 1.3x, p25 1.3x). The residual mechanism on the amended stream: a load-after-load chain (a saturated source reads one fixed word, which is the next load's address), admitted because a load injects; and the rotate-preserves-saturation path (generator.rs sets entropy_kept true for a rotate whatever it rotated), correct in code and a second admitted path if it occurs on the chain stream. Sub-version 2 must close both: dataflow freshness per register (a load fresh only if its source was fresh; add, sub, xor, mad, shfl fresh if either operand was; rotates only if the operand was; or, mul, mulhi never) plus the (c') count of saturated load sources per site as the backstop. The STOP holds on F8's evidence alone; the options and the 1.067x ceiling are unchanged. The sentence "no lossy-sourced load by construction" waits on the sub-version 2 census verdict and stays out of every public text until then. SUB-VERSION 2 IN BUILD (the hash lane, ca3-v4-amend, on the coordinator's direction, 13:4x UK): F1 (dataflow freshness per register, keyed on the class v4 shape on every draw path, era or not, so the candidate_class path and the chain path draw one stream) plus F2 (the (c') count of saturated load source values per site over the 64 units' 16,384 evaluations, rejected above 163, keyed on the same shape so v2 and v3 verdicts do not move); PROGRAM_SUBVERSION_V4 = 2, new ids, the seven packs re-exported, recheck.rs with 1a4230699a6b9c60 and c120d7963abdcd96 as the must-differ pair. Clock (UTC): the commit on the branch by 13:30; the crate suite on box 2 and the pairing against b7cc37e7 by about 13:50 (the pairing's vector test fails on the fork's sub-version-1 pin until the node lane re-pins; the compile and the other 15 are the pairing evidence); the G1 job on PC 2 under --cards-off by about 14:10, lock permitting; then the attack-pass lane's full 64-seed census and hot-set census on the chain path. Two consequences stated in the commit: the rule on every draw path moves the no-era sh256xN ladder packs' stream (packs-ca3-shadow's seven 256-block packs re-export with new fingerprints; the measured rates stand as the old stream's), and the class v5 lane's pinned string-seed packs move when it merges sub-version 2, so it re-exports them then. 0.3.20's sub-version-1 packs, ids and fingerprints untouched. OBJECT BYTES SETTLED (main, 13:5x UK): byte 5 = class v4 sub-version 1 (0.3.20), byte 6 = class v5 (pinned: class-v5 16afd0a0, class-v5-node 699db5a2, the flip case passed on 6,6,6; the v5 lane stopped), byte 7 = class v4 sub-version 2; the node and hash lanes told. b7cc37e7's MIXED-VERSION GATE: FAIL, the binary not the harness (12:16:39Z to 12:27:21Z, sha256 bc28331abf21f4d5, the string read back). Before the restart step everything held: one digest b0afb2ee on all five nodes, 268 new and 392 old blocks accepted, 0 rejected, header versions plain 2, counts equal on all five at 324 and 502 through both clean joins. At the new node's restart (12:24:19Z) it died at once on its own datadir ("IO error: While lock file: .../datadir/meta/LOCK: Resource temporarily unavailable", conn_builder.rs:167): the previous process was still shutting down, because the listener watchdog added on 6a3432a3 sleeps its whole 10 s poll before checking shutdown, so every node on the line since then takes up to 10 s longer to stop than 0.3.17 (the fleet saw the same shape as "a 12-second timeout does not stop the node"). Three of the four failed checks follow from that one death (counts, the restarted node's resync, the node it served frozen at 502). The fix on the line, one rule: the poll in 250 ms steps returning the moment shutdown is set, with a test that a shutdown returns within a second (the 10 s loop the known-failed shape); the exec suite on build-2, the fifth commit and its build about 12:45Z, its digest and ten-minute gates about 12:50 to 13:05Z, inside 14:30Z. b7cc37e7 is NOT the pin. The node-side re-pin for sub-version 2 (byte 7) once the hash lane's commit lands: the beside-the-fork igneum-pow copy archived from the commit, the two pinned ids moved in the kaspa-pow vector test (sub-version-2's epoch-0 id must-equal; sub-version-1's joins c120d7963abdcd96 as must-differ), CLASS_SIGNAL and tests for byte 7, the daemon's window line: about 20 minutes of edits plus one kaspa-pow suite run on build-2 (about 2 minutes). THE FIFTH COMMIT c4459193 on release-0.3.20-node (b7cc37e7's child, the watchdog poll returning on shutdown; the diff is the poll loop in rpc.rs alone), pairing igneum-pow 8c728ca3; its build on build-1 started 12:30:13Z, sha256 and string to follow. Line A, the shutdown test: rpc::watchdog_tests::a_shutdown_returns_within_a_second_whatever_the_poll green on build-2 at 12:29Z in the exec suite's 31 passed, beside the two other watchdog tests; its known-failed shape the old loop's 10 s stop. Line B, the kept-datadir start: b7cc37e7's fleet read carries to c4459193 since the store code is byte-identical between the two commits; the fleet re-reads on the c4459193 binary only if the shipper's rule wants the string on that line too. The digest gate and the ten-minute mixed-version gate on c4459193's own binary follow its build. THE SHIPPER'S CARRY RULING (14:1x UK): b7cc37e7's kept-datadir read stands as evidence that the store fix is right (the store code byte-identical) but is not the gate line for the pin, because the rule reads the binary, not the diff, and the binary changed (rpc.rs); the gate line is the kept read on c4459193's own binary with its string, which the fleet's canary already runs on c18-1 (wipe, then the kept read, then the restart) before the canary's restart step, at no extra cost; no re-read on p12-vast. THE PIN IS c4459193 pairing 8c728ca3 (object byte 5, sub-version 1); sub-version 2 (byte 7) is 0.3.21's, not 0.3.20's. The shipper's reading of main's F8 ruling: 0.3.20 ships object 5 as it stands because the live floor otherwise flips every node to the OLD stream on 13 October, and the 16:00 BST report tells Josh the floor move is now RECOMMENDED rather than optional, so the chain never flips to a stream that fails the 1.2x gate before sub-version 2 lands. THE FLEET'S CLOCK ON c4459193 (the fleet lane, 12:5x UTC): the kept read on pool-1's 0.3.17 datadir copy and the restart (the old process's stop time on the line) run on c18-1 before the wipe, a few minutes each, so both lines land before 14:30Z; the wipe canary (IBD from the pruning-point proof, 98 minutes on this pod class) starts when c18-1 is free of the 0.3.20 cases (about 13:00Z) and the binary is in hand, so its synced line lands about 14:40Z at the earliest, PAST the 14:30Z checkpoint; the 12 GB settled-claim line: c4459193 starts on p12-vast's kept copy of pool-1's datadir beside the 6a3432a3 IBD node on alternate ports the moment the binary lands, catches up from 129,398 blocks (15 to 20 minutes) and the 12 GB prover claims against it, the line on c4459193 itself. The binary not yet in the fleet's hand (build-1 building since 12:30:13Z); a wait armed on the sha and string, a report by 13:10Z if nothing. THE SHIPPER'S CALL ON THE CLOCK (14:2x UK): the wipe canary is the decisive read by the deploy rule; the pin never cuts without it and b7cc37e7's lineage does not stand in (the binary changed). The fleet rents a second one-shot pod of c18-1's class now and starts the wipe canary on c4459193's binary the moment the build lands, synced line about 14:15Z (15:15 BST), inside the checkpoint; c18-1 keeps the 0.3.20 cases and the pool window. If the wipe line slips past 15:30 BST the pin holds to it and main hears the clock (a slip is a report, not a cut). The set: the node lane's digest and mixed-version gates (12:50 to 13:05Z), the kept read and restart on the new pod, the wipe line on the new pod, the 12 GB settled-claim line on p12-vast. THE INTEROP FACT stands from the void run: the 5899f603 hub accepted 235 object-byte-5 blocks from the 8097d600 node with 0 rejected, one digest on all five nodes on the live sixteen-field file. The gates: the digest test and the kaspa-pow vector test (the amended devnet epoch-0 id 1a4230699a6b9c60 must equal, c120d7963abdcd96 must differ, the v3 control unchanged) on the box; the mixed-version Devnet 2 gate (the amended 0.3.20 node beside a 5899f603 node for ten minutes on the live file without the v4 fields) after the Mac build; the fresh-join canary the 0.3.20 cut's | +| JOSH'S WORD (15:2x UK, 7 October): OPTION A, "do this but limit the testing, get it pushed" | the class v4 amendment: a load's source drawn only from registers whose last writer injects or is a rotate (the v5 rule applied now), a new program stream and vectors, the seven gate packs re-exported, the amended class with its own generator stamp; rides 0.3.20, the feature node (release-0.3.20-node = dc141409; 0.3.19 is an app-only cut with nothing of ours), on the shipper's line. The rollout arithmetic for the flip clock (the shipper): the standing fleet's one-box-at-a-time rollout took 32 minutes for 14 boxes (04:56 to 05:28Z, 7 October), the hands and the seed about 3 minutes after the miners, the Mac and the PCs within minutes of the publish; every 0.3.20 worker must accept the amended stamp before any flip. Owners: the hash lane (ca3-v4-amend: the generator, the vectors, the packs, the pairing on the box, one G1 run on PC 2, the ledger row), the node lane (release-0.3.20-node: the stamp agreed with the hash lane, the split-protection mechanism and the earliest flip time, the digest test, the mixed-version Devnet 2 gate), the attack-pass lane (the F8 census at 2^24 on the new stream, the gate 1.2x of the window model over 64 seeds), the shipper (the cut, the rollout order that sets the earliest flip). Testing limited to what prevents a split and proves the fix; G2, G3, the ladder re-measure and the rest of G4 to G6 OWED. THE STAMP agreed (the node and hash lanes, 7 October afternoon): generator 4 with sub-version 1 inside igneum-pow's id function, so the amended v4's program id for a seed differs from the old v4's (the old devnet epoch-0 id c120d7963abdcd96 pinned as the must-differ vector in kaspa-pow's test). SPLIT PROTECTION SETTLED (the node lane, plan section 6.6, ca3-v4-node fa5bc9e6; the node side on release-0.3.20-node): a fresh object byte. CLASS_SIGNAL_V4 is 5; the amended binary stamps 5 and the tally counts a block only at byte 5 or above; object 4 was stamped only by the unpublished dc141409 canary, so no published block carries it and a byte-4 block never counts; a node of the 6 October stream that sees byte 5 counts it as v4 (its rule is at least 4), flips to its own stream at the same epoch and forks ALONE (its blocks fail the amended id check, generator 4 sub-version 1 inside every id; the amended blocks fail its own), ours to upgrade in the sweep; object 6 is class v5's; the two holds already in the rule keep the window shut until every node is on 0.3.20 (a node stamps and tallies only with both v4 fields in its file; the fields publish only after the one-sweep rollout); a lagging worker refuses the amended pack at packcheck and mines nothing after the flip, costing that box, never the chain; no extra window hold: seven full day-windows are the hold. THE EARLIEST FLIP (approximate, measured 09:40Z: DAA 270,659, 1.095 DAA/s over 25 hours, 1.165 over 4; epoch 3,600, lead 600; seven windows 604,800 DAA wholly after the sweep's end D_s = T + about 40 minutes; the flip epoch the first e with 3600 e - 600 >= D_s + 604,800): T + 6 days 10 hours to T + 6 days 11 hours UK; for a publish at 12:00 UK on 7 October, 13 October between 22:20 and 23:10 UK (about 13:00 UK if the 4-hour rate holds). The floor as it stands (831,600, about 13 October 09:00 UK) would fire before any seven-window signal from a publish today completes, so it moves by the 0.3.16 rule to the publish DAA + 604,800 rounded up to the epoch boundary (882,000 for a 12:00 UK publish), firing about 30 minutes before the earliest signal flip: either way about 6 days 10 hours after the publish, never before every node has had the sweep plus a week. THE CLOCK (the node lane, 11:3x UK, after a Mac reboot moved its runs to the box): the 0.3.20 node line (dc141409 plus the proof archive aea0ca5c plus the amended v4 at object byte 5, igneum-pow at the hash lane's a0aaca92 beside the fork on the box) tested on the box, committed on release-0.3.20-node, pushed to the mirror and origin, igneumd and igneum-miner built, the tip to the shipper: about 12:00 UK; the mixed-version Devnet 2 gate (node-compat.mjs on the box, the amended node beside the 5899f603 pair for ten minutes) and the digest test (digest-compat.mjs): about 12:45 UK; the object-byte pin 5 unless the v5 lane answers both lanes with another assignment (v5 at 6 proposed). THE HASH SIDE on ca3-v4-amend (tip 8c728ca3, read from the branch 14:0x UK; the hash lane's own report pending): 1748fd1d the PC 2 G1-only playbook; e1f48d63 the fud-ledger entry AP-F8-1 (the fault, Josh's ruling, the amendment, the split protection, the owed tests); d8859522 the G1 line (the eight fingerprints equal on the RTX 5090, self-test PASS) and the node lane's signal byte 5; 4aa0c665 the v4 unit test following the amendment; 965d9e96 igneum-pow taken from release-0.3.20's 3f1652bf (the ladder's chain_program_shadow with the reps argument, never on master) with the amendment re-applied, the seven packs re-exporting byte-identical; 8c728ca3 the source rule keyed on the class with the shadow's pass count set aside, so every ladder rung draws under it (the fork's ladder test). The shipper took this igneum-pow tree into release-0.3.20 (00249643, byte-equal); nothing after 8c728ca3 touches igneum-pow. THE VECTORS AND THE PACKS (read from the branch and its ledger entry, 14:1x UK): the seven amended v4 packs (v4-devnet-epoch0, v4-era-0 to 5) carry generator 4, sub-version 1, one program id 1a4230699a6b9c60 (the 2.0 one-id-per-seed rule across the eras; the old c120d7963abdcd96 pinned as must-differ); the v3 control mx8-devnet-epoch0 untouched (73bcbfe8ccf988f1, fingerprint 90f794dd556f7a3b); the seven 2^24 fingerprints, Metal equal to Apple OpenCL: 867dbc45cfb36b4d, 2146ecacc8c75a8e, fe52602393f6d3d4, 3b206471a13912b4, c3f03c4a5d7333aa, f1dfd7209f15bb97, 8c194da64fadf31d; the zip of the eight packs sha256 889ec99976d2728b4b5035bfa476032e5b6a13b928968fc45236d5f25084aa39; the per-pack vectors.json sha256 prefixes 756301bf (devnet epoch 0), 1b5f4568, d430cadc, 1a1b21d8, 460fff9e, 4a85d49d, f83a1196 (eras 0 to 5). G1 on the RTX 5090 (PC 2 job run-ca3-v4-amend-g1-pc2-20261007, 09:41:07 to 09:41:28Z, exit 0, the installed worker): every fingerprint equal to the Mac's (the seven above and the control), NVRTC 188 to 332 ms per pack, the 1 GiB build 38 to 49 ms. hash-gates.md's older table still lists the pre-amendment fingerprints (f410c731... and the eras), which no longer apply to the amended packs; the ledger entry is the record. THE FIRST GREEN (11:31 UK, the box): the kaspa-pow suite on release-0.3.20-node (dc141409 plus the proof archive aea0ca5c plus the object-5 change) against the hash lane's igneum-pow 8c728ca3: 17 passed, 0 failed; the amended devnet epoch-0 id 1a4230699a6b9c60 pinned equal and c120d7963abdcd96 differing, the ladder's rung test green under the rekeyed rule, the v3 control unchanged; the consensus-core and exec RPC suites follow, then the node line (commit, push, box build, the tip to the shipper), then the digest and mixed-version gates. CLOCK RE-CUT (the node lane, 13:0x UK): the node line now carries, beside the object-5 change and the vector test, the lane's 0.3.20 fixes from the day (isSynced from the hook's stamp, the lazy template snapshot, the weight-table cache, the submit path returning after the block task, the watchdog, the RPC fields), about 13:30 UK if the box suites are green; the shipper's fresh-join canary 60 to 100 minutes after the cut; PC 1 as its first machine about 16:00 UK at the earliest, approximate until the shipper names the cut; the earliest flip about 6 days 10 hours after the publish. BUILD-2 LINES (12:28 to 12:33 UK): consensus-core 123 passed (the 60x file test green with the ladder window and activation pinned), the behind test green, kaspa-pow 17 passed (the amended vectors, earlier on build-1), the exec RPC suite green, the flows and rpc-service checks green with the submit-path change; the 24-requester latency test's first run tripped an unrelated flapping-fork double insert (24 equal forks from one parent; the test now builds on the sink as a real miner does; the double insert owed to a small fork harness before it is called a bug); THE NODE LINE COMMITTED (13:1x UK): release-0.3.20-node = 8097d600 (dc141409 + the proof archive aea0ca5c + one commit) on the mirror, pairing igneum-pow 8c728ca3, the hash with the shipper; in it the amended class v4 as object 5 (CLASS_SIGNAL_V4 = 5, byte 4 never counts, the kaspa-pow vector test pinning 1a4230699a6b9c60 equal and c120d7963abdcd96 differing, the daemon's window line naming object 5 and sub-version 1) beside the day's fixes (isSynced from the hook's stamp, the weight-table cache, the lazy snapshot, the submit path, the 100 ms template wait); the suites green on build-2 (consensus-core 123, the exec RPC suite, the four finality tests including 24 requesters under 200 ms: the worst template 100 ms, the worst submit 102 ms) and kaspa-pow 17 on build-1. Next: igneumd and igneum-miner building from 8097d600 on build-1, then the two gate lines (the mixed-version Devnet 2 gate: the 8097d600 node mining beside the 5899f603 pair for ten minutes on the live file without the v4 fields, the old node accepting every block; the digest test: the thirteen-field file b18ed271 unchanged, the sixteen-field object re-read on the 8097d600 binary), expected about 13:30 UK; the shipper picks the cut point. THE DATE FIXED (the node lane, from the hub's live file, 13:3x UK): publish 2 of 6 October (22:49:45Z, digest eada4bda) already put BOTH v4 fields on the live devnet (floor 831,600, window 86,400), so the 0.3.17 fleet has stamped object byte 4 since 7 October 00:2x UK and the floor is live at about 13 October 09:00 UK, before any seven-window signal completes; a 0.3.17 node left on that file flips to the OLD v4 stream at epoch 231 whatever anyone signals, a 0.3.20 node to the amended stream at the same epoch, and the two never share an id, so each straggler forks alone there. REQUIREMENT for the 0.3.20 publish (with the shipper and main): a new file with the floor at the publish DAA + 604,800 rounded up (about 882,000 for a publish today), the digest moving, the one-sweep rollout replacing every 0.3.17 node before 13 October 09:00 UK; any node that misses the sweep is alone then; the earliest flip after that about 6 days 10 hours past the publish; plan section 6.6 amended today. IN THE 0.3.20 PLAN (the shipper, 13:4x UK): both requirements; the node pin by main's rule is the node lane's second commit (the claim floor, the listener watchdog, the claim RPCs, on top of 8097d600) if its suites, both gates and the fleet's 12 GB prover line are green by 15:30 UK, else 8097d600; igneum-pow 8c728ca3 either way; the digest read on whichever binary pins. THE LINE AT 13:5x UK: three commits on release-0.3.20-node, 8097d600 (the object-5 amended class v4 and the day's fixes), 6b94c823 (test-only: the stale PC 1 test from 500ddd66 inverted by the isSynced ruling; the FALLBACK pin, code byte-identical to 8097d600, so the module reads green whole) and 6a3432a3 (the app lane's key methods, the observer's claims, the settled claim floor, the listener watchdog); suites on build-2 on 6a3432a3's code (the whole finality module 25, the exec suite 29 with the watchdog test, the kaspad, flows and rpc-service checks; consensus-core 123 and kaspa-pow 17 earlier); the cut 6a3432a3 if its gates and the fleet's 12 GB settled-claim line are green by 15:30 UK, else 6b94c823; both binaries building on build-1, the two gates (the digest gate, then the ten-minute mixed-version gate beside the 5899f603 pair) on the 8097d600 build, lines about 14:05 UK. GATE NEWS (13:53 UK): on 6a3432a3's own digest gate the listener watchdog counted a bind failure (the four harness nodes share one exec JSON-RPC port) as a listener death and exited three of four nodes at 20 s, where 0.3.17 and 8097d600 only warn and live without the exec RPC; the digest facts came out first and stand (the thirteen-field file a89be8a7 on both binaries, the compat case; the sixteen-field object db9a85f9 refused with the mismatch line, the refusal case); the ten-minute gate on 6a3432a3 stopped as void for the same cause. The fix: a bind failure is a retry every poll, one line a minute, no death counted and never an exit, with a second watchdog test whose known-failed shape is the old rule's exit on a held port; the third commit and its build about 14:15 UK, its gates about 14:35 UK; the fallback 6b94c823's gates on build-1 on their own binary (no watchdog there), lines about 14:20 UK; ledger row N12 for the bind-failure class. A ROLL BLOCKER on every kept datadir (the node lane, 14:1x UK, ledger N13): the fleet started 6a3432a3 on a kept 0.3.17 datadir (pool-1's copy) and it died at start (virtual_state.rs:250, DeserializationError(UnexpectedEof)); the cause 10db4b61 on the 0.3.16 feature line added `silent: bool` to BlockRewardData under serde(default), which bincode ignores, so every build from 10db4b61 on (dc141409, 8097d600, 6b94c823, 6a3432a3, 09124180) reads a 0.3.17 node's virtual-state row short; no canary saw it because every canary wiped, and a one-box roll keeps datadirs, so it blocks the roll on every standing box, the hands and the hub whatever the pin. The fix on the line: the store reads the current layout first and on a deserialization error decodes the row as a v1 mirror, converts with silent false and rewrites it under the same key, with the known-failed test first; the fourth commit and build about 14:40 UK, the fleet's kept-datadir start on the fixed binary about 14:50 UK, its gates after. THE RULE IT ADDS for every node cut from now: a kept-datadir restart gate on a standing box's datadir copy beside the wiped canary. THE CANDIDATE PIN (14:2x UK): b7cc37e7 (8097d600, 6b94c823, 6a3432a3, 09124180, b7cc37e7; igneum-pow 8c728ca3): the N13 fix with its test green on build-2 at 14:04 UK and the kaspad check green, the build on build-1; the fallback 6b94c823 is no longer a pin for the one-box roll (it dies on a kept datadir like every build since 10db4b61): if b7cc37e7's gates are not green by 15:30 UK the honest fallback is 0.3.17's 5899f603 staying live. In flight on build-1: the earlier commits' gates, then b7cc37e7's own digest and ten-minute mixed-version gates on its binary with the read-back, lines about 15:05 UK; on the fleet the kept-datadir start on b7cc37e7 about 14:50 UK and the 12 GB settled-claim line 14:50 to 15:00 UK. Plan section 6.6 amended with the hard date (ca3-v4-node 9d763edd, merged to master); N12 and N13 on the ledger. THE GATES ON THE FALLBACK'S OWN BINARY (6b94c823, sha b1b7d47b, 13:56 to 14:08 UK; code byte-identical to 8097d600, so the amendment's node side): the digest gate, the thirteen-field file a89be8a7 on both binaries (the compat case, n0 peering n1 and n2) and the sixteen-field object db9a85f9 refused with the mismatch line (the refusal case); the mixed-version gate, ten minutes, one digest b0afb2ee on all five nodes, the 5899f603 hub accepting every block the amended node mined (146 new, 246 old, 0 rejected), plain header version 2 on the thirteen-field file, counts equal on all five through the two clean joins and the restart. Two FAILED checks, both the harness's own and fixed (36d3efdc): a refused peer's count read 1 with the reconnect in flight (now the minimum of five), and six address-in-use panics in the two old nodes because the second gate reused the first's ports the second they were sent SIGTERM (a 20 s gap now). CLOCK CORRECTION (the node lane, 12:12Z = 13:12 BST): every "UK" stamp it sent today was the box's CEST, an hour fast of BST; its lines read UTC from now. Restated: b7cc37e7's build about 12:15Z, its digest and mixed-version gates on that binary with the sha and string about 12:32Z (13:32 BST), the fleet's kept-datadir start on it about 12:25Z, its 12 GB settled-claim line 12:50 to 13:00Z; the shipper's checkpoint 14:30Z (15:30 BST), two hours of room. The 13 October date stands (derived from UTC DAA rates): the floor 831,600 about 08:00Z, 09:00 BST. b7cc37e7'S OWN LINES (binary sha256 bc28331abf21f4d5, the string read back on build-1 and on the fleet's pod): the digest gate 12:14:39Z to 12:16:18Z SUMMARY PASS (thirteen fields a89be8a7 on both binaries with the peers as the gate wants them; the sixteen-field object db9a85f9 refused with the line and no peer; the live file's digest eada4bda on the binary, unmoved); the kept-datadir start on the fleet's copy of pool-1's 0.3.17 datadir: the first start 12:17:12Z reads the v1 row through the mirror and rewrites it ("1 mergeset rewards"), the finality blob converts (1,747 locks), the node comes up on its ports with no panic; the second start 12:18:53Z reads first-try with no rewrite line and no panic; 6a3432a3's death on the same copy is the known-failed shape. The ten-minute mixed-version gate beside the 5899f603 pair runs on the same binary since 12:16:39Z, its line about 12:28Z; then the only line outstanding for the shipper's 14:30Z rule is the fleet's 12 GB settled-claim line, 12:50 to 13:00Z. AP-F8-1 RESIDUAL CLASS ON THE AMENDED STREAM (attack-pass lane 12:18Z on igneum-pow 8c728ca3, sub-version 1). F9 over 1,000,000 seeds: programs flagged (hot share at least 1 percent or 7 constant address bits) 1,871 (0.19 percent) against 11,696 (1.17 percent) unamended; worst hot share 9.66 percent against 17.3; mean 0.011 against 0.063 percent; 84 percent of the flagged programs and the whole or-saturation tail gone. F8 at 30 of 64 seeds: nine over 1.2x of the window model (p31 29.3x, p11 5.5x, p19 3.3x, p6 3.1x, p23 2.0x, the rest 1.3x to 1.6x); the 64-seed 1.2x gate is heading to FAIL on sub-version 1. Mechanism, confirmed on the two worst seeds: an all-ones load source (image 0x0ca59e4c under the era map) delivered through a writer the source rule counts as entropy-keeping, a rotate (rotl and rotr map all-ones to itself) or a load whose own source was saturated, with the saturation made one or more writes upstream by or. The rule looks one writer back; it must look through saturation-preserving writers or test the source's values. The ceiling has not moved: rule (c)'s 120-of-128 floor still caps any program at one saturated site, 6.25 percent of reads, a chip edge of at most 1.067x, and the residual (worst seed two sites at 0.53 and 0.56) sits inside it. THE SENTENCE "no lossy-sourced load by construction" IS HELD: it goes in no plan row and no ledger entry as true; sub-version 1 removes the or-source class and bounds the rest. MAIN'S RULING (13:2x UK): 0.3.20 ships object byte 5 on sub-version 1 as it stands, strictly better than the old stream the live floor flips to on 13 October; the fix is sub-version 2 on ca3-v4-amend (object byte 6 or whatever the v5 alignment leaves free) with both fixes: (F1) the static rule made transitive (rotates do not keep entropy; a load keeps entropy only if its own source did; one draw change, no attempts lost) and (F2) the dynamic source check (saturated load SOURCE values counted per site over the 64 units' 16,384 evaluations, rejected above 163 of 16,384, the same 1 percent the final-value rule uses; costs attempts on about 0.2 percent of seeds; rides with F1 because an or-written source is all-ones only (3/4)^32 of the time). Gate before sub-version 2 is proposed, run by the attack-pass lane and not by the hash lane: the full 64-seed census under 1.2x on every seed and the hot-set census. Hash lane's estimate about an hour its side (implement, re-export seven packs, vectors, crate suite, pairing, one G1 on PC 2) plus the node lane's vector re-pin and the attack-pass re-gate. The flip floor for sub-version 1 is expected to move (Josh's word) so the chain never flips to a stream that fails this gate. Also recorded: the crate suite at 8c728ca3 100 of 100 on the box (rc 0, 77 s); the pairing against the fork at dc141409 compiled and ran 15 of 16, the one failure the fork's own pre-amendment assertion (base equals v3's, igneum.rs:972), which 8097d600 on the release-0.3.20-node line turns into assert_ne; the pairing re-runs at b7cc37e7, its line to follow. CORRECTION (the attack-pass lane's own retraction, 13:3x UK): the F9 hot-set figures above (1,871 of 1,000,000, worst 9.66 percent, 84 percent removed, the two or-then-rotate listings) are WITHDRAWN: F9's harness draws through candidate_class with its own era class, outside candidate_from_words_class where the source rule lives, so it measured the old stream (the 8c728ca3 binary prints the identical program to the sub-version-0 binary for its worst seed). F8's 64-seed census on the chain path (pairing verified on 1a4230699a6b9c60) is the valid re-gate and STANDS: at 30 of 64 seeds, nine over 1.2x of the window model (p31 29.3x, p11 5.5x, p19 3.3x, p6 3.1x, p23 2.0x, p4 1.6x, p10 1.5x, p26 1.3x, p25 1.3x). The residual mechanism on the amended stream: a load-after-load chain (a saturated source reads one fixed word, which is the next load's address), admitted because a load injects; and the rotate-preserves-saturation path (generator.rs sets entropy_kept true for a rotate whatever it rotated), correct in code and a second admitted path if it occurs on the chain stream. Sub-version 2 must close both: dataflow freshness per register (a load fresh only if its source was fresh; add, sub, xor, mad, shfl fresh if either operand was; rotates only if the operand was; or, mul, mulhi never) plus the (c') count of saturated load sources per site as the backstop. The STOP holds on F8's evidence alone; the options and the 1.067x ceiling are unchanged. The sentence "no lossy-sourced load by construction" waits on the sub-version 2 census verdict and stays out of every public text until then. SUB-VERSION 2 IN BUILD (the hash lane, ca3-v4-amend, on the coordinator's direction, 13:4x UK): F1 (dataflow freshness per register, keyed on the class v4 shape on every draw path, era or not, so the candidate_class path and the chain path draw one stream) plus F2 (the (c') count of saturated load source values per site over the 64 units' 16,384 evaluations, rejected above 163, keyed on the same shape so v2 and v3 verdicts do not move); PROGRAM_SUBVERSION_V4 = 2, new ids, the seven packs re-exported, recheck.rs with 1a4230699a6b9c60 and c120d7963abdcd96 as the must-differ pair. Clock (UTC): the commit on the branch by 13:30; the crate suite on box 2 and the pairing against b7cc37e7 by about 13:50 (the pairing's vector test fails on the fork's sub-version-1 pin until the node lane re-pins; the compile and the other 15 are the pairing evidence); the G1 job on PC 2 under --cards-off by about 14:10, lock permitting; then the attack-pass lane's full 64-seed census and hot-set census on the chain path. Two consequences stated in the commit: the rule on every draw path moves the no-era sh256xN ladder packs' stream (packs-ca3-shadow's seven 256-block packs re-export with new fingerprints; the measured rates stand as the old stream's), and the class v5 lane's pinned string-seed packs move when it merges sub-version 2, so it re-exports them then. 0.3.20's sub-version-1 packs, ids and fingerprints untouched. OBJECT BYTES SETTLED (main, 13:5x UK): byte 5 = class v4 sub-version 1 (0.3.20), byte 6 = class v5 (pinned: class-v5 16afd0a0, class-v5-node 699db5a2, the flip case passed on 6,6,6; the v5 lane stopped), byte 7 = class v4 sub-version 2; the node and hash lanes told. b7cc37e7's MIXED-VERSION GATE: FAIL, the binary not the harness (12:16:39Z to 12:27:21Z, sha256 bc28331abf21f4d5, the string read back). Before the restart step everything held: one digest b0afb2ee on all five nodes, 268 new and 392 old blocks accepted, 0 rejected, header versions plain 2, counts equal on all five at 324 and 502 through both clean joins. At the new node's restart (12:24:19Z) it died at once on its own datadir ("IO error: While lock file: .../datadir/meta/LOCK: Resource temporarily unavailable", conn_builder.rs:167): the previous process was still shutting down, because the listener watchdog added on 6a3432a3 sleeps its whole 10 s poll before checking shutdown, so every node on the line since then takes up to 10 s longer to stop than 0.3.17 (the fleet saw the same shape as "a 12-second timeout does not stop the node"). Three of the four failed checks follow from that one death (counts, the restarted node's resync, the node it served frozen at 502). The fix on the line, one rule: the poll in 250 ms steps returning the moment shutdown is set, with a test that a shutdown returns within a second (the 10 s loop the known-failed shape); the exec suite on build-2, the fifth commit and its build about 12:45Z, its digest and ten-minute gates about 12:50 to 13:05Z, inside 14:30Z. b7cc37e7 is NOT the pin. The node-side re-pin for sub-version 2 (byte 7) once the hash lane's commit lands: the beside-the-fork igneum-pow copy archived from the commit, the two pinned ids moved in the kaspa-pow vector test (sub-version-2's epoch-0 id must-equal; sub-version-1's joins c120d7963abdcd96 as must-differ), CLASS_SIGNAL and tests for byte 7, the daemon's window line: about 20 minutes of edits plus one kaspa-pow suite run on build-2 (about 2 minutes). THE FIFTH COMMIT c4459193 on release-0.3.20-node (b7cc37e7's child, the watchdog poll returning on shutdown; the diff is the poll loop in rpc.rs alone), pairing igneum-pow 8c728ca3; its build on build-1 started 12:30:13Z, sha256 and string to follow. Line A, the shutdown test: rpc::watchdog_tests::a_shutdown_returns_within_a_second_whatever_the_poll green on build-2 at 12:29Z in the exec suite's 31 passed, beside the two other watchdog tests; its known-failed shape the old loop's 10 s stop. Line B, the kept-datadir start: b7cc37e7's fleet read carries to c4459193 since the store code is byte-identical between the two commits; the fleet re-reads on the c4459193 binary only if the shipper's rule wants the string on that line too. The digest gate and the ten-minute mixed-version gate on c4459193's own binary follow its build. THE SHIPPER'S CARRY RULING (14:1x UK): b7cc37e7's kept-datadir read stands as evidence that the store fix is right (the store code byte-identical) but is not the gate line for the pin, because the rule reads the binary, not the diff, and the binary changed (rpc.rs); the gate line is the kept read on c4459193's own binary with its string, which the fleet's canary already runs on c18-1 (wipe, then the kept read, then the restart) before the canary's restart step, at no extra cost; no re-read on p12-vast. THE PIN IS c4459193 pairing 8c728ca3 (object byte 5, sub-version 1); sub-version 2 (byte 7) is 0.3.21's, not 0.3.20's. The shipper's reading of main's F8 ruling: 0.3.20 ships object 5 as it stands because the live floor otherwise flips every node to the OLD stream on 13 October, and the 16:00 BST report tells Josh the floor move is now RECOMMENDED rather than optional, so the chain never flips to a stream that fails the 1.2x gate before sub-version 2 lands. THE FLEET'S CLOCK ON c4459193 (the fleet lane, 12:5x UTC): the kept read on pool-1's 0.3.17 datadir copy and the restart (the old process's stop time on the line) run on c18-1 before the wipe, a few minutes each, so both lines land before 14:30Z; the wipe canary (IBD from the pruning-point proof, 98 minutes on this pod class) starts when c18-1 is free of the 0.3.20 cases (about 13:00Z) and the binary is in hand, so its synced line lands about 14:40Z at the earliest, PAST the 14:30Z checkpoint; the 12 GB settled-claim line: c4459193 starts on p12-vast's kept copy of pool-1's datadir beside the 6a3432a3 IBD node on alternate ports the moment the binary lands, catches up from 129,398 blocks (15 to 20 minutes) and the 12 GB prover claims against it, the line on c4459193 itself. The binary not yet in the fleet's hand (build-1 building since 12:30:13Z); a wait armed on the sha and string, a report by 13:10Z if nothing. THE SHIPPER'S CALL ON THE CLOCK (14:2x UK): the wipe canary is the decisive read by the deploy rule; the pin never cuts without it and b7cc37e7's lineage does not stand in (the binary changed). The fleet rents a second one-shot pod of c18-1's class now and starts the wipe canary on c4459193's binary the moment the build lands, synced line about 14:15Z (15:15 BST), inside the checkpoint; c18-1 keeps the 0.3.20 cases and the pool window. If the wipe line slips past 15:30 BST the pin holds to it and main hears the clock (a slip is a report, not a cut). The set: the node lane's digest and mixed-version gates (12:50 to 13:05Z), the kept read and restart on the new pod, the wipe line on the new pod, the 12 GB settled-claim line on p12-vast. c4459193's BINARY IN THE FLEET'S HAND (12:34:54Z from build-1): igneumd sha256 45be9b02d1b002f5486d0f0108571c3b6042094113ad9da6f3d3d9ffc0072bba with the string c4459193 read back from the file, igneum-miner c7cfc40bc8b0e357. The wipe pod c19-1 (RunPod wpuke4tfu0vr49, RTX 3070 community, c18-1's class, USD 0.13/h, rented 12:37:03Z, one-shot; the day at USD 124 of work plus the 248 leak, 37 percent of the ceiling): the canary form (wipe, IBD from the pruning-point proof, synced, ten minutes mining with the exec poller, the hub read, the restart read) starts the moment the pod answers ssh; the kept read on pool-1's 0.3.17 copy armed behind its synced line on the same pod; the IBD start stamp its own line; synced about 14:20Z if the pod answers by 12:42Z (ten minutes inside the checkpoint), a slip reported the moment a poll shows it. CASES END on c18-1 at 12:37:18Z rc 0 (the relay and poison lines to the shipper); c18-1 and the two case pods destroyed by the run; the ten-member pool window rented its ten at 12:37:36Z. The 12 GB settled-claim line on p12-vast runs against a c4459193 node on the pod's kept copy, up since 12:36:35Z first-try, catching up. THE INTEROP FACT stands from the void run: the 5899f603 hub accepted 235 object-byte-5 blocks from the 8097d600 node with 0 rejected, one digest on all five nodes on the live sixteen-field file. The gates: the digest test and the kaspa-pow vector test (the amended devnet epoch-0 id 1a4230699a6b9c60 must equal, c120d7963abdcd96 must differ, the v3 control unchanged) on the box; the mixed-version Devnet 2 gate (the amended 0.3.20 node beside a 5899f603 node for ten minutes on the live file without the v4 fields) after the Mac build; the fresh-join canary the 0.3.20 cut's | | Main's rulings (7 October, morning) | no generator change to v4 on the live devnet; the record's null is the window model with numbers, sent by the hash lane to the attack-pass lane so AP-F8-1 re-gates against it; a fault beyond the model (a low-entropy source at site 15) stops at the coordinator with the two options priced (a 0.3.19 class amendment before the flip, or the flip held at the floor), nothing shipping without Josh's word; the tighter tail, an acceptance bound on the hot-set share, is a CLASS V5 item (sent to the v5 lane a6410f3b8abefb762 with the 64-seed census as its gate; the bound's number follows from the model) | ### AP-F4-1, the weak-day MUL draw (the attack-pass lane, 7 October, morning): PASS against v4, a class v5 rule From c31da40dfbe9fb40525c9cf28863c5daef7d0c33 Mon Sep 17 00:00:00 2001 From: igneum-josh <337424239+igneum-josh@users.noreply.github.com> Date: Wed, 7 Oct 2026 13:40:00 +0100 Subject: [PATCH 06/19] Counter ASIC 3.0 status: the wipe canary on c19-1 started 12:38:55Z, synced about 14:17Z Co-Authored-By: Claude Fable 5.1 --- docs/plans/counter-asic-3-status.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/plans/counter-asic-3-status.md b/docs/plans/counter-asic-3-status.md index 0bb524425..12b487061 100644 --- a/docs/plans/counter-asic-3-status.md +++ b/docs/plans/counter-asic-3-status.md @@ -338,7 +338,7 @@ Josh gave the go in advance for tonight: the shipper runs publish 1 on the 0.3.1 | THE ANALYSIS (the hash lane, ca3-v4-uniform 095f84a7, `docs/analysis/ca3-v4-uniform.md`, the tool on igneum-build-1) | the window model moves the null from 0.115 to 0.160 percent (1.39x, not 4.05x); the rest is a FAULT beyond it: site 15 reads a register last written by `or r6, r4`, so all-ones recurs at (3/4)^32 per read and the era map sends it to F8's hottest item exactly (the popcount model predicts 77,348 all-ones reads against 78,479; the top-0.1-percent share 0.58 against 0.52); it passes the acceptance rule because part (a) takes any write as a fresh source and part (c) counts saturation on final values only. The census of 1,024 chain-shaped v4 programs: 96.6 percent carry a lossy-sourced load (or, mul, mulhi as the last writer), 48.5 percent an or-sourced one (0.30 percent of all reads per site), 4.9 percent an or-of-or chain (4.6 percent of all reads on 0.1 percent of items); F8's 1.2x gate fails 96.6 percent of today's programs. Worth to a chip: 1.07 MB of SRAM ($0.25) serving 0.52 percent of a typical program's reads and 4.6 percent of the worst class's, at most 1.005x and 1.048x in rate; the ceiling under rule (c)'s 120-of-128 floor one site repeating its item in all 8 iterations, 6.25 percent of reads, 1.067x in 64 bytes; the 2x margin stands; the public line says "bounded at 1.067x", not "uniform" (the public text corrected) | | The two options, priced, STOPPED at the coordinator for Josh's word | A: a 0.3.19 class amendment before the flip (the generator draws a load's source from the registers whose last writer injects): a new program stream, new vectors, the seven gate packs re-exported, the six gates again (G1 to G3 and the verifier about an hour on the Mac and PC 2; G4 to G6 the node lane), every node before the flip under the one-box-at-a-time rule; the risk a node that misses the build splits the chain at the flip. B: hold the flip at the floor with v4 as it is; the bound documented; the source rule to class v5: a hot set worth up to 1.005x on about half the hours and 1.05x on 5 percent, 1.067x at the ceiling; no chain risk. The number: 1.067x at the ceiling against the 2x margin. The lane recommends B | | The v5 bound (sent to the v5 lane) | H = W_0.1 (the window term, 0.115 to 0.251 percent) + the sum over load sites of h(last writer) (or 0.30 percent, an or chain 4.5, mul 0.067, mulhi 0.049, an injecting op or a rotate 0), H at or under 1.2 x W_0.1, which is the static rule "every load's source was last written by an injecting op or a rotate"; as a rejection it costs 96.6 percent of candidates (about 30 attempts per seed), as a generator draw nothing; gate F8's 64-seed census with the saturated-source count | -| JOSH'S WORD (15:2x UK, 7 October): OPTION A, "do this but limit the testing, get it pushed" | the class v4 amendment: a load's source drawn only from registers whose last writer injects or is a rotate (the v5 rule applied now), a new program stream and vectors, the seven gate packs re-exported, the amended class with its own generator stamp; rides 0.3.20, the feature node (release-0.3.20-node = dc141409; 0.3.19 is an app-only cut with nothing of ours), on the shipper's line. The rollout arithmetic for the flip clock (the shipper): the standing fleet's one-box-at-a-time rollout took 32 minutes for 14 boxes (04:56 to 05:28Z, 7 October), the hands and the seed about 3 minutes after the miners, the Mac and the PCs within minutes of the publish; every 0.3.20 worker must accept the amended stamp before any flip. Owners: the hash lane (ca3-v4-amend: the generator, the vectors, the packs, the pairing on the box, one G1 run on PC 2, the ledger row), the node lane (release-0.3.20-node: the stamp agreed with the hash lane, the split-protection mechanism and the earliest flip time, the digest test, the mixed-version Devnet 2 gate), the attack-pass lane (the F8 census at 2^24 on the new stream, the gate 1.2x of the window model over 64 seeds), the shipper (the cut, the rollout order that sets the earliest flip). Testing limited to what prevents a split and proves the fix; G2, G3, the ladder re-measure and the rest of G4 to G6 OWED. THE STAMP agreed (the node and hash lanes, 7 October afternoon): generator 4 with sub-version 1 inside igneum-pow's id function, so the amended v4's program id for a seed differs from the old v4's (the old devnet epoch-0 id c120d7963abdcd96 pinned as the must-differ vector in kaspa-pow's test). SPLIT PROTECTION SETTLED (the node lane, plan section 6.6, ca3-v4-node fa5bc9e6; the node side on release-0.3.20-node): a fresh object byte. CLASS_SIGNAL_V4 is 5; the amended binary stamps 5 and the tally counts a block only at byte 5 or above; object 4 was stamped only by the unpublished dc141409 canary, so no published block carries it and a byte-4 block never counts; a node of the 6 October stream that sees byte 5 counts it as v4 (its rule is at least 4), flips to its own stream at the same epoch and forks ALONE (its blocks fail the amended id check, generator 4 sub-version 1 inside every id; the amended blocks fail its own), ours to upgrade in the sweep; object 6 is class v5's; the two holds already in the rule keep the window shut until every node is on 0.3.20 (a node stamps and tallies only with both v4 fields in its file; the fields publish only after the one-sweep rollout); a lagging worker refuses the amended pack at packcheck and mines nothing after the flip, costing that box, never the chain; no extra window hold: seven full day-windows are the hold. THE EARLIEST FLIP (approximate, measured 09:40Z: DAA 270,659, 1.095 DAA/s over 25 hours, 1.165 over 4; epoch 3,600, lead 600; seven windows 604,800 DAA wholly after the sweep's end D_s = T + about 40 minutes; the flip epoch the first e with 3600 e - 600 >= D_s + 604,800): T + 6 days 10 hours to T + 6 days 11 hours UK; for a publish at 12:00 UK on 7 October, 13 October between 22:20 and 23:10 UK (about 13:00 UK if the 4-hour rate holds). The floor as it stands (831,600, about 13 October 09:00 UK) would fire before any seven-window signal from a publish today completes, so it moves by the 0.3.16 rule to the publish DAA + 604,800 rounded up to the epoch boundary (882,000 for a 12:00 UK publish), firing about 30 minutes before the earliest signal flip: either way about 6 days 10 hours after the publish, never before every node has had the sweep plus a week. THE CLOCK (the node lane, 11:3x UK, after a Mac reboot moved its runs to the box): the 0.3.20 node line (dc141409 plus the proof archive aea0ca5c plus the amended v4 at object byte 5, igneum-pow at the hash lane's a0aaca92 beside the fork on the box) tested on the box, committed on release-0.3.20-node, pushed to the mirror and origin, igneumd and igneum-miner built, the tip to the shipper: about 12:00 UK; the mixed-version Devnet 2 gate (node-compat.mjs on the box, the amended node beside the 5899f603 pair for ten minutes) and the digest test (digest-compat.mjs): about 12:45 UK; the object-byte pin 5 unless the v5 lane answers both lanes with another assignment (v5 at 6 proposed). THE HASH SIDE on ca3-v4-amend (tip 8c728ca3, read from the branch 14:0x UK; the hash lane's own report pending): 1748fd1d the PC 2 G1-only playbook; e1f48d63 the fud-ledger entry AP-F8-1 (the fault, Josh's ruling, the amendment, the split protection, the owed tests); d8859522 the G1 line (the eight fingerprints equal on the RTX 5090, self-test PASS) and the node lane's signal byte 5; 4aa0c665 the v4 unit test following the amendment; 965d9e96 igneum-pow taken from release-0.3.20's 3f1652bf (the ladder's chain_program_shadow with the reps argument, never on master) with the amendment re-applied, the seven packs re-exporting byte-identical; 8c728ca3 the source rule keyed on the class with the shadow's pass count set aside, so every ladder rung draws under it (the fork's ladder test). The shipper took this igneum-pow tree into release-0.3.20 (00249643, byte-equal); nothing after 8c728ca3 touches igneum-pow. THE VECTORS AND THE PACKS (read from the branch and its ledger entry, 14:1x UK): the seven amended v4 packs (v4-devnet-epoch0, v4-era-0 to 5) carry generator 4, sub-version 1, one program id 1a4230699a6b9c60 (the 2.0 one-id-per-seed rule across the eras; the old c120d7963abdcd96 pinned as must-differ); the v3 control mx8-devnet-epoch0 untouched (73bcbfe8ccf988f1, fingerprint 90f794dd556f7a3b); the seven 2^24 fingerprints, Metal equal to Apple OpenCL: 867dbc45cfb36b4d, 2146ecacc8c75a8e, fe52602393f6d3d4, 3b206471a13912b4, c3f03c4a5d7333aa, f1dfd7209f15bb97, 8c194da64fadf31d; the zip of the eight packs sha256 889ec99976d2728b4b5035bfa476032e5b6a13b928968fc45236d5f25084aa39; the per-pack vectors.json sha256 prefixes 756301bf (devnet epoch 0), 1b5f4568, d430cadc, 1a1b21d8, 460fff9e, 4a85d49d, f83a1196 (eras 0 to 5). G1 on the RTX 5090 (PC 2 job run-ca3-v4-amend-g1-pc2-20261007, 09:41:07 to 09:41:28Z, exit 0, the installed worker): every fingerprint equal to the Mac's (the seven above and the control), NVRTC 188 to 332 ms per pack, the 1 GiB build 38 to 49 ms. hash-gates.md's older table still lists the pre-amendment fingerprints (f410c731... and the eras), which no longer apply to the amended packs; the ledger entry is the record. THE FIRST GREEN (11:31 UK, the box): the kaspa-pow suite on release-0.3.20-node (dc141409 plus the proof archive aea0ca5c plus the object-5 change) against the hash lane's igneum-pow 8c728ca3: 17 passed, 0 failed; the amended devnet epoch-0 id 1a4230699a6b9c60 pinned equal and c120d7963abdcd96 differing, the ladder's rung test green under the rekeyed rule, the v3 control unchanged; the consensus-core and exec RPC suites follow, then the node line (commit, push, box build, the tip to the shipper), then the digest and mixed-version gates. CLOCK RE-CUT (the node lane, 13:0x UK): the node line now carries, beside the object-5 change and the vector test, the lane's 0.3.20 fixes from the day (isSynced from the hook's stamp, the lazy template snapshot, the weight-table cache, the submit path returning after the block task, the watchdog, the RPC fields), about 13:30 UK if the box suites are green; the shipper's fresh-join canary 60 to 100 minutes after the cut; PC 1 as its first machine about 16:00 UK at the earliest, approximate until the shipper names the cut; the earliest flip about 6 days 10 hours after the publish. BUILD-2 LINES (12:28 to 12:33 UK): consensus-core 123 passed (the 60x file test green with the ladder window and activation pinned), the behind test green, kaspa-pow 17 passed (the amended vectors, earlier on build-1), the exec RPC suite green, the flows and rpc-service checks green with the submit-path change; the 24-requester latency test's first run tripped an unrelated flapping-fork double insert (24 equal forks from one parent; the test now builds on the sink as a real miner does; the double insert owed to a small fork harness before it is called a bug); THE NODE LINE COMMITTED (13:1x UK): release-0.3.20-node = 8097d600 (dc141409 + the proof archive aea0ca5c + one commit) on the mirror, pairing igneum-pow 8c728ca3, the hash with the shipper; in it the amended class v4 as object 5 (CLASS_SIGNAL_V4 = 5, byte 4 never counts, the kaspa-pow vector test pinning 1a4230699a6b9c60 equal and c120d7963abdcd96 differing, the daemon's window line naming object 5 and sub-version 1) beside the day's fixes (isSynced from the hook's stamp, the weight-table cache, the lazy snapshot, the submit path, the 100 ms template wait); the suites green on build-2 (consensus-core 123, the exec RPC suite, the four finality tests including 24 requesters under 200 ms: the worst template 100 ms, the worst submit 102 ms) and kaspa-pow 17 on build-1. Next: igneumd and igneum-miner building from 8097d600 on build-1, then the two gate lines (the mixed-version Devnet 2 gate: the 8097d600 node mining beside the 5899f603 pair for ten minutes on the live file without the v4 fields, the old node accepting every block; the digest test: the thirteen-field file b18ed271 unchanged, the sixteen-field object re-read on the 8097d600 binary), expected about 13:30 UK; the shipper picks the cut point. THE DATE FIXED (the node lane, from the hub's live file, 13:3x UK): publish 2 of 6 October (22:49:45Z, digest eada4bda) already put BOTH v4 fields on the live devnet (floor 831,600, window 86,400), so the 0.3.17 fleet has stamped object byte 4 since 7 October 00:2x UK and the floor is live at about 13 October 09:00 UK, before any seven-window signal completes; a 0.3.17 node left on that file flips to the OLD v4 stream at epoch 231 whatever anyone signals, a 0.3.20 node to the amended stream at the same epoch, and the two never share an id, so each straggler forks alone there. REQUIREMENT for the 0.3.20 publish (with the shipper and main): a new file with the floor at the publish DAA + 604,800 rounded up (about 882,000 for a publish today), the digest moving, the one-sweep rollout replacing every 0.3.17 node before 13 October 09:00 UK; any node that misses the sweep is alone then; the earliest flip after that about 6 days 10 hours past the publish; plan section 6.6 amended today. IN THE 0.3.20 PLAN (the shipper, 13:4x UK): both requirements; the node pin by main's rule is the node lane's second commit (the claim floor, the listener watchdog, the claim RPCs, on top of 8097d600) if its suites, both gates and the fleet's 12 GB prover line are green by 15:30 UK, else 8097d600; igneum-pow 8c728ca3 either way; the digest read on whichever binary pins. THE LINE AT 13:5x UK: three commits on release-0.3.20-node, 8097d600 (the object-5 amended class v4 and the day's fixes), 6b94c823 (test-only: the stale PC 1 test from 500ddd66 inverted by the isSynced ruling; the FALLBACK pin, code byte-identical to 8097d600, so the module reads green whole) and 6a3432a3 (the app lane's key methods, the observer's claims, the settled claim floor, the listener watchdog); suites on build-2 on 6a3432a3's code (the whole finality module 25, the exec suite 29 with the watchdog test, the kaspad, flows and rpc-service checks; consensus-core 123 and kaspa-pow 17 earlier); the cut 6a3432a3 if its gates and the fleet's 12 GB settled-claim line are green by 15:30 UK, else 6b94c823; both binaries building on build-1, the two gates (the digest gate, then the ten-minute mixed-version gate beside the 5899f603 pair) on the 8097d600 build, lines about 14:05 UK. GATE NEWS (13:53 UK): on 6a3432a3's own digest gate the listener watchdog counted a bind failure (the four harness nodes share one exec JSON-RPC port) as a listener death and exited three of four nodes at 20 s, where 0.3.17 and 8097d600 only warn and live without the exec RPC; the digest facts came out first and stand (the thirteen-field file a89be8a7 on both binaries, the compat case; the sixteen-field object db9a85f9 refused with the mismatch line, the refusal case); the ten-minute gate on 6a3432a3 stopped as void for the same cause. The fix: a bind failure is a retry every poll, one line a minute, no death counted and never an exit, with a second watchdog test whose known-failed shape is the old rule's exit on a held port; the third commit and its build about 14:15 UK, its gates about 14:35 UK; the fallback 6b94c823's gates on build-1 on their own binary (no watchdog there), lines about 14:20 UK; ledger row N12 for the bind-failure class. A ROLL BLOCKER on every kept datadir (the node lane, 14:1x UK, ledger N13): the fleet started 6a3432a3 on a kept 0.3.17 datadir (pool-1's copy) and it died at start (virtual_state.rs:250, DeserializationError(UnexpectedEof)); the cause 10db4b61 on the 0.3.16 feature line added `silent: bool` to BlockRewardData under serde(default), which bincode ignores, so every build from 10db4b61 on (dc141409, 8097d600, 6b94c823, 6a3432a3, 09124180) reads a 0.3.17 node's virtual-state row short; no canary saw it because every canary wiped, and a one-box roll keeps datadirs, so it blocks the roll on every standing box, the hands and the hub whatever the pin. The fix on the line: the store reads the current layout first and on a deserialization error decodes the row as a v1 mirror, converts with silent false and rewrites it under the same key, with the known-failed test first; the fourth commit and build about 14:40 UK, the fleet's kept-datadir start on the fixed binary about 14:50 UK, its gates after. THE RULE IT ADDS for every node cut from now: a kept-datadir restart gate on a standing box's datadir copy beside the wiped canary. THE CANDIDATE PIN (14:2x UK): b7cc37e7 (8097d600, 6b94c823, 6a3432a3, 09124180, b7cc37e7; igneum-pow 8c728ca3): the N13 fix with its test green on build-2 at 14:04 UK and the kaspad check green, the build on build-1; the fallback 6b94c823 is no longer a pin for the one-box roll (it dies on a kept datadir like every build since 10db4b61): if b7cc37e7's gates are not green by 15:30 UK the honest fallback is 0.3.17's 5899f603 staying live. In flight on build-1: the earlier commits' gates, then b7cc37e7's own digest and ten-minute mixed-version gates on its binary with the read-back, lines about 15:05 UK; on the fleet the kept-datadir start on b7cc37e7 about 14:50 UK and the 12 GB settled-claim line 14:50 to 15:00 UK. Plan section 6.6 amended with the hard date (ca3-v4-node 9d763edd, merged to master); N12 and N13 on the ledger. THE GATES ON THE FALLBACK'S OWN BINARY (6b94c823, sha b1b7d47b, 13:56 to 14:08 UK; code byte-identical to 8097d600, so the amendment's node side): the digest gate, the thirteen-field file a89be8a7 on both binaries (the compat case, n0 peering n1 and n2) and the sixteen-field object db9a85f9 refused with the mismatch line (the refusal case); the mixed-version gate, ten minutes, one digest b0afb2ee on all five nodes, the 5899f603 hub accepting every block the amended node mined (146 new, 246 old, 0 rejected), plain header version 2 on the thirteen-field file, counts equal on all five through the two clean joins and the restart. Two FAILED checks, both the harness's own and fixed (36d3efdc): a refused peer's count read 1 with the reconnect in flight (now the minimum of five), and six address-in-use panics in the two old nodes because the second gate reused the first's ports the second they were sent SIGTERM (a 20 s gap now). CLOCK CORRECTION (the node lane, 12:12Z = 13:12 BST): every "UK" stamp it sent today was the box's CEST, an hour fast of BST; its lines read UTC from now. Restated: b7cc37e7's build about 12:15Z, its digest and mixed-version gates on that binary with the sha and string about 12:32Z (13:32 BST), the fleet's kept-datadir start on it about 12:25Z, its 12 GB settled-claim line 12:50 to 13:00Z; the shipper's checkpoint 14:30Z (15:30 BST), two hours of room. The 13 October date stands (derived from UTC DAA rates): the floor 831,600 about 08:00Z, 09:00 BST. b7cc37e7'S OWN LINES (binary sha256 bc28331abf21f4d5, the string read back on build-1 and on the fleet's pod): the digest gate 12:14:39Z to 12:16:18Z SUMMARY PASS (thirteen fields a89be8a7 on both binaries with the peers as the gate wants them; the sixteen-field object db9a85f9 refused with the line and no peer; the live file's digest eada4bda on the binary, unmoved); the kept-datadir start on the fleet's copy of pool-1's 0.3.17 datadir: the first start 12:17:12Z reads the v1 row through the mirror and rewrites it ("1 mergeset rewards"), the finality blob converts (1,747 locks), the node comes up on its ports with no panic; the second start 12:18:53Z reads first-try with no rewrite line and no panic; 6a3432a3's death on the same copy is the known-failed shape. The ten-minute mixed-version gate beside the 5899f603 pair runs on the same binary since 12:16:39Z, its line about 12:28Z; then the only line outstanding for the shipper's 14:30Z rule is the fleet's 12 GB settled-claim line, 12:50 to 13:00Z. AP-F8-1 RESIDUAL CLASS ON THE AMENDED STREAM (attack-pass lane 12:18Z on igneum-pow 8c728ca3, sub-version 1). F9 over 1,000,000 seeds: programs flagged (hot share at least 1 percent or 7 constant address bits) 1,871 (0.19 percent) against 11,696 (1.17 percent) unamended; worst hot share 9.66 percent against 17.3; mean 0.011 against 0.063 percent; 84 percent of the flagged programs and the whole or-saturation tail gone. F8 at 30 of 64 seeds: nine over 1.2x of the window model (p31 29.3x, p11 5.5x, p19 3.3x, p6 3.1x, p23 2.0x, the rest 1.3x to 1.6x); the 64-seed 1.2x gate is heading to FAIL on sub-version 1. Mechanism, confirmed on the two worst seeds: an all-ones load source (image 0x0ca59e4c under the era map) delivered through a writer the source rule counts as entropy-keeping, a rotate (rotl and rotr map all-ones to itself) or a load whose own source was saturated, with the saturation made one or more writes upstream by or. The rule looks one writer back; it must look through saturation-preserving writers or test the source's values. The ceiling has not moved: rule (c)'s 120-of-128 floor still caps any program at one saturated site, 6.25 percent of reads, a chip edge of at most 1.067x, and the residual (worst seed two sites at 0.53 and 0.56) sits inside it. THE SENTENCE "no lossy-sourced load by construction" IS HELD: it goes in no plan row and no ledger entry as true; sub-version 1 removes the or-source class and bounds the rest. MAIN'S RULING (13:2x UK): 0.3.20 ships object byte 5 on sub-version 1 as it stands, strictly better than the old stream the live floor flips to on 13 October; the fix is sub-version 2 on ca3-v4-amend (object byte 6 or whatever the v5 alignment leaves free) with both fixes: (F1) the static rule made transitive (rotates do not keep entropy; a load keeps entropy only if its own source did; one draw change, no attempts lost) and (F2) the dynamic source check (saturated load SOURCE values counted per site over the 64 units' 16,384 evaluations, rejected above 163 of 16,384, the same 1 percent the final-value rule uses; costs attempts on about 0.2 percent of seeds; rides with F1 because an or-written source is all-ones only (3/4)^32 of the time). Gate before sub-version 2 is proposed, run by the attack-pass lane and not by the hash lane: the full 64-seed census under 1.2x on every seed and the hot-set census. Hash lane's estimate about an hour its side (implement, re-export seven packs, vectors, crate suite, pairing, one G1 on PC 2) plus the node lane's vector re-pin and the attack-pass re-gate. The flip floor for sub-version 1 is expected to move (Josh's word) so the chain never flips to a stream that fails this gate. Also recorded: the crate suite at 8c728ca3 100 of 100 on the box (rc 0, 77 s); the pairing against the fork at dc141409 compiled and ran 15 of 16, the one failure the fork's own pre-amendment assertion (base equals v3's, igneum.rs:972), which 8097d600 on the release-0.3.20-node line turns into assert_ne; the pairing re-runs at b7cc37e7, its line to follow. CORRECTION (the attack-pass lane's own retraction, 13:3x UK): the F9 hot-set figures above (1,871 of 1,000,000, worst 9.66 percent, 84 percent removed, the two or-then-rotate listings) are WITHDRAWN: F9's harness draws through candidate_class with its own era class, outside candidate_from_words_class where the source rule lives, so it measured the old stream (the 8c728ca3 binary prints the identical program to the sub-version-0 binary for its worst seed). F8's 64-seed census on the chain path (pairing verified on 1a4230699a6b9c60) is the valid re-gate and STANDS: at 30 of 64 seeds, nine over 1.2x of the window model (p31 29.3x, p11 5.5x, p19 3.3x, p6 3.1x, p23 2.0x, p4 1.6x, p10 1.5x, p26 1.3x, p25 1.3x). The residual mechanism on the amended stream: a load-after-load chain (a saturated source reads one fixed word, which is the next load's address), admitted because a load injects; and the rotate-preserves-saturation path (generator.rs sets entropy_kept true for a rotate whatever it rotated), correct in code and a second admitted path if it occurs on the chain stream. Sub-version 2 must close both: dataflow freshness per register (a load fresh only if its source was fresh; add, sub, xor, mad, shfl fresh if either operand was; rotates only if the operand was; or, mul, mulhi never) plus the (c') count of saturated load sources per site as the backstop. The STOP holds on F8's evidence alone; the options and the 1.067x ceiling are unchanged. The sentence "no lossy-sourced load by construction" waits on the sub-version 2 census verdict and stays out of every public text until then. SUB-VERSION 2 IN BUILD (the hash lane, ca3-v4-amend, on the coordinator's direction, 13:4x UK): F1 (dataflow freshness per register, keyed on the class v4 shape on every draw path, era or not, so the candidate_class path and the chain path draw one stream) plus F2 (the (c') count of saturated load source values per site over the 64 units' 16,384 evaluations, rejected above 163, keyed on the same shape so v2 and v3 verdicts do not move); PROGRAM_SUBVERSION_V4 = 2, new ids, the seven packs re-exported, recheck.rs with 1a4230699a6b9c60 and c120d7963abdcd96 as the must-differ pair. Clock (UTC): the commit on the branch by 13:30; the crate suite on box 2 and the pairing against b7cc37e7 by about 13:50 (the pairing's vector test fails on the fork's sub-version-1 pin until the node lane re-pins; the compile and the other 15 are the pairing evidence); the G1 job on PC 2 under --cards-off by about 14:10, lock permitting; then the attack-pass lane's full 64-seed census and hot-set census on the chain path. Two consequences stated in the commit: the rule on every draw path moves the no-era sh256xN ladder packs' stream (packs-ca3-shadow's seven 256-block packs re-export with new fingerprints; the measured rates stand as the old stream's), and the class v5 lane's pinned string-seed packs move when it merges sub-version 2, so it re-exports them then. 0.3.20's sub-version-1 packs, ids and fingerprints untouched. OBJECT BYTES SETTLED (main, 13:5x UK): byte 5 = class v4 sub-version 1 (0.3.20), byte 6 = class v5 (pinned: class-v5 16afd0a0, class-v5-node 699db5a2, the flip case passed on 6,6,6; the v5 lane stopped), byte 7 = class v4 sub-version 2; the node and hash lanes told. b7cc37e7's MIXED-VERSION GATE: FAIL, the binary not the harness (12:16:39Z to 12:27:21Z, sha256 bc28331abf21f4d5, the string read back). Before the restart step everything held: one digest b0afb2ee on all five nodes, 268 new and 392 old blocks accepted, 0 rejected, header versions plain 2, counts equal on all five at 324 and 502 through both clean joins. At the new node's restart (12:24:19Z) it died at once on its own datadir ("IO error: While lock file: .../datadir/meta/LOCK: Resource temporarily unavailable", conn_builder.rs:167): the previous process was still shutting down, because the listener watchdog added on 6a3432a3 sleeps its whole 10 s poll before checking shutdown, so every node on the line since then takes up to 10 s longer to stop than 0.3.17 (the fleet saw the same shape as "a 12-second timeout does not stop the node"). Three of the four failed checks follow from that one death (counts, the restarted node's resync, the node it served frozen at 502). The fix on the line, one rule: the poll in 250 ms steps returning the moment shutdown is set, with a test that a shutdown returns within a second (the 10 s loop the known-failed shape); the exec suite on build-2, the fifth commit and its build about 12:45Z, its digest and ten-minute gates about 12:50 to 13:05Z, inside 14:30Z. b7cc37e7 is NOT the pin. The node-side re-pin for sub-version 2 (byte 7) once the hash lane's commit lands: the beside-the-fork igneum-pow copy archived from the commit, the two pinned ids moved in the kaspa-pow vector test (sub-version-2's epoch-0 id must-equal; sub-version-1's joins c120d7963abdcd96 as must-differ), CLASS_SIGNAL and tests for byte 7, the daemon's window line: about 20 minutes of edits plus one kaspa-pow suite run on build-2 (about 2 minutes). THE FIFTH COMMIT c4459193 on release-0.3.20-node (b7cc37e7's child, the watchdog poll returning on shutdown; the diff is the poll loop in rpc.rs alone), pairing igneum-pow 8c728ca3; its build on build-1 started 12:30:13Z, sha256 and string to follow. Line A, the shutdown test: rpc::watchdog_tests::a_shutdown_returns_within_a_second_whatever_the_poll green on build-2 at 12:29Z in the exec suite's 31 passed, beside the two other watchdog tests; its known-failed shape the old loop's 10 s stop. Line B, the kept-datadir start: b7cc37e7's fleet read carries to c4459193 since the store code is byte-identical between the two commits; the fleet re-reads on the c4459193 binary only if the shipper's rule wants the string on that line too. The digest gate and the ten-minute mixed-version gate on c4459193's own binary follow its build. THE SHIPPER'S CARRY RULING (14:1x UK): b7cc37e7's kept-datadir read stands as evidence that the store fix is right (the store code byte-identical) but is not the gate line for the pin, because the rule reads the binary, not the diff, and the binary changed (rpc.rs); the gate line is the kept read on c4459193's own binary with its string, which the fleet's canary already runs on c18-1 (wipe, then the kept read, then the restart) before the canary's restart step, at no extra cost; no re-read on p12-vast. THE PIN IS c4459193 pairing 8c728ca3 (object byte 5, sub-version 1); sub-version 2 (byte 7) is 0.3.21's, not 0.3.20's. The shipper's reading of main's F8 ruling: 0.3.20 ships object 5 as it stands because the live floor otherwise flips every node to the OLD stream on 13 October, and the 16:00 BST report tells Josh the floor move is now RECOMMENDED rather than optional, so the chain never flips to a stream that fails the 1.2x gate before sub-version 2 lands. THE FLEET'S CLOCK ON c4459193 (the fleet lane, 12:5x UTC): the kept read on pool-1's 0.3.17 datadir copy and the restart (the old process's stop time on the line) run on c18-1 before the wipe, a few minutes each, so both lines land before 14:30Z; the wipe canary (IBD from the pruning-point proof, 98 minutes on this pod class) starts when c18-1 is free of the 0.3.20 cases (about 13:00Z) and the binary is in hand, so its synced line lands about 14:40Z at the earliest, PAST the 14:30Z checkpoint; the 12 GB settled-claim line: c4459193 starts on p12-vast's kept copy of pool-1's datadir beside the 6a3432a3 IBD node on alternate ports the moment the binary lands, catches up from 129,398 blocks (15 to 20 minutes) and the 12 GB prover claims against it, the line on c4459193 itself. The binary not yet in the fleet's hand (build-1 building since 12:30:13Z); a wait armed on the sha and string, a report by 13:10Z if nothing. THE SHIPPER'S CALL ON THE CLOCK (14:2x UK): the wipe canary is the decisive read by the deploy rule; the pin never cuts without it and b7cc37e7's lineage does not stand in (the binary changed). The fleet rents a second one-shot pod of c18-1's class now and starts the wipe canary on c4459193's binary the moment the build lands, synced line about 14:15Z (15:15 BST), inside the checkpoint; c18-1 keeps the 0.3.20 cases and the pool window. If the wipe line slips past 15:30 BST the pin holds to it and main hears the clock (a slip is a report, not a cut). The set: the node lane's digest and mixed-version gates (12:50 to 13:05Z), the kept read and restart on the new pod, the wipe line on the new pod, the 12 GB settled-claim line on p12-vast. c4459193's BINARY IN THE FLEET'S HAND (12:34:54Z from build-1): igneumd sha256 45be9b02d1b002f5486d0f0108571c3b6042094113ad9da6f3d3d9ffc0072bba with the string c4459193 read back from the file, igneum-miner c7cfc40bc8b0e357. The wipe pod c19-1 (RunPod wpuke4tfu0vr49, RTX 3070 community, c18-1's class, USD 0.13/h, rented 12:37:03Z, one-shot; the day at USD 124 of work plus the 248 leak, 37 percent of the ceiling): the canary form (wipe, IBD from the pruning-point proof, synced, ten minutes mining with the exec poller, the hub read, the restart read) starts the moment the pod answers ssh; the kept read on pool-1's 0.3.17 copy armed behind its synced line on the same pod; the IBD start stamp its own line; synced about 14:20Z if the pod answers by 12:42Z (ten minutes inside the checkpoint), a slip reported the moment a poll shows it. CASES END on c18-1 at 12:37:18Z rc 0 (the relay and poison lines to the shipper); c18-1 and the two case pods destroyed by the run; the ten-member pool window rented its ten at 12:37:36Z. The 12 GB settled-claim line on p12-vast runs against a c4459193 node on the pod's kept copy, up since 12:36:35Z first-try, catching up. THE INTEROP FACT stands from the void run: the 5899f603 hub accepted 235 object-byte-5 blocks from the 8097d600 node with 0 rejected, one digest on all five nodes on the live sixteen-field file. The gates: the digest test and the kaspa-pow vector test (the amended devnet epoch-0 id 1a4230699a6b9c60 must equal, c120d7963abdcd96 must differ, the v3 control unchanged) on the box; the mixed-version Devnet 2 gate (the amended 0.3.20 node beside a 5899f603 node for ten minutes on the live file without the v4 fields) after the Mac build; the fresh-join canary the 0.3.20 cut's | +| JOSH'S WORD (15:2x UK, 7 October): OPTION A, "do this but limit the testing, get it pushed" | the class v4 amendment: a load's source drawn only from registers whose last writer injects or is a rotate (the v5 rule applied now), a new program stream and vectors, the seven gate packs re-exported, the amended class with its own generator stamp; rides 0.3.20, the feature node (release-0.3.20-node = dc141409; 0.3.19 is an app-only cut with nothing of ours), on the shipper's line. The rollout arithmetic for the flip clock (the shipper): the standing fleet's one-box-at-a-time rollout took 32 minutes for 14 boxes (04:56 to 05:28Z, 7 October), the hands and the seed about 3 minutes after the miners, the Mac and the PCs within minutes of the publish; every 0.3.20 worker must accept the amended stamp before any flip. Owners: the hash lane (ca3-v4-amend: the generator, the vectors, the packs, the pairing on the box, one G1 run on PC 2, the ledger row), the node lane (release-0.3.20-node: the stamp agreed with the hash lane, the split-protection mechanism and the earliest flip time, the digest test, the mixed-version Devnet 2 gate), the attack-pass lane (the F8 census at 2^24 on the new stream, the gate 1.2x of the window model over 64 seeds), the shipper (the cut, the rollout order that sets the earliest flip). Testing limited to what prevents a split and proves the fix; G2, G3, the ladder re-measure and the rest of G4 to G6 OWED. THE STAMP agreed (the node and hash lanes, 7 October afternoon): generator 4 with sub-version 1 inside igneum-pow's id function, so the amended v4's program id for a seed differs from the old v4's (the old devnet epoch-0 id c120d7963abdcd96 pinned as the must-differ vector in kaspa-pow's test). SPLIT PROTECTION SETTLED (the node lane, plan section 6.6, ca3-v4-node fa5bc9e6; the node side on release-0.3.20-node): a fresh object byte. CLASS_SIGNAL_V4 is 5; the amended binary stamps 5 and the tally counts a block only at byte 5 or above; object 4 was stamped only by the unpublished dc141409 canary, so no published block carries it and a byte-4 block never counts; a node of the 6 October stream that sees byte 5 counts it as v4 (its rule is at least 4), flips to its own stream at the same epoch and forks ALONE (its blocks fail the amended id check, generator 4 sub-version 1 inside every id; the amended blocks fail its own), ours to upgrade in the sweep; object 6 is class v5's; the two holds already in the rule keep the window shut until every node is on 0.3.20 (a node stamps and tallies only with both v4 fields in its file; the fields publish only after the one-sweep rollout); a lagging worker refuses the amended pack at packcheck and mines nothing after the flip, costing that box, never the chain; no extra window hold: seven full day-windows are the hold. THE EARLIEST FLIP (approximate, measured 09:40Z: DAA 270,659, 1.095 DAA/s over 25 hours, 1.165 over 4; epoch 3,600, lead 600; seven windows 604,800 DAA wholly after the sweep's end D_s = T + about 40 minutes; the flip epoch the first e with 3600 e - 600 >= D_s + 604,800): T + 6 days 10 hours to T + 6 days 11 hours UK; for a publish at 12:00 UK on 7 October, 13 October between 22:20 and 23:10 UK (about 13:00 UK if the 4-hour rate holds). The floor as it stands (831,600, about 13 October 09:00 UK) would fire before any seven-window signal from a publish today completes, so it moves by the 0.3.16 rule to the publish DAA + 604,800 rounded up to the epoch boundary (882,000 for a 12:00 UK publish), firing about 30 minutes before the earliest signal flip: either way about 6 days 10 hours after the publish, never before every node has had the sweep plus a week. THE CLOCK (the node lane, 11:3x UK, after a Mac reboot moved its runs to the box): the 0.3.20 node line (dc141409 plus the proof archive aea0ca5c plus the amended v4 at object byte 5, igneum-pow at the hash lane's a0aaca92 beside the fork on the box) tested on the box, committed on release-0.3.20-node, pushed to the mirror and origin, igneumd and igneum-miner built, the tip to the shipper: about 12:00 UK; the mixed-version Devnet 2 gate (node-compat.mjs on the box, the amended node beside the 5899f603 pair for ten minutes) and the digest test (digest-compat.mjs): about 12:45 UK; the object-byte pin 5 unless the v5 lane answers both lanes with another assignment (v5 at 6 proposed). THE HASH SIDE on ca3-v4-amend (tip 8c728ca3, read from the branch 14:0x UK; the hash lane's own report pending): 1748fd1d the PC 2 G1-only playbook; e1f48d63 the fud-ledger entry AP-F8-1 (the fault, Josh's ruling, the amendment, the split protection, the owed tests); d8859522 the G1 line (the eight fingerprints equal on the RTX 5090, self-test PASS) and the node lane's signal byte 5; 4aa0c665 the v4 unit test following the amendment; 965d9e96 igneum-pow taken from release-0.3.20's 3f1652bf (the ladder's chain_program_shadow with the reps argument, never on master) with the amendment re-applied, the seven packs re-exporting byte-identical; 8c728ca3 the source rule keyed on the class with the shadow's pass count set aside, so every ladder rung draws under it (the fork's ladder test). The shipper took this igneum-pow tree into release-0.3.20 (00249643, byte-equal); nothing after 8c728ca3 touches igneum-pow. THE VECTORS AND THE PACKS (read from the branch and its ledger entry, 14:1x UK): the seven amended v4 packs (v4-devnet-epoch0, v4-era-0 to 5) carry generator 4, sub-version 1, one program id 1a4230699a6b9c60 (the 2.0 one-id-per-seed rule across the eras; the old c120d7963abdcd96 pinned as must-differ); the v3 control mx8-devnet-epoch0 untouched (73bcbfe8ccf988f1, fingerprint 90f794dd556f7a3b); the seven 2^24 fingerprints, Metal equal to Apple OpenCL: 867dbc45cfb36b4d, 2146ecacc8c75a8e, fe52602393f6d3d4, 3b206471a13912b4, c3f03c4a5d7333aa, f1dfd7209f15bb97, 8c194da64fadf31d; the zip of the eight packs sha256 889ec99976d2728b4b5035bfa476032e5b6a13b928968fc45236d5f25084aa39; the per-pack vectors.json sha256 prefixes 756301bf (devnet epoch 0), 1b5f4568, d430cadc, 1a1b21d8, 460fff9e, 4a85d49d, f83a1196 (eras 0 to 5). G1 on the RTX 5090 (PC 2 job run-ca3-v4-amend-g1-pc2-20261007, 09:41:07 to 09:41:28Z, exit 0, the installed worker): every fingerprint equal to the Mac's (the seven above and the control), NVRTC 188 to 332 ms per pack, the 1 GiB build 38 to 49 ms. hash-gates.md's older table still lists the pre-amendment fingerprints (f410c731... and the eras), which no longer apply to the amended packs; the ledger entry is the record. THE FIRST GREEN (11:31 UK, the box): the kaspa-pow suite on release-0.3.20-node (dc141409 plus the proof archive aea0ca5c plus the object-5 change) against the hash lane's igneum-pow 8c728ca3: 17 passed, 0 failed; the amended devnet epoch-0 id 1a4230699a6b9c60 pinned equal and c120d7963abdcd96 differing, the ladder's rung test green under the rekeyed rule, the v3 control unchanged; the consensus-core and exec RPC suites follow, then the node line (commit, push, box build, the tip to the shipper), then the digest and mixed-version gates. CLOCK RE-CUT (the node lane, 13:0x UK): the node line now carries, beside the object-5 change and the vector test, the lane's 0.3.20 fixes from the day (isSynced from the hook's stamp, the lazy template snapshot, the weight-table cache, the submit path returning after the block task, the watchdog, the RPC fields), about 13:30 UK if the box suites are green; the shipper's fresh-join canary 60 to 100 minutes after the cut; PC 1 as its first machine about 16:00 UK at the earliest, approximate until the shipper names the cut; the earliest flip about 6 days 10 hours after the publish. BUILD-2 LINES (12:28 to 12:33 UK): consensus-core 123 passed (the 60x file test green with the ladder window and activation pinned), the behind test green, kaspa-pow 17 passed (the amended vectors, earlier on build-1), the exec RPC suite green, the flows and rpc-service checks green with the submit-path change; the 24-requester latency test's first run tripped an unrelated flapping-fork double insert (24 equal forks from one parent; the test now builds on the sink as a real miner does; the double insert owed to a small fork harness before it is called a bug); THE NODE LINE COMMITTED (13:1x UK): release-0.3.20-node = 8097d600 (dc141409 + the proof archive aea0ca5c + one commit) on the mirror, pairing igneum-pow 8c728ca3, the hash with the shipper; in it the amended class v4 as object 5 (CLASS_SIGNAL_V4 = 5, byte 4 never counts, the kaspa-pow vector test pinning 1a4230699a6b9c60 equal and c120d7963abdcd96 differing, the daemon's window line naming object 5 and sub-version 1) beside the day's fixes (isSynced from the hook's stamp, the weight-table cache, the lazy snapshot, the submit path, the 100 ms template wait); the suites green on build-2 (consensus-core 123, the exec RPC suite, the four finality tests including 24 requesters under 200 ms: the worst template 100 ms, the worst submit 102 ms) and kaspa-pow 17 on build-1. Next: igneumd and igneum-miner building from 8097d600 on build-1, then the two gate lines (the mixed-version Devnet 2 gate: the 8097d600 node mining beside the 5899f603 pair for ten minutes on the live file without the v4 fields, the old node accepting every block; the digest test: the thirteen-field file b18ed271 unchanged, the sixteen-field object re-read on the 8097d600 binary), expected about 13:30 UK; the shipper picks the cut point. THE DATE FIXED (the node lane, from the hub's live file, 13:3x UK): publish 2 of 6 October (22:49:45Z, digest eada4bda) already put BOTH v4 fields on the live devnet (floor 831,600, window 86,400), so the 0.3.17 fleet has stamped object byte 4 since 7 October 00:2x UK and the floor is live at about 13 October 09:00 UK, before any seven-window signal completes; a 0.3.17 node left on that file flips to the OLD v4 stream at epoch 231 whatever anyone signals, a 0.3.20 node to the amended stream at the same epoch, and the two never share an id, so each straggler forks alone there. REQUIREMENT for the 0.3.20 publish (with the shipper and main): a new file with the floor at the publish DAA + 604,800 rounded up (about 882,000 for a publish today), the digest moving, the one-sweep rollout replacing every 0.3.17 node before 13 October 09:00 UK; any node that misses the sweep is alone then; the earliest flip after that about 6 days 10 hours past the publish; plan section 6.6 amended today. IN THE 0.3.20 PLAN (the shipper, 13:4x UK): both requirements; the node pin by main's rule is the node lane's second commit (the claim floor, the listener watchdog, the claim RPCs, on top of 8097d600) if its suites, both gates and the fleet's 12 GB prover line are green by 15:30 UK, else 8097d600; igneum-pow 8c728ca3 either way; the digest read on whichever binary pins. THE LINE AT 13:5x UK: three commits on release-0.3.20-node, 8097d600 (the object-5 amended class v4 and the day's fixes), 6b94c823 (test-only: the stale PC 1 test from 500ddd66 inverted by the isSynced ruling; the FALLBACK pin, code byte-identical to 8097d600, so the module reads green whole) and 6a3432a3 (the app lane's key methods, the observer's claims, the settled claim floor, the listener watchdog); suites on build-2 on 6a3432a3's code (the whole finality module 25, the exec suite 29 with the watchdog test, the kaspad, flows and rpc-service checks; consensus-core 123 and kaspa-pow 17 earlier); the cut 6a3432a3 if its gates and the fleet's 12 GB settled-claim line are green by 15:30 UK, else 6b94c823; both binaries building on build-1, the two gates (the digest gate, then the ten-minute mixed-version gate beside the 5899f603 pair) on the 8097d600 build, lines about 14:05 UK. GATE NEWS (13:53 UK): on 6a3432a3's own digest gate the listener watchdog counted a bind failure (the four harness nodes share one exec JSON-RPC port) as a listener death and exited three of four nodes at 20 s, where 0.3.17 and 8097d600 only warn and live without the exec RPC; the digest facts came out first and stand (the thirteen-field file a89be8a7 on both binaries, the compat case; the sixteen-field object db9a85f9 refused with the mismatch line, the refusal case); the ten-minute gate on 6a3432a3 stopped as void for the same cause. The fix: a bind failure is a retry every poll, one line a minute, no death counted and never an exit, with a second watchdog test whose known-failed shape is the old rule's exit on a held port; the third commit and its build about 14:15 UK, its gates about 14:35 UK; the fallback 6b94c823's gates on build-1 on their own binary (no watchdog there), lines about 14:20 UK; ledger row N12 for the bind-failure class. A ROLL BLOCKER on every kept datadir (the node lane, 14:1x UK, ledger N13): the fleet started 6a3432a3 on a kept 0.3.17 datadir (pool-1's copy) and it died at start (virtual_state.rs:250, DeserializationError(UnexpectedEof)); the cause 10db4b61 on the 0.3.16 feature line added `silent: bool` to BlockRewardData under serde(default), which bincode ignores, so every build from 10db4b61 on (dc141409, 8097d600, 6b94c823, 6a3432a3, 09124180) reads a 0.3.17 node's virtual-state row short; no canary saw it because every canary wiped, and a one-box roll keeps datadirs, so it blocks the roll on every standing box, the hands and the hub whatever the pin. The fix on the line: the store reads the current layout first and on a deserialization error decodes the row as a v1 mirror, converts with silent false and rewrites it under the same key, with the known-failed test first; the fourth commit and build about 14:40 UK, the fleet's kept-datadir start on the fixed binary about 14:50 UK, its gates after. THE RULE IT ADDS for every node cut from now: a kept-datadir restart gate on a standing box's datadir copy beside the wiped canary. THE CANDIDATE PIN (14:2x UK): b7cc37e7 (8097d600, 6b94c823, 6a3432a3, 09124180, b7cc37e7; igneum-pow 8c728ca3): the N13 fix with its test green on build-2 at 14:04 UK and the kaspad check green, the build on build-1; the fallback 6b94c823 is no longer a pin for the one-box roll (it dies on a kept datadir like every build since 10db4b61): if b7cc37e7's gates are not green by 15:30 UK the honest fallback is 0.3.17's 5899f603 staying live. In flight on build-1: the earlier commits' gates, then b7cc37e7's own digest and ten-minute mixed-version gates on its binary with the read-back, lines about 15:05 UK; on the fleet the kept-datadir start on b7cc37e7 about 14:50 UK and the 12 GB settled-claim line 14:50 to 15:00 UK. Plan section 6.6 amended with the hard date (ca3-v4-node 9d763edd, merged to master); N12 and N13 on the ledger. THE GATES ON THE FALLBACK'S OWN BINARY (6b94c823, sha b1b7d47b, 13:56 to 14:08 UK; code byte-identical to 8097d600, so the amendment's node side): the digest gate, the thirteen-field file a89be8a7 on both binaries (the compat case, n0 peering n1 and n2) and the sixteen-field object db9a85f9 refused with the mismatch line (the refusal case); the mixed-version gate, ten minutes, one digest b0afb2ee on all five nodes, the 5899f603 hub accepting every block the amended node mined (146 new, 246 old, 0 rejected), plain header version 2 on the thirteen-field file, counts equal on all five through the two clean joins and the restart. Two FAILED checks, both the harness's own and fixed (36d3efdc): a refused peer's count read 1 with the reconnect in flight (now the minimum of five), and six address-in-use panics in the two old nodes because the second gate reused the first's ports the second they were sent SIGTERM (a 20 s gap now). CLOCK CORRECTION (the node lane, 12:12Z = 13:12 BST): every "UK" stamp it sent today was the box's CEST, an hour fast of BST; its lines read UTC from now. Restated: b7cc37e7's build about 12:15Z, its digest and mixed-version gates on that binary with the sha and string about 12:32Z (13:32 BST), the fleet's kept-datadir start on it about 12:25Z, its 12 GB settled-claim line 12:50 to 13:00Z; the shipper's checkpoint 14:30Z (15:30 BST), two hours of room. The 13 October date stands (derived from UTC DAA rates): the floor 831,600 about 08:00Z, 09:00 BST. b7cc37e7'S OWN LINES (binary sha256 bc28331abf21f4d5, the string read back on build-1 and on the fleet's pod): the digest gate 12:14:39Z to 12:16:18Z SUMMARY PASS (thirteen fields a89be8a7 on both binaries with the peers as the gate wants them; the sixteen-field object db9a85f9 refused with the line and no peer; the live file's digest eada4bda on the binary, unmoved); the kept-datadir start on the fleet's copy of pool-1's 0.3.17 datadir: the first start 12:17:12Z reads the v1 row through the mirror and rewrites it ("1 mergeset rewards"), the finality blob converts (1,747 locks), the node comes up on its ports with no panic; the second start 12:18:53Z reads first-try with no rewrite line and no panic; 6a3432a3's death on the same copy is the known-failed shape. The ten-minute mixed-version gate beside the 5899f603 pair runs on the same binary since 12:16:39Z, its line about 12:28Z; then the only line outstanding for the shipper's 14:30Z rule is the fleet's 12 GB settled-claim line, 12:50 to 13:00Z. AP-F8-1 RESIDUAL CLASS ON THE AMENDED STREAM (attack-pass lane 12:18Z on igneum-pow 8c728ca3, sub-version 1). F9 over 1,000,000 seeds: programs flagged (hot share at least 1 percent or 7 constant address bits) 1,871 (0.19 percent) against 11,696 (1.17 percent) unamended; worst hot share 9.66 percent against 17.3; mean 0.011 against 0.063 percent; 84 percent of the flagged programs and the whole or-saturation tail gone. F8 at 30 of 64 seeds: nine over 1.2x of the window model (p31 29.3x, p11 5.5x, p19 3.3x, p6 3.1x, p23 2.0x, the rest 1.3x to 1.6x); the 64-seed 1.2x gate is heading to FAIL on sub-version 1. Mechanism, confirmed on the two worst seeds: an all-ones load source (image 0x0ca59e4c under the era map) delivered through a writer the source rule counts as entropy-keeping, a rotate (rotl and rotr map all-ones to itself) or a load whose own source was saturated, with the saturation made one or more writes upstream by or. The rule looks one writer back; it must look through saturation-preserving writers or test the source's values. The ceiling has not moved: rule (c)'s 120-of-128 floor still caps any program at one saturated site, 6.25 percent of reads, a chip edge of at most 1.067x, and the residual (worst seed two sites at 0.53 and 0.56) sits inside it. THE SENTENCE "no lossy-sourced load by construction" IS HELD: it goes in no plan row and no ledger entry as true; sub-version 1 removes the or-source class and bounds the rest. MAIN'S RULING (13:2x UK): 0.3.20 ships object byte 5 on sub-version 1 as it stands, strictly better than the old stream the live floor flips to on 13 October; the fix is sub-version 2 on ca3-v4-amend (object byte 6 or whatever the v5 alignment leaves free) with both fixes: (F1) the static rule made transitive (rotates do not keep entropy; a load keeps entropy only if its own source did; one draw change, no attempts lost) and (F2) the dynamic source check (saturated load SOURCE values counted per site over the 64 units' 16,384 evaluations, rejected above 163 of 16,384, the same 1 percent the final-value rule uses; costs attempts on about 0.2 percent of seeds; rides with F1 because an or-written source is all-ones only (3/4)^32 of the time). Gate before sub-version 2 is proposed, run by the attack-pass lane and not by the hash lane: the full 64-seed census under 1.2x on every seed and the hot-set census. Hash lane's estimate about an hour its side (implement, re-export seven packs, vectors, crate suite, pairing, one G1 on PC 2) plus the node lane's vector re-pin and the attack-pass re-gate. The flip floor for sub-version 1 is expected to move (Josh's word) so the chain never flips to a stream that fails this gate. Also recorded: the crate suite at 8c728ca3 100 of 100 on the box (rc 0, 77 s); the pairing against the fork at dc141409 compiled and ran 15 of 16, the one failure the fork's own pre-amendment assertion (base equals v3's, igneum.rs:972), which 8097d600 on the release-0.3.20-node line turns into assert_ne; the pairing re-runs at b7cc37e7, its line to follow. CORRECTION (the attack-pass lane's own retraction, 13:3x UK): the F9 hot-set figures above (1,871 of 1,000,000, worst 9.66 percent, 84 percent removed, the two or-then-rotate listings) are WITHDRAWN: F9's harness draws through candidate_class with its own era class, outside candidate_from_words_class where the source rule lives, so it measured the old stream (the 8c728ca3 binary prints the identical program to the sub-version-0 binary for its worst seed). F8's 64-seed census on the chain path (pairing verified on 1a4230699a6b9c60) is the valid re-gate and STANDS: at 30 of 64 seeds, nine over 1.2x of the window model (p31 29.3x, p11 5.5x, p19 3.3x, p6 3.1x, p23 2.0x, p4 1.6x, p10 1.5x, p26 1.3x, p25 1.3x). The residual mechanism on the amended stream: a load-after-load chain (a saturated source reads one fixed word, which is the next load's address), admitted because a load injects; and the rotate-preserves-saturation path (generator.rs sets entropy_kept true for a rotate whatever it rotated), correct in code and a second admitted path if it occurs on the chain stream. Sub-version 2 must close both: dataflow freshness per register (a load fresh only if its source was fresh; add, sub, xor, mad, shfl fresh if either operand was; rotates only if the operand was; or, mul, mulhi never) plus the (c') count of saturated load sources per site as the backstop. The STOP holds on F8's evidence alone; the options and the 1.067x ceiling are unchanged. The sentence "no lossy-sourced load by construction" waits on the sub-version 2 census verdict and stays out of every public text until then. SUB-VERSION 2 IN BUILD (the hash lane, ca3-v4-amend, on the coordinator's direction, 13:4x UK): F1 (dataflow freshness per register, keyed on the class v4 shape on every draw path, era or not, so the candidate_class path and the chain path draw one stream) plus F2 (the (c') count of saturated load source values per site over the 64 units' 16,384 evaluations, rejected above 163, keyed on the same shape so v2 and v3 verdicts do not move); PROGRAM_SUBVERSION_V4 = 2, new ids, the seven packs re-exported, recheck.rs with 1a4230699a6b9c60 and c120d7963abdcd96 as the must-differ pair. Clock (UTC): the commit on the branch by 13:30; the crate suite on box 2 and the pairing against b7cc37e7 by about 13:50 (the pairing's vector test fails on the fork's sub-version-1 pin until the node lane re-pins; the compile and the other 15 are the pairing evidence); the G1 job on PC 2 under --cards-off by about 14:10, lock permitting; then the attack-pass lane's full 64-seed census and hot-set census on the chain path. Two consequences stated in the commit: the rule on every draw path moves the no-era sh256xN ladder packs' stream (packs-ca3-shadow's seven 256-block packs re-export with new fingerprints; the measured rates stand as the old stream's), and the class v5 lane's pinned string-seed packs move when it merges sub-version 2, so it re-exports them then. 0.3.20's sub-version-1 packs, ids and fingerprints untouched. OBJECT BYTES SETTLED (main, 13:5x UK): byte 5 = class v4 sub-version 1 (0.3.20), byte 6 = class v5 (pinned: class-v5 16afd0a0, class-v5-node 699db5a2, the flip case passed on 6,6,6; the v5 lane stopped), byte 7 = class v4 sub-version 2; the node and hash lanes told. b7cc37e7's MIXED-VERSION GATE: FAIL, the binary not the harness (12:16:39Z to 12:27:21Z, sha256 bc28331abf21f4d5, the string read back). Before the restart step everything held: one digest b0afb2ee on all five nodes, 268 new and 392 old blocks accepted, 0 rejected, header versions plain 2, counts equal on all five at 324 and 502 through both clean joins. At the new node's restart (12:24:19Z) it died at once on its own datadir ("IO error: While lock file: .../datadir/meta/LOCK: Resource temporarily unavailable", conn_builder.rs:167): the previous process was still shutting down, because the listener watchdog added on 6a3432a3 sleeps its whole 10 s poll before checking shutdown, so every node on the line since then takes up to 10 s longer to stop than 0.3.17 (the fleet saw the same shape as "a 12-second timeout does not stop the node"). Three of the four failed checks follow from that one death (counts, the restarted node's resync, the node it served frozen at 502). The fix on the line, one rule: the poll in 250 ms steps returning the moment shutdown is set, with a test that a shutdown returns within a second (the 10 s loop the known-failed shape); the exec suite on build-2, the fifth commit and its build about 12:45Z, its digest and ten-minute gates about 12:50 to 13:05Z, inside 14:30Z. b7cc37e7 is NOT the pin. The node-side re-pin for sub-version 2 (byte 7) once the hash lane's commit lands: the beside-the-fork igneum-pow copy archived from the commit, the two pinned ids moved in the kaspa-pow vector test (sub-version-2's epoch-0 id must-equal; sub-version-1's joins c120d7963abdcd96 as must-differ), CLASS_SIGNAL and tests for byte 7, the daemon's window line: about 20 minutes of edits plus one kaspa-pow suite run on build-2 (about 2 minutes). THE FIFTH COMMIT c4459193 on release-0.3.20-node (b7cc37e7's child, the watchdog poll returning on shutdown; the diff is the poll loop in rpc.rs alone), pairing igneum-pow 8c728ca3; its build on build-1 started 12:30:13Z, sha256 and string to follow. Line A, the shutdown test: rpc::watchdog_tests::a_shutdown_returns_within_a_second_whatever_the_poll green on build-2 at 12:29Z in the exec suite's 31 passed, beside the two other watchdog tests; its known-failed shape the old loop's 10 s stop. Line B, the kept-datadir start: b7cc37e7's fleet read carries to c4459193 since the store code is byte-identical between the two commits; the fleet re-reads on the c4459193 binary only if the shipper's rule wants the string on that line too. The digest gate and the ten-minute mixed-version gate on c4459193's own binary follow its build. THE SHIPPER'S CARRY RULING (14:1x UK): b7cc37e7's kept-datadir read stands as evidence that the store fix is right (the store code byte-identical) but is not the gate line for the pin, because the rule reads the binary, not the diff, and the binary changed (rpc.rs); the gate line is the kept read on c4459193's own binary with its string, which the fleet's canary already runs on c18-1 (wipe, then the kept read, then the restart) before the canary's restart step, at no extra cost; no re-read on p12-vast. THE PIN IS c4459193 pairing 8c728ca3 (object byte 5, sub-version 1); sub-version 2 (byte 7) is 0.3.21's, not 0.3.20's. The shipper's reading of main's F8 ruling: 0.3.20 ships object 5 as it stands because the live floor otherwise flips every node to the OLD stream on 13 October, and the 16:00 BST report tells Josh the floor move is now RECOMMENDED rather than optional, so the chain never flips to a stream that fails the 1.2x gate before sub-version 2 lands. THE FLEET'S CLOCK ON c4459193 (the fleet lane, 12:5x UTC): the kept read on pool-1's 0.3.17 datadir copy and the restart (the old process's stop time on the line) run on c18-1 before the wipe, a few minutes each, so both lines land before 14:30Z; the wipe canary (IBD from the pruning-point proof, 98 minutes on this pod class) starts when c18-1 is free of the 0.3.20 cases (about 13:00Z) and the binary is in hand, so its synced line lands about 14:40Z at the earliest, PAST the 14:30Z checkpoint; the 12 GB settled-claim line: c4459193 starts on p12-vast's kept copy of pool-1's datadir beside the 6a3432a3 IBD node on alternate ports the moment the binary lands, catches up from 129,398 blocks (15 to 20 minutes) and the 12 GB prover claims against it, the line on c4459193 itself. The binary not yet in the fleet's hand (build-1 building since 12:30:13Z); a wait armed on the sha and string, a report by 13:10Z if nothing. THE SHIPPER'S CALL ON THE CLOCK (14:2x UK): the wipe canary is the decisive read by the deploy rule; the pin never cuts without it and b7cc37e7's lineage does not stand in (the binary changed). The fleet rents a second one-shot pod of c18-1's class now and starts the wipe canary on c4459193's binary the moment the build lands, synced line about 14:15Z (15:15 BST), inside the checkpoint; c18-1 keeps the 0.3.20 cases and the pool window. If the wipe line slips past 15:30 BST the pin holds to it and main hears the clock (a slip is a report, not a cut). The set: the node lane's digest and mixed-version gates (12:50 to 13:05Z), the kept read and restart on the new pod, the wipe line on the new pod, the 12 GB settled-claim line on p12-vast. c4459193's BINARY IN THE FLEET'S HAND (12:34:54Z from build-1): igneumd sha256 45be9b02d1b002f5486d0f0108571c3b6042094113ad9da6f3d3d9ffc0072bba with the string c4459193 read back from the file, igneum-miner c7cfc40bc8b0e357. The wipe pod c19-1 (RunPod wpuke4tfu0vr49, RTX 3070 community, c18-1's class, USD 0.13/h, rented 12:37:03Z, one-shot; the day at USD 124 of work plus the 248 leak, 37 percent of the ceiling): the canary form (wipe, IBD from the pruning-point proof, synced, ten minutes mining with the exec poller, the hub read, the restart read) starts the moment the pod answers ssh; the kept read on pool-1's 0.3.17 copy armed behind its synced line on the same pod; the IBD start stamp its own line; synced about 14:20Z if the pod answers by 12:42Z (ten minutes inside the checkpoint), a slip reported the moment a poll shows it. CASES END on c18-1 at 12:37:18Z rc 0 (the relay and poison lines to the shipper); c18-1 and the two case pods destroyed by the run; the ten-member pool window rented its ten at 12:37:36Z. The 12 GB settled-claim line on p12-vast runs against a c4459193 node on the pod's kept copy, up since 12:36:35Z first-try, catching up. THE WIPE CANARY ON c19-1 STARTED: IBD at 12:38:55Z on c4459193 (sha256 45be9b02... asserted on the Mac before the put; the node's own line igneumd/2.1.0-c4459193 and digest eada4bda8aa8368c read back on the pod; a wiped datadir; IBD from the pruning-point proof with 4 peers at 12:39:26Z); synced about 14:17Z by the 98-minute class, thirteen minutes inside the checkpoint; the mining read, hub read, restart and kept read follow on the same pod, each its own line. THE INTEROP FACT stands from the void run: the 5899f603 hub accepted 235 object-byte-5 blocks from the 8097d600 node with 0 rejected, one digest on all five nodes on the live sixteen-field file. The gates: the digest test and the kaspa-pow vector test (the amended devnet epoch-0 id 1a4230699a6b9c60 must equal, c120d7963abdcd96 must differ, the v3 control unchanged) on the box; the mixed-version Devnet 2 gate (the amended 0.3.20 node beside a 5899f603 node for ten minutes on the live file without the v4 fields) after the Mac build; the fresh-join canary the 0.3.20 cut's | | Main's rulings (7 October, morning) | no generator change to v4 on the live devnet; the record's null is the window model with numbers, sent by the hash lane to the attack-pass lane so AP-F8-1 re-gates against it; a fault beyond the model (a low-entropy source at site 15) stops at the coordinator with the two options priced (a 0.3.19 class amendment before the flip, or the flip held at the floor), nothing shipping without Josh's word; the tighter tail, an acceptance bound on the hot-set share, is a CLASS V5 item (sent to the v5 lane a6410f3b8abefb762 with the 64-seed census as its gate; the bound's number follows from the model) | ### AP-F4-1, the weak-day MUL draw (the attack-pass lane, 7 October, morning): PASS against v4, a class v5 rule From 44e9cab5654d3eae2b24f30209a9cc73e5e24ad6 Mon Sep 17 00:00:00 2001 From: igneum-josh <337424239+igneum-josh@users.noreply.github.com> Date: Wed, 7 Oct 2026 13:46:16 +0100 Subject: [PATCH 07/19] Counter ASIC 3.0 status: c4459193's build line and digest gate PASS Co-Authored-By: Claude Fable 5.1 --- docs/plans/counter-asic-3-status.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/plans/counter-asic-3-status.md b/docs/plans/counter-asic-3-status.md index 12b487061..099e03c3b 100644 --- a/docs/plans/counter-asic-3-status.md +++ b/docs/plans/counter-asic-3-status.md @@ -338,7 +338,7 @@ Josh gave the go in advance for tonight: the shipper runs publish 1 on the 0.3.1 | THE ANALYSIS (the hash lane, ca3-v4-uniform 095f84a7, `docs/analysis/ca3-v4-uniform.md`, the tool on igneum-build-1) | the window model moves the null from 0.115 to 0.160 percent (1.39x, not 4.05x); the rest is a FAULT beyond it: site 15 reads a register last written by `or r6, r4`, so all-ones recurs at (3/4)^32 per read and the era map sends it to F8's hottest item exactly (the popcount model predicts 77,348 all-ones reads against 78,479; the top-0.1-percent share 0.58 against 0.52); it passes the acceptance rule because part (a) takes any write as a fresh source and part (c) counts saturation on final values only. The census of 1,024 chain-shaped v4 programs: 96.6 percent carry a lossy-sourced load (or, mul, mulhi as the last writer), 48.5 percent an or-sourced one (0.30 percent of all reads per site), 4.9 percent an or-of-or chain (4.6 percent of all reads on 0.1 percent of items); F8's 1.2x gate fails 96.6 percent of today's programs. Worth to a chip: 1.07 MB of SRAM ($0.25) serving 0.52 percent of a typical program's reads and 4.6 percent of the worst class's, at most 1.005x and 1.048x in rate; the ceiling under rule (c)'s 120-of-128 floor one site repeating its item in all 8 iterations, 6.25 percent of reads, 1.067x in 64 bytes; the 2x margin stands; the public line says "bounded at 1.067x", not "uniform" (the public text corrected) | | The two options, priced, STOPPED at the coordinator for Josh's word | A: a 0.3.19 class amendment before the flip (the generator draws a load's source from the registers whose last writer injects): a new program stream, new vectors, the seven gate packs re-exported, the six gates again (G1 to G3 and the verifier about an hour on the Mac and PC 2; G4 to G6 the node lane), every node before the flip under the one-box-at-a-time rule; the risk a node that misses the build splits the chain at the flip. B: hold the flip at the floor with v4 as it is; the bound documented; the source rule to class v5: a hot set worth up to 1.005x on about half the hours and 1.05x on 5 percent, 1.067x at the ceiling; no chain risk. The number: 1.067x at the ceiling against the 2x margin. The lane recommends B | | The v5 bound (sent to the v5 lane) | H = W_0.1 (the window term, 0.115 to 0.251 percent) + the sum over load sites of h(last writer) (or 0.30 percent, an or chain 4.5, mul 0.067, mulhi 0.049, an injecting op or a rotate 0), H at or under 1.2 x W_0.1, which is the static rule "every load's source was last written by an injecting op or a rotate"; as a rejection it costs 96.6 percent of candidates (about 30 attempts per seed), as a generator draw nothing; gate F8's 64-seed census with the saturated-source count | -| JOSH'S WORD (15:2x UK, 7 October): OPTION A, "do this but limit the testing, get it pushed" | the class v4 amendment: a load's source drawn only from registers whose last writer injects or is a rotate (the v5 rule applied now), a new program stream and vectors, the seven gate packs re-exported, the amended class with its own generator stamp; rides 0.3.20, the feature node (release-0.3.20-node = dc141409; 0.3.19 is an app-only cut with nothing of ours), on the shipper's line. The rollout arithmetic for the flip clock (the shipper): the standing fleet's one-box-at-a-time rollout took 32 minutes for 14 boxes (04:56 to 05:28Z, 7 October), the hands and the seed about 3 minutes after the miners, the Mac and the PCs within minutes of the publish; every 0.3.20 worker must accept the amended stamp before any flip. Owners: the hash lane (ca3-v4-amend: the generator, the vectors, the packs, the pairing on the box, one G1 run on PC 2, the ledger row), the node lane (release-0.3.20-node: the stamp agreed with the hash lane, the split-protection mechanism and the earliest flip time, the digest test, the mixed-version Devnet 2 gate), the attack-pass lane (the F8 census at 2^24 on the new stream, the gate 1.2x of the window model over 64 seeds), the shipper (the cut, the rollout order that sets the earliest flip). Testing limited to what prevents a split and proves the fix; G2, G3, the ladder re-measure and the rest of G4 to G6 OWED. THE STAMP agreed (the node and hash lanes, 7 October afternoon): generator 4 with sub-version 1 inside igneum-pow's id function, so the amended v4's program id for a seed differs from the old v4's (the old devnet epoch-0 id c120d7963abdcd96 pinned as the must-differ vector in kaspa-pow's test). SPLIT PROTECTION SETTLED (the node lane, plan section 6.6, ca3-v4-node fa5bc9e6; the node side on release-0.3.20-node): a fresh object byte. CLASS_SIGNAL_V4 is 5; the amended binary stamps 5 and the tally counts a block only at byte 5 or above; object 4 was stamped only by the unpublished dc141409 canary, so no published block carries it and a byte-4 block never counts; a node of the 6 October stream that sees byte 5 counts it as v4 (its rule is at least 4), flips to its own stream at the same epoch and forks ALONE (its blocks fail the amended id check, generator 4 sub-version 1 inside every id; the amended blocks fail its own), ours to upgrade in the sweep; object 6 is class v5's; the two holds already in the rule keep the window shut until every node is on 0.3.20 (a node stamps and tallies only with both v4 fields in its file; the fields publish only after the one-sweep rollout); a lagging worker refuses the amended pack at packcheck and mines nothing after the flip, costing that box, never the chain; no extra window hold: seven full day-windows are the hold. THE EARLIEST FLIP (approximate, measured 09:40Z: DAA 270,659, 1.095 DAA/s over 25 hours, 1.165 over 4; epoch 3,600, lead 600; seven windows 604,800 DAA wholly after the sweep's end D_s = T + about 40 minutes; the flip epoch the first e with 3600 e - 600 >= D_s + 604,800): T + 6 days 10 hours to T + 6 days 11 hours UK; for a publish at 12:00 UK on 7 October, 13 October between 22:20 and 23:10 UK (about 13:00 UK if the 4-hour rate holds). The floor as it stands (831,600, about 13 October 09:00 UK) would fire before any seven-window signal from a publish today completes, so it moves by the 0.3.16 rule to the publish DAA + 604,800 rounded up to the epoch boundary (882,000 for a 12:00 UK publish), firing about 30 minutes before the earliest signal flip: either way about 6 days 10 hours after the publish, never before every node has had the sweep plus a week. THE CLOCK (the node lane, 11:3x UK, after a Mac reboot moved its runs to the box): the 0.3.20 node line (dc141409 plus the proof archive aea0ca5c plus the amended v4 at object byte 5, igneum-pow at the hash lane's a0aaca92 beside the fork on the box) tested on the box, committed on release-0.3.20-node, pushed to the mirror and origin, igneumd and igneum-miner built, the tip to the shipper: about 12:00 UK; the mixed-version Devnet 2 gate (node-compat.mjs on the box, the amended node beside the 5899f603 pair for ten minutes) and the digest test (digest-compat.mjs): about 12:45 UK; the object-byte pin 5 unless the v5 lane answers both lanes with another assignment (v5 at 6 proposed). THE HASH SIDE on ca3-v4-amend (tip 8c728ca3, read from the branch 14:0x UK; the hash lane's own report pending): 1748fd1d the PC 2 G1-only playbook; e1f48d63 the fud-ledger entry AP-F8-1 (the fault, Josh's ruling, the amendment, the split protection, the owed tests); d8859522 the G1 line (the eight fingerprints equal on the RTX 5090, self-test PASS) and the node lane's signal byte 5; 4aa0c665 the v4 unit test following the amendment; 965d9e96 igneum-pow taken from release-0.3.20's 3f1652bf (the ladder's chain_program_shadow with the reps argument, never on master) with the amendment re-applied, the seven packs re-exporting byte-identical; 8c728ca3 the source rule keyed on the class with the shadow's pass count set aside, so every ladder rung draws under it (the fork's ladder test). The shipper took this igneum-pow tree into release-0.3.20 (00249643, byte-equal); nothing after 8c728ca3 touches igneum-pow. THE VECTORS AND THE PACKS (read from the branch and its ledger entry, 14:1x UK): the seven amended v4 packs (v4-devnet-epoch0, v4-era-0 to 5) carry generator 4, sub-version 1, one program id 1a4230699a6b9c60 (the 2.0 one-id-per-seed rule across the eras; the old c120d7963abdcd96 pinned as must-differ); the v3 control mx8-devnet-epoch0 untouched (73bcbfe8ccf988f1, fingerprint 90f794dd556f7a3b); the seven 2^24 fingerprints, Metal equal to Apple OpenCL: 867dbc45cfb36b4d, 2146ecacc8c75a8e, fe52602393f6d3d4, 3b206471a13912b4, c3f03c4a5d7333aa, f1dfd7209f15bb97, 8c194da64fadf31d; the zip of the eight packs sha256 889ec99976d2728b4b5035bfa476032e5b6a13b928968fc45236d5f25084aa39; the per-pack vectors.json sha256 prefixes 756301bf (devnet epoch 0), 1b5f4568, d430cadc, 1a1b21d8, 460fff9e, 4a85d49d, f83a1196 (eras 0 to 5). G1 on the RTX 5090 (PC 2 job run-ca3-v4-amend-g1-pc2-20261007, 09:41:07 to 09:41:28Z, exit 0, the installed worker): every fingerprint equal to the Mac's (the seven above and the control), NVRTC 188 to 332 ms per pack, the 1 GiB build 38 to 49 ms. hash-gates.md's older table still lists the pre-amendment fingerprints (f410c731... and the eras), which no longer apply to the amended packs; the ledger entry is the record. THE FIRST GREEN (11:31 UK, the box): the kaspa-pow suite on release-0.3.20-node (dc141409 plus the proof archive aea0ca5c plus the object-5 change) against the hash lane's igneum-pow 8c728ca3: 17 passed, 0 failed; the amended devnet epoch-0 id 1a4230699a6b9c60 pinned equal and c120d7963abdcd96 differing, the ladder's rung test green under the rekeyed rule, the v3 control unchanged; the consensus-core and exec RPC suites follow, then the node line (commit, push, box build, the tip to the shipper), then the digest and mixed-version gates. CLOCK RE-CUT (the node lane, 13:0x UK): the node line now carries, beside the object-5 change and the vector test, the lane's 0.3.20 fixes from the day (isSynced from the hook's stamp, the lazy template snapshot, the weight-table cache, the submit path returning after the block task, the watchdog, the RPC fields), about 13:30 UK if the box suites are green; the shipper's fresh-join canary 60 to 100 minutes after the cut; PC 1 as its first machine about 16:00 UK at the earliest, approximate until the shipper names the cut; the earliest flip about 6 days 10 hours after the publish. BUILD-2 LINES (12:28 to 12:33 UK): consensus-core 123 passed (the 60x file test green with the ladder window and activation pinned), the behind test green, kaspa-pow 17 passed (the amended vectors, earlier on build-1), the exec RPC suite green, the flows and rpc-service checks green with the submit-path change; the 24-requester latency test's first run tripped an unrelated flapping-fork double insert (24 equal forks from one parent; the test now builds on the sink as a real miner does; the double insert owed to a small fork harness before it is called a bug); THE NODE LINE COMMITTED (13:1x UK): release-0.3.20-node = 8097d600 (dc141409 + the proof archive aea0ca5c + one commit) on the mirror, pairing igneum-pow 8c728ca3, the hash with the shipper; in it the amended class v4 as object 5 (CLASS_SIGNAL_V4 = 5, byte 4 never counts, the kaspa-pow vector test pinning 1a4230699a6b9c60 equal and c120d7963abdcd96 differing, the daemon's window line naming object 5 and sub-version 1) beside the day's fixes (isSynced from the hook's stamp, the weight-table cache, the lazy snapshot, the submit path, the 100 ms template wait); the suites green on build-2 (consensus-core 123, the exec RPC suite, the four finality tests including 24 requesters under 200 ms: the worst template 100 ms, the worst submit 102 ms) and kaspa-pow 17 on build-1. Next: igneumd and igneum-miner building from 8097d600 on build-1, then the two gate lines (the mixed-version Devnet 2 gate: the 8097d600 node mining beside the 5899f603 pair for ten minutes on the live file without the v4 fields, the old node accepting every block; the digest test: the thirteen-field file b18ed271 unchanged, the sixteen-field object re-read on the 8097d600 binary), expected about 13:30 UK; the shipper picks the cut point. THE DATE FIXED (the node lane, from the hub's live file, 13:3x UK): publish 2 of 6 October (22:49:45Z, digest eada4bda) already put BOTH v4 fields on the live devnet (floor 831,600, window 86,400), so the 0.3.17 fleet has stamped object byte 4 since 7 October 00:2x UK and the floor is live at about 13 October 09:00 UK, before any seven-window signal completes; a 0.3.17 node left on that file flips to the OLD v4 stream at epoch 231 whatever anyone signals, a 0.3.20 node to the amended stream at the same epoch, and the two never share an id, so each straggler forks alone there. REQUIREMENT for the 0.3.20 publish (with the shipper and main): a new file with the floor at the publish DAA + 604,800 rounded up (about 882,000 for a publish today), the digest moving, the one-sweep rollout replacing every 0.3.17 node before 13 October 09:00 UK; any node that misses the sweep is alone then; the earliest flip after that about 6 days 10 hours past the publish; plan section 6.6 amended today. IN THE 0.3.20 PLAN (the shipper, 13:4x UK): both requirements; the node pin by main's rule is the node lane's second commit (the claim floor, the listener watchdog, the claim RPCs, on top of 8097d600) if its suites, both gates and the fleet's 12 GB prover line are green by 15:30 UK, else 8097d600; igneum-pow 8c728ca3 either way; the digest read on whichever binary pins. THE LINE AT 13:5x UK: three commits on release-0.3.20-node, 8097d600 (the object-5 amended class v4 and the day's fixes), 6b94c823 (test-only: the stale PC 1 test from 500ddd66 inverted by the isSynced ruling; the FALLBACK pin, code byte-identical to 8097d600, so the module reads green whole) and 6a3432a3 (the app lane's key methods, the observer's claims, the settled claim floor, the listener watchdog); suites on build-2 on 6a3432a3's code (the whole finality module 25, the exec suite 29 with the watchdog test, the kaspad, flows and rpc-service checks; consensus-core 123 and kaspa-pow 17 earlier); the cut 6a3432a3 if its gates and the fleet's 12 GB settled-claim line are green by 15:30 UK, else 6b94c823; both binaries building on build-1, the two gates (the digest gate, then the ten-minute mixed-version gate beside the 5899f603 pair) on the 8097d600 build, lines about 14:05 UK. GATE NEWS (13:53 UK): on 6a3432a3's own digest gate the listener watchdog counted a bind failure (the four harness nodes share one exec JSON-RPC port) as a listener death and exited three of four nodes at 20 s, where 0.3.17 and 8097d600 only warn and live without the exec RPC; the digest facts came out first and stand (the thirteen-field file a89be8a7 on both binaries, the compat case; the sixteen-field object db9a85f9 refused with the mismatch line, the refusal case); the ten-minute gate on 6a3432a3 stopped as void for the same cause. The fix: a bind failure is a retry every poll, one line a minute, no death counted and never an exit, with a second watchdog test whose known-failed shape is the old rule's exit on a held port; the third commit and its build about 14:15 UK, its gates about 14:35 UK; the fallback 6b94c823's gates on build-1 on their own binary (no watchdog there), lines about 14:20 UK; ledger row N12 for the bind-failure class. A ROLL BLOCKER on every kept datadir (the node lane, 14:1x UK, ledger N13): the fleet started 6a3432a3 on a kept 0.3.17 datadir (pool-1's copy) and it died at start (virtual_state.rs:250, DeserializationError(UnexpectedEof)); the cause 10db4b61 on the 0.3.16 feature line added `silent: bool` to BlockRewardData under serde(default), which bincode ignores, so every build from 10db4b61 on (dc141409, 8097d600, 6b94c823, 6a3432a3, 09124180) reads a 0.3.17 node's virtual-state row short; no canary saw it because every canary wiped, and a one-box roll keeps datadirs, so it blocks the roll on every standing box, the hands and the hub whatever the pin. The fix on the line: the store reads the current layout first and on a deserialization error decodes the row as a v1 mirror, converts with silent false and rewrites it under the same key, with the known-failed test first; the fourth commit and build about 14:40 UK, the fleet's kept-datadir start on the fixed binary about 14:50 UK, its gates after. THE RULE IT ADDS for every node cut from now: a kept-datadir restart gate on a standing box's datadir copy beside the wiped canary. THE CANDIDATE PIN (14:2x UK): b7cc37e7 (8097d600, 6b94c823, 6a3432a3, 09124180, b7cc37e7; igneum-pow 8c728ca3): the N13 fix with its test green on build-2 at 14:04 UK and the kaspad check green, the build on build-1; the fallback 6b94c823 is no longer a pin for the one-box roll (it dies on a kept datadir like every build since 10db4b61): if b7cc37e7's gates are not green by 15:30 UK the honest fallback is 0.3.17's 5899f603 staying live. In flight on build-1: the earlier commits' gates, then b7cc37e7's own digest and ten-minute mixed-version gates on its binary with the read-back, lines about 15:05 UK; on the fleet the kept-datadir start on b7cc37e7 about 14:50 UK and the 12 GB settled-claim line 14:50 to 15:00 UK. Plan section 6.6 amended with the hard date (ca3-v4-node 9d763edd, merged to master); N12 and N13 on the ledger. THE GATES ON THE FALLBACK'S OWN BINARY (6b94c823, sha b1b7d47b, 13:56 to 14:08 UK; code byte-identical to 8097d600, so the amendment's node side): the digest gate, the thirteen-field file a89be8a7 on both binaries (the compat case, n0 peering n1 and n2) and the sixteen-field object db9a85f9 refused with the mismatch line (the refusal case); the mixed-version gate, ten minutes, one digest b0afb2ee on all five nodes, the 5899f603 hub accepting every block the amended node mined (146 new, 246 old, 0 rejected), plain header version 2 on the thirteen-field file, counts equal on all five through the two clean joins and the restart. Two FAILED checks, both the harness's own and fixed (36d3efdc): a refused peer's count read 1 with the reconnect in flight (now the minimum of five), and six address-in-use panics in the two old nodes because the second gate reused the first's ports the second they were sent SIGTERM (a 20 s gap now). CLOCK CORRECTION (the node lane, 12:12Z = 13:12 BST): every "UK" stamp it sent today was the box's CEST, an hour fast of BST; its lines read UTC from now. Restated: b7cc37e7's build about 12:15Z, its digest and mixed-version gates on that binary with the sha and string about 12:32Z (13:32 BST), the fleet's kept-datadir start on it about 12:25Z, its 12 GB settled-claim line 12:50 to 13:00Z; the shipper's checkpoint 14:30Z (15:30 BST), two hours of room. The 13 October date stands (derived from UTC DAA rates): the floor 831,600 about 08:00Z, 09:00 BST. b7cc37e7'S OWN LINES (binary sha256 bc28331abf21f4d5, the string read back on build-1 and on the fleet's pod): the digest gate 12:14:39Z to 12:16:18Z SUMMARY PASS (thirteen fields a89be8a7 on both binaries with the peers as the gate wants them; the sixteen-field object db9a85f9 refused with the line and no peer; the live file's digest eada4bda on the binary, unmoved); the kept-datadir start on the fleet's copy of pool-1's 0.3.17 datadir: the first start 12:17:12Z reads the v1 row through the mirror and rewrites it ("1 mergeset rewards"), the finality blob converts (1,747 locks), the node comes up on its ports with no panic; the second start 12:18:53Z reads first-try with no rewrite line and no panic; 6a3432a3's death on the same copy is the known-failed shape. The ten-minute mixed-version gate beside the 5899f603 pair runs on the same binary since 12:16:39Z, its line about 12:28Z; then the only line outstanding for the shipper's 14:30Z rule is the fleet's 12 GB settled-claim line, 12:50 to 13:00Z. AP-F8-1 RESIDUAL CLASS ON THE AMENDED STREAM (attack-pass lane 12:18Z on igneum-pow 8c728ca3, sub-version 1). F9 over 1,000,000 seeds: programs flagged (hot share at least 1 percent or 7 constant address bits) 1,871 (0.19 percent) against 11,696 (1.17 percent) unamended; worst hot share 9.66 percent against 17.3; mean 0.011 against 0.063 percent; 84 percent of the flagged programs and the whole or-saturation tail gone. F8 at 30 of 64 seeds: nine over 1.2x of the window model (p31 29.3x, p11 5.5x, p19 3.3x, p6 3.1x, p23 2.0x, the rest 1.3x to 1.6x); the 64-seed 1.2x gate is heading to FAIL on sub-version 1. Mechanism, confirmed on the two worst seeds: an all-ones load source (image 0x0ca59e4c under the era map) delivered through a writer the source rule counts as entropy-keeping, a rotate (rotl and rotr map all-ones to itself) or a load whose own source was saturated, with the saturation made one or more writes upstream by or. The rule looks one writer back; it must look through saturation-preserving writers or test the source's values. The ceiling has not moved: rule (c)'s 120-of-128 floor still caps any program at one saturated site, 6.25 percent of reads, a chip edge of at most 1.067x, and the residual (worst seed two sites at 0.53 and 0.56) sits inside it. THE SENTENCE "no lossy-sourced load by construction" IS HELD: it goes in no plan row and no ledger entry as true; sub-version 1 removes the or-source class and bounds the rest. MAIN'S RULING (13:2x UK): 0.3.20 ships object byte 5 on sub-version 1 as it stands, strictly better than the old stream the live floor flips to on 13 October; the fix is sub-version 2 on ca3-v4-amend (object byte 6 or whatever the v5 alignment leaves free) with both fixes: (F1) the static rule made transitive (rotates do not keep entropy; a load keeps entropy only if its own source did; one draw change, no attempts lost) and (F2) the dynamic source check (saturated load SOURCE values counted per site over the 64 units' 16,384 evaluations, rejected above 163 of 16,384, the same 1 percent the final-value rule uses; costs attempts on about 0.2 percent of seeds; rides with F1 because an or-written source is all-ones only (3/4)^32 of the time). Gate before sub-version 2 is proposed, run by the attack-pass lane and not by the hash lane: the full 64-seed census under 1.2x on every seed and the hot-set census. Hash lane's estimate about an hour its side (implement, re-export seven packs, vectors, crate suite, pairing, one G1 on PC 2) plus the node lane's vector re-pin and the attack-pass re-gate. The flip floor for sub-version 1 is expected to move (Josh's word) so the chain never flips to a stream that fails this gate. Also recorded: the crate suite at 8c728ca3 100 of 100 on the box (rc 0, 77 s); the pairing against the fork at dc141409 compiled and ran 15 of 16, the one failure the fork's own pre-amendment assertion (base equals v3's, igneum.rs:972), which 8097d600 on the release-0.3.20-node line turns into assert_ne; the pairing re-runs at b7cc37e7, its line to follow. CORRECTION (the attack-pass lane's own retraction, 13:3x UK): the F9 hot-set figures above (1,871 of 1,000,000, worst 9.66 percent, 84 percent removed, the two or-then-rotate listings) are WITHDRAWN: F9's harness draws through candidate_class with its own era class, outside candidate_from_words_class where the source rule lives, so it measured the old stream (the 8c728ca3 binary prints the identical program to the sub-version-0 binary for its worst seed). F8's 64-seed census on the chain path (pairing verified on 1a4230699a6b9c60) is the valid re-gate and STANDS: at 30 of 64 seeds, nine over 1.2x of the window model (p31 29.3x, p11 5.5x, p19 3.3x, p6 3.1x, p23 2.0x, p4 1.6x, p10 1.5x, p26 1.3x, p25 1.3x). The residual mechanism on the amended stream: a load-after-load chain (a saturated source reads one fixed word, which is the next load's address), admitted because a load injects; and the rotate-preserves-saturation path (generator.rs sets entropy_kept true for a rotate whatever it rotated), correct in code and a second admitted path if it occurs on the chain stream. Sub-version 2 must close both: dataflow freshness per register (a load fresh only if its source was fresh; add, sub, xor, mad, shfl fresh if either operand was; rotates only if the operand was; or, mul, mulhi never) plus the (c') count of saturated load sources per site as the backstop. The STOP holds on F8's evidence alone; the options and the 1.067x ceiling are unchanged. The sentence "no lossy-sourced load by construction" waits on the sub-version 2 census verdict and stays out of every public text until then. SUB-VERSION 2 IN BUILD (the hash lane, ca3-v4-amend, on the coordinator's direction, 13:4x UK): F1 (dataflow freshness per register, keyed on the class v4 shape on every draw path, era or not, so the candidate_class path and the chain path draw one stream) plus F2 (the (c') count of saturated load source values per site over the 64 units' 16,384 evaluations, rejected above 163, keyed on the same shape so v2 and v3 verdicts do not move); PROGRAM_SUBVERSION_V4 = 2, new ids, the seven packs re-exported, recheck.rs with 1a4230699a6b9c60 and c120d7963abdcd96 as the must-differ pair. Clock (UTC): the commit on the branch by 13:30; the crate suite on box 2 and the pairing against b7cc37e7 by about 13:50 (the pairing's vector test fails on the fork's sub-version-1 pin until the node lane re-pins; the compile and the other 15 are the pairing evidence); the G1 job on PC 2 under --cards-off by about 14:10, lock permitting; then the attack-pass lane's full 64-seed census and hot-set census on the chain path. Two consequences stated in the commit: the rule on every draw path moves the no-era sh256xN ladder packs' stream (packs-ca3-shadow's seven 256-block packs re-export with new fingerprints; the measured rates stand as the old stream's), and the class v5 lane's pinned string-seed packs move when it merges sub-version 2, so it re-exports them then. 0.3.20's sub-version-1 packs, ids and fingerprints untouched. OBJECT BYTES SETTLED (main, 13:5x UK): byte 5 = class v4 sub-version 1 (0.3.20), byte 6 = class v5 (pinned: class-v5 16afd0a0, class-v5-node 699db5a2, the flip case passed on 6,6,6; the v5 lane stopped), byte 7 = class v4 sub-version 2; the node and hash lanes told. b7cc37e7's MIXED-VERSION GATE: FAIL, the binary not the harness (12:16:39Z to 12:27:21Z, sha256 bc28331abf21f4d5, the string read back). Before the restart step everything held: one digest b0afb2ee on all five nodes, 268 new and 392 old blocks accepted, 0 rejected, header versions plain 2, counts equal on all five at 324 and 502 through both clean joins. At the new node's restart (12:24:19Z) it died at once on its own datadir ("IO error: While lock file: .../datadir/meta/LOCK: Resource temporarily unavailable", conn_builder.rs:167): the previous process was still shutting down, because the listener watchdog added on 6a3432a3 sleeps its whole 10 s poll before checking shutdown, so every node on the line since then takes up to 10 s longer to stop than 0.3.17 (the fleet saw the same shape as "a 12-second timeout does not stop the node"). Three of the four failed checks follow from that one death (counts, the restarted node's resync, the node it served frozen at 502). The fix on the line, one rule: the poll in 250 ms steps returning the moment shutdown is set, with a test that a shutdown returns within a second (the 10 s loop the known-failed shape); the exec suite on build-2, the fifth commit and its build about 12:45Z, its digest and ten-minute gates about 12:50 to 13:05Z, inside 14:30Z. b7cc37e7 is NOT the pin. The node-side re-pin for sub-version 2 (byte 7) once the hash lane's commit lands: the beside-the-fork igneum-pow copy archived from the commit, the two pinned ids moved in the kaspa-pow vector test (sub-version-2's epoch-0 id must-equal; sub-version-1's joins c120d7963abdcd96 as must-differ), CLASS_SIGNAL and tests for byte 7, the daemon's window line: about 20 minutes of edits plus one kaspa-pow suite run on build-2 (about 2 minutes). THE FIFTH COMMIT c4459193 on release-0.3.20-node (b7cc37e7's child, the watchdog poll returning on shutdown; the diff is the poll loop in rpc.rs alone), pairing igneum-pow 8c728ca3; its build on build-1 started 12:30:13Z, sha256 and string to follow. Line A, the shutdown test: rpc::watchdog_tests::a_shutdown_returns_within_a_second_whatever_the_poll green on build-2 at 12:29Z in the exec suite's 31 passed, beside the two other watchdog tests; its known-failed shape the old loop's 10 s stop. Line B, the kept-datadir start: b7cc37e7's fleet read carries to c4459193 since the store code is byte-identical between the two commits; the fleet re-reads on the c4459193 binary only if the shipper's rule wants the string on that line too. The digest gate and the ten-minute mixed-version gate on c4459193's own binary follow its build. THE SHIPPER'S CARRY RULING (14:1x UK): b7cc37e7's kept-datadir read stands as evidence that the store fix is right (the store code byte-identical) but is not the gate line for the pin, because the rule reads the binary, not the diff, and the binary changed (rpc.rs); the gate line is the kept read on c4459193's own binary with its string, which the fleet's canary already runs on c18-1 (wipe, then the kept read, then the restart) before the canary's restart step, at no extra cost; no re-read on p12-vast. THE PIN IS c4459193 pairing 8c728ca3 (object byte 5, sub-version 1); sub-version 2 (byte 7) is 0.3.21's, not 0.3.20's. The shipper's reading of main's F8 ruling: 0.3.20 ships object 5 as it stands because the live floor otherwise flips every node to the OLD stream on 13 October, and the 16:00 BST report tells Josh the floor move is now RECOMMENDED rather than optional, so the chain never flips to a stream that fails the 1.2x gate before sub-version 2 lands. THE FLEET'S CLOCK ON c4459193 (the fleet lane, 12:5x UTC): the kept read on pool-1's 0.3.17 datadir copy and the restart (the old process's stop time on the line) run on c18-1 before the wipe, a few minutes each, so both lines land before 14:30Z; the wipe canary (IBD from the pruning-point proof, 98 minutes on this pod class) starts when c18-1 is free of the 0.3.20 cases (about 13:00Z) and the binary is in hand, so its synced line lands about 14:40Z at the earliest, PAST the 14:30Z checkpoint; the 12 GB settled-claim line: c4459193 starts on p12-vast's kept copy of pool-1's datadir beside the 6a3432a3 IBD node on alternate ports the moment the binary lands, catches up from 129,398 blocks (15 to 20 minutes) and the 12 GB prover claims against it, the line on c4459193 itself. The binary not yet in the fleet's hand (build-1 building since 12:30:13Z); a wait armed on the sha and string, a report by 13:10Z if nothing. THE SHIPPER'S CALL ON THE CLOCK (14:2x UK): the wipe canary is the decisive read by the deploy rule; the pin never cuts without it and b7cc37e7's lineage does not stand in (the binary changed). The fleet rents a second one-shot pod of c18-1's class now and starts the wipe canary on c4459193's binary the moment the build lands, synced line about 14:15Z (15:15 BST), inside the checkpoint; c18-1 keeps the 0.3.20 cases and the pool window. If the wipe line slips past 15:30 BST the pin holds to it and main hears the clock (a slip is a report, not a cut). The set: the node lane's digest and mixed-version gates (12:50 to 13:05Z), the kept read and restart on the new pod, the wipe line on the new pod, the 12 GB settled-claim line on p12-vast. c4459193's BINARY IN THE FLEET'S HAND (12:34:54Z from build-1): igneumd sha256 45be9b02d1b002f5486d0f0108571c3b6042094113ad9da6f3d3d9ffc0072bba with the string c4459193 read back from the file, igneum-miner c7cfc40bc8b0e357. The wipe pod c19-1 (RunPod wpuke4tfu0vr49, RTX 3070 community, c18-1's class, USD 0.13/h, rented 12:37:03Z, one-shot; the day at USD 124 of work plus the 248 leak, 37 percent of the ceiling): the canary form (wipe, IBD from the pruning-point proof, synced, ten minutes mining with the exec poller, the hub read, the restart read) starts the moment the pod answers ssh; the kept read on pool-1's 0.3.17 copy armed behind its synced line on the same pod; the IBD start stamp its own line; synced about 14:20Z if the pod answers by 12:42Z (ten minutes inside the checkpoint), a slip reported the moment a poll shows it. CASES END on c18-1 at 12:37:18Z rc 0 (the relay and poison lines to the shipper); c18-1 and the two case pods destroyed by the run; the ten-member pool window rented its ten at 12:37:36Z. The 12 GB settled-claim line on p12-vast runs against a c4459193 node on the pod's kept copy, up since 12:36:35Z first-try, catching up. THE WIPE CANARY ON c19-1 STARTED: IBD at 12:38:55Z on c4459193 (sha256 45be9b02... asserted on the Mac before the put; the node's own line igneumd/2.1.0-c4459193 and digest eada4bda8aa8368c read back on the pod; a wiped datadir; IBD from the pruning-point proof with 4 peers at 12:39:26Z); synced about 14:17Z by the 98-minute class, thirteen minutes inside the checkpoint; the mining read, hub read, restart and kept read follow on the same pod, each its own line. THE INTEROP FACT stands from the void run: the 5899f603 hub accepted 235 object-byte-5 blocks from the 8097d600 node with 0 rejected, one digest on all five nodes on the live sixteen-field file. The gates: the digest test and the kaspa-pow vector test (the amended devnet epoch-0 id 1a4230699a6b9c60 must equal, c120d7963abdcd96 must differ, the v3 control unchanged) on the box; the mixed-version Devnet 2 gate (the amended 0.3.20 node beside a 5899f603 node for ten minutes on the live file without the v4 fields) after the Mac build; the fresh-join canary the 0.3.20 cut's | +| JOSH'S WORD (15:2x UK, 7 October): OPTION A, "do this but limit the testing, get it pushed" | the class v4 amendment: a load's source drawn only from registers whose last writer injects or is a rotate (the v5 rule applied now), a new program stream and vectors, the seven gate packs re-exported, the amended class with its own generator stamp; rides 0.3.20, the feature node (release-0.3.20-node = dc141409; 0.3.19 is an app-only cut with nothing of ours), on the shipper's line. The rollout arithmetic for the flip clock (the shipper): the standing fleet's one-box-at-a-time rollout took 32 minutes for 14 boxes (04:56 to 05:28Z, 7 October), the hands and the seed about 3 minutes after the miners, the Mac and the PCs within minutes of the publish; every 0.3.20 worker must accept the amended stamp before any flip. Owners: the hash lane (ca3-v4-amend: the generator, the vectors, the packs, the pairing on the box, one G1 run on PC 2, the ledger row), the node lane (release-0.3.20-node: the stamp agreed with the hash lane, the split-protection mechanism and the earliest flip time, the digest test, the mixed-version Devnet 2 gate), the attack-pass lane (the F8 census at 2^24 on the new stream, the gate 1.2x of the window model over 64 seeds), the shipper (the cut, the rollout order that sets the earliest flip). Testing limited to what prevents a split and proves the fix; G2, G3, the ladder re-measure and the rest of G4 to G6 OWED. THE STAMP agreed (the node and hash lanes, 7 October afternoon): generator 4 with sub-version 1 inside igneum-pow's id function, so the amended v4's program id for a seed differs from the old v4's (the old devnet epoch-0 id c120d7963abdcd96 pinned as the must-differ vector in kaspa-pow's test). SPLIT PROTECTION SETTLED (the node lane, plan section 6.6, ca3-v4-node fa5bc9e6; the node side on release-0.3.20-node): a fresh object byte. CLASS_SIGNAL_V4 is 5; the amended binary stamps 5 and the tally counts a block only at byte 5 or above; object 4 was stamped only by the unpublished dc141409 canary, so no published block carries it and a byte-4 block never counts; a node of the 6 October stream that sees byte 5 counts it as v4 (its rule is at least 4), flips to its own stream at the same epoch and forks ALONE (its blocks fail the amended id check, generator 4 sub-version 1 inside every id; the amended blocks fail its own), ours to upgrade in the sweep; object 6 is class v5's; the two holds already in the rule keep the window shut until every node is on 0.3.20 (a node stamps and tallies only with both v4 fields in its file; the fields publish only after the one-sweep rollout); a lagging worker refuses the amended pack at packcheck and mines nothing after the flip, costing that box, never the chain; no extra window hold: seven full day-windows are the hold. THE EARLIEST FLIP (approximate, measured 09:40Z: DAA 270,659, 1.095 DAA/s over 25 hours, 1.165 over 4; epoch 3,600, lead 600; seven windows 604,800 DAA wholly after the sweep's end D_s = T + about 40 minutes; the flip epoch the first e with 3600 e - 600 >= D_s + 604,800): T + 6 days 10 hours to T + 6 days 11 hours UK; for a publish at 12:00 UK on 7 October, 13 October between 22:20 and 23:10 UK (about 13:00 UK if the 4-hour rate holds). The floor as it stands (831,600, about 13 October 09:00 UK) would fire before any seven-window signal from a publish today completes, so it moves by the 0.3.16 rule to the publish DAA + 604,800 rounded up to the epoch boundary (882,000 for a 12:00 UK publish), firing about 30 minutes before the earliest signal flip: either way about 6 days 10 hours after the publish, never before every node has had the sweep plus a week. THE CLOCK (the node lane, 11:3x UK, after a Mac reboot moved its runs to the box): the 0.3.20 node line (dc141409 plus the proof archive aea0ca5c plus the amended v4 at object byte 5, igneum-pow at the hash lane's a0aaca92 beside the fork on the box) tested on the box, committed on release-0.3.20-node, pushed to the mirror and origin, igneumd and igneum-miner built, the tip to the shipper: about 12:00 UK; the mixed-version Devnet 2 gate (node-compat.mjs on the box, the amended node beside the 5899f603 pair for ten minutes) and the digest test (digest-compat.mjs): about 12:45 UK; the object-byte pin 5 unless the v5 lane answers both lanes with another assignment (v5 at 6 proposed). THE HASH SIDE on ca3-v4-amend (tip 8c728ca3, read from the branch 14:0x UK; the hash lane's own report pending): 1748fd1d the PC 2 G1-only playbook; e1f48d63 the fud-ledger entry AP-F8-1 (the fault, Josh's ruling, the amendment, the split protection, the owed tests); d8859522 the G1 line (the eight fingerprints equal on the RTX 5090, self-test PASS) and the node lane's signal byte 5; 4aa0c665 the v4 unit test following the amendment; 965d9e96 igneum-pow taken from release-0.3.20's 3f1652bf (the ladder's chain_program_shadow with the reps argument, never on master) with the amendment re-applied, the seven packs re-exporting byte-identical; 8c728ca3 the source rule keyed on the class with the shadow's pass count set aside, so every ladder rung draws under it (the fork's ladder test). The shipper took this igneum-pow tree into release-0.3.20 (00249643, byte-equal); nothing after 8c728ca3 touches igneum-pow. THE VECTORS AND THE PACKS (read from the branch and its ledger entry, 14:1x UK): the seven amended v4 packs (v4-devnet-epoch0, v4-era-0 to 5) carry generator 4, sub-version 1, one program id 1a4230699a6b9c60 (the 2.0 one-id-per-seed rule across the eras; the old c120d7963abdcd96 pinned as must-differ); the v3 control mx8-devnet-epoch0 untouched (73bcbfe8ccf988f1, fingerprint 90f794dd556f7a3b); the seven 2^24 fingerprints, Metal equal to Apple OpenCL: 867dbc45cfb36b4d, 2146ecacc8c75a8e, fe52602393f6d3d4, 3b206471a13912b4, c3f03c4a5d7333aa, f1dfd7209f15bb97, 8c194da64fadf31d; the zip of the eight packs sha256 889ec99976d2728b4b5035bfa476032e5b6a13b928968fc45236d5f25084aa39; the per-pack vectors.json sha256 prefixes 756301bf (devnet epoch 0), 1b5f4568, d430cadc, 1a1b21d8, 460fff9e, 4a85d49d, f83a1196 (eras 0 to 5). G1 on the RTX 5090 (PC 2 job run-ca3-v4-amend-g1-pc2-20261007, 09:41:07 to 09:41:28Z, exit 0, the installed worker): every fingerprint equal to the Mac's (the seven above and the control), NVRTC 188 to 332 ms per pack, the 1 GiB build 38 to 49 ms. hash-gates.md's older table still lists the pre-amendment fingerprints (f410c731... and the eras), which no longer apply to the amended packs; the ledger entry is the record. THE FIRST GREEN (11:31 UK, the box): the kaspa-pow suite on release-0.3.20-node (dc141409 plus the proof archive aea0ca5c plus the object-5 change) against the hash lane's igneum-pow 8c728ca3: 17 passed, 0 failed; the amended devnet epoch-0 id 1a4230699a6b9c60 pinned equal and c120d7963abdcd96 differing, the ladder's rung test green under the rekeyed rule, the v3 control unchanged; the consensus-core and exec RPC suites follow, then the node line (commit, push, box build, the tip to the shipper), then the digest and mixed-version gates. CLOCK RE-CUT (the node lane, 13:0x UK): the node line now carries, beside the object-5 change and the vector test, the lane's 0.3.20 fixes from the day (isSynced from the hook's stamp, the lazy template snapshot, the weight-table cache, the submit path returning after the block task, the watchdog, the RPC fields), about 13:30 UK if the box suites are green; the shipper's fresh-join canary 60 to 100 minutes after the cut; PC 1 as its first machine about 16:00 UK at the earliest, approximate until the shipper names the cut; the earliest flip about 6 days 10 hours after the publish. BUILD-2 LINES (12:28 to 12:33 UK): consensus-core 123 passed (the 60x file test green with the ladder window and activation pinned), the behind test green, kaspa-pow 17 passed (the amended vectors, earlier on build-1), the exec RPC suite green, the flows and rpc-service checks green with the submit-path change; the 24-requester latency test's first run tripped an unrelated flapping-fork double insert (24 equal forks from one parent; the test now builds on the sink as a real miner does; the double insert owed to a small fork harness before it is called a bug); THE NODE LINE COMMITTED (13:1x UK): release-0.3.20-node = 8097d600 (dc141409 + the proof archive aea0ca5c + one commit) on the mirror, pairing igneum-pow 8c728ca3, the hash with the shipper; in it the amended class v4 as object 5 (CLASS_SIGNAL_V4 = 5, byte 4 never counts, the kaspa-pow vector test pinning 1a4230699a6b9c60 equal and c120d7963abdcd96 differing, the daemon's window line naming object 5 and sub-version 1) beside the day's fixes (isSynced from the hook's stamp, the weight-table cache, the lazy snapshot, the submit path, the 100 ms template wait); the suites green on build-2 (consensus-core 123, the exec RPC suite, the four finality tests including 24 requesters under 200 ms: the worst template 100 ms, the worst submit 102 ms) and kaspa-pow 17 on build-1. Next: igneumd and igneum-miner building from 8097d600 on build-1, then the two gate lines (the mixed-version Devnet 2 gate: the 8097d600 node mining beside the 5899f603 pair for ten minutes on the live file without the v4 fields, the old node accepting every block; the digest test: the thirteen-field file b18ed271 unchanged, the sixteen-field object re-read on the 8097d600 binary), expected about 13:30 UK; the shipper picks the cut point. THE DATE FIXED (the node lane, from the hub's live file, 13:3x UK): publish 2 of 6 October (22:49:45Z, digest eada4bda) already put BOTH v4 fields on the live devnet (floor 831,600, window 86,400), so the 0.3.17 fleet has stamped object byte 4 since 7 October 00:2x UK and the floor is live at about 13 October 09:00 UK, before any seven-window signal completes; a 0.3.17 node left on that file flips to the OLD v4 stream at epoch 231 whatever anyone signals, a 0.3.20 node to the amended stream at the same epoch, and the two never share an id, so each straggler forks alone there. REQUIREMENT for the 0.3.20 publish (with the shipper and main): a new file with the floor at the publish DAA + 604,800 rounded up (about 882,000 for a publish today), the digest moving, the one-sweep rollout replacing every 0.3.17 node before 13 October 09:00 UK; any node that misses the sweep is alone then; the earliest flip after that about 6 days 10 hours past the publish; plan section 6.6 amended today. IN THE 0.3.20 PLAN (the shipper, 13:4x UK): both requirements; the node pin by main's rule is the node lane's second commit (the claim floor, the listener watchdog, the claim RPCs, on top of 8097d600) if its suites, both gates and the fleet's 12 GB prover line are green by 15:30 UK, else 8097d600; igneum-pow 8c728ca3 either way; the digest read on whichever binary pins. THE LINE AT 13:5x UK: three commits on release-0.3.20-node, 8097d600 (the object-5 amended class v4 and the day's fixes), 6b94c823 (test-only: the stale PC 1 test from 500ddd66 inverted by the isSynced ruling; the FALLBACK pin, code byte-identical to 8097d600, so the module reads green whole) and 6a3432a3 (the app lane's key methods, the observer's claims, the settled claim floor, the listener watchdog); suites on build-2 on 6a3432a3's code (the whole finality module 25, the exec suite 29 with the watchdog test, the kaspad, flows and rpc-service checks; consensus-core 123 and kaspa-pow 17 earlier); the cut 6a3432a3 if its gates and the fleet's 12 GB settled-claim line are green by 15:30 UK, else 6b94c823; both binaries building on build-1, the two gates (the digest gate, then the ten-minute mixed-version gate beside the 5899f603 pair) on the 8097d600 build, lines about 14:05 UK. GATE NEWS (13:53 UK): on 6a3432a3's own digest gate the listener watchdog counted a bind failure (the four harness nodes share one exec JSON-RPC port) as a listener death and exited three of four nodes at 20 s, where 0.3.17 and 8097d600 only warn and live without the exec RPC; the digest facts came out first and stand (the thirteen-field file a89be8a7 on both binaries, the compat case; the sixteen-field object db9a85f9 refused with the mismatch line, the refusal case); the ten-minute gate on 6a3432a3 stopped as void for the same cause. The fix: a bind failure is a retry every poll, one line a minute, no death counted and never an exit, with a second watchdog test whose known-failed shape is the old rule's exit on a held port; the third commit and its build about 14:15 UK, its gates about 14:35 UK; the fallback 6b94c823's gates on build-1 on their own binary (no watchdog there), lines about 14:20 UK; ledger row N12 for the bind-failure class. A ROLL BLOCKER on every kept datadir (the node lane, 14:1x UK, ledger N13): the fleet started 6a3432a3 on a kept 0.3.17 datadir (pool-1's copy) and it died at start (virtual_state.rs:250, DeserializationError(UnexpectedEof)); the cause 10db4b61 on the 0.3.16 feature line added `silent: bool` to BlockRewardData under serde(default), which bincode ignores, so every build from 10db4b61 on (dc141409, 8097d600, 6b94c823, 6a3432a3, 09124180) reads a 0.3.17 node's virtual-state row short; no canary saw it because every canary wiped, and a one-box roll keeps datadirs, so it blocks the roll on every standing box, the hands and the hub whatever the pin. The fix on the line: the store reads the current layout first and on a deserialization error decodes the row as a v1 mirror, converts with silent false and rewrites it under the same key, with the known-failed test first; the fourth commit and build about 14:40 UK, the fleet's kept-datadir start on the fixed binary about 14:50 UK, its gates after. THE RULE IT ADDS for every node cut from now: a kept-datadir restart gate on a standing box's datadir copy beside the wiped canary. THE CANDIDATE PIN (14:2x UK): b7cc37e7 (8097d600, 6b94c823, 6a3432a3, 09124180, b7cc37e7; igneum-pow 8c728ca3): the N13 fix with its test green on build-2 at 14:04 UK and the kaspad check green, the build on build-1; the fallback 6b94c823 is no longer a pin for the one-box roll (it dies on a kept datadir like every build since 10db4b61): if b7cc37e7's gates are not green by 15:30 UK the honest fallback is 0.3.17's 5899f603 staying live. In flight on build-1: the earlier commits' gates, then b7cc37e7's own digest and ten-minute mixed-version gates on its binary with the read-back, lines about 15:05 UK; on the fleet the kept-datadir start on b7cc37e7 about 14:50 UK and the 12 GB settled-claim line 14:50 to 15:00 UK. Plan section 6.6 amended with the hard date (ca3-v4-node 9d763edd, merged to master); N12 and N13 on the ledger. THE GATES ON THE FALLBACK'S OWN BINARY (6b94c823, sha b1b7d47b, 13:56 to 14:08 UK; code byte-identical to 8097d600, so the amendment's node side): the digest gate, the thirteen-field file a89be8a7 on both binaries (the compat case, n0 peering n1 and n2) and the sixteen-field object db9a85f9 refused with the mismatch line (the refusal case); the mixed-version gate, ten minutes, one digest b0afb2ee on all five nodes, the 5899f603 hub accepting every block the amended node mined (146 new, 246 old, 0 rejected), plain header version 2 on the thirteen-field file, counts equal on all five through the two clean joins and the restart. Two FAILED checks, both the harness's own and fixed (36d3efdc): a refused peer's count read 1 with the reconnect in flight (now the minimum of five), and six address-in-use panics in the two old nodes because the second gate reused the first's ports the second they were sent SIGTERM (a 20 s gap now). CLOCK CORRECTION (the node lane, 12:12Z = 13:12 BST): every "UK" stamp it sent today was the box's CEST, an hour fast of BST; its lines read UTC from now. Restated: b7cc37e7's build about 12:15Z, its digest and mixed-version gates on that binary with the sha and string about 12:32Z (13:32 BST), the fleet's kept-datadir start on it about 12:25Z, its 12 GB settled-claim line 12:50 to 13:00Z; the shipper's checkpoint 14:30Z (15:30 BST), two hours of room. The 13 October date stands (derived from UTC DAA rates): the floor 831,600 about 08:00Z, 09:00 BST. b7cc37e7'S OWN LINES (binary sha256 bc28331abf21f4d5, the string read back on build-1 and on the fleet's pod): the digest gate 12:14:39Z to 12:16:18Z SUMMARY PASS (thirteen fields a89be8a7 on both binaries with the peers as the gate wants them; the sixteen-field object db9a85f9 refused with the line and no peer; the live file's digest eada4bda on the binary, unmoved); the kept-datadir start on the fleet's copy of pool-1's 0.3.17 datadir: the first start 12:17:12Z reads the v1 row through the mirror and rewrites it ("1 mergeset rewards"), the finality blob converts (1,747 locks), the node comes up on its ports with no panic; the second start 12:18:53Z reads first-try with no rewrite line and no panic; 6a3432a3's death on the same copy is the known-failed shape. The ten-minute mixed-version gate beside the 5899f603 pair runs on the same binary since 12:16:39Z, its line about 12:28Z; then the only line outstanding for the shipper's 14:30Z rule is the fleet's 12 GB settled-claim line, 12:50 to 13:00Z. AP-F8-1 RESIDUAL CLASS ON THE AMENDED STREAM (attack-pass lane 12:18Z on igneum-pow 8c728ca3, sub-version 1). F9 over 1,000,000 seeds: programs flagged (hot share at least 1 percent or 7 constant address bits) 1,871 (0.19 percent) against 11,696 (1.17 percent) unamended; worst hot share 9.66 percent against 17.3; mean 0.011 against 0.063 percent; 84 percent of the flagged programs and the whole or-saturation tail gone. F8 at 30 of 64 seeds: nine over 1.2x of the window model (p31 29.3x, p11 5.5x, p19 3.3x, p6 3.1x, p23 2.0x, the rest 1.3x to 1.6x); the 64-seed 1.2x gate is heading to FAIL on sub-version 1. Mechanism, confirmed on the two worst seeds: an all-ones load source (image 0x0ca59e4c under the era map) delivered through a writer the source rule counts as entropy-keeping, a rotate (rotl and rotr map all-ones to itself) or a load whose own source was saturated, with the saturation made one or more writes upstream by or. The rule looks one writer back; it must look through saturation-preserving writers or test the source's values. The ceiling has not moved: rule (c)'s 120-of-128 floor still caps any program at one saturated site, 6.25 percent of reads, a chip edge of at most 1.067x, and the residual (worst seed two sites at 0.53 and 0.56) sits inside it. THE SENTENCE "no lossy-sourced load by construction" IS HELD: it goes in no plan row and no ledger entry as true; sub-version 1 removes the or-source class and bounds the rest. MAIN'S RULING (13:2x UK): 0.3.20 ships object byte 5 on sub-version 1 as it stands, strictly better than the old stream the live floor flips to on 13 October; the fix is sub-version 2 on ca3-v4-amend (object byte 6 or whatever the v5 alignment leaves free) with both fixes: (F1) the static rule made transitive (rotates do not keep entropy; a load keeps entropy only if its own source did; one draw change, no attempts lost) and (F2) the dynamic source check (saturated load SOURCE values counted per site over the 64 units' 16,384 evaluations, rejected above 163 of 16,384, the same 1 percent the final-value rule uses; costs attempts on about 0.2 percent of seeds; rides with F1 because an or-written source is all-ones only (3/4)^32 of the time). Gate before sub-version 2 is proposed, run by the attack-pass lane and not by the hash lane: the full 64-seed census under 1.2x on every seed and the hot-set census. Hash lane's estimate about an hour its side (implement, re-export seven packs, vectors, crate suite, pairing, one G1 on PC 2) plus the node lane's vector re-pin and the attack-pass re-gate. The flip floor for sub-version 1 is expected to move (Josh's word) so the chain never flips to a stream that fails this gate. Also recorded: the crate suite at 8c728ca3 100 of 100 on the box (rc 0, 77 s); the pairing against the fork at dc141409 compiled and ran 15 of 16, the one failure the fork's own pre-amendment assertion (base equals v3's, igneum.rs:972), which 8097d600 on the release-0.3.20-node line turns into assert_ne; the pairing re-runs at b7cc37e7, its line to follow. CORRECTION (the attack-pass lane's own retraction, 13:3x UK): the F9 hot-set figures above (1,871 of 1,000,000, worst 9.66 percent, 84 percent removed, the two or-then-rotate listings) are WITHDRAWN: F9's harness draws through candidate_class with its own era class, outside candidate_from_words_class where the source rule lives, so it measured the old stream (the 8c728ca3 binary prints the identical program to the sub-version-0 binary for its worst seed). F8's 64-seed census on the chain path (pairing verified on 1a4230699a6b9c60) is the valid re-gate and STANDS: at 30 of 64 seeds, nine over 1.2x of the window model (p31 29.3x, p11 5.5x, p19 3.3x, p6 3.1x, p23 2.0x, p4 1.6x, p10 1.5x, p26 1.3x, p25 1.3x). The residual mechanism on the amended stream: a load-after-load chain (a saturated source reads one fixed word, which is the next load's address), admitted because a load injects; and the rotate-preserves-saturation path (generator.rs sets entropy_kept true for a rotate whatever it rotated), correct in code and a second admitted path if it occurs on the chain stream. Sub-version 2 must close both: dataflow freshness per register (a load fresh only if its source was fresh; add, sub, xor, mad, shfl fresh if either operand was; rotates only if the operand was; or, mul, mulhi never) plus the (c') count of saturated load sources per site as the backstop. The STOP holds on F8's evidence alone; the options and the 1.067x ceiling are unchanged. The sentence "no lossy-sourced load by construction" waits on the sub-version 2 census verdict and stays out of every public text until then. SUB-VERSION 2 IN BUILD (the hash lane, ca3-v4-amend, on the coordinator's direction, 13:4x UK): F1 (dataflow freshness per register, keyed on the class v4 shape on every draw path, era or not, so the candidate_class path and the chain path draw one stream) plus F2 (the (c') count of saturated load source values per site over the 64 units' 16,384 evaluations, rejected above 163, keyed on the same shape so v2 and v3 verdicts do not move); PROGRAM_SUBVERSION_V4 = 2, new ids, the seven packs re-exported, recheck.rs with 1a4230699a6b9c60 and c120d7963abdcd96 as the must-differ pair. Clock (UTC): the commit on the branch by 13:30; the crate suite on box 2 and the pairing against b7cc37e7 by about 13:50 (the pairing's vector test fails on the fork's sub-version-1 pin until the node lane re-pins; the compile and the other 15 are the pairing evidence); the G1 job on PC 2 under --cards-off by about 14:10, lock permitting; then the attack-pass lane's full 64-seed census and hot-set census on the chain path. Two consequences stated in the commit: the rule on every draw path moves the no-era sh256xN ladder packs' stream (packs-ca3-shadow's seven 256-block packs re-export with new fingerprints; the measured rates stand as the old stream's), and the class v5 lane's pinned string-seed packs move when it merges sub-version 2, so it re-exports them then. 0.3.20's sub-version-1 packs, ids and fingerprints untouched. OBJECT BYTES SETTLED (main, 13:5x UK): byte 5 = class v4 sub-version 1 (0.3.20), byte 6 = class v5 (pinned: class-v5 16afd0a0, class-v5-node 699db5a2, the flip case passed on 6,6,6; the v5 lane stopped), byte 7 = class v4 sub-version 2; the node and hash lanes told. b7cc37e7's MIXED-VERSION GATE: FAIL, the binary not the harness (12:16:39Z to 12:27:21Z, sha256 bc28331abf21f4d5, the string read back). Before the restart step everything held: one digest b0afb2ee on all five nodes, 268 new and 392 old blocks accepted, 0 rejected, header versions plain 2, counts equal on all five at 324 and 502 through both clean joins. At the new node's restart (12:24:19Z) it died at once on its own datadir ("IO error: While lock file: .../datadir/meta/LOCK: Resource temporarily unavailable", conn_builder.rs:167): the previous process was still shutting down, because the listener watchdog added on 6a3432a3 sleeps its whole 10 s poll before checking shutdown, so every node on the line since then takes up to 10 s longer to stop than 0.3.17 (the fleet saw the same shape as "a 12-second timeout does not stop the node"). Three of the four failed checks follow from that one death (counts, the restarted node's resync, the node it served frozen at 502). The fix on the line, one rule: the poll in 250 ms steps returning the moment shutdown is set, with a test that a shutdown returns within a second (the 10 s loop the known-failed shape); the exec suite on build-2, the fifth commit and its build about 12:45Z, its digest and ten-minute gates about 12:50 to 13:05Z, inside 14:30Z. b7cc37e7 is NOT the pin. The node-side re-pin for sub-version 2 (byte 7) once the hash lane's commit lands: the beside-the-fork igneum-pow copy archived from the commit, the two pinned ids moved in the kaspa-pow vector test (sub-version-2's epoch-0 id must-equal; sub-version-1's joins c120d7963abdcd96 as must-differ), CLASS_SIGNAL and tests for byte 7, the daemon's window line: about 20 minutes of edits plus one kaspa-pow suite run on build-2 (about 2 minutes). THE FIFTH COMMIT c4459193 on release-0.3.20-node (b7cc37e7's child, the watchdog poll returning on shutdown; the diff is the poll loop in rpc.rs alone), pairing igneum-pow 8c728ca3; its build on build-1 started 12:30:13Z, sha256 and string to follow. Line A, the shutdown test: rpc::watchdog_tests::a_shutdown_returns_within_a_second_whatever_the_poll green on build-2 at 12:29Z in the exec suite's 31 passed, beside the two other watchdog tests; its known-failed shape the old loop's 10 s stop. Line B, the kept-datadir start: b7cc37e7's fleet read carries to c4459193 since the store code is byte-identical between the two commits; the fleet re-reads on the c4459193 binary only if the shipper's rule wants the string on that line too. The digest gate and the ten-minute mixed-version gate on c4459193's own binary follow its build. THE SHIPPER'S CARRY RULING (14:1x UK): b7cc37e7's kept-datadir read stands as evidence that the store fix is right (the store code byte-identical) but is not the gate line for the pin, because the rule reads the binary, not the diff, and the binary changed (rpc.rs); the gate line is the kept read on c4459193's own binary with its string, which the fleet's canary already runs on c18-1 (wipe, then the kept read, then the restart) before the canary's restart step, at no extra cost; no re-read on p12-vast. THE PIN IS c4459193 pairing 8c728ca3 (object byte 5, sub-version 1); sub-version 2 (byte 7) is 0.3.21's, not 0.3.20's. The shipper's reading of main's F8 ruling: 0.3.20 ships object 5 as it stands because the live floor otherwise flips every node to the OLD stream on 13 October, and the 16:00 BST report tells Josh the floor move is now RECOMMENDED rather than optional, so the chain never flips to a stream that fails the 1.2x gate before sub-version 2 lands. THE FLEET'S CLOCK ON c4459193 (the fleet lane, 12:5x UTC): the kept read on pool-1's 0.3.17 datadir copy and the restart (the old process's stop time on the line) run on c18-1 before the wipe, a few minutes each, so both lines land before 14:30Z; the wipe canary (IBD from the pruning-point proof, 98 minutes on this pod class) starts when c18-1 is free of the 0.3.20 cases (about 13:00Z) and the binary is in hand, so its synced line lands about 14:40Z at the earliest, PAST the 14:30Z checkpoint; the 12 GB settled-claim line: c4459193 starts on p12-vast's kept copy of pool-1's datadir beside the 6a3432a3 IBD node on alternate ports the moment the binary lands, catches up from 129,398 blocks (15 to 20 minutes) and the 12 GB prover claims against it, the line on c4459193 itself. The binary not yet in the fleet's hand (build-1 building since 12:30:13Z); a wait armed on the sha and string, a report by 13:10Z if nothing. THE SHIPPER'S CALL ON THE CLOCK (14:2x UK): the wipe canary is the decisive read by the deploy rule; the pin never cuts without it and b7cc37e7's lineage does not stand in (the binary changed). The fleet rents a second one-shot pod of c18-1's class now and starts the wipe canary on c4459193's binary the moment the build lands, synced line about 14:15Z (15:15 BST), inside the checkpoint; c18-1 keeps the 0.3.20 cases and the pool window. If the wipe line slips past 15:30 BST the pin holds to it and main hears the clock (a slip is a report, not a cut). The set: the node lane's digest and mixed-version gates (12:50 to 13:05Z), the kept read and restart on the new pod, the wipe line on the new pod, the 12 GB settled-claim line on p12-vast. c4459193's BINARY IN THE FLEET'S HAND (12:34:54Z from build-1): igneumd sha256 45be9b02d1b002f5486d0f0108571c3b6042094113ad9da6f3d3d9ffc0072bba with the string c4459193 read back from the file, igneum-miner c7cfc40bc8b0e357. The wipe pod c19-1 (RunPod wpuke4tfu0vr49, RTX 3070 community, c18-1's class, USD 0.13/h, rented 12:37:03Z, one-shot; the day at USD 124 of work plus the 248 leak, 37 percent of the ceiling): the canary form (wipe, IBD from the pruning-point proof, synced, ten minutes mining with the exec poller, the hub read, the restart read) starts the moment the pod answers ssh; the kept read on pool-1's 0.3.17 copy armed behind its synced line on the same pod; the IBD start stamp its own line; synced about 14:20Z if the pod answers by 12:42Z (ten minutes inside the checkpoint), a slip reported the moment a poll shows it. CASES END on c18-1 at 12:37:18Z rc 0 (the relay and poison lines to the shipper); c18-1 and the two case pods destroyed by the run; the ten-member pool window rented its ten at 12:37:36Z. The 12 GB settled-claim line on p12-vast runs against a c4459193 node on the pod's kept copy, up since 12:36:35Z first-try, catching up. THE WIPE CANARY ON c19-1 STARTED: IBD at 12:38:55Z on c4459193 (sha256 45be9b02... asserted on the Mac before the put; the node's own line igneumd/2.1.0-c4459193 and digest eada4bda8aa8368c read back on the pod; a wiped datadir; IBD from the pruning-point proof with 4 peers at 12:39:26Z); synced about 14:17Z by the 98-minute class, thirteen minutes inside the checkpoint; the mining read, hub read, restart and kept read follow on the same pod, each its own line. c4459193's GATE LINES (the node lane): the binary built on build-1 at 12:33Z (1 m 07 s), sha256 45be9b02d1b002f5, the string read back from the binary (strings, two hits) and the worktree HEAD; igneum-miner beside it at /srv/builds/igneum-wt-ca3-v4-node/vendor/igneum-node-0318-release/target/release/. THE DIGEST GATE 12:33:27Z to 12:35:05Z SUMMARY PASS: the thirteen-field object a89be8a7 on both binaries, n0 peering n1 and n2 and the old node peering the new (the compat case); the sixteen-field object db9a85f9, n3 with no peer and the refusal line "consensus params digest mismatch, local db9a… remote a89b…" (the refusal case); the live file's digest on this binary eada4bda, as 5899f603 reads it. The ten-minute mixed-version gate's line follows. THE INTEROP FACT stands from the void run: the 5899f603 hub accepted 235 object-byte-5 blocks from the 8097d600 node with 0 rejected, one digest on all five nodes on the live sixteen-field file. The gates: the digest test and the kaspa-pow vector test (the amended devnet epoch-0 id 1a4230699a6b9c60 must equal, c120d7963abdcd96 must differ, the v3 control unchanged) on the box; the mixed-version Devnet 2 gate (the amended 0.3.20 node beside a 5899f603 node for ten minutes on the live file without the v4 fields) after the Mac build; the fresh-join canary the 0.3.20 cut's | | Main's rulings (7 October, morning) | no generator change to v4 on the live devnet; the record's null is the window model with numbers, sent by the hash lane to the attack-pass lane so AP-F8-1 re-gates against it; a fault beyond the model (a low-entropy source at site 15) stops at the coordinator with the two options priced (a 0.3.19 class amendment before the flip, or the flip held at the floor), nothing shipping without Josh's word; the tighter tail, an acceptance bound on the hot-set share, is a CLASS V5 item (sent to the v5 lane a6410f3b8abefb762 with the 64-seed census as its gate; the bound's number follows from the model) | ### AP-F4-1, the weak-day MUL draw (the attack-pass lane, 7 October, morning): PASS against v4, a class v5 rule From 3848ac88bded464b1ff74673bc22536b43b67a78 Mon Sep 17 00:00:00 2001 From: igneum-josh <337424239+igneum-josh@users.noreply.github.com> Date: Wed, 7 Oct 2026 13:46:58 +0100 Subject: [PATCH 08/19] Counter ASIC 3.0 status: c4459193's mixed-version gate PASS, the restart step green Co-Authored-By: Claude Fable 5.1 --- docs/plans/counter-asic-3-status.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/plans/counter-asic-3-status.md b/docs/plans/counter-asic-3-status.md index 099e03c3b..e263a02ff 100644 --- a/docs/plans/counter-asic-3-status.md +++ b/docs/plans/counter-asic-3-status.md @@ -338,7 +338,7 @@ Josh gave the go in advance for tonight: the shipper runs publish 1 on the 0.3.1 | THE ANALYSIS (the hash lane, ca3-v4-uniform 095f84a7, `docs/analysis/ca3-v4-uniform.md`, the tool on igneum-build-1) | the window model moves the null from 0.115 to 0.160 percent (1.39x, not 4.05x); the rest is a FAULT beyond it: site 15 reads a register last written by `or r6, r4`, so all-ones recurs at (3/4)^32 per read and the era map sends it to F8's hottest item exactly (the popcount model predicts 77,348 all-ones reads against 78,479; the top-0.1-percent share 0.58 against 0.52); it passes the acceptance rule because part (a) takes any write as a fresh source and part (c) counts saturation on final values only. The census of 1,024 chain-shaped v4 programs: 96.6 percent carry a lossy-sourced load (or, mul, mulhi as the last writer), 48.5 percent an or-sourced one (0.30 percent of all reads per site), 4.9 percent an or-of-or chain (4.6 percent of all reads on 0.1 percent of items); F8's 1.2x gate fails 96.6 percent of today's programs. Worth to a chip: 1.07 MB of SRAM ($0.25) serving 0.52 percent of a typical program's reads and 4.6 percent of the worst class's, at most 1.005x and 1.048x in rate; the ceiling under rule (c)'s 120-of-128 floor one site repeating its item in all 8 iterations, 6.25 percent of reads, 1.067x in 64 bytes; the 2x margin stands; the public line says "bounded at 1.067x", not "uniform" (the public text corrected) | | The two options, priced, STOPPED at the coordinator for Josh's word | A: a 0.3.19 class amendment before the flip (the generator draws a load's source from the registers whose last writer injects): a new program stream, new vectors, the seven gate packs re-exported, the six gates again (G1 to G3 and the verifier about an hour on the Mac and PC 2; G4 to G6 the node lane), every node before the flip under the one-box-at-a-time rule; the risk a node that misses the build splits the chain at the flip. B: hold the flip at the floor with v4 as it is; the bound documented; the source rule to class v5: a hot set worth up to 1.005x on about half the hours and 1.05x on 5 percent, 1.067x at the ceiling; no chain risk. The number: 1.067x at the ceiling against the 2x margin. The lane recommends B | | The v5 bound (sent to the v5 lane) | H = W_0.1 (the window term, 0.115 to 0.251 percent) + the sum over load sites of h(last writer) (or 0.30 percent, an or chain 4.5, mul 0.067, mulhi 0.049, an injecting op or a rotate 0), H at or under 1.2 x W_0.1, which is the static rule "every load's source was last written by an injecting op or a rotate"; as a rejection it costs 96.6 percent of candidates (about 30 attempts per seed), as a generator draw nothing; gate F8's 64-seed census with the saturated-source count | -| JOSH'S WORD (15:2x UK, 7 October): OPTION A, "do this but limit the testing, get it pushed" | the class v4 amendment: a load's source drawn only from registers whose last writer injects or is a rotate (the v5 rule applied now), a new program stream and vectors, the seven gate packs re-exported, the amended class with its own generator stamp; rides 0.3.20, the feature node (release-0.3.20-node = dc141409; 0.3.19 is an app-only cut with nothing of ours), on the shipper's line. The rollout arithmetic for the flip clock (the shipper): the standing fleet's one-box-at-a-time rollout took 32 minutes for 14 boxes (04:56 to 05:28Z, 7 October), the hands and the seed about 3 minutes after the miners, the Mac and the PCs within minutes of the publish; every 0.3.20 worker must accept the amended stamp before any flip. Owners: the hash lane (ca3-v4-amend: the generator, the vectors, the packs, the pairing on the box, one G1 run on PC 2, the ledger row), the node lane (release-0.3.20-node: the stamp agreed with the hash lane, the split-protection mechanism and the earliest flip time, the digest test, the mixed-version Devnet 2 gate), the attack-pass lane (the F8 census at 2^24 on the new stream, the gate 1.2x of the window model over 64 seeds), the shipper (the cut, the rollout order that sets the earliest flip). Testing limited to what prevents a split and proves the fix; G2, G3, the ladder re-measure and the rest of G4 to G6 OWED. THE STAMP agreed (the node and hash lanes, 7 October afternoon): generator 4 with sub-version 1 inside igneum-pow's id function, so the amended v4's program id for a seed differs from the old v4's (the old devnet epoch-0 id c120d7963abdcd96 pinned as the must-differ vector in kaspa-pow's test). SPLIT PROTECTION SETTLED (the node lane, plan section 6.6, ca3-v4-node fa5bc9e6; the node side on release-0.3.20-node): a fresh object byte. CLASS_SIGNAL_V4 is 5; the amended binary stamps 5 and the tally counts a block only at byte 5 or above; object 4 was stamped only by the unpublished dc141409 canary, so no published block carries it and a byte-4 block never counts; a node of the 6 October stream that sees byte 5 counts it as v4 (its rule is at least 4), flips to its own stream at the same epoch and forks ALONE (its blocks fail the amended id check, generator 4 sub-version 1 inside every id; the amended blocks fail its own), ours to upgrade in the sweep; object 6 is class v5's; the two holds already in the rule keep the window shut until every node is on 0.3.20 (a node stamps and tallies only with both v4 fields in its file; the fields publish only after the one-sweep rollout); a lagging worker refuses the amended pack at packcheck and mines nothing after the flip, costing that box, never the chain; no extra window hold: seven full day-windows are the hold. THE EARLIEST FLIP (approximate, measured 09:40Z: DAA 270,659, 1.095 DAA/s over 25 hours, 1.165 over 4; epoch 3,600, lead 600; seven windows 604,800 DAA wholly after the sweep's end D_s = T + about 40 minutes; the flip epoch the first e with 3600 e - 600 >= D_s + 604,800): T + 6 days 10 hours to T + 6 days 11 hours UK; for a publish at 12:00 UK on 7 October, 13 October between 22:20 and 23:10 UK (about 13:00 UK if the 4-hour rate holds). The floor as it stands (831,600, about 13 October 09:00 UK) would fire before any seven-window signal from a publish today completes, so it moves by the 0.3.16 rule to the publish DAA + 604,800 rounded up to the epoch boundary (882,000 for a 12:00 UK publish), firing about 30 minutes before the earliest signal flip: either way about 6 days 10 hours after the publish, never before every node has had the sweep plus a week. THE CLOCK (the node lane, 11:3x UK, after a Mac reboot moved its runs to the box): the 0.3.20 node line (dc141409 plus the proof archive aea0ca5c plus the amended v4 at object byte 5, igneum-pow at the hash lane's a0aaca92 beside the fork on the box) tested on the box, committed on release-0.3.20-node, pushed to the mirror and origin, igneumd and igneum-miner built, the tip to the shipper: about 12:00 UK; the mixed-version Devnet 2 gate (node-compat.mjs on the box, the amended node beside the 5899f603 pair for ten minutes) and the digest test (digest-compat.mjs): about 12:45 UK; the object-byte pin 5 unless the v5 lane answers both lanes with another assignment (v5 at 6 proposed). THE HASH SIDE on ca3-v4-amend (tip 8c728ca3, read from the branch 14:0x UK; the hash lane's own report pending): 1748fd1d the PC 2 G1-only playbook; e1f48d63 the fud-ledger entry AP-F8-1 (the fault, Josh's ruling, the amendment, the split protection, the owed tests); d8859522 the G1 line (the eight fingerprints equal on the RTX 5090, self-test PASS) and the node lane's signal byte 5; 4aa0c665 the v4 unit test following the amendment; 965d9e96 igneum-pow taken from release-0.3.20's 3f1652bf (the ladder's chain_program_shadow with the reps argument, never on master) with the amendment re-applied, the seven packs re-exporting byte-identical; 8c728ca3 the source rule keyed on the class with the shadow's pass count set aside, so every ladder rung draws under it (the fork's ladder test). The shipper took this igneum-pow tree into release-0.3.20 (00249643, byte-equal); nothing after 8c728ca3 touches igneum-pow. THE VECTORS AND THE PACKS (read from the branch and its ledger entry, 14:1x UK): the seven amended v4 packs (v4-devnet-epoch0, v4-era-0 to 5) carry generator 4, sub-version 1, one program id 1a4230699a6b9c60 (the 2.0 one-id-per-seed rule across the eras; the old c120d7963abdcd96 pinned as must-differ); the v3 control mx8-devnet-epoch0 untouched (73bcbfe8ccf988f1, fingerprint 90f794dd556f7a3b); the seven 2^24 fingerprints, Metal equal to Apple OpenCL: 867dbc45cfb36b4d, 2146ecacc8c75a8e, fe52602393f6d3d4, 3b206471a13912b4, c3f03c4a5d7333aa, f1dfd7209f15bb97, 8c194da64fadf31d; the zip of the eight packs sha256 889ec99976d2728b4b5035bfa476032e5b6a13b928968fc45236d5f25084aa39; the per-pack vectors.json sha256 prefixes 756301bf (devnet epoch 0), 1b5f4568, d430cadc, 1a1b21d8, 460fff9e, 4a85d49d, f83a1196 (eras 0 to 5). G1 on the RTX 5090 (PC 2 job run-ca3-v4-amend-g1-pc2-20261007, 09:41:07 to 09:41:28Z, exit 0, the installed worker): every fingerprint equal to the Mac's (the seven above and the control), NVRTC 188 to 332 ms per pack, the 1 GiB build 38 to 49 ms. hash-gates.md's older table still lists the pre-amendment fingerprints (f410c731... and the eras), which no longer apply to the amended packs; the ledger entry is the record. THE FIRST GREEN (11:31 UK, the box): the kaspa-pow suite on release-0.3.20-node (dc141409 plus the proof archive aea0ca5c plus the object-5 change) against the hash lane's igneum-pow 8c728ca3: 17 passed, 0 failed; the amended devnet epoch-0 id 1a4230699a6b9c60 pinned equal and c120d7963abdcd96 differing, the ladder's rung test green under the rekeyed rule, the v3 control unchanged; the consensus-core and exec RPC suites follow, then the node line (commit, push, box build, the tip to the shipper), then the digest and mixed-version gates. CLOCK RE-CUT (the node lane, 13:0x UK): the node line now carries, beside the object-5 change and the vector test, the lane's 0.3.20 fixes from the day (isSynced from the hook's stamp, the lazy template snapshot, the weight-table cache, the submit path returning after the block task, the watchdog, the RPC fields), about 13:30 UK if the box suites are green; the shipper's fresh-join canary 60 to 100 minutes after the cut; PC 1 as its first machine about 16:00 UK at the earliest, approximate until the shipper names the cut; the earliest flip about 6 days 10 hours after the publish. BUILD-2 LINES (12:28 to 12:33 UK): consensus-core 123 passed (the 60x file test green with the ladder window and activation pinned), the behind test green, kaspa-pow 17 passed (the amended vectors, earlier on build-1), the exec RPC suite green, the flows and rpc-service checks green with the submit-path change; the 24-requester latency test's first run tripped an unrelated flapping-fork double insert (24 equal forks from one parent; the test now builds on the sink as a real miner does; the double insert owed to a small fork harness before it is called a bug); THE NODE LINE COMMITTED (13:1x UK): release-0.3.20-node = 8097d600 (dc141409 + the proof archive aea0ca5c + one commit) on the mirror, pairing igneum-pow 8c728ca3, the hash with the shipper; in it the amended class v4 as object 5 (CLASS_SIGNAL_V4 = 5, byte 4 never counts, the kaspa-pow vector test pinning 1a4230699a6b9c60 equal and c120d7963abdcd96 differing, the daemon's window line naming object 5 and sub-version 1) beside the day's fixes (isSynced from the hook's stamp, the weight-table cache, the lazy snapshot, the submit path, the 100 ms template wait); the suites green on build-2 (consensus-core 123, the exec RPC suite, the four finality tests including 24 requesters under 200 ms: the worst template 100 ms, the worst submit 102 ms) and kaspa-pow 17 on build-1. Next: igneumd and igneum-miner building from 8097d600 on build-1, then the two gate lines (the mixed-version Devnet 2 gate: the 8097d600 node mining beside the 5899f603 pair for ten minutes on the live file without the v4 fields, the old node accepting every block; the digest test: the thirteen-field file b18ed271 unchanged, the sixteen-field object re-read on the 8097d600 binary), expected about 13:30 UK; the shipper picks the cut point. THE DATE FIXED (the node lane, from the hub's live file, 13:3x UK): publish 2 of 6 October (22:49:45Z, digest eada4bda) already put BOTH v4 fields on the live devnet (floor 831,600, window 86,400), so the 0.3.17 fleet has stamped object byte 4 since 7 October 00:2x UK and the floor is live at about 13 October 09:00 UK, before any seven-window signal completes; a 0.3.17 node left on that file flips to the OLD v4 stream at epoch 231 whatever anyone signals, a 0.3.20 node to the amended stream at the same epoch, and the two never share an id, so each straggler forks alone there. REQUIREMENT for the 0.3.20 publish (with the shipper and main): a new file with the floor at the publish DAA + 604,800 rounded up (about 882,000 for a publish today), the digest moving, the one-sweep rollout replacing every 0.3.17 node before 13 October 09:00 UK; any node that misses the sweep is alone then; the earliest flip after that about 6 days 10 hours past the publish; plan section 6.6 amended today. IN THE 0.3.20 PLAN (the shipper, 13:4x UK): both requirements; the node pin by main's rule is the node lane's second commit (the claim floor, the listener watchdog, the claim RPCs, on top of 8097d600) if its suites, both gates and the fleet's 12 GB prover line are green by 15:30 UK, else 8097d600; igneum-pow 8c728ca3 either way; the digest read on whichever binary pins. THE LINE AT 13:5x UK: three commits on release-0.3.20-node, 8097d600 (the object-5 amended class v4 and the day's fixes), 6b94c823 (test-only: the stale PC 1 test from 500ddd66 inverted by the isSynced ruling; the FALLBACK pin, code byte-identical to 8097d600, so the module reads green whole) and 6a3432a3 (the app lane's key methods, the observer's claims, the settled claim floor, the listener watchdog); suites on build-2 on 6a3432a3's code (the whole finality module 25, the exec suite 29 with the watchdog test, the kaspad, flows and rpc-service checks; consensus-core 123 and kaspa-pow 17 earlier); the cut 6a3432a3 if its gates and the fleet's 12 GB settled-claim line are green by 15:30 UK, else 6b94c823; both binaries building on build-1, the two gates (the digest gate, then the ten-minute mixed-version gate beside the 5899f603 pair) on the 8097d600 build, lines about 14:05 UK. GATE NEWS (13:53 UK): on 6a3432a3's own digest gate the listener watchdog counted a bind failure (the four harness nodes share one exec JSON-RPC port) as a listener death and exited three of four nodes at 20 s, where 0.3.17 and 8097d600 only warn and live without the exec RPC; the digest facts came out first and stand (the thirteen-field file a89be8a7 on both binaries, the compat case; the sixteen-field object db9a85f9 refused with the mismatch line, the refusal case); the ten-minute gate on 6a3432a3 stopped as void for the same cause. The fix: a bind failure is a retry every poll, one line a minute, no death counted and never an exit, with a second watchdog test whose known-failed shape is the old rule's exit on a held port; the third commit and its build about 14:15 UK, its gates about 14:35 UK; the fallback 6b94c823's gates on build-1 on their own binary (no watchdog there), lines about 14:20 UK; ledger row N12 for the bind-failure class. A ROLL BLOCKER on every kept datadir (the node lane, 14:1x UK, ledger N13): the fleet started 6a3432a3 on a kept 0.3.17 datadir (pool-1's copy) and it died at start (virtual_state.rs:250, DeserializationError(UnexpectedEof)); the cause 10db4b61 on the 0.3.16 feature line added `silent: bool` to BlockRewardData under serde(default), which bincode ignores, so every build from 10db4b61 on (dc141409, 8097d600, 6b94c823, 6a3432a3, 09124180) reads a 0.3.17 node's virtual-state row short; no canary saw it because every canary wiped, and a one-box roll keeps datadirs, so it blocks the roll on every standing box, the hands and the hub whatever the pin. The fix on the line: the store reads the current layout first and on a deserialization error decodes the row as a v1 mirror, converts with silent false and rewrites it under the same key, with the known-failed test first; the fourth commit and build about 14:40 UK, the fleet's kept-datadir start on the fixed binary about 14:50 UK, its gates after. THE RULE IT ADDS for every node cut from now: a kept-datadir restart gate on a standing box's datadir copy beside the wiped canary. THE CANDIDATE PIN (14:2x UK): b7cc37e7 (8097d600, 6b94c823, 6a3432a3, 09124180, b7cc37e7; igneum-pow 8c728ca3): the N13 fix with its test green on build-2 at 14:04 UK and the kaspad check green, the build on build-1; the fallback 6b94c823 is no longer a pin for the one-box roll (it dies on a kept datadir like every build since 10db4b61): if b7cc37e7's gates are not green by 15:30 UK the honest fallback is 0.3.17's 5899f603 staying live. In flight on build-1: the earlier commits' gates, then b7cc37e7's own digest and ten-minute mixed-version gates on its binary with the read-back, lines about 15:05 UK; on the fleet the kept-datadir start on b7cc37e7 about 14:50 UK and the 12 GB settled-claim line 14:50 to 15:00 UK. Plan section 6.6 amended with the hard date (ca3-v4-node 9d763edd, merged to master); N12 and N13 on the ledger. THE GATES ON THE FALLBACK'S OWN BINARY (6b94c823, sha b1b7d47b, 13:56 to 14:08 UK; code byte-identical to 8097d600, so the amendment's node side): the digest gate, the thirteen-field file a89be8a7 on both binaries (the compat case, n0 peering n1 and n2) and the sixteen-field object db9a85f9 refused with the mismatch line (the refusal case); the mixed-version gate, ten minutes, one digest b0afb2ee on all five nodes, the 5899f603 hub accepting every block the amended node mined (146 new, 246 old, 0 rejected), plain header version 2 on the thirteen-field file, counts equal on all five through the two clean joins and the restart. Two FAILED checks, both the harness's own and fixed (36d3efdc): a refused peer's count read 1 with the reconnect in flight (now the minimum of five), and six address-in-use panics in the two old nodes because the second gate reused the first's ports the second they were sent SIGTERM (a 20 s gap now). CLOCK CORRECTION (the node lane, 12:12Z = 13:12 BST): every "UK" stamp it sent today was the box's CEST, an hour fast of BST; its lines read UTC from now. Restated: b7cc37e7's build about 12:15Z, its digest and mixed-version gates on that binary with the sha and string about 12:32Z (13:32 BST), the fleet's kept-datadir start on it about 12:25Z, its 12 GB settled-claim line 12:50 to 13:00Z; the shipper's checkpoint 14:30Z (15:30 BST), two hours of room. The 13 October date stands (derived from UTC DAA rates): the floor 831,600 about 08:00Z, 09:00 BST. b7cc37e7'S OWN LINES (binary sha256 bc28331abf21f4d5, the string read back on build-1 and on the fleet's pod): the digest gate 12:14:39Z to 12:16:18Z SUMMARY PASS (thirteen fields a89be8a7 on both binaries with the peers as the gate wants them; the sixteen-field object db9a85f9 refused with the line and no peer; the live file's digest eada4bda on the binary, unmoved); the kept-datadir start on the fleet's copy of pool-1's 0.3.17 datadir: the first start 12:17:12Z reads the v1 row through the mirror and rewrites it ("1 mergeset rewards"), the finality blob converts (1,747 locks), the node comes up on its ports with no panic; the second start 12:18:53Z reads first-try with no rewrite line and no panic; 6a3432a3's death on the same copy is the known-failed shape. The ten-minute mixed-version gate beside the 5899f603 pair runs on the same binary since 12:16:39Z, its line about 12:28Z; then the only line outstanding for the shipper's 14:30Z rule is the fleet's 12 GB settled-claim line, 12:50 to 13:00Z. AP-F8-1 RESIDUAL CLASS ON THE AMENDED STREAM (attack-pass lane 12:18Z on igneum-pow 8c728ca3, sub-version 1). F9 over 1,000,000 seeds: programs flagged (hot share at least 1 percent or 7 constant address bits) 1,871 (0.19 percent) against 11,696 (1.17 percent) unamended; worst hot share 9.66 percent against 17.3; mean 0.011 against 0.063 percent; 84 percent of the flagged programs and the whole or-saturation tail gone. F8 at 30 of 64 seeds: nine over 1.2x of the window model (p31 29.3x, p11 5.5x, p19 3.3x, p6 3.1x, p23 2.0x, the rest 1.3x to 1.6x); the 64-seed 1.2x gate is heading to FAIL on sub-version 1. Mechanism, confirmed on the two worst seeds: an all-ones load source (image 0x0ca59e4c under the era map) delivered through a writer the source rule counts as entropy-keeping, a rotate (rotl and rotr map all-ones to itself) or a load whose own source was saturated, with the saturation made one or more writes upstream by or. The rule looks one writer back; it must look through saturation-preserving writers or test the source's values. The ceiling has not moved: rule (c)'s 120-of-128 floor still caps any program at one saturated site, 6.25 percent of reads, a chip edge of at most 1.067x, and the residual (worst seed two sites at 0.53 and 0.56) sits inside it. THE SENTENCE "no lossy-sourced load by construction" IS HELD: it goes in no plan row and no ledger entry as true; sub-version 1 removes the or-source class and bounds the rest. MAIN'S RULING (13:2x UK): 0.3.20 ships object byte 5 on sub-version 1 as it stands, strictly better than the old stream the live floor flips to on 13 October; the fix is sub-version 2 on ca3-v4-amend (object byte 6 or whatever the v5 alignment leaves free) with both fixes: (F1) the static rule made transitive (rotates do not keep entropy; a load keeps entropy only if its own source did; one draw change, no attempts lost) and (F2) the dynamic source check (saturated load SOURCE values counted per site over the 64 units' 16,384 evaluations, rejected above 163 of 16,384, the same 1 percent the final-value rule uses; costs attempts on about 0.2 percent of seeds; rides with F1 because an or-written source is all-ones only (3/4)^32 of the time). Gate before sub-version 2 is proposed, run by the attack-pass lane and not by the hash lane: the full 64-seed census under 1.2x on every seed and the hot-set census. Hash lane's estimate about an hour its side (implement, re-export seven packs, vectors, crate suite, pairing, one G1 on PC 2) plus the node lane's vector re-pin and the attack-pass re-gate. The flip floor for sub-version 1 is expected to move (Josh's word) so the chain never flips to a stream that fails this gate. Also recorded: the crate suite at 8c728ca3 100 of 100 on the box (rc 0, 77 s); the pairing against the fork at dc141409 compiled and ran 15 of 16, the one failure the fork's own pre-amendment assertion (base equals v3's, igneum.rs:972), which 8097d600 on the release-0.3.20-node line turns into assert_ne; the pairing re-runs at b7cc37e7, its line to follow. CORRECTION (the attack-pass lane's own retraction, 13:3x UK): the F9 hot-set figures above (1,871 of 1,000,000, worst 9.66 percent, 84 percent removed, the two or-then-rotate listings) are WITHDRAWN: F9's harness draws through candidate_class with its own era class, outside candidate_from_words_class where the source rule lives, so it measured the old stream (the 8c728ca3 binary prints the identical program to the sub-version-0 binary for its worst seed). F8's 64-seed census on the chain path (pairing verified on 1a4230699a6b9c60) is the valid re-gate and STANDS: at 30 of 64 seeds, nine over 1.2x of the window model (p31 29.3x, p11 5.5x, p19 3.3x, p6 3.1x, p23 2.0x, p4 1.6x, p10 1.5x, p26 1.3x, p25 1.3x). The residual mechanism on the amended stream: a load-after-load chain (a saturated source reads one fixed word, which is the next load's address), admitted because a load injects; and the rotate-preserves-saturation path (generator.rs sets entropy_kept true for a rotate whatever it rotated), correct in code and a second admitted path if it occurs on the chain stream. Sub-version 2 must close both: dataflow freshness per register (a load fresh only if its source was fresh; add, sub, xor, mad, shfl fresh if either operand was; rotates only if the operand was; or, mul, mulhi never) plus the (c') count of saturated load sources per site as the backstop. The STOP holds on F8's evidence alone; the options and the 1.067x ceiling are unchanged. The sentence "no lossy-sourced load by construction" waits on the sub-version 2 census verdict and stays out of every public text until then. SUB-VERSION 2 IN BUILD (the hash lane, ca3-v4-amend, on the coordinator's direction, 13:4x UK): F1 (dataflow freshness per register, keyed on the class v4 shape on every draw path, era or not, so the candidate_class path and the chain path draw one stream) plus F2 (the (c') count of saturated load source values per site over the 64 units' 16,384 evaluations, rejected above 163, keyed on the same shape so v2 and v3 verdicts do not move); PROGRAM_SUBVERSION_V4 = 2, new ids, the seven packs re-exported, recheck.rs with 1a4230699a6b9c60 and c120d7963abdcd96 as the must-differ pair. Clock (UTC): the commit on the branch by 13:30; the crate suite on box 2 and the pairing against b7cc37e7 by about 13:50 (the pairing's vector test fails on the fork's sub-version-1 pin until the node lane re-pins; the compile and the other 15 are the pairing evidence); the G1 job on PC 2 under --cards-off by about 14:10, lock permitting; then the attack-pass lane's full 64-seed census and hot-set census on the chain path. Two consequences stated in the commit: the rule on every draw path moves the no-era sh256xN ladder packs' stream (packs-ca3-shadow's seven 256-block packs re-export with new fingerprints; the measured rates stand as the old stream's), and the class v5 lane's pinned string-seed packs move when it merges sub-version 2, so it re-exports them then. 0.3.20's sub-version-1 packs, ids and fingerprints untouched. OBJECT BYTES SETTLED (main, 13:5x UK): byte 5 = class v4 sub-version 1 (0.3.20), byte 6 = class v5 (pinned: class-v5 16afd0a0, class-v5-node 699db5a2, the flip case passed on 6,6,6; the v5 lane stopped), byte 7 = class v4 sub-version 2; the node and hash lanes told. b7cc37e7's MIXED-VERSION GATE: FAIL, the binary not the harness (12:16:39Z to 12:27:21Z, sha256 bc28331abf21f4d5, the string read back). Before the restart step everything held: one digest b0afb2ee on all five nodes, 268 new and 392 old blocks accepted, 0 rejected, header versions plain 2, counts equal on all five at 324 and 502 through both clean joins. At the new node's restart (12:24:19Z) it died at once on its own datadir ("IO error: While lock file: .../datadir/meta/LOCK: Resource temporarily unavailable", conn_builder.rs:167): the previous process was still shutting down, because the listener watchdog added on 6a3432a3 sleeps its whole 10 s poll before checking shutdown, so every node on the line since then takes up to 10 s longer to stop than 0.3.17 (the fleet saw the same shape as "a 12-second timeout does not stop the node"). Three of the four failed checks follow from that one death (counts, the restarted node's resync, the node it served frozen at 502). The fix on the line, one rule: the poll in 250 ms steps returning the moment shutdown is set, with a test that a shutdown returns within a second (the 10 s loop the known-failed shape); the exec suite on build-2, the fifth commit and its build about 12:45Z, its digest and ten-minute gates about 12:50 to 13:05Z, inside 14:30Z. b7cc37e7 is NOT the pin. The node-side re-pin for sub-version 2 (byte 7) once the hash lane's commit lands: the beside-the-fork igneum-pow copy archived from the commit, the two pinned ids moved in the kaspa-pow vector test (sub-version-2's epoch-0 id must-equal; sub-version-1's joins c120d7963abdcd96 as must-differ), CLASS_SIGNAL and tests for byte 7, the daemon's window line: about 20 minutes of edits plus one kaspa-pow suite run on build-2 (about 2 minutes). THE FIFTH COMMIT c4459193 on release-0.3.20-node (b7cc37e7's child, the watchdog poll returning on shutdown; the diff is the poll loop in rpc.rs alone), pairing igneum-pow 8c728ca3; its build on build-1 started 12:30:13Z, sha256 and string to follow. Line A, the shutdown test: rpc::watchdog_tests::a_shutdown_returns_within_a_second_whatever_the_poll green on build-2 at 12:29Z in the exec suite's 31 passed, beside the two other watchdog tests; its known-failed shape the old loop's 10 s stop. Line B, the kept-datadir start: b7cc37e7's fleet read carries to c4459193 since the store code is byte-identical between the two commits; the fleet re-reads on the c4459193 binary only if the shipper's rule wants the string on that line too. The digest gate and the ten-minute mixed-version gate on c4459193's own binary follow its build. THE SHIPPER'S CARRY RULING (14:1x UK): b7cc37e7's kept-datadir read stands as evidence that the store fix is right (the store code byte-identical) but is not the gate line for the pin, because the rule reads the binary, not the diff, and the binary changed (rpc.rs); the gate line is the kept read on c4459193's own binary with its string, which the fleet's canary already runs on c18-1 (wipe, then the kept read, then the restart) before the canary's restart step, at no extra cost; no re-read on p12-vast. THE PIN IS c4459193 pairing 8c728ca3 (object byte 5, sub-version 1); sub-version 2 (byte 7) is 0.3.21's, not 0.3.20's. The shipper's reading of main's F8 ruling: 0.3.20 ships object 5 as it stands because the live floor otherwise flips every node to the OLD stream on 13 October, and the 16:00 BST report tells Josh the floor move is now RECOMMENDED rather than optional, so the chain never flips to a stream that fails the 1.2x gate before sub-version 2 lands. THE FLEET'S CLOCK ON c4459193 (the fleet lane, 12:5x UTC): the kept read on pool-1's 0.3.17 datadir copy and the restart (the old process's stop time on the line) run on c18-1 before the wipe, a few minutes each, so both lines land before 14:30Z; the wipe canary (IBD from the pruning-point proof, 98 minutes on this pod class) starts when c18-1 is free of the 0.3.20 cases (about 13:00Z) and the binary is in hand, so its synced line lands about 14:40Z at the earliest, PAST the 14:30Z checkpoint; the 12 GB settled-claim line: c4459193 starts on p12-vast's kept copy of pool-1's datadir beside the 6a3432a3 IBD node on alternate ports the moment the binary lands, catches up from 129,398 blocks (15 to 20 minutes) and the 12 GB prover claims against it, the line on c4459193 itself. The binary not yet in the fleet's hand (build-1 building since 12:30:13Z); a wait armed on the sha and string, a report by 13:10Z if nothing. THE SHIPPER'S CALL ON THE CLOCK (14:2x UK): the wipe canary is the decisive read by the deploy rule; the pin never cuts without it and b7cc37e7's lineage does not stand in (the binary changed). The fleet rents a second one-shot pod of c18-1's class now and starts the wipe canary on c4459193's binary the moment the build lands, synced line about 14:15Z (15:15 BST), inside the checkpoint; c18-1 keeps the 0.3.20 cases and the pool window. If the wipe line slips past 15:30 BST the pin holds to it and main hears the clock (a slip is a report, not a cut). The set: the node lane's digest and mixed-version gates (12:50 to 13:05Z), the kept read and restart on the new pod, the wipe line on the new pod, the 12 GB settled-claim line on p12-vast. c4459193's BINARY IN THE FLEET'S HAND (12:34:54Z from build-1): igneumd sha256 45be9b02d1b002f5486d0f0108571c3b6042094113ad9da6f3d3d9ffc0072bba with the string c4459193 read back from the file, igneum-miner c7cfc40bc8b0e357. The wipe pod c19-1 (RunPod wpuke4tfu0vr49, RTX 3070 community, c18-1's class, USD 0.13/h, rented 12:37:03Z, one-shot; the day at USD 124 of work plus the 248 leak, 37 percent of the ceiling): the canary form (wipe, IBD from the pruning-point proof, synced, ten minutes mining with the exec poller, the hub read, the restart read) starts the moment the pod answers ssh; the kept read on pool-1's 0.3.17 copy armed behind its synced line on the same pod; the IBD start stamp its own line; synced about 14:20Z if the pod answers by 12:42Z (ten minutes inside the checkpoint), a slip reported the moment a poll shows it. CASES END on c18-1 at 12:37:18Z rc 0 (the relay and poison lines to the shipper); c18-1 and the two case pods destroyed by the run; the ten-member pool window rented its ten at 12:37:36Z. The 12 GB settled-claim line on p12-vast runs against a c4459193 node on the pod's kept copy, up since 12:36:35Z first-try, catching up. THE WIPE CANARY ON c19-1 STARTED: IBD at 12:38:55Z on c4459193 (sha256 45be9b02... asserted on the Mac before the put; the node's own line igneumd/2.1.0-c4459193 and digest eada4bda8aa8368c read back on the pod; a wiped datadir; IBD from the pruning-point proof with 4 peers at 12:39:26Z); synced about 14:17Z by the 98-minute class, thirteen minutes inside the checkpoint; the mining read, hub read, restart and kept read follow on the same pod, each its own line. c4459193's GATE LINES (the node lane): the binary built on build-1 at 12:33Z (1 m 07 s), sha256 45be9b02d1b002f5, the string read back from the binary (strings, two hits) and the worktree HEAD; igneum-miner beside it at /srv/builds/igneum-wt-ca3-v4-node/vendor/igneum-node-0318-release/target/release/. THE DIGEST GATE 12:33:27Z to 12:35:05Z SUMMARY PASS: the thirteen-field object a89be8a7 on both binaries, n0 peering n1 and n2 and the old node peering the new (the compat case); the sixteen-field object db9a85f9, n3 with no peer and the refusal line "consensus params digest mismatch, local db9a… remote a89b…" (the refusal case); the live file's digest on this binary eada4bda, as 5899f603 reads it. The ten-minute mixed-version gate's line follows. THE INTEROP FACT stands from the void run: the 5899f603 hub accepted 235 object-byte-5 blocks from the 8097d600 node with 0 rejected, one digest on all five nodes on the live sixteen-field file. The gates: the digest test and the kaspa-pow vector test (the amended devnet epoch-0 id 1a4230699a6b9c60 must equal, c120d7963abdcd96 must differ, the v3 control unchanged) on the box; the mixed-version Devnet 2 gate (the amended 0.3.20 node beside a 5899f603 node for ten minutes on the live file without the v4 fields) after the Mac build; the fresh-join canary the 0.3.20 cut's | +| JOSH'S WORD (15:2x UK, 7 October): OPTION A, "do this but limit the testing, get it pushed" | the class v4 amendment: a load's source drawn only from registers whose last writer injects or is a rotate (the v5 rule applied now), a new program stream and vectors, the seven gate packs re-exported, the amended class with its own generator stamp; rides 0.3.20, the feature node (release-0.3.20-node = dc141409; 0.3.19 is an app-only cut with nothing of ours), on the shipper's line. The rollout arithmetic for the flip clock (the shipper): the standing fleet's one-box-at-a-time rollout took 32 minutes for 14 boxes (04:56 to 05:28Z, 7 October), the hands and the seed about 3 minutes after the miners, the Mac and the PCs within minutes of the publish; every 0.3.20 worker must accept the amended stamp before any flip. Owners: the hash lane (ca3-v4-amend: the generator, the vectors, the packs, the pairing on the box, one G1 run on PC 2, the ledger row), the node lane (release-0.3.20-node: the stamp agreed with the hash lane, the split-protection mechanism and the earliest flip time, the digest test, the mixed-version Devnet 2 gate), the attack-pass lane (the F8 census at 2^24 on the new stream, the gate 1.2x of the window model over 64 seeds), the shipper (the cut, the rollout order that sets the earliest flip). Testing limited to what prevents a split and proves the fix; G2, G3, the ladder re-measure and the rest of G4 to G6 OWED. THE STAMP agreed (the node and hash lanes, 7 October afternoon): generator 4 with sub-version 1 inside igneum-pow's id function, so the amended v4's program id for a seed differs from the old v4's (the old devnet epoch-0 id c120d7963abdcd96 pinned as the must-differ vector in kaspa-pow's test). SPLIT PROTECTION SETTLED (the node lane, plan section 6.6, ca3-v4-node fa5bc9e6; the node side on release-0.3.20-node): a fresh object byte. CLASS_SIGNAL_V4 is 5; the amended binary stamps 5 and the tally counts a block only at byte 5 or above; object 4 was stamped only by the unpublished dc141409 canary, so no published block carries it and a byte-4 block never counts; a node of the 6 October stream that sees byte 5 counts it as v4 (its rule is at least 4), flips to its own stream at the same epoch and forks ALONE (its blocks fail the amended id check, generator 4 sub-version 1 inside every id; the amended blocks fail its own), ours to upgrade in the sweep; object 6 is class v5's; the two holds already in the rule keep the window shut until every node is on 0.3.20 (a node stamps and tallies only with both v4 fields in its file; the fields publish only after the one-sweep rollout); a lagging worker refuses the amended pack at packcheck and mines nothing after the flip, costing that box, never the chain; no extra window hold: seven full day-windows are the hold. THE EARLIEST FLIP (approximate, measured 09:40Z: DAA 270,659, 1.095 DAA/s over 25 hours, 1.165 over 4; epoch 3,600, lead 600; seven windows 604,800 DAA wholly after the sweep's end D_s = T + about 40 minutes; the flip epoch the first e with 3600 e - 600 >= D_s + 604,800): T + 6 days 10 hours to T + 6 days 11 hours UK; for a publish at 12:00 UK on 7 October, 13 October between 22:20 and 23:10 UK (about 13:00 UK if the 4-hour rate holds). The floor as it stands (831,600, about 13 October 09:00 UK) would fire before any seven-window signal from a publish today completes, so it moves by the 0.3.16 rule to the publish DAA + 604,800 rounded up to the epoch boundary (882,000 for a 12:00 UK publish), firing about 30 minutes before the earliest signal flip: either way about 6 days 10 hours after the publish, never before every node has had the sweep plus a week. THE CLOCK (the node lane, 11:3x UK, after a Mac reboot moved its runs to the box): the 0.3.20 node line (dc141409 plus the proof archive aea0ca5c plus the amended v4 at object byte 5, igneum-pow at the hash lane's a0aaca92 beside the fork on the box) tested on the box, committed on release-0.3.20-node, pushed to the mirror and origin, igneumd and igneum-miner built, the tip to the shipper: about 12:00 UK; the mixed-version Devnet 2 gate (node-compat.mjs on the box, the amended node beside the 5899f603 pair for ten minutes) and the digest test (digest-compat.mjs): about 12:45 UK; the object-byte pin 5 unless the v5 lane answers both lanes with another assignment (v5 at 6 proposed). THE HASH SIDE on ca3-v4-amend (tip 8c728ca3, read from the branch 14:0x UK; the hash lane's own report pending): 1748fd1d the PC 2 G1-only playbook; e1f48d63 the fud-ledger entry AP-F8-1 (the fault, Josh's ruling, the amendment, the split protection, the owed tests); d8859522 the G1 line (the eight fingerprints equal on the RTX 5090, self-test PASS) and the node lane's signal byte 5; 4aa0c665 the v4 unit test following the amendment; 965d9e96 igneum-pow taken from release-0.3.20's 3f1652bf (the ladder's chain_program_shadow with the reps argument, never on master) with the amendment re-applied, the seven packs re-exporting byte-identical; 8c728ca3 the source rule keyed on the class with the shadow's pass count set aside, so every ladder rung draws under it (the fork's ladder test). The shipper took this igneum-pow tree into release-0.3.20 (00249643, byte-equal); nothing after 8c728ca3 touches igneum-pow. THE VECTORS AND THE PACKS (read from the branch and its ledger entry, 14:1x UK): the seven amended v4 packs (v4-devnet-epoch0, v4-era-0 to 5) carry generator 4, sub-version 1, one program id 1a4230699a6b9c60 (the 2.0 one-id-per-seed rule across the eras; the old c120d7963abdcd96 pinned as must-differ); the v3 control mx8-devnet-epoch0 untouched (73bcbfe8ccf988f1, fingerprint 90f794dd556f7a3b); the seven 2^24 fingerprints, Metal equal to Apple OpenCL: 867dbc45cfb36b4d, 2146ecacc8c75a8e, fe52602393f6d3d4, 3b206471a13912b4, c3f03c4a5d7333aa, f1dfd7209f15bb97, 8c194da64fadf31d; the zip of the eight packs sha256 889ec99976d2728b4b5035bfa476032e5b6a13b928968fc45236d5f25084aa39; the per-pack vectors.json sha256 prefixes 756301bf (devnet epoch 0), 1b5f4568, d430cadc, 1a1b21d8, 460fff9e, 4a85d49d, f83a1196 (eras 0 to 5). G1 on the RTX 5090 (PC 2 job run-ca3-v4-amend-g1-pc2-20261007, 09:41:07 to 09:41:28Z, exit 0, the installed worker): every fingerprint equal to the Mac's (the seven above and the control), NVRTC 188 to 332 ms per pack, the 1 GiB build 38 to 49 ms. hash-gates.md's older table still lists the pre-amendment fingerprints (f410c731... and the eras), which no longer apply to the amended packs; the ledger entry is the record. THE FIRST GREEN (11:31 UK, the box): the kaspa-pow suite on release-0.3.20-node (dc141409 plus the proof archive aea0ca5c plus the object-5 change) against the hash lane's igneum-pow 8c728ca3: 17 passed, 0 failed; the amended devnet epoch-0 id 1a4230699a6b9c60 pinned equal and c120d7963abdcd96 differing, the ladder's rung test green under the rekeyed rule, the v3 control unchanged; the consensus-core and exec RPC suites follow, then the node line (commit, push, box build, the tip to the shipper), then the digest and mixed-version gates. CLOCK RE-CUT (the node lane, 13:0x UK): the node line now carries, beside the object-5 change and the vector test, the lane's 0.3.20 fixes from the day (isSynced from the hook's stamp, the lazy template snapshot, the weight-table cache, the submit path returning after the block task, the watchdog, the RPC fields), about 13:30 UK if the box suites are green; the shipper's fresh-join canary 60 to 100 minutes after the cut; PC 1 as its first machine about 16:00 UK at the earliest, approximate until the shipper names the cut; the earliest flip about 6 days 10 hours after the publish. BUILD-2 LINES (12:28 to 12:33 UK): consensus-core 123 passed (the 60x file test green with the ladder window and activation pinned), the behind test green, kaspa-pow 17 passed (the amended vectors, earlier on build-1), the exec RPC suite green, the flows and rpc-service checks green with the submit-path change; the 24-requester latency test's first run tripped an unrelated flapping-fork double insert (24 equal forks from one parent; the test now builds on the sink as a real miner does; the double insert owed to a small fork harness before it is called a bug); THE NODE LINE COMMITTED (13:1x UK): release-0.3.20-node = 8097d600 (dc141409 + the proof archive aea0ca5c + one commit) on the mirror, pairing igneum-pow 8c728ca3, the hash with the shipper; in it the amended class v4 as object 5 (CLASS_SIGNAL_V4 = 5, byte 4 never counts, the kaspa-pow vector test pinning 1a4230699a6b9c60 equal and c120d7963abdcd96 differing, the daemon's window line naming object 5 and sub-version 1) beside the day's fixes (isSynced from the hook's stamp, the weight-table cache, the lazy snapshot, the submit path, the 100 ms template wait); the suites green on build-2 (consensus-core 123, the exec RPC suite, the four finality tests including 24 requesters under 200 ms: the worst template 100 ms, the worst submit 102 ms) and kaspa-pow 17 on build-1. Next: igneumd and igneum-miner building from 8097d600 on build-1, then the two gate lines (the mixed-version Devnet 2 gate: the 8097d600 node mining beside the 5899f603 pair for ten minutes on the live file without the v4 fields, the old node accepting every block; the digest test: the thirteen-field file b18ed271 unchanged, the sixteen-field object re-read on the 8097d600 binary), expected about 13:30 UK; the shipper picks the cut point. THE DATE FIXED (the node lane, from the hub's live file, 13:3x UK): publish 2 of 6 October (22:49:45Z, digest eada4bda) already put BOTH v4 fields on the live devnet (floor 831,600, window 86,400), so the 0.3.17 fleet has stamped object byte 4 since 7 October 00:2x UK and the floor is live at about 13 October 09:00 UK, before any seven-window signal completes; a 0.3.17 node left on that file flips to the OLD v4 stream at epoch 231 whatever anyone signals, a 0.3.20 node to the amended stream at the same epoch, and the two never share an id, so each straggler forks alone there. REQUIREMENT for the 0.3.20 publish (with the shipper and main): a new file with the floor at the publish DAA + 604,800 rounded up (about 882,000 for a publish today), the digest moving, the one-sweep rollout replacing every 0.3.17 node before 13 October 09:00 UK; any node that misses the sweep is alone then; the earliest flip after that about 6 days 10 hours past the publish; plan section 6.6 amended today. IN THE 0.3.20 PLAN (the shipper, 13:4x UK): both requirements; the node pin by main's rule is the node lane's second commit (the claim floor, the listener watchdog, the claim RPCs, on top of 8097d600) if its suites, both gates and the fleet's 12 GB prover line are green by 15:30 UK, else 8097d600; igneum-pow 8c728ca3 either way; the digest read on whichever binary pins. THE LINE AT 13:5x UK: three commits on release-0.3.20-node, 8097d600 (the object-5 amended class v4 and the day's fixes), 6b94c823 (test-only: the stale PC 1 test from 500ddd66 inverted by the isSynced ruling; the FALLBACK pin, code byte-identical to 8097d600, so the module reads green whole) and 6a3432a3 (the app lane's key methods, the observer's claims, the settled claim floor, the listener watchdog); suites on build-2 on 6a3432a3's code (the whole finality module 25, the exec suite 29 with the watchdog test, the kaspad, flows and rpc-service checks; consensus-core 123 and kaspa-pow 17 earlier); the cut 6a3432a3 if its gates and the fleet's 12 GB settled-claim line are green by 15:30 UK, else 6b94c823; both binaries building on build-1, the two gates (the digest gate, then the ten-minute mixed-version gate beside the 5899f603 pair) on the 8097d600 build, lines about 14:05 UK. GATE NEWS (13:53 UK): on 6a3432a3's own digest gate the listener watchdog counted a bind failure (the four harness nodes share one exec JSON-RPC port) as a listener death and exited three of four nodes at 20 s, where 0.3.17 and 8097d600 only warn and live without the exec RPC; the digest facts came out first and stand (the thirteen-field file a89be8a7 on both binaries, the compat case; the sixteen-field object db9a85f9 refused with the mismatch line, the refusal case); the ten-minute gate on 6a3432a3 stopped as void for the same cause. The fix: a bind failure is a retry every poll, one line a minute, no death counted and never an exit, with a second watchdog test whose known-failed shape is the old rule's exit on a held port; the third commit and its build about 14:15 UK, its gates about 14:35 UK; the fallback 6b94c823's gates on build-1 on their own binary (no watchdog there), lines about 14:20 UK; ledger row N12 for the bind-failure class. A ROLL BLOCKER on every kept datadir (the node lane, 14:1x UK, ledger N13): the fleet started 6a3432a3 on a kept 0.3.17 datadir (pool-1's copy) and it died at start (virtual_state.rs:250, DeserializationError(UnexpectedEof)); the cause 10db4b61 on the 0.3.16 feature line added `silent: bool` to BlockRewardData under serde(default), which bincode ignores, so every build from 10db4b61 on (dc141409, 8097d600, 6b94c823, 6a3432a3, 09124180) reads a 0.3.17 node's virtual-state row short; no canary saw it because every canary wiped, and a one-box roll keeps datadirs, so it blocks the roll on every standing box, the hands and the hub whatever the pin. The fix on the line: the store reads the current layout first and on a deserialization error decodes the row as a v1 mirror, converts with silent false and rewrites it under the same key, with the known-failed test first; the fourth commit and build about 14:40 UK, the fleet's kept-datadir start on the fixed binary about 14:50 UK, its gates after. THE RULE IT ADDS for every node cut from now: a kept-datadir restart gate on a standing box's datadir copy beside the wiped canary. THE CANDIDATE PIN (14:2x UK): b7cc37e7 (8097d600, 6b94c823, 6a3432a3, 09124180, b7cc37e7; igneum-pow 8c728ca3): the N13 fix with its test green on build-2 at 14:04 UK and the kaspad check green, the build on build-1; the fallback 6b94c823 is no longer a pin for the one-box roll (it dies on a kept datadir like every build since 10db4b61): if b7cc37e7's gates are not green by 15:30 UK the honest fallback is 0.3.17's 5899f603 staying live. In flight on build-1: the earlier commits' gates, then b7cc37e7's own digest and ten-minute mixed-version gates on its binary with the read-back, lines about 15:05 UK; on the fleet the kept-datadir start on b7cc37e7 about 14:50 UK and the 12 GB settled-claim line 14:50 to 15:00 UK. Plan section 6.6 amended with the hard date (ca3-v4-node 9d763edd, merged to master); N12 and N13 on the ledger. THE GATES ON THE FALLBACK'S OWN BINARY (6b94c823, sha b1b7d47b, 13:56 to 14:08 UK; code byte-identical to 8097d600, so the amendment's node side): the digest gate, the thirteen-field file a89be8a7 on both binaries (the compat case, n0 peering n1 and n2) and the sixteen-field object db9a85f9 refused with the mismatch line (the refusal case); the mixed-version gate, ten minutes, one digest b0afb2ee on all five nodes, the 5899f603 hub accepting every block the amended node mined (146 new, 246 old, 0 rejected), plain header version 2 on the thirteen-field file, counts equal on all five through the two clean joins and the restart. Two FAILED checks, both the harness's own and fixed (36d3efdc): a refused peer's count read 1 with the reconnect in flight (now the minimum of five), and six address-in-use panics in the two old nodes because the second gate reused the first's ports the second they were sent SIGTERM (a 20 s gap now). CLOCK CORRECTION (the node lane, 12:12Z = 13:12 BST): every "UK" stamp it sent today was the box's CEST, an hour fast of BST; its lines read UTC from now. Restated: b7cc37e7's build about 12:15Z, its digest and mixed-version gates on that binary with the sha and string about 12:32Z (13:32 BST), the fleet's kept-datadir start on it about 12:25Z, its 12 GB settled-claim line 12:50 to 13:00Z; the shipper's checkpoint 14:30Z (15:30 BST), two hours of room. The 13 October date stands (derived from UTC DAA rates): the floor 831,600 about 08:00Z, 09:00 BST. b7cc37e7'S OWN LINES (binary sha256 bc28331abf21f4d5, the string read back on build-1 and on the fleet's pod): the digest gate 12:14:39Z to 12:16:18Z SUMMARY PASS (thirteen fields a89be8a7 on both binaries with the peers as the gate wants them; the sixteen-field object db9a85f9 refused with the line and no peer; the live file's digest eada4bda on the binary, unmoved); the kept-datadir start on the fleet's copy of pool-1's 0.3.17 datadir: the first start 12:17:12Z reads the v1 row through the mirror and rewrites it ("1 mergeset rewards"), the finality blob converts (1,747 locks), the node comes up on its ports with no panic; the second start 12:18:53Z reads first-try with no rewrite line and no panic; 6a3432a3's death on the same copy is the known-failed shape. The ten-minute mixed-version gate beside the 5899f603 pair runs on the same binary since 12:16:39Z, its line about 12:28Z; then the only line outstanding for the shipper's 14:30Z rule is the fleet's 12 GB settled-claim line, 12:50 to 13:00Z. AP-F8-1 RESIDUAL CLASS ON THE AMENDED STREAM (attack-pass lane 12:18Z on igneum-pow 8c728ca3, sub-version 1). F9 over 1,000,000 seeds: programs flagged (hot share at least 1 percent or 7 constant address bits) 1,871 (0.19 percent) against 11,696 (1.17 percent) unamended; worst hot share 9.66 percent against 17.3; mean 0.011 against 0.063 percent; 84 percent of the flagged programs and the whole or-saturation tail gone. F8 at 30 of 64 seeds: nine over 1.2x of the window model (p31 29.3x, p11 5.5x, p19 3.3x, p6 3.1x, p23 2.0x, the rest 1.3x to 1.6x); the 64-seed 1.2x gate is heading to FAIL on sub-version 1. Mechanism, confirmed on the two worst seeds: an all-ones load source (image 0x0ca59e4c under the era map) delivered through a writer the source rule counts as entropy-keeping, a rotate (rotl and rotr map all-ones to itself) or a load whose own source was saturated, with the saturation made one or more writes upstream by or. The rule looks one writer back; it must look through saturation-preserving writers or test the source's values. The ceiling has not moved: rule (c)'s 120-of-128 floor still caps any program at one saturated site, 6.25 percent of reads, a chip edge of at most 1.067x, and the residual (worst seed two sites at 0.53 and 0.56) sits inside it. THE SENTENCE "no lossy-sourced load by construction" IS HELD: it goes in no plan row and no ledger entry as true; sub-version 1 removes the or-source class and bounds the rest. MAIN'S RULING (13:2x UK): 0.3.20 ships object byte 5 on sub-version 1 as it stands, strictly better than the old stream the live floor flips to on 13 October; the fix is sub-version 2 on ca3-v4-amend (object byte 6 or whatever the v5 alignment leaves free) with both fixes: (F1) the static rule made transitive (rotates do not keep entropy; a load keeps entropy only if its own source did; one draw change, no attempts lost) and (F2) the dynamic source check (saturated load SOURCE values counted per site over the 64 units' 16,384 evaluations, rejected above 163 of 16,384, the same 1 percent the final-value rule uses; costs attempts on about 0.2 percent of seeds; rides with F1 because an or-written source is all-ones only (3/4)^32 of the time). Gate before sub-version 2 is proposed, run by the attack-pass lane and not by the hash lane: the full 64-seed census under 1.2x on every seed and the hot-set census. Hash lane's estimate about an hour its side (implement, re-export seven packs, vectors, crate suite, pairing, one G1 on PC 2) plus the node lane's vector re-pin and the attack-pass re-gate. The flip floor for sub-version 1 is expected to move (Josh's word) so the chain never flips to a stream that fails this gate. Also recorded: the crate suite at 8c728ca3 100 of 100 on the box (rc 0, 77 s); the pairing against the fork at dc141409 compiled and ran 15 of 16, the one failure the fork's own pre-amendment assertion (base equals v3's, igneum.rs:972), which 8097d600 on the release-0.3.20-node line turns into assert_ne; the pairing re-runs at b7cc37e7, its line to follow. CORRECTION (the attack-pass lane's own retraction, 13:3x UK): the F9 hot-set figures above (1,871 of 1,000,000, worst 9.66 percent, 84 percent removed, the two or-then-rotate listings) are WITHDRAWN: F9's harness draws through candidate_class with its own era class, outside candidate_from_words_class where the source rule lives, so it measured the old stream (the 8c728ca3 binary prints the identical program to the sub-version-0 binary for its worst seed). F8's 64-seed census on the chain path (pairing verified on 1a4230699a6b9c60) is the valid re-gate and STANDS: at 30 of 64 seeds, nine over 1.2x of the window model (p31 29.3x, p11 5.5x, p19 3.3x, p6 3.1x, p23 2.0x, p4 1.6x, p10 1.5x, p26 1.3x, p25 1.3x). The residual mechanism on the amended stream: a load-after-load chain (a saturated source reads one fixed word, which is the next load's address), admitted because a load injects; and the rotate-preserves-saturation path (generator.rs sets entropy_kept true for a rotate whatever it rotated), correct in code and a second admitted path if it occurs on the chain stream. Sub-version 2 must close both: dataflow freshness per register (a load fresh only if its source was fresh; add, sub, xor, mad, shfl fresh if either operand was; rotates only if the operand was; or, mul, mulhi never) plus the (c') count of saturated load sources per site as the backstop. The STOP holds on F8's evidence alone; the options and the 1.067x ceiling are unchanged. The sentence "no lossy-sourced load by construction" waits on the sub-version 2 census verdict and stays out of every public text until then. SUB-VERSION 2 IN BUILD (the hash lane, ca3-v4-amend, on the coordinator's direction, 13:4x UK): F1 (dataflow freshness per register, keyed on the class v4 shape on every draw path, era or not, so the candidate_class path and the chain path draw one stream) plus F2 (the (c') count of saturated load source values per site over the 64 units' 16,384 evaluations, rejected above 163, keyed on the same shape so v2 and v3 verdicts do not move); PROGRAM_SUBVERSION_V4 = 2, new ids, the seven packs re-exported, recheck.rs with 1a4230699a6b9c60 and c120d7963abdcd96 as the must-differ pair. Clock (UTC): the commit on the branch by 13:30; the crate suite on box 2 and the pairing against b7cc37e7 by about 13:50 (the pairing's vector test fails on the fork's sub-version-1 pin until the node lane re-pins; the compile and the other 15 are the pairing evidence); the G1 job on PC 2 under --cards-off by about 14:10, lock permitting; then the attack-pass lane's full 64-seed census and hot-set census on the chain path. Two consequences stated in the commit: the rule on every draw path moves the no-era sh256xN ladder packs' stream (packs-ca3-shadow's seven 256-block packs re-export with new fingerprints; the measured rates stand as the old stream's), and the class v5 lane's pinned string-seed packs move when it merges sub-version 2, so it re-exports them then. 0.3.20's sub-version-1 packs, ids and fingerprints untouched. OBJECT BYTES SETTLED (main, 13:5x UK): byte 5 = class v4 sub-version 1 (0.3.20), byte 6 = class v5 (pinned: class-v5 16afd0a0, class-v5-node 699db5a2, the flip case passed on 6,6,6; the v5 lane stopped), byte 7 = class v4 sub-version 2; the node and hash lanes told. b7cc37e7's MIXED-VERSION GATE: FAIL, the binary not the harness (12:16:39Z to 12:27:21Z, sha256 bc28331abf21f4d5, the string read back). Before the restart step everything held: one digest b0afb2ee on all five nodes, 268 new and 392 old blocks accepted, 0 rejected, header versions plain 2, counts equal on all five at 324 and 502 through both clean joins. At the new node's restart (12:24:19Z) it died at once on its own datadir ("IO error: While lock file: .../datadir/meta/LOCK: Resource temporarily unavailable", conn_builder.rs:167): the previous process was still shutting down, because the listener watchdog added on 6a3432a3 sleeps its whole 10 s poll before checking shutdown, so every node on the line since then takes up to 10 s longer to stop than 0.3.17 (the fleet saw the same shape as "a 12-second timeout does not stop the node"). Three of the four failed checks follow from that one death (counts, the restarted node's resync, the node it served frozen at 502). The fix on the line, one rule: the poll in 250 ms steps returning the moment shutdown is set, with a test that a shutdown returns within a second (the 10 s loop the known-failed shape); the exec suite on build-2, the fifth commit and its build about 12:45Z, its digest and ten-minute gates about 12:50 to 13:05Z, inside 14:30Z. b7cc37e7 is NOT the pin. The node-side re-pin for sub-version 2 (byte 7) once the hash lane's commit lands: the beside-the-fork igneum-pow copy archived from the commit, the two pinned ids moved in the kaspa-pow vector test (sub-version-2's epoch-0 id must-equal; sub-version-1's joins c120d7963abdcd96 as must-differ), CLASS_SIGNAL and tests for byte 7, the daemon's window line: about 20 minutes of edits plus one kaspa-pow suite run on build-2 (about 2 minutes). THE FIFTH COMMIT c4459193 on release-0.3.20-node (b7cc37e7's child, the watchdog poll returning on shutdown; the diff is the poll loop in rpc.rs alone), pairing igneum-pow 8c728ca3; its build on build-1 started 12:30:13Z, sha256 and string to follow. Line A, the shutdown test: rpc::watchdog_tests::a_shutdown_returns_within_a_second_whatever_the_poll green on build-2 at 12:29Z in the exec suite's 31 passed, beside the two other watchdog tests; its known-failed shape the old loop's 10 s stop. Line B, the kept-datadir start: b7cc37e7's fleet read carries to c4459193 since the store code is byte-identical between the two commits; the fleet re-reads on the c4459193 binary only if the shipper's rule wants the string on that line too. The digest gate and the ten-minute mixed-version gate on c4459193's own binary follow its build. THE SHIPPER'S CARRY RULING (14:1x UK): b7cc37e7's kept-datadir read stands as evidence that the store fix is right (the store code byte-identical) but is not the gate line for the pin, because the rule reads the binary, not the diff, and the binary changed (rpc.rs); the gate line is the kept read on c4459193's own binary with its string, which the fleet's canary already runs on c18-1 (wipe, then the kept read, then the restart) before the canary's restart step, at no extra cost; no re-read on p12-vast. THE PIN IS c4459193 pairing 8c728ca3 (object byte 5, sub-version 1); sub-version 2 (byte 7) is 0.3.21's, not 0.3.20's. The shipper's reading of main's F8 ruling: 0.3.20 ships object 5 as it stands because the live floor otherwise flips every node to the OLD stream on 13 October, and the 16:00 BST report tells Josh the floor move is now RECOMMENDED rather than optional, so the chain never flips to a stream that fails the 1.2x gate before sub-version 2 lands. THE FLEET'S CLOCK ON c4459193 (the fleet lane, 12:5x UTC): the kept read on pool-1's 0.3.17 datadir copy and the restart (the old process's stop time on the line) run on c18-1 before the wipe, a few minutes each, so both lines land before 14:30Z; the wipe canary (IBD from the pruning-point proof, 98 minutes on this pod class) starts when c18-1 is free of the 0.3.20 cases (about 13:00Z) and the binary is in hand, so its synced line lands about 14:40Z at the earliest, PAST the 14:30Z checkpoint; the 12 GB settled-claim line: c4459193 starts on p12-vast's kept copy of pool-1's datadir beside the 6a3432a3 IBD node on alternate ports the moment the binary lands, catches up from 129,398 blocks (15 to 20 minutes) and the 12 GB prover claims against it, the line on c4459193 itself. The binary not yet in the fleet's hand (build-1 building since 12:30:13Z); a wait armed on the sha and string, a report by 13:10Z if nothing. THE SHIPPER'S CALL ON THE CLOCK (14:2x UK): the wipe canary is the decisive read by the deploy rule; the pin never cuts without it and b7cc37e7's lineage does not stand in (the binary changed). The fleet rents a second one-shot pod of c18-1's class now and starts the wipe canary on c4459193's binary the moment the build lands, synced line about 14:15Z (15:15 BST), inside the checkpoint; c18-1 keeps the 0.3.20 cases and the pool window. If the wipe line slips past 15:30 BST the pin holds to it and main hears the clock (a slip is a report, not a cut). The set: the node lane's digest and mixed-version gates (12:50 to 13:05Z), the kept read and restart on the new pod, the wipe line on the new pod, the 12 GB settled-claim line on p12-vast. c4459193's BINARY IN THE FLEET'S HAND (12:34:54Z from build-1): igneumd sha256 45be9b02d1b002f5486d0f0108571c3b6042094113ad9da6f3d3d9ffc0072bba with the string c4459193 read back from the file, igneum-miner c7cfc40bc8b0e357. The wipe pod c19-1 (RunPod wpuke4tfu0vr49, RTX 3070 community, c18-1's class, USD 0.13/h, rented 12:37:03Z, one-shot; the day at USD 124 of work plus the 248 leak, 37 percent of the ceiling): the canary form (wipe, IBD from the pruning-point proof, synced, ten minutes mining with the exec poller, the hub read, the restart read) starts the moment the pod answers ssh; the kept read on pool-1's 0.3.17 copy armed behind its synced line on the same pod; the IBD start stamp its own line; synced about 14:20Z if the pod answers by 12:42Z (ten minutes inside the checkpoint), a slip reported the moment a poll shows it. CASES END on c18-1 at 12:37:18Z rc 0 (the relay and poison lines to the shipper); c18-1 and the two case pods destroyed by the run; the ten-member pool window rented its ten at 12:37:36Z. The 12 GB settled-claim line on p12-vast runs against a c4459193 node on the pod's kept copy, up since 12:36:35Z first-try, catching up. THE WIPE CANARY ON c19-1 STARTED: IBD at 12:38:55Z on c4459193 (sha256 45be9b02... asserted on the Mac before the put; the node's own line igneumd/2.1.0-c4459193 and digest eada4bda8aa8368c read back on the pod; a wiped datadir; IBD from the pruning-point proof with 4 peers at 12:39:26Z); synced about 14:17Z by the 98-minute class, thirteen minutes inside the checkpoint; the mining read, hub read, restart and kept read follow on the same pod, each its own line. c4459193's GATE LINES (the node lane): the binary built on build-1 at 12:33Z (1 m 07 s), sha256 45be9b02d1b002f5, the string read back from the binary (strings, two hits) and the worktree HEAD; igneum-miner beside it at /srv/builds/igneum-wt-ca3-v4-node/vendor/igneum-node-0318-release/target/release/. THE DIGEST GATE 12:33:27Z to 12:35:05Z SUMMARY PASS: the thirteen-field object a89be8a7 on both binaries, n0 peering n1 and n2 and the old node peering the new (the compat case); the sixteen-field object db9a85f9, n3 with no peer and the refusal line "consensus params digest mismatch, local db9a… remote a89b…" (the refusal case); the live file's digest on this binary eada4bda, as 5899f603 reads it. THE MIXED-VERSION GATE 12:35:26Z to 12:45:39Z SUMMARY PASS, beside the 5899f603 pair: one digest b0afb2ee on all five nodes; the 5899f603 hub accepted every block the c4459193 node mined, 215 new and 314 old, 0 rejected, no reject line in any log; header versions plain 2 on the thirteen-field file; counts equal on all five at 312 after mining, 441 after the clean join through the old hub and the clean join served by the new node, 529 at the end; the restart step passed: the new node restarted at 12:43:08Z on its own datadir and resynced to 529 with the others (where b7cc37e7 died on the database lock); no panic in any node log; every check green. The node side of the set is complete; the fleet's wipe, kept read, restart and settled-claim lines remain. THE INTEROP FACT stands from the void run: the 5899f603 hub accepted 235 object-byte-5 blocks from the 8097d600 node with 0 rejected, one digest on all five nodes on the live sixteen-field file. The gates: the digest test and the kaspa-pow vector test (the amended devnet epoch-0 id 1a4230699a6b9c60 must equal, c120d7963abdcd96 must differ, the v3 control unchanged) on the box; the mixed-version Devnet 2 gate (the amended 0.3.20 node beside a 5899f603 node for ten minutes on the live file without the v4 fields) after the Mac build; the fresh-join canary the 0.3.20 cut's | | Main's rulings (7 October, morning) | no generator change to v4 on the live devnet; the record's null is the window model with numbers, sent by the hash lane to the attack-pass lane so AP-F8-1 re-gates against it; a fault beyond the model (a low-entropy source at site 15) stops at the coordinator with the two options priced (a 0.3.19 class amendment before the flip, or the flip held at the floor), nothing shipping without Josh's word; the tighter tail, an acceptance bound on the hot-set share, is a CLASS V5 item (sent to the v5 lane a6410f3b8abefb762 with the 64-seed census as its gate; the bound's number follows from the model) | ### AP-F4-1, the weak-day MUL draw (the attack-pass lane, 7 October, morning): PASS against v4, a class v5 rule From 20e10203b86a2f771f86e8b38c5c1ed804ae03c2 Mon Sep 17 00:00:00 2001 From: igneum-josh <337424239+igneum-josh@users.noreply.github.com> Date: Wed, 7 Oct 2026 13:52:55 +0100 Subject: [PATCH 09/19] Counter ASIC 3.0 status: the cases rerun slips to about 15:10Z; the wipe canary holds 14:17Z; the kept read in hand Co-Authored-By: Claude Fable 5.1 --- docs/plans/counter-asic-3-status.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/plans/counter-asic-3-status.md b/docs/plans/counter-asic-3-status.md index e263a02ff..52752f443 100644 --- a/docs/plans/counter-asic-3-status.md +++ b/docs/plans/counter-asic-3-status.md @@ -338,7 +338,7 @@ Josh gave the go in advance for tonight: the shipper runs publish 1 on the 0.3.1 | THE ANALYSIS (the hash lane, ca3-v4-uniform 095f84a7, `docs/analysis/ca3-v4-uniform.md`, the tool on igneum-build-1) | the window model moves the null from 0.115 to 0.160 percent (1.39x, not 4.05x); the rest is a FAULT beyond it: site 15 reads a register last written by `or r6, r4`, so all-ones recurs at (3/4)^32 per read and the era map sends it to F8's hottest item exactly (the popcount model predicts 77,348 all-ones reads against 78,479; the top-0.1-percent share 0.58 against 0.52); it passes the acceptance rule because part (a) takes any write as a fresh source and part (c) counts saturation on final values only. The census of 1,024 chain-shaped v4 programs: 96.6 percent carry a lossy-sourced load (or, mul, mulhi as the last writer), 48.5 percent an or-sourced one (0.30 percent of all reads per site), 4.9 percent an or-of-or chain (4.6 percent of all reads on 0.1 percent of items); F8's 1.2x gate fails 96.6 percent of today's programs. Worth to a chip: 1.07 MB of SRAM ($0.25) serving 0.52 percent of a typical program's reads and 4.6 percent of the worst class's, at most 1.005x and 1.048x in rate; the ceiling under rule (c)'s 120-of-128 floor one site repeating its item in all 8 iterations, 6.25 percent of reads, 1.067x in 64 bytes; the 2x margin stands; the public line says "bounded at 1.067x", not "uniform" (the public text corrected) | | The two options, priced, STOPPED at the coordinator for Josh's word | A: a 0.3.19 class amendment before the flip (the generator draws a load's source from the registers whose last writer injects): a new program stream, new vectors, the seven gate packs re-exported, the six gates again (G1 to G3 and the verifier about an hour on the Mac and PC 2; G4 to G6 the node lane), every node before the flip under the one-box-at-a-time rule; the risk a node that misses the build splits the chain at the flip. B: hold the flip at the floor with v4 as it is; the bound documented; the source rule to class v5: a hot set worth up to 1.005x on about half the hours and 1.05x on 5 percent, 1.067x at the ceiling; no chain risk. The number: 1.067x at the ceiling against the 2x margin. The lane recommends B | | The v5 bound (sent to the v5 lane) | H = W_0.1 (the window term, 0.115 to 0.251 percent) + the sum over load sites of h(last writer) (or 0.30 percent, an or chain 4.5, mul 0.067, mulhi 0.049, an injecting op or a rotate 0), H at or under 1.2 x W_0.1, which is the static rule "every load's source was last written by an injecting op or a rotate"; as a rejection it costs 96.6 percent of candidates (about 30 attempts per seed), as a generator draw nothing; gate F8's 64-seed census with the saturated-source count | -| JOSH'S WORD (15:2x UK, 7 October): OPTION A, "do this but limit the testing, get it pushed" | the class v4 amendment: a load's source drawn only from registers whose last writer injects or is a rotate (the v5 rule applied now), a new program stream and vectors, the seven gate packs re-exported, the amended class with its own generator stamp; rides 0.3.20, the feature node (release-0.3.20-node = dc141409; 0.3.19 is an app-only cut with nothing of ours), on the shipper's line. The rollout arithmetic for the flip clock (the shipper): the standing fleet's one-box-at-a-time rollout took 32 minutes for 14 boxes (04:56 to 05:28Z, 7 October), the hands and the seed about 3 minutes after the miners, the Mac and the PCs within minutes of the publish; every 0.3.20 worker must accept the amended stamp before any flip. Owners: the hash lane (ca3-v4-amend: the generator, the vectors, the packs, the pairing on the box, one G1 run on PC 2, the ledger row), the node lane (release-0.3.20-node: the stamp agreed with the hash lane, the split-protection mechanism and the earliest flip time, the digest test, the mixed-version Devnet 2 gate), the attack-pass lane (the F8 census at 2^24 on the new stream, the gate 1.2x of the window model over 64 seeds), the shipper (the cut, the rollout order that sets the earliest flip). Testing limited to what prevents a split and proves the fix; G2, G3, the ladder re-measure and the rest of G4 to G6 OWED. THE STAMP agreed (the node and hash lanes, 7 October afternoon): generator 4 with sub-version 1 inside igneum-pow's id function, so the amended v4's program id for a seed differs from the old v4's (the old devnet epoch-0 id c120d7963abdcd96 pinned as the must-differ vector in kaspa-pow's test). SPLIT PROTECTION SETTLED (the node lane, plan section 6.6, ca3-v4-node fa5bc9e6; the node side on release-0.3.20-node): a fresh object byte. CLASS_SIGNAL_V4 is 5; the amended binary stamps 5 and the tally counts a block only at byte 5 or above; object 4 was stamped only by the unpublished dc141409 canary, so no published block carries it and a byte-4 block never counts; a node of the 6 October stream that sees byte 5 counts it as v4 (its rule is at least 4), flips to its own stream at the same epoch and forks ALONE (its blocks fail the amended id check, generator 4 sub-version 1 inside every id; the amended blocks fail its own), ours to upgrade in the sweep; object 6 is class v5's; the two holds already in the rule keep the window shut until every node is on 0.3.20 (a node stamps and tallies only with both v4 fields in its file; the fields publish only after the one-sweep rollout); a lagging worker refuses the amended pack at packcheck and mines nothing after the flip, costing that box, never the chain; no extra window hold: seven full day-windows are the hold. THE EARLIEST FLIP (approximate, measured 09:40Z: DAA 270,659, 1.095 DAA/s over 25 hours, 1.165 over 4; epoch 3,600, lead 600; seven windows 604,800 DAA wholly after the sweep's end D_s = T + about 40 minutes; the flip epoch the first e with 3600 e - 600 >= D_s + 604,800): T + 6 days 10 hours to T + 6 days 11 hours UK; for a publish at 12:00 UK on 7 October, 13 October between 22:20 and 23:10 UK (about 13:00 UK if the 4-hour rate holds). The floor as it stands (831,600, about 13 October 09:00 UK) would fire before any seven-window signal from a publish today completes, so it moves by the 0.3.16 rule to the publish DAA + 604,800 rounded up to the epoch boundary (882,000 for a 12:00 UK publish), firing about 30 minutes before the earliest signal flip: either way about 6 days 10 hours after the publish, never before every node has had the sweep plus a week. THE CLOCK (the node lane, 11:3x UK, after a Mac reboot moved its runs to the box): the 0.3.20 node line (dc141409 plus the proof archive aea0ca5c plus the amended v4 at object byte 5, igneum-pow at the hash lane's a0aaca92 beside the fork on the box) tested on the box, committed on release-0.3.20-node, pushed to the mirror and origin, igneumd and igneum-miner built, the tip to the shipper: about 12:00 UK; the mixed-version Devnet 2 gate (node-compat.mjs on the box, the amended node beside the 5899f603 pair for ten minutes) and the digest test (digest-compat.mjs): about 12:45 UK; the object-byte pin 5 unless the v5 lane answers both lanes with another assignment (v5 at 6 proposed). THE HASH SIDE on ca3-v4-amend (tip 8c728ca3, read from the branch 14:0x UK; the hash lane's own report pending): 1748fd1d the PC 2 G1-only playbook; e1f48d63 the fud-ledger entry AP-F8-1 (the fault, Josh's ruling, the amendment, the split protection, the owed tests); d8859522 the G1 line (the eight fingerprints equal on the RTX 5090, self-test PASS) and the node lane's signal byte 5; 4aa0c665 the v4 unit test following the amendment; 965d9e96 igneum-pow taken from release-0.3.20's 3f1652bf (the ladder's chain_program_shadow with the reps argument, never on master) with the amendment re-applied, the seven packs re-exporting byte-identical; 8c728ca3 the source rule keyed on the class with the shadow's pass count set aside, so every ladder rung draws under it (the fork's ladder test). The shipper took this igneum-pow tree into release-0.3.20 (00249643, byte-equal); nothing after 8c728ca3 touches igneum-pow. THE VECTORS AND THE PACKS (read from the branch and its ledger entry, 14:1x UK): the seven amended v4 packs (v4-devnet-epoch0, v4-era-0 to 5) carry generator 4, sub-version 1, one program id 1a4230699a6b9c60 (the 2.0 one-id-per-seed rule across the eras; the old c120d7963abdcd96 pinned as must-differ); the v3 control mx8-devnet-epoch0 untouched (73bcbfe8ccf988f1, fingerprint 90f794dd556f7a3b); the seven 2^24 fingerprints, Metal equal to Apple OpenCL: 867dbc45cfb36b4d, 2146ecacc8c75a8e, fe52602393f6d3d4, 3b206471a13912b4, c3f03c4a5d7333aa, f1dfd7209f15bb97, 8c194da64fadf31d; the zip of the eight packs sha256 889ec99976d2728b4b5035bfa476032e5b6a13b928968fc45236d5f25084aa39; the per-pack vectors.json sha256 prefixes 756301bf (devnet epoch 0), 1b5f4568, d430cadc, 1a1b21d8, 460fff9e, 4a85d49d, f83a1196 (eras 0 to 5). G1 on the RTX 5090 (PC 2 job run-ca3-v4-amend-g1-pc2-20261007, 09:41:07 to 09:41:28Z, exit 0, the installed worker): every fingerprint equal to the Mac's (the seven above and the control), NVRTC 188 to 332 ms per pack, the 1 GiB build 38 to 49 ms. hash-gates.md's older table still lists the pre-amendment fingerprints (f410c731... and the eras), which no longer apply to the amended packs; the ledger entry is the record. THE FIRST GREEN (11:31 UK, the box): the kaspa-pow suite on release-0.3.20-node (dc141409 plus the proof archive aea0ca5c plus the object-5 change) against the hash lane's igneum-pow 8c728ca3: 17 passed, 0 failed; the amended devnet epoch-0 id 1a4230699a6b9c60 pinned equal and c120d7963abdcd96 differing, the ladder's rung test green under the rekeyed rule, the v3 control unchanged; the consensus-core and exec RPC suites follow, then the node line (commit, push, box build, the tip to the shipper), then the digest and mixed-version gates. CLOCK RE-CUT (the node lane, 13:0x UK): the node line now carries, beside the object-5 change and the vector test, the lane's 0.3.20 fixes from the day (isSynced from the hook's stamp, the lazy template snapshot, the weight-table cache, the submit path returning after the block task, the watchdog, the RPC fields), about 13:30 UK if the box suites are green; the shipper's fresh-join canary 60 to 100 minutes after the cut; PC 1 as its first machine about 16:00 UK at the earliest, approximate until the shipper names the cut; the earliest flip about 6 days 10 hours after the publish. BUILD-2 LINES (12:28 to 12:33 UK): consensus-core 123 passed (the 60x file test green with the ladder window and activation pinned), the behind test green, kaspa-pow 17 passed (the amended vectors, earlier on build-1), the exec RPC suite green, the flows and rpc-service checks green with the submit-path change; the 24-requester latency test's first run tripped an unrelated flapping-fork double insert (24 equal forks from one parent; the test now builds on the sink as a real miner does; the double insert owed to a small fork harness before it is called a bug); THE NODE LINE COMMITTED (13:1x UK): release-0.3.20-node = 8097d600 (dc141409 + the proof archive aea0ca5c + one commit) on the mirror, pairing igneum-pow 8c728ca3, the hash with the shipper; in it the amended class v4 as object 5 (CLASS_SIGNAL_V4 = 5, byte 4 never counts, the kaspa-pow vector test pinning 1a4230699a6b9c60 equal and c120d7963abdcd96 differing, the daemon's window line naming object 5 and sub-version 1) beside the day's fixes (isSynced from the hook's stamp, the weight-table cache, the lazy snapshot, the submit path, the 100 ms template wait); the suites green on build-2 (consensus-core 123, the exec RPC suite, the four finality tests including 24 requesters under 200 ms: the worst template 100 ms, the worst submit 102 ms) and kaspa-pow 17 on build-1. Next: igneumd and igneum-miner building from 8097d600 on build-1, then the two gate lines (the mixed-version Devnet 2 gate: the 8097d600 node mining beside the 5899f603 pair for ten minutes on the live file without the v4 fields, the old node accepting every block; the digest test: the thirteen-field file b18ed271 unchanged, the sixteen-field object re-read on the 8097d600 binary), expected about 13:30 UK; the shipper picks the cut point. THE DATE FIXED (the node lane, from the hub's live file, 13:3x UK): publish 2 of 6 October (22:49:45Z, digest eada4bda) already put BOTH v4 fields on the live devnet (floor 831,600, window 86,400), so the 0.3.17 fleet has stamped object byte 4 since 7 October 00:2x UK and the floor is live at about 13 October 09:00 UK, before any seven-window signal completes; a 0.3.17 node left on that file flips to the OLD v4 stream at epoch 231 whatever anyone signals, a 0.3.20 node to the amended stream at the same epoch, and the two never share an id, so each straggler forks alone there. REQUIREMENT for the 0.3.20 publish (with the shipper and main): a new file with the floor at the publish DAA + 604,800 rounded up (about 882,000 for a publish today), the digest moving, the one-sweep rollout replacing every 0.3.17 node before 13 October 09:00 UK; any node that misses the sweep is alone then; the earliest flip after that about 6 days 10 hours past the publish; plan section 6.6 amended today. IN THE 0.3.20 PLAN (the shipper, 13:4x UK): both requirements; the node pin by main's rule is the node lane's second commit (the claim floor, the listener watchdog, the claim RPCs, on top of 8097d600) if its suites, both gates and the fleet's 12 GB prover line are green by 15:30 UK, else 8097d600; igneum-pow 8c728ca3 either way; the digest read on whichever binary pins. THE LINE AT 13:5x UK: three commits on release-0.3.20-node, 8097d600 (the object-5 amended class v4 and the day's fixes), 6b94c823 (test-only: the stale PC 1 test from 500ddd66 inverted by the isSynced ruling; the FALLBACK pin, code byte-identical to 8097d600, so the module reads green whole) and 6a3432a3 (the app lane's key methods, the observer's claims, the settled claim floor, the listener watchdog); suites on build-2 on 6a3432a3's code (the whole finality module 25, the exec suite 29 with the watchdog test, the kaspad, flows and rpc-service checks; consensus-core 123 and kaspa-pow 17 earlier); the cut 6a3432a3 if its gates and the fleet's 12 GB settled-claim line are green by 15:30 UK, else 6b94c823; both binaries building on build-1, the two gates (the digest gate, then the ten-minute mixed-version gate beside the 5899f603 pair) on the 8097d600 build, lines about 14:05 UK. GATE NEWS (13:53 UK): on 6a3432a3's own digest gate the listener watchdog counted a bind failure (the four harness nodes share one exec JSON-RPC port) as a listener death and exited three of four nodes at 20 s, where 0.3.17 and 8097d600 only warn and live without the exec RPC; the digest facts came out first and stand (the thirteen-field file a89be8a7 on both binaries, the compat case; the sixteen-field object db9a85f9 refused with the mismatch line, the refusal case); the ten-minute gate on 6a3432a3 stopped as void for the same cause. The fix: a bind failure is a retry every poll, one line a minute, no death counted and never an exit, with a second watchdog test whose known-failed shape is the old rule's exit on a held port; the third commit and its build about 14:15 UK, its gates about 14:35 UK; the fallback 6b94c823's gates on build-1 on their own binary (no watchdog there), lines about 14:20 UK; ledger row N12 for the bind-failure class. A ROLL BLOCKER on every kept datadir (the node lane, 14:1x UK, ledger N13): the fleet started 6a3432a3 on a kept 0.3.17 datadir (pool-1's copy) and it died at start (virtual_state.rs:250, DeserializationError(UnexpectedEof)); the cause 10db4b61 on the 0.3.16 feature line added `silent: bool` to BlockRewardData under serde(default), which bincode ignores, so every build from 10db4b61 on (dc141409, 8097d600, 6b94c823, 6a3432a3, 09124180) reads a 0.3.17 node's virtual-state row short; no canary saw it because every canary wiped, and a one-box roll keeps datadirs, so it blocks the roll on every standing box, the hands and the hub whatever the pin. The fix on the line: the store reads the current layout first and on a deserialization error decodes the row as a v1 mirror, converts with silent false and rewrites it under the same key, with the known-failed test first; the fourth commit and build about 14:40 UK, the fleet's kept-datadir start on the fixed binary about 14:50 UK, its gates after. THE RULE IT ADDS for every node cut from now: a kept-datadir restart gate on a standing box's datadir copy beside the wiped canary. THE CANDIDATE PIN (14:2x UK): b7cc37e7 (8097d600, 6b94c823, 6a3432a3, 09124180, b7cc37e7; igneum-pow 8c728ca3): the N13 fix with its test green on build-2 at 14:04 UK and the kaspad check green, the build on build-1; the fallback 6b94c823 is no longer a pin for the one-box roll (it dies on a kept datadir like every build since 10db4b61): if b7cc37e7's gates are not green by 15:30 UK the honest fallback is 0.3.17's 5899f603 staying live. In flight on build-1: the earlier commits' gates, then b7cc37e7's own digest and ten-minute mixed-version gates on its binary with the read-back, lines about 15:05 UK; on the fleet the kept-datadir start on b7cc37e7 about 14:50 UK and the 12 GB settled-claim line 14:50 to 15:00 UK. Plan section 6.6 amended with the hard date (ca3-v4-node 9d763edd, merged to master); N12 and N13 on the ledger. THE GATES ON THE FALLBACK'S OWN BINARY (6b94c823, sha b1b7d47b, 13:56 to 14:08 UK; code byte-identical to 8097d600, so the amendment's node side): the digest gate, the thirteen-field file a89be8a7 on both binaries (the compat case, n0 peering n1 and n2) and the sixteen-field object db9a85f9 refused with the mismatch line (the refusal case); the mixed-version gate, ten minutes, one digest b0afb2ee on all five nodes, the 5899f603 hub accepting every block the amended node mined (146 new, 246 old, 0 rejected), plain header version 2 on the thirteen-field file, counts equal on all five through the two clean joins and the restart. Two FAILED checks, both the harness's own and fixed (36d3efdc): a refused peer's count read 1 with the reconnect in flight (now the minimum of five), and six address-in-use panics in the two old nodes because the second gate reused the first's ports the second they were sent SIGTERM (a 20 s gap now). CLOCK CORRECTION (the node lane, 12:12Z = 13:12 BST): every "UK" stamp it sent today was the box's CEST, an hour fast of BST; its lines read UTC from now. Restated: b7cc37e7's build about 12:15Z, its digest and mixed-version gates on that binary with the sha and string about 12:32Z (13:32 BST), the fleet's kept-datadir start on it about 12:25Z, its 12 GB settled-claim line 12:50 to 13:00Z; the shipper's checkpoint 14:30Z (15:30 BST), two hours of room. The 13 October date stands (derived from UTC DAA rates): the floor 831,600 about 08:00Z, 09:00 BST. b7cc37e7'S OWN LINES (binary sha256 bc28331abf21f4d5, the string read back on build-1 and on the fleet's pod): the digest gate 12:14:39Z to 12:16:18Z SUMMARY PASS (thirteen fields a89be8a7 on both binaries with the peers as the gate wants them; the sixteen-field object db9a85f9 refused with the line and no peer; the live file's digest eada4bda on the binary, unmoved); the kept-datadir start on the fleet's copy of pool-1's 0.3.17 datadir: the first start 12:17:12Z reads the v1 row through the mirror and rewrites it ("1 mergeset rewards"), the finality blob converts (1,747 locks), the node comes up on its ports with no panic; the second start 12:18:53Z reads first-try with no rewrite line and no panic; 6a3432a3's death on the same copy is the known-failed shape. The ten-minute mixed-version gate beside the 5899f603 pair runs on the same binary since 12:16:39Z, its line about 12:28Z; then the only line outstanding for the shipper's 14:30Z rule is the fleet's 12 GB settled-claim line, 12:50 to 13:00Z. AP-F8-1 RESIDUAL CLASS ON THE AMENDED STREAM (attack-pass lane 12:18Z on igneum-pow 8c728ca3, sub-version 1). F9 over 1,000,000 seeds: programs flagged (hot share at least 1 percent or 7 constant address bits) 1,871 (0.19 percent) against 11,696 (1.17 percent) unamended; worst hot share 9.66 percent against 17.3; mean 0.011 against 0.063 percent; 84 percent of the flagged programs and the whole or-saturation tail gone. F8 at 30 of 64 seeds: nine over 1.2x of the window model (p31 29.3x, p11 5.5x, p19 3.3x, p6 3.1x, p23 2.0x, the rest 1.3x to 1.6x); the 64-seed 1.2x gate is heading to FAIL on sub-version 1. Mechanism, confirmed on the two worst seeds: an all-ones load source (image 0x0ca59e4c under the era map) delivered through a writer the source rule counts as entropy-keeping, a rotate (rotl and rotr map all-ones to itself) or a load whose own source was saturated, with the saturation made one or more writes upstream by or. The rule looks one writer back; it must look through saturation-preserving writers or test the source's values. The ceiling has not moved: rule (c)'s 120-of-128 floor still caps any program at one saturated site, 6.25 percent of reads, a chip edge of at most 1.067x, and the residual (worst seed two sites at 0.53 and 0.56) sits inside it. THE SENTENCE "no lossy-sourced load by construction" IS HELD: it goes in no plan row and no ledger entry as true; sub-version 1 removes the or-source class and bounds the rest. MAIN'S RULING (13:2x UK): 0.3.20 ships object byte 5 on sub-version 1 as it stands, strictly better than the old stream the live floor flips to on 13 October; the fix is sub-version 2 on ca3-v4-amend (object byte 6 or whatever the v5 alignment leaves free) with both fixes: (F1) the static rule made transitive (rotates do not keep entropy; a load keeps entropy only if its own source did; one draw change, no attempts lost) and (F2) the dynamic source check (saturated load SOURCE values counted per site over the 64 units' 16,384 evaluations, rejected above 163 of 16,384, the same 1 percent the final-value rule uses; costs attempts on about 0.2 percent of seeds; rides with F1 because an or-written source is all-ones only (3/4)^32 of the time). Gate before sub-version 2 is proposed, run by the attack-pass lane and not by the hash lane: the full 64-seed census under 1.2x on every seed and the hot-set census. Hash lane's estimate about an hour its side (implement, re-export seven packs, vectors, crate suite, pairing, one G1 on PC 2) plus the node lane's vector re-pin and the attack-pass re-gate. The flip floor for sub-version 1 is expected to move (Josh's word) so the chain never flips to a stream that fails this gate. Also recorded: the crate suite at 8c728ca3 100 of 100 on the box (rc 0, 77 s); the pairing against the fork at dc141409 compiled and ran 15 of 16, the one failure the fork's own pre-amendment assertion (base equals v3's, igneum.rs:972), which 8097d600 on the release-0.3.20-node line turns into assert_ne; the pairing re-runs at b7cc37e7, its line to follow. CORRECTION (the attack-pass lane's own retraction, 13:3x UK): the F9 hot-set figures above (1,871 of 1,000,000, worst 9.66 percent, 84 percent removed, the two or-then-rotate listings) are WITHDRAWN: F9's harness draws through candidate_class with its own era class, outside candidate_from_words_class where the source rule lives, so it measured the old stream (the 8c728ca3 binary prints the identical program to the sub-version-0 binary for its worst seed). F8's 64-seed census on the chain path (pairing verified on 1a4230699a6b9c60) is the valid re-gate and STANDS: at 30 of 64 seeds, nine over 1.2x of the window model (p31 29.3x, p11 5.5x, p19 3.3x, p6 3.1x, p23 2.0x, p4 1.6x, p10 1.5x, p26 1.3x, p25 1.3x). The residual mechanism on the amended stream: a load-after-load chain (a saturated source reads one fixed word, which is the next load's address), admitted because a load injects; and the rotate-preserves-saturation path (generator.rs sets entropy_kept true for a rotate whatever it rotated), correct in code and a second admitted path if it occurs on the chain stream. Sub-version 2 must close both: dataflow freshness per register (a load fresh only if its source was fresh; add, sub, xor, mad, shfl fresh if either operand was; rotates only if the operand was; or, mul, mulhi never) plus the (c') count of saturated load sources per site as the backstop. The STOP holds on F8's evidence alone; the options and the 1.067x ceiling are unchanged. The sentence "no lossy-sourced load by construction" waits on the sub-version 2 census verdict and stays out of every public text until then. SUB-VERSION 2 IN BUILD (the hash lane, ca3-v4-amend, on the coordinator's direction, 13:4x UK): F1 (dataflow freshness per register, keyed on the class v4 shape on every draw path, era or not, so the candidate_class path and the chain path draw one stream) plus F2 (the (c') count of saturated load source values per site over the 64 units' 16,384 evaluations, rejected above 163, keyed on the same shape so v2 and v3 verdicts do not move); PROGRAM_SUBVERSION_V4 = 2, new ids, the seven packs re-exported, recheck.rs with 1a4230699a6b9c60 and c120d7963abdcd96 as the must-differ pair. Clock (UTC): the commit on the branch by 13:30; the crate suite on box 2 and the pairing against b7cc37e7 by about 13:50 (the pairing's vector test fails on the fork's sub-version-1 pin until the node lane re-pins; the compile and the other 15 are the pairing evidence); the G1 job on PC 2 under --cards-off by about 14:10, lock permitting; then the attack-pass lane's full 64-seed census and hot-set census on the chain path. Two consequences stated in the commit: the rule on every draw path moves the no-era sh256xN ladder packs' stream (packs-ca3-shadow's seven 256-block packs re-export with new fingerprints; the measured rates stand as the old stream's), and the class v5 lane's pinned string-seed packs move when it merges sub-version 2, so it re-exports them then. 0.3.20's sub-version-1 packs, ids and fingerprints untouched. OBJECT BYTES SETTLED (main, 13:5x UK): byte 5 = class v4 sub-version 1 (0.3.20), byte 6 = class v5 (pinned: class-v5 16afd0a0, class-v5-node 699db5a2, the flip case passed on 6,6,6; the v5 lane stopped), byte 7 = class v4 sub-version 2; the node and hash lanes told. b7cc37e7's MIXED-VERSION GATE: FAIL, the binary not the harness (12:16:39Z to 12:27:21Z, sha256 bc28331abf21f4d5, the string read back). Before the restart step everything held: one digest b0afb2ee on all five nodes, 268 new and 392 old blocks accepted, 0 rejected, header versions plain 2, counts equal on all five at 324 and 502 through both clean joins. At the new node's restart (12:24:19Z) it died at once on its own datadir ("IO error: While lock file: .../datadir/meta/LOCK: Resource temporarily unavailable", conn_builder.rs:167): the previous process was still shutting down, because the listener watchdog added on 6a3432a3 sleeps its whole 10 s poll before checking shutdown, so every node on the line since then takes up to 10 s longer to stop than 0.3.17 (the fleet saw the same shape as "a 12-second timeout does not stop the node"). Three of the four failed checks follow from that one death (counts, the restarted node's resync, the node it served frozen at 502). The fix on the line, one rule: the poll in 250 ms steps returning the moment shutdown is set, with a test that a shutdown returns within a second (the 10 s loop the known-failed shape); the exec suite on build-2, the fifth commit and its build about 12:45Z, its digest and ten-minute gates about 12:50 to 13:05Z, inside 14:30Z. b7cc37e7 is NOT the pin. The node-side re-pin for sub-version 2 (byte 7) once the hash lane's commit lands: the beside-the-fork igneum-pow copy archived from the commit, the two pinned ids moved in the kaspa-pow vector test (sub-version-2's epoch-0 id must-equal; sub-version-1's joins c120d7963abdcd96 as must-differ), CLASS_SIGNAL and tests for byte 7, the daemon's window line: about 20 minutes of edits plus one kaspa-pow suite run on build-2 (about 2 minutes). THE FIFTH COMMIT c4459193 on release-0.3.20-node (b7cc37e7's child, the watchdog poll returning on shutdown; the diff is the poll loop in rpc.rs alone), pairing igneum-pow 8c728ca3; its build on build-1 started 12:30:13Z, sha256 and string to follow. Line A, the shutdown test: rpc::watchdog_tests::a_shutdown_returns_within_a_second_whatever_the_poll green on build-2 at 12:29Z in the exec suite's 31 passed, beside the two other watchdog tests; its known-failed shape the old loop's 10 s stop. Line B, the kept-datadir start: b7cc37e7's fleet read carries to c4459193 since the store code is byte-identical between the two commits; the fleet re-reads on the c4459193 binary only if the shipper's rule wants the string on that line too. The digest gate and the ten-minute mixed-version gate on c4459193's own binary follow its build. THE SHIPPER'S CARRY RULING (14:1x UK): b7cc37e7's kept-datadir read stands as evidence that the store fix is right (the store code byte-identical) but is not the gate line for the pin, because the rule reads the binary, not the diff, and the binary changed (rpc.rs); the gate line is the kept read on c4459193's own binary with its string, which the fleet's canary already runs on c18-1 (wipe, then the kept read, then the restart) before the canary's restart step, at no extra cost; no re-read on p12-vast. THE PIN IS c4459193 pairing 8c728ca3 (object byte 5, sub-version 1); sub-version 2 (byte 7) is 0.3.21's, not 0.3.20's. The shipper's reading of main's F8 ruling: 0.3.20 ships object 5 as it stands because the live floor otherwise flips every node to the OLD stream on 13 October, and the 16:00 BST report tells Josh the floor move is now RECOMMENDED rather than optional, so the chain never flips to a stream that fails the 1.2x gate before sub-version 2 lands. THE FLEET'S CLOCK ON c4459193 (the fleet lane, 12:5x UTC): the kept read on pool-1's 0.3.17 datadir copy and the restart (the old process's stop time on the line) run on c18-1 before the wipe, a few minutes each, so both lines land before 14:30Z; the wipe canary (IBD from the pruning-point proof, 98 minutes on this pod class) starts when c18-1 is free of the 0.3.20 cases (about 13:00Z) and the binary is in hand, so its synced line lands about 14:40Z at the earliest, PAST the 14:30Z checkpoint; the 12 GB settled-claim line: c4459193 starts on p12-vast's kept copy of pool-1's datadir beside the 6a3432a3 IBD node on alternate ports the moment the binary lands, catches up from 129,398 blocks (15 to 20 minutes) and the 12 GB prover claims against it, the line on c4459193 itself. The binary not yet in the fleet's hand (build-1 building since 12:30:13Z); a wait armed on the sha and string, a report by 13:10Z if nothing. THE SHIPPER'S CALL ON THE CLOCK (14:2x UK): the wipe canary is the decisive read by the deploy rule; the pin never cuts without it and b7cc37e7's lineage does not stand in (the binary changed). The fleet rents a second one-shot pod of c18-1's class now and starts the wipe canary on c4459193's binary the moment the build lands, synced line about 14:15Z (15:15 BST), inside the checkpoint; c18-1 keeps the 0.3.20 cases and the pool window. If the wipe line slips past 15:30 BST the pin holds to it and main hears the clock (a slip is a report, not a cut). The set: the node lane's digest and mixed-version gates (12:50 to 13:05Z), the kept read and restart on the new pod, the wipe line on the new pod, the 12 GB settled-claim line on p12-vast. c4459193's BINARY IN THE FLEET'S HAND (12:34:54Z from build-1): igneumd sha256 45be9b02d1b002f5486d0f0108571c3b6042094113ad9da6f3d3d9ffc0072bba with the string c4459193 read back from the file, igneum-miner c7cfc40bc8b0e357. The wipe pod c19-1 (RunPod wpuke4tfu0vr49, RTX 3070 community, c18-1's class, USD 0.13/h, rented 12:37:03Z, one-shot; the day at USD 124 of work plus the 248 leak, 37 percent of the ceiling): the canary form (wipe, IBD from the pruning-point proof, synced, ten minutes mining with the exec poller, the hub read, the restart read) starts the moment the pod answers ssh; the kept read on pool-1's 0.3.17 copy armed behind its synced line on the same pod; the IBD start stamp its own line; synced about 14:20Z if the pod answers by 12:42Z (ten minutes inside the checkpoint), a slip reported the moment a poll shows it. CASES END on c18-1 at 12:37:18Z rc 0 (the relay and poison lines to the shipper); c18-1 and the two case pods destroyed by the run; the ten-member pool window rented its ten at 12:37:36Z. The 12 GB settled-claim line on p12-vast runs against a c4459193 node on the pod's kept copy, up since 12:36:35Z first-try, catching up. THE WIPE CANARY ON c19-1 STARTED: IBD at 12:38:55Z on c4459193 (sha256 45be9b02... asserted on the Mac before the put; the node's own line igneumd/2.1.0-c4459193 and digest eada4bda8aa8368c read back on the pod; a wiped datadir; IBD from the pruning-point proof with 4 peers at 12:39:26Z); synced about 14:17Z by the 98-minute class, thirteen minutes inside the checkpoint; the mining read, hub read, restart and kept read follow on the same pod, each its own line. c4459193's GATE LINES (the node lane): the binary built on build-1 at 12:33Z (1 m 07 s), sha256 45be9b02d1b002f5, the string read back from the binary (strings, two hits) and the worktree HEAD; igneum-miner beside it at /srv/builds/igneum-wt-ca3-v4-node/vendor/igneum-node-0318-release/target/release/. THE DIGEST GATE 12:33:27Z to 12:35:05Z SUMMARY PASS: the thirteen-field object a89be8a7 on both binaries, n0 peering n1 and n2 and the old node peering the new (the compat case); the sixteen-field object db9a85f9, n3 with no peer and the refusal line "consensus params digest mismatch, local db9a… remote a89b…" (the refusal case); the live file's digest on this binary eada4bda, as 5899f603 reads it. THE MIXED-VERSION GATE 12:35:26Z to 12:45:39Z SUMMARY PASS, beside the 5899f603 pair: one digest b0afb2ee on all five nodes; the 5899f603 hub accepted every block the c4459193 node mined, 215 new and 314 old, 0 rejected, no reject line in any log; header versions plain 2 on the thirteen-field file; counts equal on all five at 312 after mining, 441 after the clean join through the old hub and the clean join served by the new node, 529 at the end; the restart step passed: the new node restarted at 12:43:08Z on its own datadir and resynced to 529 with the others (where b7cc37e7 died on the database lock); no panic in any node log; every check green. The node side of the set is complete; the fleet's wipe, kept read, restart and settled-claim lines remain. THE INTEROP FACT stands from the void run: the 5899f603 hub accepted 235 object-byte-5 blocks from the 8097d600 node with 0 rejected, one digest on all five nodes on the live sixteen-field file. The gates: the digest test and the kaspa-pow vector test (the amended devnet epoch-0 id 1a4230699a6b9c60 must equal, c120d7963abdcd96 must differ, the v3 control unchanged) on the box; the mixed-version Devnet 2 gate (the amended 0.3.20 node beside a 5899f603 node for ten minutes on the live file without the v4 fields) after the Mac build; the fresh-join canary the 0.3.20 cut's | +| JOSH'S WORD (15:2x UK, 7 October): OPTION A, "do this but limit the testing, get it pushed" | the class v4 amendment: a load's source drawn only from registers whose last writer injects or is a rotate (the v5 rule applied now), a new program stream and vectors, the seven gate packs re-exported, the amended class with its own generator stamp; rides 0.3.20, the feature node (release-0.3.20-node = dc141409; 0.3.19 is an app-only cut with nothing of ours), on the shipper's line. The rollout arithmetic for the flip clock (the shipper): the standing fleet's one-box-at-a-time rollout took 32 minutes for 14 boxes (04:56 to 05:28Z, 7 October), the hands and the seed about 3 minutes after the miners, the Mac and the PCs within minutes of the publish; every 0.3.20 worker must accept the amended stamp before any flip. Owners: the hash lane (ca3-v4-amend: the generator, the vectors, the packs, the pairing on the box, one G1 run on PC 2, the ledger row), the node lane (release-0.3.20-node: the stamp agreed with the hash lane, the split-protection mechanism and the earliest flip time, the digest test, the mixed-version Devnet 2 gate), the attack-pass lane (the F8 census at 2^24 on the new stream, the gate 1.2x of the window model over 64 seeds), the shipper (the cut, the rollout order that sets the earliest flip). Testing limited to what prevents a split and proves the fix; G2, G3, the ladder re-measure and the rest of G4 to G6 OWED. THE STAMP agreed (the node and hash lanes, 7 October afternoon): generator 4 with sub-version 1 inside igneum-pow's id function, so the amended v4's program id for a seed differs from the old v4's (the old devnet epoch-0 id c120d7963abdcd96 pinned as the must-differ vector in kaspa-pow's test). SPLIT PROTECTION SETTLED (the node lane, plan section 6.6, ca3-v4-node fa5bc9e6; the node side on release-0.3.20-node): a fresh object byte. CLASS_SIGNAL_V4 is 5; the amended binary stamps 5 and the tally counts a block only at byte 5 or above; object 4 was stamped only by the unpublished dc141409 canary, so no published block carries it and a byte-4 block never counts; a node of the 6 October stream that sees byte 5 counts it as v4 (its rule is at least 4), flips to its own stream at the same epoch and forks ALONE (its blocks fail the amended id check, generator 4 sub-version 1 inside every id; the amended blocks fail its own), ours to upgrade in the sweep; object 6 is class v5's; the two holds already in the rule keep the window shut until every node is on 0.3.20 (a node stamps and tallies only with both v4 fields in its file; the fields publish only after the one-sweep rollout); a lagging worker refuses the amended pack at packcheck and mines nothing after the flip, costing that box, never the chain; no extra window hold: seven full day-windows are the hold. THE EARLIEST FLIP (approximate, measured 09:40Z: DAA 270,659, 1.095 DAA/s over 25 hours, 1.165 over 4; epoch 3,600, lead 600; seven windows 604,800 DAA wholly after the sweep's end D_s = T + about 40 minutes; the flip epoch the first e with 3600 e - 600 >= D_s + 604,800): T + 6 days 10 hours to T + 6 days 11 hours UK; for a publish at 12:00 UK on 7 October, 13 October between 22:20 and 23:10 UK (about 13:00 UK if the 4-hour rate holds). The floor as it stands (831,600, about 13 October 09:00 UK) would fire before any seven-window signal from a publish today completes, so it moves by the 0.3.16 rule to the publish DAA + 604,800 rounded up to the epoch boundary (882,000 for a 12:00 UK publish), firing about 30 minutes before the earliest signal flip: either way about 6 days 10 hours after the publish, never before every node has had the sweep plus a week. THE CLOCK (the node lane, 11:3x UK, after a Mac reboot moved its runs to the box): the 0.3.20 node line (dc141409 plus the proof archive aea0ca5c plus the amended v4 at object byte 5, igneum-pow at the hash lane's a0aaca92 beside the fork on the box) tested on the box, committed on release-0.3.20-node, pushed to the mirror and origin, igneumd and igneum-miner built, the tip to the shipper: about 12:00 UK; the mixed-version Devnet 2 gate (node-compat.mjs on the box, the amended node beside the 5899f603 pair for ten minutes) and the digest test (digest-compat.mjs): about 12:45 UK; the object-byte pin 5 unless the v5 lane answers both lanes with another assignment (v5 at 6 proposed). THE HASH SIDE on ca3-v4-amend (tip 8c728ca3, read from the branch 14:0x UK; the hash lane's own report pending): 1748fd1d the PC 2 G1-only playbook; e1f48d63 the fud-ledger entry AP-F8-1 (the fault, Josh's ruling, the amendment, the split protection, the owed tests); d8859522 the G1 line (the eight fingerprints equal on the RTX 5090, self-test PASS) and the node lane's signal byte 5; 4aa0c665 the v4 unit test following the amendment; 965d9e96 igneum-pow taken from release-0.3.20's 3f1652bf (the ladder's chain_program_shadow with the reps argument, never on master) with the amendment re-applied, the seven packs re-exporting byte-identical; 8c728ca3 the source rule keyed on the class with the shadow's pass count set aside, so every ladder rung draws under it (the fork's ladder test). The shipper took this igneum-pow tree into release-0.3.20 (00249643, byte-equal); nothing after 8c728ca3 touches igneum-pow. THE VECTORS AND THE PACKS (read from the branch and its ledger entry, 14:1x UK): the seven amended v4 packs (v4-devnet-epoch0, v4-era-0 to 5) carry generator 4, sub-version 1, one program id 1a4230699a6b9c60 (the 2.0 one-id-per-seed rule across the eras; the old c120d7963abdcd96 pinned as must-differ); the v3 control mx8-devnet-epoch0 untouched (73bcbfe8ccf988f1, fingerprint 90f794dd556f7a3b); the seven 2^24 fingerprints, Metal equal to Apple OpenCL: 867dbc45cfb36b4d, 2146ecacc8c75a8e, fe52602393f6d3d4, 3b206471a13912b4, c3f03c4a5d7333aa, f1dfd7209f15bb97, 8c194da64fadf31d; the zip of the eight packs sha256 889ec99976d2728b4b5035bfa476032e5b6a13b928968fc45236d5f25084aa39; the per-pack vectors.json sha256 prefixes 756301bf (devnet epoch 0), 1b5f4568, d430cadc, 1a1b21d8, 460fff9e, 4a85d49d, f83a1196 (eras 0 to 5). G1 on the RTX 5090 (PC 2 job run-ca3-v4-amend-g1-pc2-20261007, 09:41:07 to 09:41:28Z, exit 0, the installed worker): every fingerprint equal to the Mac's (the seven above and the control), NVRTC 188 to 332 ms per pack, the 1 GiB build 38 to 49 ms. hash-gates.md's older table still lists the pre-amendment fingerprints (f410c731... and the eras), which no longer apply to the amended packs; the ledger entry is the record. THE FIRST GREEN (11:31 UK, the box): the kaspa-pow suite on release-0.3.20-node (dc141409 plus the proof archive aea0ca5c plus the object-5 change) against the hash lane's igneum-pow 8c728ca3: 17 passed, 0 failed; the amended devnet epoch-0 id 1a4230699a6b9c60 pinned equal and c120d7963abdcd96 differing, the ladder's rung test green under the rekeyed rule, the v3 control unchanged; the consensus-core and exec RPC suites follow, then the node line (commit, push, box build, the tip to the shipper), then the digest and mixed-version gates. CLOCK RE-CUT (the node lane, 13:0x UK): the node line now carries, beside the object-5 change and the vector test, the lane's 0.3.20 fixes from the day (isSynced from the hook's stamp, the lazy template snapshot, the weight-table cache, the submit path returning after the block task, the watchdog, the RPC fields), about 13:30 UK if the box suites are green; the shipper's fresh-join canary 60 to 100 minutes after the cut; PC 1 as its first machine about 16:00 UK at the earliest, approximate until the shipper names the cut; the earliest flip about 6 days 10 hours after the publish. BUILD-2 LINES (12:28 to 12:33 UK): consensus-core 123 passed (the 60x file test green with the ladder window and activation pinned), the behind test green, kaspa-pow 17 passed (the amended vectors, earlier on build-1), the exec RPC suite green, the flows and rpc-service checks green with the submit-path change; the 24-requester latency test's first run tripped an unrelated flapping-fork double insert (24 equal forks from one parent; the test now builds on the sink as a real miner does; the double insert owed to a small fork harness before it is called a bug); THE NODE LINE COMMITTED (13:1x UK): release-0.3.20-node = 8097d600 (dc141409 + the proof archive aea0ca5c + one commit) on the mirror, pairing igneum-pow 8c728ca3, the hash with the shipper; in it the amended class v4 as object 5 (CLASS_SIGNAL_V4 = 5, byte 4 never counts, the kaspa-pow vector test pinning 1a4230699a6b9c60 equal and c120d7963abdcd96 differing, the daemon's window line naming object 5 and sub-version 1) beside the day's fixes (isSynced from the hook's stamp, the weight-table cache, the lazy snapshot, the submit path, the 100 ms template wait); the suites green on build-2 (consensus-core 123, the exec RPC suite, the four finality tests including 24 requesters under 200 ms: the worst template 100 ms, the worst submit 102 ms) and kaspa-pow 17 on build-1. Next: igneumd and igneum-miner building from 8097d600 on build-1, then the two gate lines (the mixed-version Devnet 2 gate: the 8097d600 node mining beside the 5899f603 pair for ten minutes on the live file without the v4 fields, the old node accepting every block; the digest test: the thirteen-field file b18ed271 unchanged, the sixteen-field object re-read on the 8097d600 binary), expected about 13:30 UK; the shipper picks the cut point. THE DATE FIXED (the node lane, from the hub's live file, 13:3x UK): publish 2 of 6 October (22:49:45Z, digest eada4bda) already put BOTH v4 fields on the live devnet (floor 831,600, window 86,400), so the 0.3.17 fleet has stamped object byte 4 since 7 October 00:2x UK and the floor is live at about 13 October 09:00 UK, before any seven-window signal completes; a 0.3.17 node left on that file flips to the OLD v4 stream at epoch 231 whatever anyone signals, a 0.3.20 node to the amended stream at the same epoch, and the two never share an id, so each straggler forks alone there. REQUIREMENT for the 0.3.20 publish (with the shipper and main): a new file with the floor at the publish DAA + 604,800 rounded up (about 882,000 for a publish today), the digest moving, the one-sweep rollout replacing every 0.3.17 node before 13 October 09:00 UK; any node that misses the sweep is alone then; the earliest flip after that about 6 days 10 hours past the publish; plan section 6.6 amended today. IN THE 0.3.20 PLAN (the shipper, 13:4x UK): both requirements; the node pin by main's rule is the node lane's second commit (the claim floor, the listener watchdog, the claim RPCs, on top of 8097d600) if its suites, both gates and the fleet's 12 GB prover line are green by 15:30 UK, else 8097d600; igneum-pow 8c728ca3 either way; the digest read on whichever binary pins. THE LINE AT 13:5x UK: three commits on release-0.3.20-node, 8097d600 (the object-5 amended class v4 and the day's fixes), 6b94c823 (test-only: the stale PC 1 test from 500ddd66 inverted by the isSynced ruling; the FALLBACK pin, code byte-identical to 8097d600, so the module reads green whole) and 6a3432a3 (the app lane's key methods, the observer's claims, the settled claim floor, the listener watchdog); suites on build-2 on 6a3432a3's code (the whole finality module 25, the exec suite 29 with the watchdog test, the kaspad, flows and rpc-service checks; consensus-core 123 and kaspa-pow 17 earlier); the cut 6a3432a3 if its gates and the fleet's 12 GB settled-claim line are green by 15:30 UK, else 6b94c823; both binaries building on build-1, the two gates (the digest gate, then the ten-minute mixed-version gate beside the 5899f603 pair) on the 8097d600 build, lines about 14:05 UK. GATE NEWS (13:53 UK): on 6a3432a3's own digest gate the listener watchdog counted a bind failure (the four harness nodes share one exec JSON-RPC port) as a listener death and exited three of four nodes at 20 s, where 0.3.17 and 8097d600 only warn and live without the exec RPC; the digest facts came out first and stand (the thirteen-field file a89be8a7 on both binaries, the compat case; the sixteen-field object db9a85f9 refused with the mismatch line, the refusal case); the ten-minute gate on 6a3432a3 stopped as void for the same cause. The fix: a bind failure is a retry every poll, one line a minute, no death counted and never an exit, with a second watchdog test whose known-failed shape is the old rule's exit on a held port; the third commit and its build about 14:15 UK, its gates about 14:35 UK; the fallback 6b94c823's gates on build-1 on their own binary (no watchdog there), lines about 14:20 UK; ledger row N12 for the bind-failure class. A ROLL BLOCKER on every kept datadir (the node lane, 14:1x UK, ledger N13): the fleet started 6a3432a3 on a kept 0.3.17 datadir (pool-1's copy) and it died at start (virtual_state.rs:250, DeserializationError(UnexpectedEof)); the cause 10db4b61 on the 0.3.16 feature line added `silent: bool` to BlockRewardData under serde(default), which bincode ignores, so every build from 10db4b61 on (dc141409, 8097d600, 6b94c823, 6a3432a3, 09124180) reads a 0.3.17 node's virtual-state row short; no canary saw it because every canary wiped, and a one-box roll keeps datadirs, so it blocks the roll on every standing box, the hands and the hub whatever the pin. The fix on the line: the store reads the current layout first and on a deserialization error decodes the row as a v1 mirror, converts with silent false and rewrites it under the same key, with the known-failed test first; the fourth commit and build about 14:40 UK, the fleet's kept-datadir start on the fixed binary about 14:50 UK, its gates after. THE RULE IT ADDS for every node cut from now: a kept-datadir restart gate on a standing box's datadir copy beside the wiped canary. THE CANDIDATE PIN (14:2x UK): b7cc37e7 (8097d600, 6b94c823, 6a3432a3, 09124180, b7cc37e7; igneum-pow 8c728ca3): the N13 fix with its test green on build-2 at 14:04 UK and the kaspad check green, the build on build-1; the fallback 6b94c823 is no longer a pin for the one-box roll (it dies on a kept datadir like every build since 10db4b61): if b7cc37e7's gates are not green by 15:30 UK the honest fallback is 0.3.17's 5899f603 staying live. In flight on build-1: the earlier commits' gates, then b7cc37e7's own digest and ten-minute mixed-version gates on its binary with the read-back, lines about 15:05 UK; on the fleet the kept-datadir start on b7cc37e7 about 14:50 UK and the 12 GB settled-claim line 14:50 to 15:00 UK. Plan section 6.6 amended with the hard date (ca3-v4-node 9d763edd, merged to master); N12 and N13 on the ledger. THE GATES ON THE FALLBACK'S OWN BINARY (6b94c823, sha b1b7d47b, 13:56 to 14:08 UK; code byte-identical to 8097d600, so the amendment's node side): the digest gate, the thirteen-field file a89be8a7 on both binaries (the compat case, n0 peering n1 and n2) and the sixteen-field object db9a85f9 refused with the mismatch line (the refusal case); the mixed-version gate, ten minutes, one digest b0afb2ee on all five nodes, the 5899f603 hub accepting every block the amended node mined (146 new, 246 old, 0 rejected), plain header version 2 on the thirteen-field file, counts equal on all five through the two clean joins and the restart. Two FAILED checks, both the harness's own and fixed (36d3efdc): a refused peer's count read 1 with the reconnect in flight (now the minimum of five), and six address-in-use panics in the two old nodes because the second gate reused the first's ports the second they were sent SIGTERM (a 20 s gap now). CLOCK CORRECTION (the node lane, 12:12Z = 13:12 BST): every "UK" stamp it sent today was the box's CEST, an hour fast of BST; its lines read UTC from now. Restated: b7cc37e7's build about 12:15Z, its digest and mixed-version gates on that binary with the sha and string about 12:32Z (13:32 BST), the fleet's kept-datadir start on it about 12:25Z, its 12 GB settled-claim line 12:50 to 13:00Z; the shipper's checkpoint 14:30Z (15:30 BST), two hours of room. The 13 October date stands (derived from UTC DAA rates): the floor 831,600 about 08:00Z, 09:00 BST. b7cc37e7'S OWN LINES (binary sha256 bc28331abf21f4d5, the string read back on build-1 and on the fleet's pod): the digest gate 12:14:39Z to 12:16:18Z SUMMARY PASS (thirteen fields a89be8a7 on both binaries with the peers as the gate wants them; the sixteen-field object db9a85f9 refused with the line and no peer; the live file's digest eada4bda on the binary, unmoved); the kept-datadir start on the fleet's copy of pool-1's 0.3.17 datadir: the first start 12:17:12Z reads the v1 row through the mirror and rewrites it ("1 mergeset rewards"), the finality blob converts (1,747 locks), the node comes up on its ports with no panic; the second start 12:18:53Z reads first-try with no rewrite line and no panic; 6a3432a3's death on the same copy is the known-failed shape. The ten-minute mixed-version gate beside the 5899f603 pair runs on the same binary since 12:16:39Z, its line about 12:28Z; then the only line outstanding for the shipper's 14:30Z rule is the fleet's 12 GB settled-claim line, 12:50 to 13:00Z. AP-F8-1 RESIDUAL CLASS ON THE AMENDED STREAM (attack-pass lane 12:18Z on igneum-pow 8c728ca3, sub-version 1). F9 over 1,000,000 seeds: programs flagged (hot share at least 1 percent or 7 constant address bits) 1,871 (0.19 percent) against 11,696 (1.17 percent) unamended; worst hot share 9.66 percent against 17.3; mean 0.011 against 0.063 percent; 84 percent of the flagged programs and the whole or-saturation tail gone. F8 at 30 of 64 seeds: nine over 1.2x of the window model (p31 29.3x, p11 5.5x, p19 3.3x, p6 3.1x, p23 2.0x, the rest 1.3x to 1.6x); the 64-seed 1.2x gate is heading to FAIL on sub-version 1. Mechanism, confirmed on the two worst seeds: an all-ones load source (image 0x0ca59e4c under the era map) delivered through a writer the source rule counts as entropy-keeping, a rotate (rotl and rotr map all-ones to itself) or a load whose own source was saturated, with the saturation made one or more writes upstream by or. The rule looks one writer back; it must look through saturation-preserving writers or test the source's values. The ceiling has not moved: rule (c)'s 120-of-128 floor still caps any program at one saturated site, 6.25 percent of reads, a chip edge of at most 1.067x, and the residual (worst seed two sites at 0.53 and 0.56) sits inside it. THE SENTENCE "no lossy-sourced load by construction" IS HELD: it goes in no plan row and no ledger entry as true; sub-version 1 removes the or-source class and bounds the rest. MAIN'S RULING (13:2x UK): 0.3.20 ships object byte 5 on sub-version 1 as it stands, strictly better than the old stream the live floor flips to on 13 October; the fix is sub-version 2 on ca3-v4-amend (object byte 6 or whatever the v5 alignment leaves free) with both fixes: (F1) the static rule made transitive (rotates do not keep entropy; a load keeps entropy only if its own source did; one draw change, no attempts lost) and (F2) the dynamic source check (saturated load SOURCE values counted per site over the 64 units' 16,384 evaluations, rejected above 163 of 16,384, the same 1 percent the final-value rule uses; costs attempts on about 0.2 percent of seeds; rides with F1 because an or-written source is all-ones only (3/4)^32 of the time). Gate before sub-version 2 is proposed, run by the attack-pass lane and not by the hash lane: the full 64-seed census under 1.2x on every seed and the hot-set census. Hash lane's estimate about an hour its side (implement, re-export seven packs, vectors, crate suite, pairing, one G1 on PC 2) plus the node lane's vector re-pin and the attack-pass re-gate. The flip floor for sub-version 1 is expected to move (Josh's word) so the chain never flips to a stream that fails this gate. Also recorded: the crate suite at 8c728ca3 100 of 100 on the box (rc 0, 77 s); the pairing against the fork at dc141409 compiled and ran 15 of 16, the one failure the fork's own pre-amendment assertion (base equals v3's, igneum.rs:972), which 8097d600 on the release-0.3.20-node line turns into assert_ne; the pairing re-runs at b7cc37e7, its line to follow. CORRECTION (the attack-pass lane's own retraction, 13:3x UK): the F9 hot-set figures above (1,871 of 1,000,000, worst 9.66 percent, 84 percent removed, the two or-then-rotate listings) are WITHDRAWN: F9's harness draws through candidate_class with its own era class, outside candidate_from_words_class where the source rule lives, so it measured the old stream (the 8c728ca3 binary prints the identical program to the sub-version-0 binary for its worst seed). F8's 64-seed census on the chain path (pairing verified on 1a4230699a6b9c60) is the valid re-gate and STANDS: at 30 of 64 seeds, nine over 1.2x of the window model (p31 29.3x, p11 5.5x, p19 3.3x, p6 3.1x, p23 2.0x, p4 1.6x, p10 1.5x, p26 1.3x, p25 1.3x). The residual mechanism on the amended stream: a load-after-load chain (a saturated source reads one fixed word, which is the next load's address), admitted because a load injects; and the rotate-preserves-saturation path (generator.rs sets entropy_kept true for a rotate whatever it rotated), correct in code and a second admitted path if it occurs on the chain stream. Sub-version 2 must close both: dataflow freshness per register (a load fresh only if its source was fresh; add, sub, xor, mad, shfl fresh if either operand was; rotates only if the operand was; or, mul, mulhi never) plus the (c') count of saturated load sources per site as the backstop. The STOP holds on F8's evidence alone; the options and the 1.067x ceiling are unchanged. The sentence "no lossy-sourced load by construction" waits on the sub-version 2 census verdict and stays out of every public text until then. SUB-VERSION 2 IN BUILD (the hash lane, ca3-v4-amend, on the coordinator's direction, 13:4x UK): F1 (dataflow freshness per register, keyed on the class v4 shape on every draw path, era or not, so the candidate_class path and the chain path draw one stream) plus F2 (the (c') count of saturated load source values per site over the 64 units' 16,384 evaluations, rejected above 163, keyed on the same shape so v2 and v3 verdicts do not move); PROGRAM_SUBVERSION_V4 = 2, new ids, the seven packs re-exported, recheck.rs with 1a4230699a6b9c60 and c120d7963abdcd96 as the must-differ pair. Clock (UTC): the commit on the branch by 13:30; the crate suite on box 2 and the pairing against b7cc37e7 by about 13:50 (the pairing's vector test fails on the fork's sub-version-1 pin until the node lane re-pins; the compile and the other 15 are the pairing evidence); the G1 job on PC 2 under --cards-off by about 14:10, lock permitting; then the attack-pass lane's full 64-seed census and hot-set census on the chain path. Two consequences stated in the commit: the rule on every draw path moves the no-era sh256xN ladder packs' stream (packs-ca3-shadow's seven 256-block packs re-export with new fingerprints; the measured rates stand as the old stream's), and the class v5 lane's pinned string-seed packs move when it merges sub-version 2, so it re-exports them then. 0.3.20's sub-version-1 packs, ids and fingerprints untouched. OBJECT BYTES SETTLED (main, 13:5x UK): byte 5 = class v4 sub-version 1 (0.3.20), byte 6 = class v5 (pinned: class-v5 16afd0a0, class-v5-node 699db5a2, the flip case passed on 6,6,6; the v5 lane stopped), byte 7 = class v4 sub-version 2; the node and hash lanes told. b7cc37e7's MIXED-VERSION GATE: FAIL, the binary not the harness (12:16:39Z to 12:27:21Z, sha256 bc28331abf21f4d5, the string read back). Before the restart step everything held: one digest b0afb2ee on all five nodes, 268 new and 392 old blocks accepted, 0 rejected, header versions plain 2, counts equal on all five at 324 and 502 through both clean joins. At the new node's restart (12:24:19Z) it died at once on its own datadir ("IO error: While lock file: .../datadir/meta/LOCK: Resource temporarily unavailable", conn_builder.rs:167): the previous process was still shutting down, because the listener watchdog added on 6a3432a3 sleeps its whole 10 s poll before checking shutdown, so every node on the line since then takes up to 10 s longer to stop than 0.3.17 (the fleet saw the same shape as "a 12-second timeout does not stop the node"). Three of the four failed checks follow from that one death (counts, the restarted node's resync, the node it served frozen at 502). The fix on the line, one rule: the poll in 250 ms steps returning the moment shutdown is set, with a test that a shutdown returns within a second (the 10 s loop the known-failed shape); the exec suite on build-2, the fifth commit and its build about 12:45Z, its digest and ten-minute gates about 12:50 to 13:05Z, inside 14:30Z. b7cc37e7 is NOT the pin. The node-side re-pin for sub-version 2 (byte 7) once the hash lane's commit lands: the beside-the-fork igneum-pow copy archived from the commit, the two pinned ids moved in the kaspa-pow vector test (sub-version-2's epoch-0 id must-equal; sub-version-1's joins c120d7963abdcd96 as must-differ), CLASS_SIGNAL and tests for byte 7, the daemon's window line: about 20 minutes of edits plus one kaspa-pow suite run on build-2 (about 2 minutes). THE FIFTH COMMIT c4459193 on release-0.3.20-node (b7cc37e7's child, the watchdog poll returning on shutdown; the diff is the poll loop in rpc.rs alone), pairing igneum-pow 8c728ca3; its build on build-1 started 12:30:13Z, sha256 and string to follow. Line A, the shutdown test: rpc::watchdog_tests::a_shutdown_returns_within_a_second_whatever_the_poll green on build-2 at 12:29Z in the exec suite's 31 passed, beside the two other watchdog tests; its known-failed shape the old loop's 10 s stop. Line B, the kept-datadir start: b7cc37e7's fleet read carries to c4459193 since the store code is byte-identical between the two commits; the fleet re-reads on the c4459193 binary only if the shipper's rule wants the string on that line too. The digest gate and the ten-minute mixed-version gate on c4459193's own binary follow its build. THE SHIPPER'S CARRY RULING (14:1x UK): b7cc37e7's kept-datadir read stands as evidence that the store fix is right (the store code byte-identical) but is not the gate line for the pin, because the rule reads the binary, not the diff, and the binary changed (rpc.rs); the gate line is the kept read on c4459193's own binary with its string, which the fleet's canary already runs on c18-1 (wipe, then the kept read, then the restart) before the canary's restart step, at no extra cost; no re-read on p12-vast. THE PIN IS c4459193 pairing 8c728ca3 (object byte 5, sub-version 1); sub-version 2 (byte 7) is 0.3.21's, not 0.3.20's. The shipper's reading of main's F8 ruling: 0.3.20 ships object 5 as it stands because the live floor otherwise flips every node to the OLD stream on 13 October, and the 16:00 BST report tells Josh the floor move is now RECOMMENDED rather than optional, so the chain never flips to a stream that fails the 1.2x gate before sub-version 2 lands. THE FLEET'S CLOCK ON c4459193 (the fleet lane, 12:5x UTC): the kept read on pool-1's 0.3.17 datadir copy and the restart (the old process's stop time on the line) run on c18-1 before the wipe, a few minutes each, so both lines land before 14:30Z; the wipe canary (IBD from the pruning-point proof, 98 minutes on this pod class) starts when c18-1 is free of the 0.3.20 cases (about 13:00Z) and the binary is in hand, so its synced line lands about 14:40Z at the earliest, PAST the 14:30Z checkpoint; the 12 GB settled-claim line: c4459193 starts on p12-vast's kept copy of pool-1's datadir beside the 6a3432a3 IBD node on alternate ports the moment the binary lands, catches up from 129,398 blocks (15 to 20 minutes) and the 12 GB prover claims against it, the line on c4459193 itself. The binary not yet in the fleet's hand (build-1 building since 12:30:13Z); a wait armed on the sha and string, a report by 13:10Z if nothing. THE SHIPPER'S CALL ON THE CLOCK (14:2x UK): the wipe canary is the decisive read by the deploy rule; the pin never cuts without it and b7cc37e7's lineage does not stand in (the binary changed). The fleet rents a second one-shot pod of c18-1's class now and starts the wipe canary on c4459193's binary the moment the build lands, synced line about 14:15Z (15:15 BST), inside the checkpoint; c18-1 keeps the 0.3.20 cases and the pool window. If the wipe line slips past 15:30 BST the pin holds to it and main hears the clock (a slip is a report, not a cut). The set: the node lane's digest and mixed-version gates (12:50 to 13:05Z), the kept read and restart on the new pod, the wipe line on the new pod, the 12 GB settled-claim line on p12-vast. c4459193's BINARY IN THE FLEET'S HAND (12:34:54Z from build-1): igneumd sha256 45be9b02d1b002f5486d0f0108571c3b6042094113ad9da6f3d3d9ffc0072bba with the string c4459193 read back from the file, igneum-miner c7cfc40bc8b0e357. The wipe pod c19-1 (RunPod wpuke4tfu0vr49, RTX 3070 community, c18-1's class, USD 0.13/h, rented 12:37:03Z, one-shot; the day at USD 124 of work plus the 248 leak, 37 percent of the ceiling): the canary form (wipe, IBD from the pruning-point proof, synced, ten minutes mining with the exec poller, the hub read, the restart read) starts the moment the pod answers ssh; the kept read on pool-1's 0.3.17 copy armed behind its synced line on the same pod; the IBD start stamp its own line; synced about 14:20Z if the pod answers by 12:42Z (ten minutes inside the checkpoint), a slip reported the moment a poll shows it. CASES END on c18-1 at 12:37:18Z rc 0 (the relay and poison lines to the shipper); c18-1 and the two case pods destroyed by the run; the ten-member pool window rented its ten at 12:37:36Z. The 12 GB settled-claim line on p12-vast runs against a c4459193 node on the pod's kept copy, up since 12:36:35Z first-try, catching up. THE WIPE CANARY ON c19-1 STARTED: IBD at 12:38:55Z on c4459193 (sha256 45be9b02... asserted on the Mac before the put; the node's own line igneumd/2.1.0-c4459193 and digest eada4bda8aa8368c read back on the pod; a wiped datadir; IBD from the pruning-point proof with 4 peers at 12:39:26Z); synced about 14:17Z by the 98-minute class, thirteen minutes inside the checkpoint; the mining read, hub read, restart and kept read follow on the same pod, each its own line. c4459193's GATE LINES (the node lane): the binary built on build-1 at 12:33Z (1 m 07 s), sha256 45be9b02d1b002f5, the string read back from the binary (strings, two hits) and the worktree HEAD; igneum-miner beside it at /srv/builds/igneum-wt-ca3-v4-node/vendor/igneum-node-0318-release/target/release/. THE DIGEST GATE 12:33:27Z to 12:35:05Z SUMMARY PASS: the thirteen-field object a89be8a7 on both binaries, n0 peering n1 and n2 and the old node peering the new (the compat case); the sixteen-field object db9a85f9, n3 with no peer and the refusal line "consensus params digest mismatch, local db9a… remote a89b…" (the refusal case); the live file's digest on this binary eada4bda, as 5899f603 reads it. THE MIXED-VERSION GATE 12:35:26Z to 12:45:39Z SUMMARY PASS, beside the 5899f603 pair: one digest b0afb2ee on all five nodes; the 5899f603 hub accepted every block the c4459193 node mined, 215 new and 314 old, 0 rejected, no reject line in any log; header versions plain 2 on the thirteen-field file; counts equal on all five at 312 after mining, 441 after the clean join through the old hub and the clean join served by the new node, 529 at the end; the restart step passed: the new node restarted at 12:43:08Z on its own datadir and resynced to 529 with the others (where b7cc37e7 died on the database lock); no panic in any node log; every check green. The node side of the set is complete; the fleet's wipe, kept read, restart and settled-claim lines remain. A SLIP (the fleet lane, 12:5x UTC): the 0.3.20 cases rerun on c4459193 lands about 15:10Z, not 14:20Z: its target c20-1 catches up from pool-1's kept 1026 copy, 22,000 blocks behind a tip the line reaches headers-first (headers 137,405, blocks 129,398 at 12:50Z; the morning's poison pod on the same copy took 50 minutes before its blocks moved), synced about 13:50Z, the 79-minute form after; no faster path exists on a kept copy. The wipe canary on c19-1 holds its clock (29 percent of the headers at 12:47Z on dc141409's curve): synced about 14:17Z, the mining and hub reads to about 14:30Z, the restart and the kept read after; the 12 GB settled-claim line on p12-vast about 14:00 to 14:10Z. The kept read on the pinned binary is already in hand from c20-1's own start at 12:45:46Z (the rewrite line, no panic, sha 45be9b02 and the string read back), with the shipper. The shipper has the call on the cases' clock. THE INTEROP FACT stands from the void run: the 5899f603 hub accepted 235 object-byte-5 blocks from the 8097d600 node with 0 rejected, one digest on all five nodes on the live sixteen-field file. The gates: the digest test and the kaspa-pow vector test (the amended devnet epoch-0 id 1a4230699a6b9c60 must equal, c120d7963abdcd96 must differ, the v3 control unchanged) on the box; the mixed-version Devnet 2 gate (the amended 0.3.20 node beside a 5899f603 node for ten minutes on the live file without the v4 fields) after the Mac build; the fresh-join canary the 0.3.20 cut's | | Main's rulings (7 October, morning) | no generator change to v4 on the live devnet; the record's null is the window model with numbers, sent by the hash lane to the attack-pass lane so AP-F8-1 re-gates against it; a fault beyond the model (a low-entropy source at site 15) stops at the coordinator with the two options priced (a 0.3.19 class amendment before the flip, or the flip held at the floor), nothing shipping without Josh's word; the tighter tail, an acceptance bound on the hot-set share, is a CLASS V5 item (sent to the v5 lane a6410f3b8abefb762 with the 64-seed census as its gate; the bound's number follows from the model) | ### AP-F4-1, the weak-day MUL draw (the attack-pass lane, 7 October, morning): PASS against v4, a class v5 rule From 58c14e91484b89a95b859392af63a08577697195 Mon Sep 17 00:00:00 2001 From: igneum-josh <337424239+igneum-josh@users.noreply.github.com> Date: Wed, 7 Oct 2026 13:54:05 +0100 Subject: [PATCH 10/19] Counter ASIC 3.0 status: the cut gated on CASES END, the word about 15:15Z, publish on green, sweep PC 1 first Co-Authored-By: Claude Fable 5.1 --- docs/plans/counter-asic-3-status.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/plans/counter-asic-3-status.md b/docs/plans/counter-asic-3-status.md index 52752f443..74cddfa43 100644 --- a/docs/plans/counter-asic-3-status.md +++ b/docs/plans/counter-asic-3-status.md @@ -338,7 +338,7 @@ Josh gave the go in advance for tonight: the shipper runs publish 1 on the 0.3.1 | THE ANALYSIS (the hash lane, ca3-v4-uniform 095f84a7, `docs/analysis/ca3-v4-uniform.md`, the tool on igneum-build-1) | the window model moves the null from 0.115 to 0.160 percent (1.39x, not 4.05x); the rest is a FAULT beyond it: site 15 reads a register last written by `or r6, r4`, so all-ones recurs at (3/4)^32 per read and the era map sends it to F8's hottest item exactly (the popcount model predicts 77,348 all-ones reads against 78,479; the top-0.1-percent share 0.58 against 0.52); it passes the acceptance rule because part (a) takes any write as a fresh source and part (c) counts saturation on final values only. The census of 1,024 chain-shaped v4 programs: 96.6 percent carry a lossy-sourced load (or, mul, mulhi as the last writer), 48.5 percent an or-sourced one (0.30 percent of all reads per site), 4.9 percent an or-of-or chain (4.6 percent of all reads on 0.1 percent of items); F8's 1.2x gate fails 96.6 percent of today's programs. Worth to a chip: 1.07 MB of SRAM ($0.25) serving 0.52 percent of a typical program's reads and 4.6 percent of the worst class's, at most 1.005x and 1.048x in rate; the ceiling under rule (c)'s 120-of-128 floor one site repeating its item in all 8 iterations, 6.25 percent of reads, 1.067x in 64 bytes; the 2x margin stands; the public line says "bounded at 1.067x", not "uniform" (the public text corrected) | | The two options, priced, STOPPED at the coordinator for Josh's word | A: a 0.3.19 class amendment before the flip (the generator draws a load's source from the registers whose last writer injects): a new program stream, new vectors, the seven gate packs re-exported, the six gates again (G1 to G3 and the verifier about an hour on the Mac and PC 2; G4 to G6 the node lane), every node before the flip under the one-box-at-a-time rule; the risk a node that misses the build splits the chain at the flip. B: hold the flip at the floor with v4 as it is; the bound documented; the source rule to class v5: a hot set worth up to 1.005x on about half the hours and 1.05x on 5 percent, 1.067x at the ceiling; no chain risk. The number: 1.067x at the ceiling against the 2x margin. The lane recommends B | | The v5 bound (sent to the v5 lane) | H = W_0.1 (the window term, 0.115 to 0.251 percent) + the sum over load sites of h(last writer) (or 0.30 percent, an or chain 4.5, mul 0.067, mulhi 0.049, an injecting op or a rotate 0), H at or under 1.2 x W_0.1, which is the static rule "every load's source was last written by an injecting op or a rotate"; as a rejection it costs 96.6 percent of candidates (about 30 attempts per seed), as a generator draw nothing; gate F8's 64-seed census with the saturated-source count | -| JOSH'S WORD (15:2x UK, 7 October): OPTION A, "do this but limit the testing, get it pushed" | the class v4 amendment: a load's source drawn only from registers whose last writer injects or is a rotate (the v5 rule applied now), a new program stream and vectors, the seven gate packs re-exported, the amended class with its own generator stamp; rides 0.3.20, the feature node (release-0.3.20-node = dc141409; 0.3.19 is an app-only cut with nothing of ours), on the shipper's line. The rollout arithmetic for the flip clock (the shipper): the standing fleet's one-box-at-a-time rollout took 32 minutes for 14 boxes (04:56 to 05:28Z, 7 October), the hands and the seed about 3 minutes after the miners, the Mac and the PCs within minutes of the publish; every 0.3.20 worker must accept the amended stamp before any flip. Owners: the hash lane (ca3-v4-amend: the generator, the vectors, the packs, the pairing on the box, one G1 run on PC 2, the ledger row), the node lane (release-0.3.20-node: the stamp agreed with the hash lane, the split-protection mechanism and the earliest flip time, the digest test, the mixed-version Devnet 2 gate), the attack-pass lane (the F8 census at 2^24 on the new stream, the gate 1.2x of the window model over 64 seeds), the shipper (the cut, the rollout order that sets the earliest flip). Testing limited to what prevents a split and proves the fix; G2, G3, the ladder re-measure and the rest of G4 to G6 OWED. THE STAMP agreed (the node and hash lanes, 7 October afternoon): generator 4 with sub-version 1 inside igneum-pow's id function, so the amended v4's program id for a seed differs from the old v4's (the old devnet epoch-0 id c120d7963abdcd96 pinned as the must-differ vector in kaspa-pow's test). SPLIT PROTECTION SETTLED (the node lane, plan section 6.6, ca3-v4-node fa5bc9e6; the node side on release-0.3.20-node): a fresh object byte. CLASS_SIGNAL_V4 is 5; the amended binary stamps 5 and the tally counts a block only at byte 5 or above; object 4 was stamped only by the unpublished dc141409 canary, so no published block carries it and a byte-4 block never counts; a node of the 6 October stream that sees byte 5 counts it as v4 (its rule is at least 4), flips to its own stream at the same epoch and forks ALONE (its blocks fail the amended id check, generator 4 sub-version 1 inside every id; the amended blocks fail its own), ours to upgrade in the sweep; object 6 is class v5's; the two holds already in the rule keep the window shut until every node is on 0.3.20 (a node stamps and tallies only with both v4 fields in its file; the fields publish only after the one-sweep rollout); a lagging worker refuses the amended pack at packcheck and mines nothing after the flip, costing that box, never the chain; no extra window hold: seven full day-windows are the hold. THE EARLIEST FLIP (approximate, measured 09:40Z: DAA 270,659, 1.095 DAA/s over 25 hours, 1.165 over 4; epoch 3,600, lead 600; seven windows 604,800 DAA wholly after the sweep's end D_s = T + about 40 minutes; the flip epoch the first e with 3600 e - 600 >= D_s + 604,800): T + 6 days 10 hours to T + 6 days 11 hours UK; for a publish at 12:00 UK on 7 October, 13 October between 22:20 and 23:10 UK (about 13:00 UK if the 4-hour rate holds). The floor as it stands (831,600, about 13 October 09:00 UK) would fire before any seven-window signal from a publish today completes, so it moves by the 0.3.16 rule to the publish DAA + 604,800 rounded up to the epoch boundary (882,000 for a 12:00 UK publish), firing about 30 minutes before the earliest signal flip: either way about 6 days 10 hours after the publish, never before every node has had the sweep plus a week. THE CLOCK (the node lane, 11:3x UK, after a Mac reboot moved its runs to the box): the 0.3.20 node line (dc141409 plus the proof archive aea0ca5c plus the amended v4 at object byte 5, igneum-pow at the hash lane's a0aaca92 beside the fork on the box) tested on the box, committed on release-0.3.20-node, pushed to the mirror and origin, igneumd and igneum-miner built, the tip to the shipper: about 12:00 UK; the mixed-version Devnet 2 gate (node-compat.mjs on the box, the amended node beside the 5899f603 pair for ten minutes) and the digest test (digest-compat.mjs): about 12:45 UK; the object-byte pin 5 unless the v5 lane answers both lanes with another assignment (v5 at 6 proposed). THE HASH SIDE on ca3-v4-amend (tip 8c728ca3, read from the branch 14:0x UK; the hash lane's own report pending): 1748fd1d the PC 2 G1-only playbook; e1f48d63 the fud-ledger entry AP-F8-1 (the fault, Josh's ruling, the amendment, the split protection, the owed tests); d8859522 the G1 line (the eight fingerprints equal on the RTX 5090, self-test PASS) and the node lane's signal byte 5; 4aa0c665 the v4 unit test following the amendment; 965d9e96 igneum-pow taken from release-0.3.20's 3f1652bf (the ladder's chain_program_shadow with the reps argument, never on master) with the amendment re-applied, the seven packs re-exporting byte-identical; 8c728ca3 the source rule keyed on the class with the shadow's pass count set aside, so every ladder rung draws under it (the fork's ladder test). The shipper took this igneum-pow tree into release-0.3.20 (00249643, byte-equal); nothing after 8c728ca3 touches igneum-pow. THE VECTORS AND THE PACKS (read from the branch and its ledger entry, 14:1x UK): the seven amended v4 packs (v4-devnet-epoch0, v4-era-0 to 5) carry generator 4, sub-version 1, one program id 1a4230699a6b9c60 (the 2.0 one-id-per-seed rule across the eras; the old c120d7963abdcd96 pinned as must-differ); the v3 control mx8-devnet-epoch0 untouched (73bcbfe8ccf988f1, fingerprint 90f794dd556f7a3b); the seven 2^24 fingerprints, Metal equal to Apple OpenCL: 867dbc45cfb36b4d, 2146ecacc8c75a8e, fe52602393f6d3d4, 3b206471a13912b4, c3f03c4a5d7333aa, f1dfd7209f15bb97, 8c194da64fadf31d; the zip of the eight packs sha256 889ec99976d2728b4b5035bfa476032e5b6a13b928968fc45236d5f25084aa39; the per-pack vectors.json sha256 prefixes 756301bf (devnet epoch 0), 1b5f4568, d430cadc, 1a1b21d8, 460fff9e, 4a85d49d, f83a1196 (eras 0 to 5). G1 on the RTX 5090 (PC 2 job run-ca3-v4-amend-g1-pc2-20261007, 09:41:07 to 09:41:28Z, exit 0, the installed worker): every fingerprint equal to the Mac's (the seven above and the control), NVRTC 188 to 332 ms per pack, the 1 GiB build 38 to 49 ms. hash-gates.md's older table still lists the pre-amendment fingerprints (f410c731... and the eras), which no longer apply to the amended packs; the ledger entry is the record. THE FIRST GREEN (11:31 UK, the box): the kaspa-pow suite on release-0.3.20-node (dc141409 plus the proof archive aea0ca5c plus the object-5 change) against the hash lane's igneum-pow 8c728ca3: 17 passed, 0 failed; the amended devnet epoch-0 id 1a4230699a6b9c60 pinned equal and c120d7963abdcd96 differing, the ladder's rung test green under the rekeyed rule, the v3 control unchanged; the consensus-core and exec RPC suites follow, then the node line (commit, push, box build, the tip to the shipper), then the digest and mixed-version gates. CLOCK RE-CUT (the node lane, 13:0x UK): the node line now carries, beside the object-5 change and the vector test, the lane's 0.3.20 fixes from the day (isSynced from the hook's stamp, the lazy template snapshot, the weight-table cache, the submit path returning after the block task, the watchdog, the RPC fields), about 13:30 UK if the box suites are green; the shipper's fresh-join canary 60 to 100 minutes after the cut; PC 1 as its first machine about 16:00 UK at the earliest, approximate until the shipper names the cut; the earliest flip about 6 days 10 hours after the publish. BUILD-2 LINES (12:28 to 12:33 UK): consensus-core 123 passed (the 60x file test green with the ladder window and activation pinned), the behind test green, kaspa-pow 17 passed (the amended vectors, earlier on build-1), the exec RPC suite green, the flows and rpc-service checks green with the submit-path change; the 24-requester latency test's first run tripped an unrelated flapping-fork double insert (24 equal forks from one parent; the test now builds on the sink as a real miner does; the double insert owed to a small fork harness before it is called a bug); THE NODE LINE COMMITTED (13:1x UK): release-0.3.20-node = 8097d600 (dc141409 + the proof archive aea0ca5c + one commit) on the mirror, pairing igneum-pow 8c728ca3, the hash with the shipper; in it the amended class v4 as object 5 (CLASS_SIGNAL_V4 = 5, byte 4 never counts, the kaspa-pow vector test pinning 1a4230699a6b9c60 equal and c120d7963abdcd96 differing, the daemon's window line naming object 5 and sub-version 1) beside the day's fixes (isSynced from the hook's stamp, the weight-table cache, the lazy snapshot, the submit path, the 100 ms template wait); the suites green on build-2 (consensus-core 123, the exec RPC suite, the four finality tests including 24 requesters under 200 ms: the worst template 100 ms, the worst submit 102 ms) and kaspa-pow 17 on build-1. Next: igneumd and igneum-miner building from 8097d600 on build-1, then the two gate lines (the mixed-version Devnet 2 gate: the 8097d600 node mining beside the 5899f603 pair for ten minutes on the live file without the v4 fields, the old node accepting every block; the digest test: the thirteen-field file b18ed271 unchanged, the sixteen-field object re-read on the 8097d600 binary), expected about 13:30 UK; the shipper picks the cut point. THE DATE FIXED (the node lane, from the hub's live file, 13:3x UK): publish 2 of 6 October (22:49:45Z, digest eada4bda) already put BOTH v4 fields on the live devnet (floor 831,600, window 86,400), so the 0.3.17 fleet has stamped object byte 4 since 7 October 00:2x UK and the floor is live at about 13 October 09:00 UK, before any seven-window signal completes; a 0.3.17 node left on that file flips to the OLD v4 stream at epoch 231 whatever anyone signals, a 0.3.20 node to the amended stream at the same epoch, and the two never share an id, so each straggler forks alone there. REQUIREMENT for the 0.3.20 publish (with the shipper and main): a new file with the floor at the publish DAA + 604,800 rounded up (about 882,000 for a publish today), the digest moving, the one-sweep rollout replacing every 0.3.17 node before 13 October 09:00 UK; any node that misses the sweep is alone then; the earliest flip after that about 6 days 10 hours past the publish; plan section 6.6 amended today. IN THE 0.3.20 PLAN (the shipper, 13:4x UK): both requirements; the node pin by main's rule is the node lane's second commit (the claim floor, the listener watchdog, the claim RPCs, on top of 8097d600) if its suites, both gates and the fleet's 12 GB prover line are green by 15:30 UK, else 8097d600; igneum-pow 8c728ca3 either way; the digest read on whichever binary pins. THE LINE AT 13:5x UK: three commits on release-0.3.20-node, 8097d600 (the object-5 amended class v4 and the day's fixes), 6b94c823 (test-only: the stale PC 1 test from 500ddd66 inverted by the isSynced ruling; the FALLBACK pin, code byte-identical to 8097d600, so the module reads green whole) and 6a3432a3 (the app lane's key methods, the observer's claims, the settled claim floor, the listener watchdog); suites on build-2 on 6a3432a3's code (the whole finality module 25, the exec suite 29 with the watchdog test, the kaspad, flows and rpc-service checks; consensus-core 123 and kaspa-pow 17 earlier); the cut 6a3432a3 if its gates and the fleet's 12 GB settled-claim line are green by 15:30 UK, else 6b94c823; both binaries building on build-1, the two gates (the digest gate, then the ten-minute mixed-version gate beside the 5899f603 pair) on the 8097d600 build, lines about 14:05 UK. GATE NEWS (13:53 UK): on 6a3432a3's own digest gate the listener watchdog counted a bind failure (the four harness nodes share one exec JSON-RPC port) as a listener death and exited three of four nodes at 20 s, where 0.3.17 and 8097d600 only warn and live without the exec RPC; the digest facts came out first and stand (the thirteen-field file a89be8a7 on both binaries, the compat case; the sixteen-field object db9a85f9 refused with the mismatch line, the refusal case); the ten-minute gate on 6a3432a3 stopped as void for the same cause. The fix: a bind failure is a retry every poll, one line a minute, no death counted and never an exit, with a second watchdog test whose known-failed shape is the old rule's exit on a held port; the third commit and its build about 14:15 UK, its gates about 14:35 UK; the fallback 6b94c823's gates on build-1 on their own binary (no watchdog there), lines about 14:20 UK; ledger row N12 for the bind-failure class. A ROLL BLOCKER on every kept datadir (the node lane, 14:1x UK, ledger N13): the fleet started 6a3432a3 on a kept 0.3.17 datadir (pool-1's copy) and it died at start (virtual_state.rs:250, DeserializationError(UnexpectedEof)); the cause 10db4b61 on the 0.3.16 feature line added `silent: bool` to BlockRewardData under serde(default), which bincode ignores, so every build from 10db4b61 on (dc141409, 8097d600, 6b94c823, 6a3432a3, 09124180) reads a 0.3.17 node's virtual-state row short; no canary saw it because every canary wiped, and a one-box roll keeps datadirs, so it blocks the roll on every standing box, the hands and the hub whatever the pin. The fix on the line: the store reads the current layout first and on a deserialization error decodes the row as a v1 mirror, converts with silent false and rewrites it under the same key, with the known-failed test first; the fourth commit and build about 14:40 UK, the fleet's kept-datadir start on the fixed binary about 14:50 UK, its gates after. THE RULE IT ADDS for every node cut from now: a kept-datadir restart gate on a standing box's datadir copy beside the wiped canary. THE CANDIDATE PIN (14:2x UK): b7cc37e7 (8097d600, 6b94c823, 6a3432a3, 09124180, b7cc37e7; igneum-pow 8c728ca3): the N13 fix with its test green on build-2 at 14:04 UK and the kaspad check green, the build on build-1; the fallback 6b94c823 is no longer a pin for the one-box roll (it dies on a kept datadir like every build since 10db4b61): if b7cc37e7's gates are not green by 15:30 UK the honest fallback is 0.3.17's 5899f603 staying live. In flight on build-1: the earlier commits' gates, then b7cc37e7's own digest and ten-minute mixed-version gates on its binary with the read-back, lines about 15:05 UK; on the fleet the kept-datadir start on b7cc37e7 about 14:50 UK and the 12 GB settled-claim line 14:50 to 15:00 UK. Plan section 6.6 amended with the hard date (ca3-v4-node 9d763edd, merged to master); N12 and N13 on the ledger. THE GATES ON THE FALLBACK'S OWN BINARY (6b94c823, sha b1b7d47b, 13:56 to 14:08 UK; code byte-identical to 8097d600, so the amendment's node side): the digest gate, the thirteen-field file a89be8a7 on both binaries (the compat case, n0 peering n1 and n2) and the sixteen-field object db9a85f9 refused with the mismatch line (the refusal case); the mixed-version gate, ten minutes, one digest b0afb2ee on all five nodes, the 5899f603 hub accepting every block the amended node mined (146 new, 246 old, 0 rejected), plain header version 2 on the thirteen-field file, counts equal on all five through the two clean joins and the restart. Two FAILED checks, both the harness's own and fixed (36d3efdc): a refused peer's count read 1 with the reconnect in flight (now the minimum of five), and six address-in-use panics in the two old nodes because the second gate reused the first's ports the second they were sent SIGTERM (a 20 s gap now). CLOCK CORRECTION (the node lane, 12:12Z = 13:12 BST): every "UK" stamp it sent today was the box's CEST, an hour fast of BST; its lines read UTC from now. Restated: b7cc37e7's build about 12:15Z, its digest and mixed-version gates on that binary with the sha and string about 12:32Z (13:32 BST), the fleet's kept-datadir start on it about 12:25Z, its 12 GB settled-claim line 12:50 to 13:00Z; the shipper's checkpoint 14:30Z (15:30 BST), two hours of room. The 13 October date stands (derived from UTC DAA rates): the floor 831,600 about 08:00Z, 09:00 BST. b7cc37e7'S OWN LINES (binary sha256 bc28331abf21f4d5, the string read back on build-1 and on the fleet's pod): the digest gate 12:14:39Z to 12:16:18Z SUMMARY PASS (thirteen fields a89be8a7 on both binaries with the peers as the gate wants them; the sixteen-field object db9a85f9 refused with the line and no peer; the live file's digest eada4bda on the binary, unmoved); the kept-datadir start on the fleet's copy of pool-1's 0.3.17 datadir: the first start 12:17:12Z reads the v1 row through the mirror and rewrites it ("1 mergeset rewards"), the finality blob converts (1,747 locks), the node comes up on its ports with no panic; the second start 12:18:53Z reads first-try with no rewrite line and no panic; 6a3432a3's death on the same copy is the known-failed shape. The ten-minute mixed-version gate beside the 5899f603 pair runs on the same binary since 12:16:39Z, its line about 12:28Z; then the only line outstanding for the shipper's 14:30Z rule is the fleet's 12 GB settled-claim line, 12:50 to 13:00Z. AP-F8-1 RESIDUAL CLASS ON THE AMENDED STREAM (attack-pass lane 12:18Z on igneum-pow 8c728ca3, sub-version 1). F9 over 1,000,000 seeds: programs flagged (hot share at least 1 percent or 7 constant address bits) 1,871 (0.19 percent) against 11,696 (1.17 percent) unamended; worst hot share 9.66 percent against 17.3; mean 0.011 against 0.063 percent; 84 percent of the flagged programs and the whole or-saturation tail gone. F8 at 30 of 64 seeds: nine over 1.2x of the window model (p31 29.3x, p11 5.5x, p19 3.3x, p6 3.1x, p23 2.0x, the rest 1.3x to 1.6x); the 64-seed 1.2x gate is heading to FAIL on sub-version 1. Mechanism, confirmed on the two worst seeds: an all-ones load source (image 0x0ca59e4c under the era map) delivered through a writer the source rule counts as entropy-keeping, a rotate (rotl and rotr map all-ones to itself) or a load whose own source was saturated, with the saturation made one or more writes upstream by or. The rule looks one writer back; it must look through saturation-preserving writers or test the source's values. The ceiling has not moved: rule (c)'s 120-of-128 floor still caps any program at one saturated site, 6.25 percent of reads, a chip edge of at most 1.067x, and the residual (worst seed two sites at 0.53 and 0.56) sits inside it. THE SENTENCE "no lossy-sourced load by construction" IS HELD: it goes in no plan row and no ledger entry as true; sub-version 1 removes the or-source class and bounds the rest. MAIN'S RULING (13:2x UK): 0.3.20 ships object byte 5 on sub-version 1 as it stands, strictly better than the old stream the live floor flips to on 13 October; the fix is sub-version 2 on ca3-v4-amend (object byte 6 or whatever the v5 alignment leaves free) with both fixes: (F1) the static rule made transitive (rotates do not keep entropy; a load keeps entropy only if its own source did; one draw change, no attempts lost) and (F2) the dynamic source check (saturated load SOURCE values counted per site over the 64 units' 16,384 evaluations, rejected above 163 of 16,384, the same 1 percent the final-value rule uses; costs attempts on about 0.2 percent of seeds; rides with F1 because an or-written source is all-ones only (3/4)^32 of the time). Gate before sub-version 2 is proposed, run by the attack-pass lane and not by the hash lane: the full 64-seed census under 1.2x on every seed and the hot-set census. Hash lane's estimate about an hour its side (implement, re-export seven packs, vectors, crate suite, pairing, one G1 on PC 2) plus the node lane's vector re-pin and the attack-pass re-gate. The flip floor for sub-version 1 is expected to move (Josh's word) so the chain never flips to a stream that fails this gate. Also recorded: the crate suite at 8c728ca3 100 of 100 on the box (rc 0, 77 s); the pairing against the fork at dc141409 compiled and ran 15 of 16, the one failure the fork's own pre-amendment assertion (base equals v3's, igneum.rs:972), which 8097d600 on the release-0.3.20-node line turns into assert_ne; the pairing re-runs at b7cc37e7, its line to follow. CORRECTION (the attack-pass lane's own retraction, 13:3x UK): the F9 hot-set figures above (1,871 of 1,000,000, worst 9.66 percent, 84 percent removed, the two or-then-rotate listings) are WITHDRAWN: F9's harness draws through candidate_class with its own era class, outside candidate_from_words_class where the source rule lives, so it measured the old stream (the 8c728ca3 binary prints the identical program to the sub-version-0 binary for its worst seed). F8's 64-seed census on the chain path (pairing verified on 1a4230699a6b9c60) is the valid re-gate and STANDS: at 30 of 64 seeds, nine over 1.2x of the window model (p31 29.3x, p11 5.5x, p19 3.3x, p6 3.1x, p23 2.0x, p4 1.6x, p10 1.5x, p26 1.3x, p25 1.3x). The residual mechanism on the amended stream: a load-after-load chain (a saturated source reads one fixed word, which is the next load's address), admitted because a load injects; and the rotate-preserves-saturation path (generator.rs sets entropy_kept true for a rotate whatever it rotated), correct in code and a second admitted path if it occurs on the chain stream. Sub-version 2 must close both: dataflow freshness per register (a load fresh only if its source was fresh; add, sub, xor, mad, shfl fresh if either operand was; rotates only if the operand was; or, mul, mulhi never) plus the (c') count of saturated load sources per site as the backstop. The STOP holds on F8's evidence alone; the options and the 1.067x ceiling are unchanged. The sentence "no lossy-sourced load by construction" waits on the sub-version 2 census verdict and stays out of every public text until then. SUB-VERSION 2 IN BUILD (the hash lane, ca3-v4-amend, on the coordinator's direction, 13:4x UK): F1 (dataflow freshness per register, keyed on the class v4 shape on every draw path, era or not, so the candidate_class path and the chain path draw one stream) plus F2 (the (c') count of saturated load source values per site over the 64 units' 16,384 evaluations, rejected above 163, keyed on the same shape so v2 and v3 verdicts do not move); PROGRAM_SUBVERSION_V4 = 2, new ids, the seven packs re-exported, recheck.rs with 1a4230699a6b9c60 and c120d7963abdcd96 as the must-differ pair. Clock (UTC): the commit on the branch by 13:30; the crate suite on box 2 and the pairing against b7cc37e7 by about 13:50 (the pairing's vector test fails on the fork's sub-version-1 pin until the node lane re-pins; the compile and the other 15 are the pairing evidence); the G1 job on PC 2 under --cards-off by about 14:10, lock permitting; then the attack-pass lane's full 64-seed census and hot-set census on the chain path. Two consequences stated in the commit: the rule on every draw path moves the no-era sh256xN ladder packs' stream (packs-ca3-shadow's seven 256-block packs re-export with new fingerprints; the measured rates stand as the old stream's), and the class v5 lane's pinned string-seed packs move when it merges sub-version 2, so it re-exports them then. 0.3.20's sub-version-1 packs, ids and fingerprints untouched. OBJECT BYTES SETTLED (main, 13:5x UK): byte 5 = class v4 sub-version 1 (0.3.20), byte 6 = class v5 (pinned: class-v5 16afd0a0, class-v5-node 699db5a2, the flip case passed on 6,6,6; the v5 lane stopped), byte 7 = class v4 sub-version 2; the node and hash lanes told. b7cc37e7's MIXED-VERSION GATE: FAIL, the binary not the harness (12:16:39Z to 12:27:21Z, sha256 bc28331abf21f4d5, the string read back). Before the restart step everything held: one digest b0afb2ee on all five nodes, 268 new and 392 old blocks accepted, 0 rejected, header versions plain 2, counts equal on all five at 324 and 502 through both clean joins. At the new node's restart (12:24:19Z) it died at once on its own datadir ("IO error: While lock file: .../datadir/meta/LOCK: Resource temporarily unavailable", conn_builder.rs:167): the previous process was still shutting down, because the listener watchdog added on 6a3432a3 sleeps its whole 10 s poll before checking shutdown, so every node on the line since then takes up to 10 s longer to stop than 0.3.17 (the fleet saw the same shape as "a 12-second timeout does not stop the node"). Three of the four failed checks follow from that one death (counts, the restarted node's resync, the node it served frozen at 502). The fix on the line, one rule: the poll in 250 ms steps returning the moment shutdown is set, with a test that a shutdown returns within a second (the 10 s loop the known-failed shape); the exec suite on build-2, the fifth commit and its build about 12:45Z, its digest and ten-minute gates about 12:50 to 13:05Z, inside 14:30Z. b7cc37e7 is NOT the pin. The node-side re-pin for sub-version 2 (byte 7) once the hash lane's commit lands: the beside-the-fork igneum-pow copy archived from the commit, the two pinned ids moved in the kaspa-pow vector test (sub-version-2's epoch-0 id must-equal; sub-version-1's joins c120d7963abdcd96 as must-differ), CLASS_SIGNAL and tests for byte 7, the daemon's window line: about 20 minutes of edits plus one kaspa-pow suite run on build-2 (about 2 minutes). THE FIFTH COMMIT c4459193 on release-0.3.20-node (b7cc37e7's child, the watchdog poll returning on shutdown; the diff is the poll loop in rpc.rs alone), pairing igneum-pow 8c728ca3; its build on build-1 started 12:30:13Z, sha256 and string to follow. Line A, the shutdown test: rpc::watchdog_tests::a_shutdown_returns_within_a_second_whatever_the_poll green on build-2 at 12:29Z in the exec suite's 31 passed, beside the two other watchdog tests; its known-failed shape the old loop's 10 s stop. Line B, the kept-datadir start: b7cc37e7's fleet read carries to c4459193 since the store code is byte-identical between the two commits; the fleet re-reads on the c4459193 binary only if the shipper's rule wants the string on that line too. The digest gate and the ten-minute mixed-version gate on c4459193's own binary follow its build. THE SHIPPER'S CARRY RULING (14:1x UK): b7cc37e7's kept-datadir read stands as evidence that the store fix is right (the store code byte-identical) but is not the gate line for the pin, because the rule reads the binary, not the diff, and the binary changed (rpc.rs); the gate line is the kept read on c4459193's own binary with its string, which the fleet's canary already runs on c18-1 (wipe, then the kept read, then the restart) before the canary's restart step, at no extra cost; no re-read on p12-vast. THE PIN IS c4459193 pairing 8c728ca3 (object byte 5, sub-version 1); sub-version 2 (byte 7) is 0.3.21's, not 0.3.20's. The shipper's reading of main's F8 ruling: 0.3.20 ships object 5 as it stands because the live floor otherwise flips every node to the OLD stream on 13 October, and the 16:00 BST report tells Josh the floor move is now RECOMMENDED rather than optional, so the chain never flips to a stream that fails the 1.2x gate before sub-version 2 lands. THE FLEET'S CLOCK ON c4459193 (the fleet lane, 12:5x UTC): the kept read on pool-1's 0.3.17 datadir copy and the restart (the old process's stop time on the line) run on c18-1 before the wipe, a few minutes each, so both lines land before 14:30Z; the wipe canary (IBD from the pruning-point proof, 98 minutes on this pod class) starts when c18-1 is free of the 0.3.20 cases (about 13:00Z) and the binary is in hand, so its synced line lands about 14:40Z at the earliest, PAST the 14:30Z checkpoint; the 12 GB settled-claim line: c4459193 starts on p12-vast's kept copy of pool-1's datadir beside the 6a3432a3 IBD node on alternate ports the moment the binary lands, catches up from 129,398 blocks (15 to 20 minutes) and the 12 GB prover claims against it, the line on c4459193 itself. The binary not yet in the fleet's hand (build-1 building since 12:30:13Z); a wait armed on the sha and string, a report by 13:10Z if nothing. THE SHIPPER'S CALL ON THE CLOCK (14:2x UK): the wipe canary is the decisive read by the deploy rule; the pin never cuts without it and b7cc37e7's lineage does not stand in (the binary changed). The fleet rents a second one-shot pod of c18-1's class now and starts the wipe canary on c4459193's binary the moment the build lands, synced line about 14:15Z (15:15 BST), inside the checkpoint; c18-1 keeps the 0.3.20 cases and the pool window. If the wipe line slips past 15:30 BST the pin holds to it and main hears the clock (a slip is a report, not a cut). The set: the node lane's digest and mixed-version gates (12:50 to 13:05Z), the kept read and restart on the new pod, the wipe line on the new pod, the 12 GB settled-claim line on p12-vast. c4459193's BINARY IN THE FLEET'S HAND (12:34:54Z from build-1): igneumd sha256 45be9b02d1b002f5486d0f0108571c3b6042094113ad9da6f3d3d9ffc0072bba with the string c4459193 read back from the file, igneum-miner c7cfc40bc8b0e357. The wipe pod c19-1 (RunPod wpuke4tfu0vr49, RTX 3070 community, c18-1's class, USD 0.13/h, rented 12:37:03Z, one-shot; the day at USD 124 of work plus the 248 leak, 37 percent of the ceiling): the canary form (wipe, IBD from the pruning-point proof, synced, ten minutes mining with the exec poller, the hub read, the restart read) starts the moment the pod answers ssh; the kept read on pool-1's 0.3.17 copy armed behind its synced line on the same pod; the IBD start stamp its own line; synced about 14:20Z if the pod answers by 12:42Z (ten minutes inside the checkpoint), a slip reported the moment a poll shows it. CASES END on c18-1 at 12:37:18Z rc 0 (the relay and poison lines to the shipper); c18-1 and the two case pods destroyed by the run; the ten-member pool window rented its ten at 12:37:36Z. The 12 GB settled-claim line on p12-vast runs against a c4459193 node on the pod's kept copy, up since 12:36:35Z first-try, catching up. THE WIPE CANARY ON c19-1 STARTED: IBD at 12:38:55Z on c4459193 (sha256 45be9b02... asserted on the Mac before the put; the node's own line igneumd/2.1.0-c4459193 and digest eada4bda8aa8368c read back on the pod; a wiped datadir; IBD from the pruning-point proof with 4 peers at 12:39:26Z); synced about 14:17Z by the 98-minute class, thirteen minutes inside the checkpoint; the mining read, hub read, restart and kept read follow on the same pod, each its own line. c4459193's GATE LINES (the node lane): the binary built on build-1 at 12:33Z (1 m 07 s), sha256 45be9b02d1b002f5, the string read back from the binary (strings, two hits) and the worktree HEAD; igneum-miner beside it at /srv/builds/igneum-wt-ca3-v4-node/vendor/igneum-node-0318-release/target/release/. THE DIGEST GATE 12:33:27Z to 12:35:05Z SUMMARY PASS: the thirteen-field object a89be8a7 on both binaries, n0 peering n1 and n2 and the old node peering the new (the compat case); the sixteen-field object db9a85f9, n3 with no peer and the refusal line "consensus params digest mismatch, local db9a… remote a89b…" (the refusal case); the live file's digest on this binary eada4bda, as 5899f603 reads it. THE MIXED-VERSION GATE 12:35:26Z to 12:45:39Z SUMMARY PASS, beside the 5899f603 pair: one digest b0afb2ee on all five nodes; the 5899f603 hub accepted every block the c4459193 node mined, 215 new and 314 old, 0 rejected, no reject line in any log; header versions plain 2 on the thirteen-field file; counts equal on all five at 312 after mining, 441 after the clean join through the old hub and the clean join served by the new node, 529 at the end; the restart step passed: the new node restarted at 12:43:08Z on its own datadir and resynced to 529 with the others (where b7cc37e7 died on the database lock); no panic in any node log; every check green. The node side of the set is complete; the fleet's wipe, kept read, restart and settled-claim lines remain. A SLIP (the fleet lane, 12:5x UTC): the 0.3.20 cases rerun on c4459193 lands about 15:10Z, not 14:20Z: its target c20-1 catches up from pool-1's kept 1026 copy, 22,000 blocks behind a tip the line reaches headers-first (headers 137,405, blocks 129,398 at 12:50Z; the morning's poison pod on the same copy took 50 minutes before its blocks moved), synced about 13:50Z, the 79-minute form after; no faster path exists on a kept copy. The wipe canary on c19-1 holds its clock (29 percent of the headers at 12:47Z on dc141409's curve): synced about 14:17Z, the mining and hub reads to about 14:30Z, the restart and the kept read after; the 12 GB settled-claim line on p12-vast about 14:00 to 14:10Z. The kept read on the pinned binary is already in hand from c20-1's own start at 12:45:46Z (the rewrite line, no panic, sha 45be9b02 and the string read back), with the shipper. The shipper has the call on the cases' clock. THE INTEROP FACT stands from the void run: the 5899f603 hub accepted 235 object-byte-5 blocks from the 8097d600 node with 0 rejected, one digest on all five nodes on the live sixteen-field file. The gates: the digest test and the kaspa-pow vector test (the amended devnet epoch-0 id 1a4230699a6b9c60 must equal, c120d7963abdcd96 must differ, the v3 control unchanged) on the box; the mixed-version Devnet 2 gate (the amended 0.3.20 node beside a 5899f603 node for ten minutes on the live file without the v4 fields) after the Mac build; the fresh-join canary the 0.3.20 cut's | +| JOSH'S WORD (15:2x UK, 7 October): OPTION A, "do this but limit the testing, get it pushed" | the class v4 amendment: a load's source drawn only from registers whose last writer injects or is a rotate (the v5 rule applied now), a new program stream and vectors, the seven gate packs re-exported, the amended class with its own generator stamp; rides 0.3.20, the feature node (release-0.3.20-node = dc141409; 0.3.19 is an app-only cut with nothing of ours), on the shipper's line. The rollout arithmetic for the flip clock (the shipper): the standing fleet's one-box-at-a-time rollout took 32 minutes for 14 boxes (04:56 to 05:28Z, 7 October), the hands and the seed about 3 minutes after the miners, the Mac and the PCs within minutes of the publish; every 0.3.20 worker must accept the amended stamp before any flip. Owners: the hash lane (ca3-v4-amend: the generator, the vectors, the packs, the pairing on the box, one G1 run on PC 2, the ledger row), the node lane (release-0.3.20-node: the stamp agreed with the hash lane, the split-protection mechanism and the earliest flip time, the digest test, the mixed-version Devnet 2 gate), the attack-pass lane (the F8 census at 2^24 on the new stream, the gate 1.2x of the window model over 64 seeds), the shipper (the cut, the rollout order that sets the earliest flip). Testing limited to what prevents a split and proves the fix; G2, G3, the ladder re-measure and the rest of G4 to G6 OWED. THE STAMP agreed (the node and hash lanes, 7 October afternoon): generator 4 with sub-version 1 inside igneum-pow's id function, so the amended v4's program id for a seed differs from the old v4's (the old devnet epoch-0 id c120d7963abdcd96 pinned as the must-differ vector in kaspa-pow's test). SPLIT PROTECTION SETTLED (the node lane, plan section 6.6, ca3-v4-node fa5bc9e6; the node side on release-0.3.20-node): a fresh object byte. CLASS_SIGNAL_V4 is 5; the amended binary stamps 5 and the tally counts a block only at byte 5 or above; object 4 was stamped only by the unpublished dc141409 canary, so no published block carries it and a byte-4 block never counts; a node of the 6 October stream that sees byte 5 counts it as v4 (its rule is at least 4), flips to its own stream at the same epoch and forks ALONE (its blocks fail the amended id check, generator 4 sub-version 1 inside every id; the amended blocks fail its own), ours to upgrade in the sweep; object 6 is class v5's; the two holds already in the rule keep the window shut until every node is on 0.3.20 (a node stamps and tallies only with both v4 fields in its file; the fields publish only after the one-sweep rollout); a lagging worker refuses the amended pack at packcheck and mines nothing after the flip, costing that box, never the chain; no extra window hold: seven full day-windows are the hold. THE EARLIEST FLIP (approximate, measured 09:40Z: DAA 270,659, 1.095 DAA/s over 25 hours, 1.165 over 4; epoch 3,600, lead 600; seven windows 604,800 DAA wholly after the sweep's end D_s = T + about 40 minutes; the flip epoch the first e with 3600 e - 600 >= D_s + 604,800): T + 6 days 10 hours to T + 6 days 11 hours UK; for a publish at 12:00 UK on 7 October, 13 October between 22:20 and 23:10 UK (about 13:00 UK if the 4-hour rate holds). The floor as it stands (831,600, about 13 October 09:00 UK) would fire before any seven-window signal from a publish today completes, so it moves by the 0.3.16 rule to the publish DAA + 604,800 rounded up to the epoch boundary (882,000 for a 12:00 UK publish), firing about 30 minutes before the earliest signal flip: either way about 6 days 10 hours after the publish, never before every node has had the sweep plus a week. THE CLOCK (the node lane, 11:3x UK, after a Mac reboot moved its runs to the box): the 0.3.20 node line (dc141409 plus the proof archive aea0ca5c plus the amended v4 at object byte 5, igneum-pow at the hash lane's a0aaca92 beside the fork on the box) tested on the box, committed on release-0.3.20-node, pushed to the mirror and origin, igneumd and igneum-miner built, the tip to the shipper: about 12:00 UK; the mixed-version Devnet 2 gate (node-compat.mjs on the box, the amended node beside the 5899f603 pair for ten minutes) and the digest test (digest-compat.mjs): about 12:45 UK; the object-byte pin 5 unless the v5 lane answers both lanes with another assignment (v5 at 6 proposed). THE HASH SIDE on ca3-v4-amend (tip 8c728ca3, read from the branch 14:0x UK; the hash lane's own report pending): 1748fd1d the PC 2 G1-only playbook; e1f48d63 the fud-ledger entry AP-F8-1 (the fault, Josh's ruling, the amendment, the split protection, the owed tests); d8859522 the G1 line (the eight fingerprints equal on the RTX 5090, self-test PASS) and the node lane's signal byte 5; 4aa0c665 the v4 unit test following the amendment; 965d9e96 igneum-pow taken from release-0.3.20's 3f1652bf (the ladder's chain_program_shadow with the reps argument, never on master) with the amendment re-applied, the seven packs re-exporting byte-identical; 8c728ca3 the source rule keyed on the class with the shadow's pass count set aside, so every ladder rung draws under it (the fork's ladder test). The shipper took this igneum-pow tree into release-0.3.20 (00249643, byte-equal); nothing after 8c728ca3 touches igneum-pow. THE VECTORS AND THE PACKS (read from the branch and its ledger entry, 14:1x UK): the seven amended v4 packs (v4-devnet-epoch0, v4-era-0 to 5) carry generator 4, sub-version 1, one program id 1a4230699a6b9c60 (the 2.0 one-id-per-seed rule across the eras; the old c120d7963abdcd96 pinned as must-differ); the v3 control mx8-devnet-epoch0 untouched (73bcbfe8ccf988f1, fingerprint 90f794dd556f7a3b); the seven 2^24 fingerprints, Metal equal to Apple OpenCL: 867dbc45cfb36b4d, 2146ecacc8c75a8e, fe52602393f6d3d4, 3b206471a13912b4, c3f03c4a5d7333aa, f1dfd7209f15bb97, 8c194da64fadf31d; the zip of the eight packs sha256 889ec99976d2728b4b5035bfa476032e5b6a13b928968fc45236d5f25084aa39; the per-pack vectors.json sha256 prefixes 756301bf (devnet epoch 0), 1b5f4568, d430cadc, 1a1b21d8, 460fff9e, 4a85d49d, f83a1196 (eras 0 to 5). G1 on the RTX 5090 (PC 2 job run-ca3-v4-amend-g1-pc2-20261007, 09:41:07 to 09:41:28Z, exit 0, the installed worker): every fingerprint equal to the Mac's (the seven above and the control), NVRTC 188 to 332 ms per pack, the 1 GiB build 38 to 49 ms. hash-gates.md's older table still lists the pre-amendment fingerprints (f410c731... and the eras), which no longer apply to the amended packs; the ledger entry is the record. THE FIRST GREEN (11:31 UK, the box): the kaspa-pow suite on release-0.3.20-node (dc141409 plus the proof archive aea0ca5c plus the object-5 change) against the hash lane's igneum-pow 8c728ca3: 17 passed, 0 failed; the amended devnet epoch-0 id 1a4230699a6b9c60 pinned equal and c120d7963abdcd96 differing, the ladder's rung test green under the rekeyed rule, the v3 control unchanged; the consensus-core and exec RPC suites follow, then the node line (commit, push, box build, the tip to the shipper), then the digest and mixed-version gates. CLOCK RE-CUT (the node lane, 13:0x UK): the node line now carries, beside the object-5 change and the vector test, the lane's 0.3.20 fixes from the day (isSynced from the hook's stamp, the lazy template snapshot, the weight-table cache, the submit path returning after the block task, the watchdog, the RPC fields), about 13:30 UK if the box suites are green; the shipper's fresh-join canary 60 to 100 minutes after the cut; PC 1 as its first machine about 16:00 UK at the earliest, approximate until the shipper names the cut; the earliest flip about 6 days 10 hours after the publish. BUILD-2 LINES (12:28 to 12:33 UK): consensus-core 123 passed (the 60x file test green with the ladder window and activation pinned), the behind test green, kaspa-pow 17 passed (the amended vectors, earlier on build-1), the exec RPC suite green, the flows and rpc-service checks green with the submit-path change; the 24-requester latency test's first run tripped an unrelated flapping-fork double insert (24 equal forks from one parent; the test now builds on the sink as a real miner does; the double insert owed to a small fork harness before it is called a bug); THE NODE LINE COMMITTED (13:1x UK): release-0.3.20-node = 8097d600 (dc141409 + the proof archive aea0ca5c + one commit) on the mirror, pairing igneum-pow 8c728ca3, the hash with the shipper; in it the amended class v4 as object 5 (CLASS_SIGNAL_V4 = 5, byte 4 never counts, the kaspa-pow vector test pinning 1a4230699a6b9c60 equal and c120d7963abdcd96 differing, the daemon's window line naming object 5 and sub-version 1) beside the day's fixes (isSynced from the hook's stamp, the weight-table cache, the lazy snapshot, the submit path, the 100 ms template wait); the suites green on build-2 (consensus-core 123, the exec RPC suite, the four finality tests including 24 requesters under 200 ms: the worst template 100 ms, the worst submit 102 ms) and kaspa-pow 17 on build-1. Next: igneumd and igneum-miner building from 8097d600 on build-1, then the two gate lines (the mixed-version Devnet 2 gate: the 8097d600 node mining beside the 5899f603 pair for ten minutes on the live file without the v4 fields, the old node accepting every block; the digest test: the thirteen-field file b18ed271 unchanged, the sixteen-field object re-read on the 8097d600 binary), expected about 13:30 UK; the shipper picks the cut point. THE DATE FIXED (the node lane, from the hub's live file, 13:3x UK): publish 2 of 6 October (22:49:45Z, digest eada4bda) already put BOTH v4 fields on the live devnet (floor 831,600, window 86,400), so the 0.3.17 fleet has stamped object byte 4 since 7 October 00:2x UK and the floor is live at about 13 October 09:00 UK, before any seven-window signal completes; a 0.3.17 node left on that file flips to the OLD v4 stream at epoch 231 whatever anyone signals, a 0.3.20 node to the amended stream at the same epoch, and the two never share an id, so each straggler forks alone there. REQUIREMENT for the 0.3.20 publish (with the shipper and main): a new file with the floor at the publish DAA + 604,800 rounded up (about 882,000 for a publish today), the digest moving, the one-sweep rollout replacing every 0.3.17 node before 13 October 09:00 UK; any node that misses the sweep is alone then; the earliest flip after that about 6 days 10 hours past the publish; plan section 6.6 amended today. IN THE 0.3.20 PLAN (the shipper, 13:4x UK): both requirements; the node pin by main's rule is the node lane's second commit (the claim floor, the listener watchdog, the claim RPCs, on top of 8097d600) if its suites, both gates and the fleet's 12 GB prover line are green by 15:30 UK, else 8097d600; igneum-pow 8c728ca3 either way; the digest read on whichever binary pins. THE LINE AT 13:5x UK: three commits on release-0.3.20-node, 8097d600 (the object-5 amended class v4 and the day's fixes), 6b94c823 (test-only: the stale PC 1 test from 500ddd66 inverted by the isSynced ruling; the FALLBACK pin, code byte-identical to 8097d600, so the module reads green whole) and 6a3432a3 (the app lane's key methods, the observer's claims, the settled claim floor, the listener watchdog); suites on build-2 on 6a3432a3's code (the whole finality module 25, the exec suite 29 with the watchdog test, the kaspad, flows and rpc-service checks; consensus-core 123 and kaspa-pow 17 earlier); the cut 6a3432a3 if its gates and the fleet's 12 GB settled-claim line are green by 15:30 UK, else 6b94c823; both binaries building on build-1, the two gates (the digest gate, then the ten-minute mixed-version gate beside the 5899f603 pair) on the 8097d600 build, lines about 14:05 UK. GATE NEWS (13:53 UK): on 6a3432a3's own digest gate the listener watchdog counted a bind failure (the four harness nodes share one exec JSON-RPC port) as a listener death and exited three of four nodes at 20 s, where 0.3.17 and 8097d600 only warn and live without the exec RPC; the digest facts came out first and stand (the thirteen-field file a89be8a7 on both binaries, the compat case; the sixteen-field object db9a85f9 refused with the mismatch line, the refusal case); the ten-minute gate on 6a3432a3 stopped as void for the same cause. The fix: a bind failure is a retry every poll, one line a minute, no death counted and never an exit, with a second watchdog test whose known-failed shape is the old rule's exit on a held port; the third commit and its build about 14:15 UK, its gates about 14:35 UK; the fallback 6b94c823's gates on build-1 on their own binary (no watchdog there), lines about 14:20 UK; ledger row N12 for the bind-failure class. A ROLL BLOCKER on every kept datadir (the node lane, 14:1x UK, ledger N13): the fleet started 6a3432a3 on a kept 0.3.17 datadir (pool-1's copy) and it died at start (virtual_state.rs:250, DeserializationError(UnexpectedEof)); the cause 10db4b61 on the 0.3.16 feature line added `silent: bool` to BlockRewardData under serde(default), which bincode ignores, so every build from 10db4b61 on (dc141409, 8097d600, 6b94c823, 6a3432a3, 09124180) reads a 0.3.17 node's virtual-state row short; no canary saw it because every canary wiped, and a one-box roll keeps datadirs, so it blocks the roll on every standing box, the hands and the hub whatever the pin. The fix on the line: the store reads the current layout first and on a deserialization error decodes the row as a v1 mirror, converts with silent false and rewrites it under the same key, with the known-failed test first; the fourth commit and build about 14:40 UK, the fleet's kept-datadir start on the fixed binary about 14:50 UK, its gates after. THE RULE IT ADDS for every node cut from now: a kept-datadir restart gate on a standing box's datadir copy beside the wiped canary. THE CANDIDATE PIN (14:2x UK): b7cc37e7 (8097d600, 6b94c823, 6a3432a3, 09124180, b7cc37e7; igneum-pow 8c728ca3): the N13 fix with its test green on build-2 at 14:04 UK and the kaspad check green, the build on build-1; the fallback 6b94c823 is no longer a pin for the one-box roll (it dies on a kept datadir like every build since 10db4b61): if b7cc37e7's gates are not green by 15:30 UK the honest fallback is 0.3.17's 5899f603 staying live. In flight on build-1: the earlier commits' gates, then b7cc37e7's own digest and ten-minute mixed-version gates on its binary with the read-back, lines about 15:05 UK; on the fleet the kept-datadir start on b7cc37e7 about 14:50 UK and the 12 GB settled-claim line 14:50 to 15:00 UK. Plan section 6.6 amended with the hard date (ca3-v4-node 9d763edd, merged to master); N12 and N13 on the ledger. THE GATES ON THE FALLBACK'S OWN BINARY (6b94c823, sha b1b7d47b, 13:56 to 14:08 UK; code byte-identical to 8097d600, so the amendment's node side): the digest gate, the thirteen-field file a89be8a7 on both binaries (the compat case, n0 peering n1 and n2) and the sixteen-field object db9a85f9 refused with the mismatch line (the refusal case); the mixed-version gate, ten minutes, one digest b0afb2ee on all five nodes, the 5899f603 hub accepting every block the amended node mined (146 new, 246 old, 0 rejected), plain header version 2 on the thirteen-field file, counts equal on all five through the two clean joins and the restart. Two FAILED checks, both the harness's own and fixed (36d3efdc): a refused peer's count read 1 with the reconnect in flight (now the minimum of five), and six address-in-use panics in the two old nodes because the second gate reused the first's ports the second they were sent SIGTERM (a 20 s gap now). CLOCK CORRECTION (the node lane, 12:12Z = 13:12 BST): every "UK" stamp it sent today was the box's CEST, an hour fast of BST; its lines read UTC from now. Restated: b7cc37e7's build about 12:15Z, its digest and mixed-version gates on that binary with the sha and string about 12:32Z (13:32 BST), the fleet's kept-datadir start on it about 12:25Z, its 12 GB settled-claim line 12:50 to 13:00Z; the shipper's checkpoint 14:30Z (15:30 BST), two hours of room. The 13 October date stands (derived from UTC DAA rates): the floor 831,600 about 08:00Z, 09:00 BST. b7cc37e7'S OWN LINES (binary sha256 bc28331abf21f4d5, the string read back on build-1 and on the fleet's pod): the digest gate 12:14:39Z to 12:16:18Z SUMMARY PASS (thirteen fields a89be8a7 on both binaries with the peers as the gate wants them; the sixteen-field object db9a85f9 refused with the line and no peer; the live file's digest eada4bda on the binary, unmoved); the kept-datadir start on the fleet's copy of pool-1's 0.3.17 datadir: the first start 12:17:12Z reads the v1 row through the mirror and rewrites it ("1 mergeset rewards"), the finality blob converts (1,747 locks), the node comes up on its ports with no panic; the second start 12:18:53Z reads first-try with no rewrite line and no panic; 6a3432a3's death on the same copy is the known-failed shape. The ten-minute mixed-version gate beside the 5899f603 pair runs on the same binary since 12:16:39Z, its line about 12:28Z; then the only line outstanding for the shipper's 14:30Z rule is the fleet's 12 GB settled-claim line, 12:50 to 13:00Z. AP-F8-1 RESIDUAL CLASS ON THE AMENDED STREAM (attack-pass lane 12:18Z on igneum-pow 8c728ca3, sub-version 1). F9 over 1,000,000 seeds: programs flagged (hot share at least 1 percent or 7 constant address bits) 1,871 (0.19 percent) against 11,696 (1.17 percent) unamended; worst hot share 9.66 percent against 17.3; mean 0.011 against 0.063 percent; 84 percent of the flagged programs and the whole or-saturation tail gone. F8 at 30 of 64 seeds: nine over 1.2x of the window model (p31 29.3x, p11 5.5x, p19 3.3x, p6 3.1x, p23 2.0x, the rest 1.3x to 1.6x); the 64-seed 1.2x gate is heading to FAIL on sub-version 1. Mechanism, confirmed on the two worst seeds: an all-ones load source (image 0x0ca59e4c under the era map) delivered through a writer the source rule counts as entropy-keeping, a rotate (rotl and rotr map all-ones to itself) or a load whose own source was saturated, with the saturation made one or more writes upstream by or. The rule looks one writer back; it must look through saturation-preserving writers or test the source's values. The ceiling has not moved: rule (c)'s 120-of-128 floor still caps any program at one saturated site, 6.25 percent of reads, a chip edge of at most 1.067x, and the residual (worst seed two sites at 0.53 and 0.56) sits inside it. THE SENTENCE "no lossy-sourced load by construction" IS HELD: it goes in no plan row and no ledger entry as true; sub-version 1 removes the or-source class and bounds the rest. MAIN'S RULING (13:2x UK): 0.3.20 ships object byte 5 on sub-version 1 as it stands, strictly better than the old stream the live floor flips to on 13 October; the fix is sub-version 2 on ca3-v4-amend (object byte 6 or whatever the v5 alignment leaves free) with both fixes: (F1) the static rule made transitive (rotates do not keep entropy; a load keeps entropy only if its own source did; one draw change, no attempts lost) and (F2) the dynamic source check (saturated load SOURCE values counted per site over the 64 units' 16,384 evaluations, rejected above 163 of 16,384, the same 1 percent the final-value rule uses; costs attempts on about 0.2 percent of seeds; rides with F1 because an or-written source is all-ones only (3/4)^32 of the time). Gate before sub-version 2 is proposed, run by the attack-pass lane and not by the hash lane: the full 64-seed census under 1.2x on every seed and the hot-set census. Hash lane's estimate about an hour its side (implement, re-export seven packs, vectors, crate suite, pairing, one G1 on PC 2) plus the node lane's vector re-pin and the attack-pass re-gate. The flip floor for sub-version 1 is expected to move (Josh's word) so the chain never flips to a stream that fails this gate. Also recorded: the crate suite at 8c728ca3 100 of 100 on the box (rc 0, 77 s); the pairing against the fork at dc141409 compiled and ran 15 of 16, the one failure the fork's own pre-amendment assertion (base equals v3's, igneum.rs:972), which 8097d600 on the release-0.3.20-node line turns into assert_ne; the pairing re-runs at b7cc37e7, its line to follow. CORRECTION (the attack-pass lane's own retraction, 13:3x UK): the F9 hot-set figures above (1,871 of 1,000,000, worst 9.66 percent, 84 percent removed, the two or-then-rotate listings) are WITHDRAWN: F9's harness draws through candidate_class with its own era class, outside candidate_from_words_class where the source rule lives, so it measured the old stream (the 8c728ca3 binary prints the identical program to the sub-version-0 binary for its worst seed). F8's 64-seed census on the chain path (pairing verified on 1a4230699a6b9c60) is the valid re-gate and STANDS: at 30 of 64 seeds, nine over 1.2x of the window model (p31 29.3x, p11 5.5x, p19 3.3x, p6 3.1x, p23 2.0x, p4 1.6x, p10 1.5x, p26 1.3x, p25 1.3x). The residual mechanism on the amended stream: a load-after-load chain (a saturated source reads one fixed word, which is the next load's address), admitted because a load injects; and the rotate-preserves-saturation path (generator.rs sets entropy_kept true for a rotate whatever it rotated), correct in code and a second admitted path if it occurs on the chain stream. Sub-version 2 must close both: dataflow freshness per register (a load fresh only if its source was fresh; add, sub, xor, mad, shfl fresh if either operand was; rotates only if the operand was; or, mul, mulhi never) plus the (c') count of saturated load sources per site as the backstop. The STOP holds on F8's evidence alone; the options and the 1.067x ceiling are unchanged. The sentence "no lossy-sourced load by construction" waits on the sub-version 2 census verdict and stays out of every public text until then. SUB-VERSION 2 IN BUILD (the hash lane, ca3-v4-amend, on the coordinator's direction, 13:4x UK): F1 (dataflow freshness per register, keyed on the class v4 shape on every draw path, era or not, so the candidate_class path and the chain path draw one stream) plus F2 (the (c') count of saturated load source values per site over the 64 units' 16,384 evaluations, rejected above 163, keyed on the same shape so v2 and v3 verdicts do not move); PROGRAM_SUBVERSION_V4 = 2, new ids, the seven packs re-exported, recheck.rs with 1a4230699a6b9c60 and c120d7963abdcd96 as the must-differ pair. Clock (UTC): the commit on the branch by 13:30; the crate suite on box 2 and the pairing against b7cc37e7 by about 13:50 (the pairing's vector test fails on the fork's sub-version-1 pin until the node lane re-pins; the compile and the other 15 are the pairing evidence); the G1 job on PC 2 under --cards-off by about 14:10, lock permitting; then the attack-pass lane's full 64-seed census and hot-set census on the chain path. Two consequences stated in the commit: the rule on every draw path moves the no-era sh256xN ladder packs' stream (packs-ca3-shadow's seven 256-block packs re-export with new fingerprints; the measured rates stand as the old stream's), and the class v5 lane's pinned string-seed packs move when it merges sub-version 2, so it re-exports them then. 0.3.20's sub-version-1 packs, ids and fingerprints untouched. OBJECT BYTES SETTLED (main, 13:5x UK): byte 5 = class v4 sub-version 1 (0.3.20), byte 6 = class v5 (pinned: class-v5 16afd0a0, class-v5-node 699db5a2, the flip case passed on 6,6,6; the v5 lane stopped), byte 7 = class v4 sub-version 2; the node and hash lanes told. b7cc37e7's MIXED-VERSION GATE: FAIL, the binary not the harness (12:16:39Z to 12:27:21Z, sha256 bc28331abf21f4d5, the string read back). Before the restart step everything held: one digest b0afb2ee on all five nodes, 268 new and 392 old blocks accepted, 0 rejected, header versions plain 2, counts equal on all five at 324 and 502 through both clean joins. At the new node's restart (12:24:19Z) it died at once on its own datadir ("IO error: While lock file: .../datadir/meta/LOCK: Resource temporarily unavailable", conn_builder.rs:167): the previous process was still shutting down, because the listener watchdog added on 6a3432a3 sleeps its whole 10 s poll before checking shutdown, so every node on the line since then takes up to 10 s longer to stop than 0.3.17 (the fleet saw the same shape as "a 12-second timeout does not stop the node"). Three of the four failed checks follow from that one death (counts, the restarted node's resync, the node it served frozen at 502). The fix on the line, one rule: the poll in 250 ms steps returning the moment shutdown is set, with a test that a shutdown returns within a second (the 10 s loop the known-failed shape); the exec suite on build-2, the fifth commit and its build about 12:45Z, its digest and ten-minute gates about 12:50 to 13:05Z, inside 14:30Z. b7cc37e7 is NOT the pin. The node-side re-pin for sub-version 2 (byte 7) once the hash lane's commit lands: the beside-the-fork igneum-pow copy archived from the commit, the two pinned ids moved in the kaspa-pow vector test (sub-version-2's epoch-0 id must-equal; sub-version-1's joins c120d7963abdcd96 as must-differ), CLASS_SIGNAL and tests for byte 7, the daemon's window line: about 20 minutes of edits plus one kaspa-pow suite run on build-2 (about 2 minutes). THE FIFTH COMMIT c4459193 on release-0.3.20-node (b7cc37e7's child, the watchdog poll returning on shutdown; the diff is the poll loop in rpc.rs alone), pairing igneum-pow 8c728ca3; its build on build-1 started 12:30:13Z, sha256 and string to follow. Line A, the shutdown test: rpc::watchdog_tests::a_shutdown_returns_within_a_second_whatever_the_poll green on build-2 at 12:29Z in the exec suite's 31 passed, beside the two other watchdog tests; its known-failed shape the old loop's 10 s stop. Line B, the kept-datadir start: b7cc37e7's fleet read carries to c4459193 since the store code is byte-identical between the two commits; the fleet re-reads on the c4459193 binary only if the shipper's rule wants the string on that line too. The digest gate and the ten-minute mixed-version gate on c4459193's own binary follow its build. THE SHIPPER'S CARRY RULING (14:1x UK): b7cc37e7's kept-datadir read stands as evidence that the store fix is right (the store code byte-identical) but is not the gate line for the pin, because the rule reads the binary, not the diff, and the binary changed (rpc.rs); the gate line is the kept read on c4459193's own binary with its string, which the fleet's canary already runs on c18-1 (wipe, then the kept read, then the restart) before the canary's restart step, at no extra cost; no re-read on p12-vast. THE PIN IS c4459193 pairing 8c728ca3 (object byte 5, sub-version 1); sub-version 2 (byte 7) is 0.3.21's, not 0.3.20's. The shipper's reading of main's F8 ruling: 0.3.20 ships object 5 as it stands because the live floor otherwise flips every node to the OLD stream on 13 October, and the 16:00 BST report tells Josh the floor move is now RECOMMENDED rather than optional, so the chain never flips to a stream that fails the 1.2x gate before sub-version 2 lands. THE FLEET'S CLOCK ON c4459193 (the fleet lane, 12:5x UTC): the kept read on pool-1's 0.3.17 datadir copy and the restart (the old process's stop time on the line) run on c18-1 before the wipe, a few minutes each, so both lines land before 14:30Z; the wipe canary (IBD from the pruning-point proof, 98 minutes on this pod class) starts when c18-1 is free of the 0.3.20 cases (about 13:00Z) and the binary is in hand, so its synced line lands about 14:40Z at the earliest, PAST the 14:30Z checkpoint; the 12 GB settled-claim line: c4459193 starts on p12-vast's kept copy of pool-1's datadir beside the 6a3432a3 IBD node on alternate ports the moment the binary lands, catches up from 129,398 blocks (15 to 20 minutes) and the 12 GB prover claims against it, the line on c4459193 itself. The binary not yet in the fleet's hand (build-1 building since 12:30:13Z); a wait armed on the sha and string, a report by 13:10Z if nothing. THE SHIPPER'S CALL ON THE CLOCK (14:2x UK): the wipe canary is the decisive read by the deploy rule; the pin never cuts without it and b7cc37e7's lineage does not stand in (the binary changed). The fleet rents a second one-shot pod of c18-1's class now and starts the wipe canary on c4459193's binary the moment the build lands, synced line about 14:15Z (15:15 BST), inside the checkpoint; c18-1 keeps the 0.3.20 cases and the pool window. If the wipe line slips past 15:30 BST the pin holds to it and main hears the clock (a slip is a report, not a cut). The set: the node lane's digest and mixed-version gates (12:50 to 13:05Z), the kept read and restart on the new pod, the wipe line on the new pod, the 12 GB settled-claim line on p12-vast. c4459193's BINARY IN THE FLEET'S HAND (12:34:54Z from build-1): igneumd sha256 45be9b02d1b002f5486d0f0108571c3b6042094113ad9da6f3d3d9ffc0072bba with the string c4459193 read back from the file, igneum-miner c7cfc40bc8b0e357. The wipe pod c19-1 (RunPod wpuke4tfu0vr49, RTX 3070 community, c18-1's class, USD 0.13/h, rented 12:37:03Z, one-shot; the day at USD 124 of work plus the 248 leak, 37 percent of the ceiling): the canary form (wipe, IBD from the pruning-point proof, synced, ten minutes mining with the exec poller, the hub read, the restart read) starts the moment the pod answers ssh; the kept read on pool-1's 0.3.17 copy armed behind its synced line on the same pod; the IBD start stamp its own line; synced about 14:20Z if the pod answers by 12:42Z (ten minutes inside the checkpoint), a slip reported the moment a poll shows it. CASES END on c18-1 at 12:37:18Z rc 0 (the relay and poison lines to the shipper); c18-1 and the two case pods destroyed by the run; the ten-member pool window rented its ten at 12:37:36Z. The 12 GB settled-claim line on p12-vast runs against a c4459193 node on the pod's kept copy, up since 12:36:35Z first-try, catching up. THE WIPE CANARY ON c19-1 STARTED: IBD at 12:38:55Z on c4459193 (sha256 45be9b02... asserted on the Mac before the put; the node's own line igneumd/2.1.0-c4459193 and digest eada4bda8aa8368c read back on the pod; a wiped datadir; IBD from the pruning-point proof with 4 peers at 12:39:26Z); synced about 14:17Z by the 98-minute class, thirteen minutes inside the checkpoint; the mining read, hub read, restart and kept read follow on the same pod, each its own line. c4459193's GATE LINES (the node lane): the binary built on build-1 at 12:33Z (1 m 07 s), sha256 45be9b02d1b002f5, the string read back from the binary (strings, two hits) and the worktree HEAD; igneum-miner beside it at /srv/builds/igneum-wt-ca3-v4-node/vendor/igneum-node-0318-release/target/release/. THE DIGEST GATE 12:33:27Z to 12:35:05Z SUMMARY PASS: the thirteen-field object a89be8a7 on both binaries, n0 peering n1 and n2 and the old node peering the new (the compat case); the sixteen-field object db9a85f9, n3 with no peer and the refusal line "consensus params digest mismatch, local db9a… remote a89b…" (the refusal case); the live file's digest on this binary eada4bda, as 5899f603 reads it. THE MIXED-VERSION GATE 12:35:26Z to 12:45:39Z SUMMARY PASS, beside the 5899f603 pair: one digest b0afb2ee on all five nodes; the 5899f603 hub accepted every block the c4459193 node mined, 215 new and 314 old, 0 rejected, no reject line in any log; header versions plain 2 on the thirteen-field file; counts equal on all five at 312 after mining, 441 after the clean join through the old hub and the clean join served by the new node, 529 at the end; the restart step passed: the new node restarted at 12:43:08Z on its own datadir and resynced to 529 with the others (where b7cc37e7 died on the database lock); no panic in any node log; every check green. The node side of the set is complete; the fleet's wipe, kept read, restart and settled-claim lines remain. A SLIP (the fleet lane, 12:5x UTC): the 0.3.20 cases rerun on c4459193 lands about 15:10Z, not 14:20Z: its target c20-1 catches up from pool-1's kept 1026 copy, 22,000 blocks behind a tip the line reaches headers-first (headers 137,405, blocks 129,398 at 12:50Z; the morning's poison pod on the same copy took 50 minutes before its blocks moved), synced about 13:50Z, the 79-minute form after; no faster path exists on a kept copy. The wipe canary on c19-1 holds its clock (29 percent of the headers at 12:47Z on dc141409's curve): synced about 14:17Z, the mining and hub reads to about 14:30Z, the restart and the kept read after; the 12 GB settled-claim line on p12-vast about 14:00 to 14:10Z. The kept read on the pinned binary is already in hand from c20-1's own start at 12:45:46Z (the rewrite line, no panic, sha 45be9b02 and the string read back), with the shipper. MAIN'S RULING WITH THE SHIPPER (14:5x UK): the cases rerun on the pin's own binary gates the cut; the cut word about 15:15Z (16:15 UK) on CASES END, the publish on green right after, the sweep from then with PC 1 first; 5899f603 the fallback until the word. THE INTEROP FACT stands from the void run: the 5899f603 hub accepted 235 object-byte-5 blocks from the 8097d600 node with 0 rejected, one digest on all five nodes on the live sixteen-field file. The gates: the digest test and the kaspa-pow vector test (the amended devnet epoch-0 id 1a4230699a6b9c60 must equal, c120d7963abdcd96 must differ, the v3 control unchanged) on the box; the mixed-version Devnet 2 gate (the amended 0.3.20 node beside a 5899f603 node for ten minutes on the live file without the v4 fields) after the Mac build; the fresh-join canary the 0.3.20 cut's | | Main's rulings (7 October, morning) | no generator change to v4 on the live devnet; the record's null is the window model with numbers, sent by the hash lane to the attack-pass lane so AP-F8-1 re-gates against it; a fault beyond the model (a low-entropy source at site 15) stops at the coordinator with the two options priced (a 0.3.19 class amendment before the flip, or the flip held at the floor), nothing shipping without Josh's word; the tighter tail, an acceptance bound on the hot-set share, is a CLASS V5 item (sent to the v5 lane a6410f3b8abefb762 with the 64-seed census as its gate; the bound's number follows from the model) | ### AP-F4-1, the weak-day MUL draw (the attack-pass lane, 7 October, morning): PASS against v4, a class v5 rule From e50206dc070a12bf9a2409c53dba19968e535006 Mon Sep 17 00:00:00 2001 From: igneum-josh <337424239+igneum-josh@users.noreply.github.com> Date: Wed, 7 Oct 2026 13:54:49 +0100 Subject: [PATCH 11/19] Counter ASIC 3.0 status: the shipper's reason for gating on the cases (dc141409 to c4459193 touches the class signal byte) Co-Authored-By: Claude Fable 5.1 --- docs/plans/counter-asic-3-status.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/plans/counter-asic-3-status.md b/docs/plans/counter-asic-3-status.md index 74cddfa43..8a7f84ea6 100644 --- a/docs/plans/counter-asic-3-status.md +++ b/docs/plans/counter-asic-3-status.md @@ -338,7 +338,7 @@ Josh gave the go in advance for tonight: the shipper runs publish 1 on the 0.3.1 | THE ANALYSIS (the hash lane, ca3-v4-uniform 095f84a7, `docs/analysis/ca3-v4-uniform.md`, the tool on igneum-build-1) | the window model moves the null from 0.115 to 0.160 percent (1.39x, not 4.05x); the rest is a FAULT beyond it: site 15 reads a register last written by `or r6, r4`, so all-ones recurs at (3/4)^32 per read and the era map sends it to F8's hottest item exactly (the popcount model predicts 77,348 all-ones reads against 78,479; the top-0.1-percent share 0.58 against 0.52); it passes the acceptance rule because part (a) takes any write as a fresh source and part (c) counts saturation on final values only. The census of 1,024 chain-shaped v4 programs: 96.6 percent carry a lossy-sourced load (or, mul, mulhi as the last writer), 48.5 percent an or-sourced one (0.30 percent of all reads per site), 4.9 percent an or-of-or chain (4.6 percent of all reads on 0.1 percent of items); F8's 1.2x gate fails 96.6 percent of today's programs. Worth to a chip: 1.07 MB of SRAM ($0.25) serving 0.52 percent of a typical program's reads and 4.6 percent of the worst class's, at most 1.005x and 1.048x in rate; the ceiling under rule (c)'s 120-of-128 floor one site repeating its item in all 8 iterations, 6.25 percent of reads, 1.067x in 64 bytes; the 2x margin stands; the public line says "bounded at 1.067x", not "uniform" (the public text corrected) | | The two options, priced, STOPPED at the coordinator for Josh's word | A: a 0.3.19 class amendment before the flip (the generator draws a load's source from the registers whose last writer injects): a new program stream, new vectors, the seven gate packs re-exported, the six gates again (G1 to G3 and the verifier about an hour on the Mac and PC 2; G4 to G6 the node lane), every node before the flip under the one-box-at-a-time rule; the risk a node that misses the build splits the chain at the flip. B: hold the flip at the floor with v4 as it is; the bound documented; the source rule to class v5: a hot set worth up to 1.005x on about half the hours and 1.05x on 5 percent, 1.067x at the ceiling; no chain risk. The number: 1.067x at the ceiling against the 2x margin. The lane recommends B | | The v5 bound (sent to the v5 lane) | H = W_0.1 (the window term, 0.115 to 0.251 percent) + the sum over load sites of h(last writer) (or 0.30 percent, an or chain 4.5, mul 0.067, mulhi 0.049, an injecting op or a rotate 0), H at or under 1.2 x W_0.1, which is the static rule "every load's source was last written by an injecting op or a rotate"; as a rejection it costs 96.6 percent of candidates (about 30 attempts per seed), as a generator draw nothing; gate F8's 64-seed census with the saturated-source count | -| JOSH'S WORD (15:2x UK, 7 October): OPTION A, "do this but limit the testing, get it pushed" | the class v4 amendment: a load's source drawn only from registers whose last writer injects or is a rotate (the v5 rule applied now), a new program stream and vectors, the seven gate packs re-exported, the amended class with its own generator stamp; rides 0.3.20, the feature node (release-0.3.20-node = dc141409; 0.3.19 is an app-only cut with nothing of ours), on the shipper's line. The rollout arithmetic for the flip clock (the shipper): the standing fleet's one-box-at-a-time rollout took 32 minutes for 14 boxes (04:56 to 05:28Z, 7 October), the hands and the seed about 3 minutes after the miners, the Mac and the PCs within minutes of the publish; every 0.3.20 worker must accept the amended stamp before any flip. Owners: the hash lane (ca3-v4-amend: the generator, the vectors, the packs, the pairing on the box, one G1 run on PC 2, the ledger row), the node lane (release-0.3.20-node: the stamp agreed with the hash lane, the split-protection mechanism and the earliest flip time, the digest test, the mixed-version Devnet 2 gate), the attack-pass lane (the F8 census at 2^24 on the new stream, the gate 1.2x of the window model over 64 seeds), the shipper (the cut, the rollout order that sets the earliest flip). Testing limited to what prevents a split and proves the fix; G2, G3, the ladder re-measure and the rest of G4 to G6 OWED. THE STAMP agreed (the node and hash lanes, 7 October afternoon): generator 4 with sub-version 1 inside igneum-pow's id function, so the amended v4's program id for a seed differs from the old v4's (the old devnet epoch-0 id c120d7963abdcd96 pinned as the must-differ vector in kaspa-pow's test). SPLIT PROTECTION SETTLED (the node lane, plan section 6.6, ca3-v4-node fa5bc9e6; the node side on release-0.3.20-node): a fresh object byte. CLASS_SIGNAL_V4 is 5; the amended binary stamps 5 and the tally counts a block only at byte 5 or above; object 4 was stamped only by the unpublished dc141409 canary, so no published block carries it and a byte-4 block never counts; a node of the 6 October stream that sees byte 5 counts it as v4 (its rule is at least 4), flips to its own stream at the same epoch and forks ALONE (its blocks fail the amended id check, generator 4 sub-version 1 inside every id; the amended blocks fail its own), ours to upgrade in the sweep; object 6 is class v5's; the two holds already in the rule keep the window shut until every node is on 0.3.20 (a node stamps and tallies only with both v4 fields in its file; the fields publish only after the one-sweep rollout); a lagging worker refuses the amended pack at packcheck and mines nothing after the flip, costing that box, never the chain; no extra window hold: seven full day-windows are the hold. THE EARLIEST FLIP (approximate, measured 09:40Z: DAA 270,659, 1.095 DAA/s over 25 hours, 1.165 over 4; epoch 3,600, lead 600; seven windows 604,800 DAA wholly after the sweep's end D_s = T + about 40 minutes; the flip epoch the first e with 3600 e - 600 >= D_s + 604,800): T + 6 days 10 hours to T + 6 days 11 hours UK; for a publish at 12:00 UK on 7 October, 13 October between 22:20 and 23:10 UK (about 13:00 UK if the 4-hour rate holds). The floor as it stands (831,600, about 13 October 09:00 UK) would fire before any seven-window signal from a publish today completes, so it moves by the 0.3.16 rule to the publish DAA + 604,800 rounded up to the epoch boundary (882,000 for a 12:00 UK publish), firing about 30 minutes before the earliest signal flip: either way about 6 days 10 hours after the publish, never before every node has had the sweep plus a week. THE CLOCK (the node lane, 11:3x UK, after a Mac reboot moved its runs to the box): the 0.3.20 node line (dc141409 plus the proof archive aea0ca5c plus the amended v4 at object byte 5, igneum-pow at the hash lane's a0aaca92 beside the fork on the box) tested on the box, committed on release-0.3.20-node, pushed to the mirror and origin, igneumd and igneum-miner built, the tip to the shipper: about 12:00 UK; the mixed-version Devnet 2 gate (node-compat.mjs on the box, the amended node beside the 5899f603 pair for ten minutes) and the digest test (digest-compat.mjs): about 12:45 UK; the object-byte pin 5 unless the v5 lane answers both lanes with another assignment (v5 at 6 proposed). THE HASH SIDE on ca3-v4-amend (tip 8c728ca3, read from the branch 14:0x UK; the hash lane's own report pending): 1748fd1d the PC 2 G1-only playbook; e1f48d63 the fud-ledger entry AP-F8-1 (the fault, Josh's ruling, the amendment, the split protection, the owed tests); d8859522 the G1 line (the eight fingerprints equal on the RTX 5090, self-test PASS) and the node lane's signal byte 5; 4aa0c665 the v4 unit test following the amendment; 965d9e96 igneum-pow taken from release-0.3.20's 3f1652bf (the ladder's chain_program_shadow with the reps argument, never on master) with the amendment re-applied, the seven packs re-exporting byte-identical; 8c728ca3 the source rule keyed on the class with the shadow's pass count set aside, so every ladder rung draws under it (the fork's ladder test). The shipper took this igneum-pow tree into release-0.3.20 (00249643, byte-equal); nothing after 8c728ca3 touches igneum-pow. THE VECTORS AND THE PACKS (read from the branch and its ledger entry, 14:1x UK): the seven amended v4 packs (v4-devnet-epoch0, v4-era-0 to 5) carry generator 4, sub-version 1, one program id 1a4230699a6b9c60 (the 2.0 one-id-per-seed rule across the eras; the old c120d7963abdcd96 pinned as must-differ); the v3 control mx8-devnet-epoch0 untouched (73bcbfe8ccf988f1, fingerprint 90f794dd556f7a3b); the seven 2^24 fingerprints, Metal equal to Apple OpenCL: 867dbc45cfb36b4d, 2146ecacc8c75a8e, fe52602393f6d3d4, 3b206471a13912b4, c3f03c4a5d7333aa, f1dfd7209f15bb97, 8c194da64fadf31d; the zip of the eight packs sha256 889ec99976d2728b4b5035bfa476032e5b6a13b928968fc45236d5f25084aa39; the per-pack vectors.json sha256 prefixes 756301bf (devnet epoch 0), 1b5f4568, d430cadc, 1a1b21d8, 460fff9e, 4a85d49d, f83a1196 (eras 0 to 5). G1 on the RTX 5090 (PC 2 job run-ca3-v4-amend-g1-pc2-20261007, 09:41:07 to 09:41:28Z, exit 0, the installed worker): every fingerprint equal to the Mac's (the seven above and the control), NVRTC 188 to 332 ms per pack, the 1 GiB build 38 to 49 ms. hash-gates.md's older table still lists the pre-amendment fingerprints (f410c731... and the eras), which no longer apply to the amended packs; the ledger entry is the record. THE FIRST GREEN (11:31 UK, the box): the kaspa-pow suite on release-0.3.20-node (dc141409 plus the proof archive aea0ca5c plus the object-5 change) against the hash lane's igneum-pow 8c728ca3: 17 passed, 0 failed; the amended devnet epoch-0 id 1a4230699a6b9c60 pinned equal and c120d7963abdcd96 differing, the ladder's rung test green under the rekeyed rule, the v3 control unchanged; the consensus-core and exec RPC suites follow, then the node line (commit, push, box build, the tip to the shipper), then the digest and mixed-version gates. CLOCK RE-CUT (the node lane, 13:0x UK): the node line now carries, beside the object-5 change and the vector test, the lane's 0.3.20 fixes from the day (isSynced from the hook's stamp, the lazy template snapshot, the weight-table cache, the submit path returning after the block task, the watchdog, the RPC fields), about 13:30 UK if the box suites are green; the shipper's fresh-join canary 60 to 100 minutes after the cut; PC 1 as its first machine about 16:00 UK at the earliest, approximate until the shipper names the cut; the earliest flip about 6 days 10 hours after the publish. BUILD-2 LINES (12:28 to 12:33 UK): consensus-core 123 passed (the 60x file test green with the ladder window and activation pinned), the behind test green, kaspa-pow 17 passed (the amended vectors, earlier on build-1), the exec RPC suite green, the flows and rpc-service checks green with the submit-path change; the 24-requester latency test's first run tripped an unrelated flapping-fork double insert (24 equal forks from one parent; the test now builds on the sink as a real miner does; the double insert owed to a small fork harness before it is called a bug); THE NODE LINE COMMITTED (13:1x UK): release-0.3.20-node = 8097d600 (dc141409 + the proof archive aea0ca5c + one commit) on the mirror, pairing igneum-pow 8c728ca3, the hash with the shipper; in it the amended class v4 as object 5 (CLASS_SIGNAL_V4 = 5, byte 4 never counts, the kaspa-pow vector test pinning 1a4230699a6b9c60 equal and c120d7963abdcd96 differing, the daemon's window line naming object 5 and sub-version 1) beside the day's fixes (isSynced from the hook's stamp, the weight-table cache, the lazy snapshot, the submit path, the 100 ms template wait); the suites green on build-2 (consensus-core 123, the exec RPC suite, the four finality tests including 24 requesters under 200 ms: the worst template 100 ms, the worst submit 102 ms) and kaspa-pow 17 on build-1. Next: igneumd and igneum-miner building from 8097d600 on build-1, then the two gate lines (the mixed-version Devnet 2 gate: the 8097d600 node mining beside the 5899f603 pair for ten minutes on the live file without the v4 fields, the old node accepting every block; the digest test: the thirteen-field file b18ed271 unchanged, the sixteen-field object re-read on the 8097d600 binary), expected about 13:30 UK; the shipper picks the cut point. THE DATE FIXED (the node lane, from the hub's live file, 13:3x UK): publish 2 of 6 October (22:49:45Z, digest eada4bda) already put BOTH v4 fields on the live devnet (floor 831,600, window 86,400), so the 0.3.17 fleet has stamped object byte 4 since 7 October 00:2x UK and the floor is live at about 13 October 09:00 UK, before any seven-window signal completes; a 0.3.17 node left on that file flips to the OLD v4 stream at epoch 231 whatever anyone signals, a 0.3.20 node to the amended stream at the same epoch, and the two never share an id, so each straggler forks alone there. REQUIREMENT for the 0.3.20 publish (with the shipper and main): a new file with the floor at the publish DAA + 604,800 rounded up (about 882,000 for a publish today), the digest moving, the one-sweep rollout replacing every 0.3.17 node before 13 October 09:00 UK; any node that misses the sweep is alone then; the earliest flip after that about 6 days 10 hours past the publish; plan section 6.6 amended today. IN THE 0.3.20 PLAN (the shipper, 13:4x UK): both requirements; the node pin by main's rule is the node lane's second commit (the claim floor, the listener watchdog, the claim RPCs, on top of 8097d600) if its suites, both gates and the fleet's 12 GB prover line are green by 15:30 UK, else 8097d600; igneum-pow 8c728ca3 either way; the digest read on whichever binary pins. THE LINE AT 13:5x UK: three commits on release-0.3.20-node, 8097d600 (the object-5 amended class v4 and the day's fixes), 6b94c823 (test-only: the stale PC 1 test from 500ddd66 inverted by the isSynced ruling; the FALLBACK pin, code byte-identical to 8097d600, so the module reads green whole) and 6a3432a3 (the app lane's key methods, the observer's claims, the settled claim floor, the listener watchdog); suites on build-2 on 6a3432a3's code (the whole finality module 25, the exec suite 29 with the watchdog test, the kaspad, flows and rpc-service checks; consensus-core 123 and kaspa-pow 17 earlier); the cut 6a3432a3 if its gates and the fleet's 12 GB settled-claim line are green by 15:30 UK, else 6b94c823; both binaries building on build-1, the two gates (the digest gate, then the ten-minute mixed-version gate beside the 5899f603 pair) on the 8097d600 build, lines about 14:05 UK. GATE NEWS (13:53 UK): on 6a3432a3's own digest gate the listener watchdog counted a bind failure (the four harness nodes share one exec JSON-RPC port) as a listener death and exited three of four nodes at 20 s, where 0.3.17 and 8097d600 only warn and live without the exec RPC; the digest facts came out first and stand (the thirteen-field file a89be8a7 on both binaries, the compat case; the sixteen-field object db9a85f9 refused with the mismatch line, the refusal case); the ten-minute gate on 6a3432a3 stopped as void for the same cause. The fix: a bind failure is a retry every poll, one line a minute, no death counted and never an exit, with a second watchdog test whose known-failed shape is the old rule's exit on a held port; the third commit and its build about 14:15 UK, its gates about 14:35 UK; the fallback 6b94c823's gates on build-1 on their own binary (no watchdog there), lines about 14:20 UK; ledger row N12 for the bind-failure class. A ROLL BLOCKER on every kept datadir (the node lane, 14:1x UK, ledger N13): the fleet started 6a3432a3 on a kept 0.3.17 datadir (pool-1's copy) and it died at start (virtual_state.rs:250, DeserializationError(UnexpectedEof)); the cause 10db4b61 on the 0.3.16 feature line added `silent: bool` to BlockRewardData under serde(default), which bincode ignores, so every build from 10db4b61 on (dc141409, 8097d600, 6b94c823, 6a3432a3, 09124180) reads a 0.3.17 node's virtual-state row short; no canary saw it because every canary wiped, and a one-box roll keeps datadirs, so it blocks the roll on every standing box, the hands and the hub whatever the pin. The fix on the line: the store reads the current layout first and on a deserialization error decodes the row as a v1 mirror, converts with silent false and rewrites it under the same key, with the known-failed test first; the fourth commit and build about 14:40 UK, the fleet's kept-datadir start on the fixed binary about 14:50 UK, its gates after. THE RULE IT ADDS for every node cut from now: a kept-datadir restart gate on a standing box's datadir copy beside the wiped canary. THE CANDIDATE PIN (14:2x UK): b7cc37e7 (8097d600, 6b94c823, 6a3432a3, 09124180, b7cc37e7; igneum-pow 8c728ca3): the N13 fix with its test green on build-2 at 14:04 UK and the kaspad check green, the build on build-1; the fallback 6b94c823 is no longer a pin for the one-box roll (it dies on a kept datadir like every build since 10db4b61): if b7cc37e7's gates are not green by 15:30 UK the honest fallback is 0.3.17's 5899f603 staying live. In flight on build-1: the earlier commits' gates, then b7cc37e7's own digest and ten-minute mixed-version gates on its binary with the read-back, lines about 15:05 UK; on the fleet the kept-datadir start on b7cc37e7 about 14:50 UK and the 12 GB settled-claim line 14:50 to 15:00 UK. Plan section 6.6 amended with the hard date (ca3-v4-node 9d763edd, merged to master); N12 and N13 on the ledger. THE GATES ON THE FALLBACK'S OWN BINARY (6b94c823, sha b1b7d47b, 13:56 to 14:08 UK; code byte-identical to 8097d600, so the amendment's node side): the digest gate, the thirteen-field file a89be8a7 on both binaries (the compat case, n0 peering n1 and n2) and the sixteen-field object db9a85f9 refused with the mismatch line (the refusal case); the mixed-version gate, ten minutes, one digest b0afb2ee on all five nodes, the 5899f603 hub accepting every block the amended node mined (146 new, 246 old, 0 rejected), plain header version 2 on the thirteen-field file, counts equal on all five through the two clean joins and the restart. Two FAILED checks, both the harness's own and fixed (36d3efdc): a refused peer's count read 1 with the reconnect in flight (now the minimum of five), and six address-in-use panics in the two old nodes because the second gate reused the first's ports the second they were sent SIGTERM (a 20 s gap now). CLOCK CORRECTION (the node lane, 12:12Z = 13:12 BST): every "UK" stamp it sent today was the box's CEST, an hour fast of BST; its lines read UTC from now. Restated: b7cc37e7's build about 12:15Z, its digest and mixed-version gates on that binary with the sha and string about 12:32Z (13:32 BST), the fleet's kept-datadir start on it about 12:25Z, its 12 GB settled-claim line 12:50 to 13:00Z; the shipper's checkpoint 14:30Z (15:30 BST), two hours of room. The 13 October date stands (derived from UTC DAA rates): the floor 831,600 about 08:00Z, 09:00 BST. b7cc37e7'S OWN LINES (binary sha256 bc28331abf21f4d5, the string read back on build-1 and on the fleet's pod): the digest gate 12:14:39Z to 12:16:18Z SUMMARY PASS (thirteen fields a89be8a7 on both binaries with the peers as the gate wants them; the sixteen-field object db9a85f9 refused with the line and no peer; the live file's digest eada4bda on the binary, unmoved); the kept-datadir start on the fleet's copy of pool-1's 0.3.17 datadir: the first start 12:17:12Z reads the v1 row through the mirror and rewrites it ("1 mergeset rewards"), the finality blob converts (1,747 locks), the node comes up on its ports with no panic; the second start 12:18:53Z reads first-try with no rewrite line and no panic; 6a3432a3's death on the same copy is the known-failed shape. The ten-minute mixed-version gate beside the 5899f603 pair runs on the same binary since 12:16:39Z, its line about 12:28Z; then the only line outstanding for the shipper's 14:30Z rule is the fleet's 12 GB settled-claim line, 12:50 to 13:00Z. AP-F8-1 RESIDUAL CLASS ON THE AMENDED STREAM (attack-pass lane 12:18Z on igneum-pow 8c728ca3, sub-version 1). F9 over 1,000,000 seeds: programs flagged (hot share at least 1 percent or 7 constant address bits) 1,871 (0.19 percent) against 11,696 (1.17 percent) unamended; worst hot share 9.66 percent against 17.3; mean 0.011 against 0.063 percent; 84 percent of the flagged programs and the whole or-saturation tail gone. F8 at 30 of 64 seeds: nine over 1.2x of the window model (p31 29.3x, p11 5.5x, p19 3.3x, p6 3.1x, p23 2.0x, the rest 1.3x to 1.6x); the 64-seed 1.2x gate is heading to FAIL on sub-version 1. Mechanism, confirmed on the two worst seeds: an all-ones load source (image 0x0ca59e4c under the era map) delivered through a writer the source rule counts as entropy-keeping, a rotate (rotl and rotr map all-ones to itself) or a load whose own source was saturated, with the saturation made one or more writes upstream by or. The rule looks one writer back; it must look through saturation-preserving writers or test the source's values. The ceiling has not moved: rule (c)'s 120-of-128 floor still caps any program at one saturated site, 6.25 percent of reads, a chip edge of at most 1.067x, and the residual (worst seed two sites at 0.53 and 0.56) sits inside it. THE SENTENCE "no lossy-sourced load by construction" IS HELD: it goes in no plan row and no ledger entry as true; sub-version 1 removes the or-source class and bounds the rest. MAIN'S RULING (13:2x UK): 0.3.20 ships object byte 5 on sub-version 1 as it stands, strictly better than the old stream the live floor flips to on 13 October; the fix is sub-version 2 on ca3-v4-amend (object byte 6 or whatever the v5 alignment leaves free) with both fixes: (F1) the static rule made transitive (rotates do not keep entropy; a load keeps entropy only if its own source did; one draw change, no attempts lost) and (F2) the dynamic source check (saturated load SOURCE values counted per site over the 64 units' 16,384 evaluations, rejected above 163 of 16,384, the same 1 percent the final-value rule uses; costs attempts on about 0.2 percent of seeds; rides with F1 because an or-written source is all-ones only (3/4)^32 of the time). Gate before sub-version 2 is proposed, run by the attack-pass lane and not by the hash lane: the full 64-seed census under 1.2x on every seed and the hot-set census. Hash lane's estimate about an hour its side (implement, re-export seven packs, vectors, crate suite, pairing, one G1 on PC 2) plus the node lane's vector re-pin and the attack-pass re-gate. The flip floor for sub-version 1 is expected to move (Josh's word) so the chain never flips to a stream that fails this gate. Also recorded: the crate suite at 8c728ca3 100 of 100 on the box (rc 0, 77 s); the pairing against the fork at dc141409 compiled and ran 15 of 16, the one failure the fork's own pre-amendment assertion (base equals v3's, igneum.rs:972), which 8097d600 on the release-0.3.20-node line turns into assert_ne; the pairing re-runs at b7cc37e7, its line to follow. CORRECTION (the attack-pass lane's own retraction, 13:3x UK): the F9 hot-set figures above (1,871 of 1,000,000, worst 9.66 percent, 84 percent removed, the two or-then-rotate listings) are WITHDRAWN: F9's harness draws through candidate_class with its own era class, outside candidate_from_words_class where the source rule lives, so it measured the old stream (the 8c728ca3 binary prints the identical program to the sub-version-0 binary for its worst seed). F8's 64-seed census on the chain path (pairing verified on 1a4230699a6b9c60) is the valid re-gate and STANDS: at 30 of 64 seeds, nine over 1.2x of the window model (p31 29.3x, p11 5.5x, p19 3.3x, p6 3.1x, p23 2.0x, p4 1.6x, p10 1.5x, p26 1.3x, p25 1.3x). The residual mechanism on the amended stream: a load-after-load chain (a saturated source reads one fixed word, which is the next load's address), admitted because a load injects; and the rotate-preserves-saturation path (generator.rs sets entropy_kept true for a rotate whatever it rotated), correct in code and a second admitted path if it occurs on the chain stream. Sub-version 2 must close both: dataflow freshness per register (a load fresh only if its source was fresh; add, sub, xor, mad, shfl fresh if either operand was; rotates only if the operand was; or, mul, mulhi never) plus the (c') count of saturated load sources per site as the backstop. The STOP holds on F8's evidence alone; the options and the 1.067x ceiling are unchanged. The sentence "no lossy-sourced load by construction" waits on the sub-version 2 census verdict and stays out of every public text until then. SUB-VERSION 2 IN BUILD (the hash lane, ca3-v4-amend, on the coordinator's direction, 13:4x UK): F1 (dataflow freshness per register, keyed on the class v4 shape on every draw path, era or not, so the candidate_class path and the chain path draw one stream) plus F2 (the (c') count of saturated load source values per site over the 64 units' 16,384 evaluations, rejected above 163, keyed on the same shape so v2 and v3 verdicts do not move); PROGRAM_SUBVERSION_V4 = 2, new ids, the seven packs re-exported, recheck.rs with 1a4230699a6b9c60 and c120d7963abdcd96 as the must-differ pair. Clock (UTC): the commit on the branch by 13:30; the crate suite on box 2 and the pairing against b7cc37e7 by about 13:50 (the pairing's vector test fails on the fork's sub-version-1 pin until the node lane re-pins; the compile and the other 15 are the pairing evidence); the G1 job on PC 2 under --cards-off by about 14:10, lock permitting; then the attack-pass lane's full 64-seed census and hot-set census on the chain path. Two consequences stated in the commit: the rule on every draw path moves the no-era sh256xN ladder packs' stream (packs-ca3-shadow's seven 256-block packs re-export with new fingerprints; the measured rates stand as the old stream's), and the class v5 lane's pinned string-seed packs move when it merges sub-version 2, so it re-exports them then. 0.3.20's sub-version-1 packs, ids and fingerprints untouched. OBJECT BYTES SETTLED (main, 13:5x UK): byte 5 = class v4 sub-version 1 (0.3.20), byte 6 = class v5 (pinned: class-v5 16afd0a0, class-v5-node 699db5a2, the flip case passed on 6,6,6; the v5 lane stopped), byte 7 = class v4 sub-version 2; the node and hash lanes told. b7cc37e7's MIXED-VERSION GATE: FAIL, the binary not the harness (12:16:39Z to 12:27:21Z, sha256 bc28331abf21f4d5, the string read back). Before the restart step everything held: one digest b0afb2ee on all five nodes, 268 new and 392 old blocks accepted, 0 rejected, header versions plain 2, counts equal on all five at 324 and 502 through both clean joins. At the new node's restart (12:24:19Z) it died at once on its own datadir ("IO error: While lock file: .../datadir/meta/LOCK: Resource temporarily unavailable", conn_builder.rs:167): the previous process was still shutting down, because the listener watchdog added on 6a3432a3 sleeps its whole 10 s poll before checking shutdown, so every node on the line since then takes up to 10 s longer to stop than 0.3.17 (the fleet saw the same shape as "a 12-second timeout does not stop the node"). Three of the four failed checks follow from that one death (counts, the restarted node's resync, the node it served frozen at 502). The fix on the line, one rule: the poll in 250 ms steps returning the moment shutdown is set, with a test that a shutdown returns within a second (the 10 s loop the known-failed shape); the exec suite on build-2, the fifth commit and its build about 12:45Z, its digest and ten-minute gates about 12:50 to 13:05Z, inside 14:30Z. b7cc37e7 is NOT the pin. The node-side re-pin for sub-version 2 (byte 7) once the hash lane's commit lands: the beside-the-fork igneum-pow copy archived from the commit, the two pinned ids moved in the kaspa-pow vector test (sub-version-2's epoch-0 id must-equal; sub-version-1's joins c120d7963abdcd96 as must-differ), CLASS_SIGNAL and tests for byte 7, the daemon's window line: about 20 minutes of edits plus one kaspa-pow suite run on build-2 (about 2 minutes). THE FIFTH COMMIT c4459193 on release-0.3.20-node (b7cc37e7's child, the watchdog poll returning on shutdown; the diff is the poll loop in rpc.rs alone), pairing igneum-pow 8c728ca3; its build on build-1 started 12:30:13Z, sha256 and string to follow. Line A, the shutdown test: rpc::watchdog_tests::a_shutdown_returns_within_a_second_whatever_the_poll green on build-2 at 12:29Z in the exec suite's 31 passed, beside the two other watchdog tests; its known-failed shape the old loop's 10 s stop. Line B, the kept-datadir start: b7cc37e7's fleet read carries to c4459193 since the store code is byte-identical between the two commits; the fleet re-reads on the c4459193 binary only if the shipper's rule wants the string on that line too. The digest gate and the ten-minute mixed-version gate on c4459193's own binary follow its build. THE SHIPPER'S CARRY RULING (14:1x UK): b7cc37e7's kept-datadir read stands as evidence that the store fix is right (the store code byte-identical) but is not the gate line for the pin, because the rule reads the binary, not the diff, and the binary changed (rpc.rs); the gate line is the kept read on c4459193's own binary with its string, which the fleet's canary already runs on c18-1 (wipe, then the kept read, then the restart) before the canary's restart step, at no extra cost; no re-read on p12-vast. THE PIN IS c4459193 pairing 8c728ca3 (object byte 5, sub-version 1); sub-version 2 (byte 7) is 0.3.21's, not 0.3.20's. The shipper's reading of main's F8 ruling: 0.3.20 ships object 5 as it stands because the live floor otherwise flips every node to the OLD stream on 13 October, and the 16:00 BST report tells Josh the floor move is now RECOMMENDED rather than optional, so the chain never flips to a stream that fails the 1.2x gate before sub-version 2 lands. THE FLEET'S CLOCK ON c4459193 (the fleet lane, 12:5x UTC): the kept read on pool-1's 0.3.17 datadir copy and the restart (the old process's stop time on the line) run on c18-1 before the wipe, a few minutes each, so both lines land before 14:30Z; the wipe canary (IBD from the pruning-point proof, 98 minutes on this pod class) starts when c18-1 is free of the 0.3.20 cases (about 13:00Z) and the binary is in hand, so its synced line lands about 14:40Z at the earliest, PAST the 14:30Z checkpoint; the 12 GB settled-claim line: c4459193 starts on p12-vast's kept copy of pool-1's datadir beside the 6a3432a3 IBD node on alternate ports the moment the binary lands, catches up from 129,398 blocks (15 to 20 minutes) and the 12 GB prover claims against it, the line on c4459193 itself. The binary not yet in the fleet's hand (build-1 building since 12:30:13Z); a wait armed on the sha and string, a report by 13:10Z if nothing. THE SHIPPER'S CALL ON THE CLOCK (14:2x UK): the wipe canary is the decisive read by the deploy rule; the pin never cuts without it and b7cc37e7's lineage does not stand in (the binary changed). The fleet rents a second one-shot pod of c18-1's class now and starts the wipe canary on c4459193's binary the moment the build lands, synced line about 14:15Z (15:15 BST), inside the checkpoint; c18-1 keeps the 0.3.20 cases and the pool window. If the wipe line slips past 15:30 BST the pin holds to it and main hears the clock (a slip is a report, not a cut). The set: the node lane's digest and mixed-version gates (12:50 to 13:05Z), the kept read and restart on the new pod, the wipe line on the new pod, the 12 GB settled-claim line on p12-vast. c4459193's BINARY IN THE FLEET'S HAND (12:34:54Z from build-1): igneumd sha256 45be9b02d1b002f5486d0f0108571c3b6042094113ad9da6f3d3d9ffc0072bba with the string c4459193 read back from the file, igneum-miner c7cfc40bc8b0e357. The wipe pod c19-1 (RunPod wpuke4tfu0vr49, RTX 3070 community, c18-1's class, USD 0.13/h, rented 12:37:03Z, one-shot; the day at USD 124 of work plus the 248 leak, 37 percent of the ceiling): the canary form (wipe, IBD from the pruning-point proof, synced, ten minutes mining with the exec poller, the hub read, the restart read) starts the moment the pod answers ssh; the kept read on pool-1's 0.3.17 copy armed behind its synced line on the same pod; the IBD start stamp its own line; synced about 14:20Z if the pod answers by 12:42Z (ten minutes inside the checkpoint), a slip reported the moment a poll shows it. CASES END on c18-1 at 12:37:18Z rc 0 (the relay and poison lines to the shipper); c18-1 and the two case pods destroyed by the run; the ten-member pool window rented its ten at 12:37:36Z. The 12 GB settled-claim line on p12-vast runs against a c4459193 node on the pod's kept copy, up since 12:36:35Z first-try, catching up. THE WIPE CANARY ON c19-1 STARTED: IBD at 12:38:55Z on c4459193 (sha256 45be9b02... asserted on the Mac before the put; the node's own line igneumd/2.1.0-c4459193 and digest eada4bda8aa8368c read back on the pod; a wiped datadir; IBD from the pruning-point proof with 4 peers at 12:39:26Z); synced about 14:17Z by the 98-minute class, thirteen minutes inside the checkpoint; the mining read, hub read, restart and kept read follow on the same pod, each its own line. c4459193's GATE LINES (the node lane): the binary built on build-1 at 12:33Z (1 m 07 s), sha256 45be9b02d1b002f5, the string read back from the binary (strings, two hits) and the worktree HEAD; igneum-miner beside it at /srv/builds/igneum-wt-ca3-v4-node/vendor/igneum-node-0318-release/target/release/. THE DIGEST GATE 12:33:27Z to 12:35:05Z SUMMARY PASS: the thirteen-field object a89be8a7 on both binaries, n0 peering n1 and n2 and the old node peering the new (the compat case); the sixteen-field object db9a85f9, n3 with no peer and the refusal line "consensus params digest mismatch, local db9a… remote a89b…" (the refusal case); the live file's digest on this binary eada4bda, as 5899f603 reads it. THE MIXED-VERSION GATE 12:35:26Z to 12:45:39Z SUMMARY PASS, beside the 5899f603 pair: one digest b0afb2ee on all five nodes; the 5899f603 hub accepted every block the c4459193 node mined, 215 new and 314 old, 0 rejected, no reject line in any log; header versions plain 2 on the thirteen-field file; counts equal on all five at 312 after mining, 441 after the clean join through the old hub and the clean join served by the new node, 529 at the end; the restart step passed: the new node restarted at 12:43:08Z on its own datadir and resynced to 529 with the others (where b7cc37e7 died on the database lock); no panic in any node log; every check green. The node side of the set is complete; the fleet's wipe, kept read, restart and settled-claim lines remain. A SLIP (the fleet lane, 12:5x UTC): the 0.3.20 cases rerun on c4459193 lands about 15:10Z, not 14:20Z: its target c20-1 catches up from pool-1's kept 1026 copy, 22,000 blocks behind a tip the line reaches headers-first (headers 137,405, blocks 129,398 at 12:50Z; the morning's poison pod on the same copy took 50 minutes before its blocks moved), synced about 13:50Z, the 79-minute form after; no faster path exists on a kept copy. The wipe canary on c19-1 holds its clock (29 percent of the headers at 12:47Z on dc141409's curve): synced about 14:17Z, the mining and hub reads to about 14:30Z, the restart and the kept read after; the 12 GB settled-claim line on p12-vast about 14:00 to 14:10Z. The kept read on the pinned binary is already in hand from c20-1's own start at 12:45:46Z (the rewrite line, no panic, sha 45be9b02 and the string read back), with the shipper. MAIN'S RULING WITH THE SHIPPER (14:5x UK): the cases rerun on the pin's own binary gates the cut; the cut word about 15:15Z (16:15 UK) on CASES END, the publish on green right after, the sweep from then with PC 1 first; 5899f603 the fallback until the word. THE INTEROP FACT stands from the void run: the 5899f603 hub accepted 235 object-byte-5 blocks from the 8097d600 node with 0 rejected, one digest on all five nodes on the live sixteen-field file. The gates: the digest test and the kaspa-pow vector test (the amended devnet epoch-0 id 1a4230699a6b9c60 must equal, c120d7963abdcd96 must differ, the v3 control unchanged) on the box; the mixed-version Devnet 2 gate (the amended 0.3.20 node beside a 5899f603 node for ten minutes on the live file without the v4 fields) after the Mac build; the fresh-join canary the 0.3.20 cut's | +| JOSH'S WORD (15:2x UK, 7 October): OPTION A, "do this but limit the testing, get it pushed" | the class v4 amendment: a load's source drawn only from registers whose last writer injects or is a rotate (the v5 rule applied now), a new program stream and vectors, the seven gate packs re-exported, the amended class with its own generator stamp; rides 0.3.20, the feature node (release-0.3.20-node = dc141409; 0.3.19 is an app-only cut with nothing of ours), on the shipper's line. The rollout arithmetic for the flip clock (the shipper): the standing fleet's one-box-at-a-time rollout took 32 minutes for 14 boxes (04:56 to 05:28Z, 7 October), the hands and the seed about 3 minutes after the miners, the Mac and the PCs within minutes of the publish; every 0.3.20 worker must accept the amended stamp before any flip. Owners: the hash lane (ca3-v4-amend: the generator, the vectors, the packs, the pairing on the box, one G1 run on PC 2, the ledger row), the node lane (release-0.3.20-node: the stamp agreed with the hash lane, the split-protection mechanism and the earliest flip time, the digest test, the mixed-version Devnet 2 gate), the attack-pass lane (the F8 census at 2^24 on the new stream, the gate 1.2x of the window model over 64 seeds), the shipper (the cut, the rollout order that sets the earliest flip). Testing limited to what prevents a split and proves the fix; G2, G3, the ladder re-measure and the rest of G4 to G6 OWED. THE STAMP agreed (the node and hash lanes, 7 October afternoon): generator 4 with sub-version 1 inside igneum-pow's id function, so the amended v4's program id for a seed differs from the old v4's (the old devnet epoch-0 id c120d7963abdcd96 pinned as the must-differ vector in kaspa-pow's test). SPLIT PROTECTION SETTLED (the node lane, plan section 6.6, ca3-v4-node fa5bc9e6; the node side on release-0.3.20-node): a fresh object byte. CLASS_SIGNAL_V4 is 5; the amended binary stamps 5 and the tally counts a block only at byte 5 or above; object 4 was stamped only by the unpublished dc141409 canary, so no published block carries it and a byte-4 block never counts; a node of the 6 October stream that sees byte 5 counts it as v4 (its rule is at least 4), flips to its own stream at the same epoch and forks ALONE (its blocks fail the amended id check, generator 4 sub-version 1 inside every id; the amended blocks fail its own), ours to upgrade in the sweep; object 6 is class v5's; the two holds already in the rule keep the window shut until every node is on 0.3.20 (a node stamps and tallies only with both v4 fields in its file; the fields publish only after the one-sweep rollout); a lagging worker refuses the amended pack at packcheck and mines nothing after the flip, costing that box, never the chain; no extra window hold: seven full day-windows are the hold. THE EARLIEST FLIP (approximate, measured 09:40Z: DAA 270,659, 1.095 DAA/s over 25 hours, 1.165 over 4; epoch 3,600, lead 600; seven windows 604,800 DAA wholly after the sweep's end D_s = T + about 40 minutes; the flip epoch the first e with 3600 e - 600 >= D_s + 604,800): T + 6 days 10 hours to T + 6 days 11 hours UK; for a publish at 12:00 UK on 7 October, 13 October between 22:20 and 23:10 UK (about 13:00 UK if the 4-hour rate holds). The floor as it stands (831,600, about 13 October 09:00 UK) would fire before any seven-window signal from a publish today completes, so it moves by the 0.3.16 rule to the publish DAA + 604,800 rounded up to the epoch boundary (882,000 for a 12:00 UK publish), firing about 30 minutes before the earliest signal flip: either way about 6 days 10 hours after the publish, never before every node has had the sweep plus a week. THE CLOCK (the node lane, 11:3x UK, after a Mac reboot moved its runs to the box): the 0.3.20 node line (dc141409 plus the proof archive aea0ca5c plus the amended v4 at object byte 5, igneum-pow at the hash lane's a0aaca92 beside the fork on the box) tested on the box, committed on release-0.3.20-node, pushed to the mirror and origin, igneumd and igneum-miner built, the tip to the shipper: about 12:00 UK; the mixed-version Devnet 2 gate (node-compat.mjs on the box, the amended node beside the 5899f603 pair for ten minutes) and the digest test (digest-compat.mjs): about 12:45 UK; the object-byte pin 5 unless the v5 lane answers both lanes with another assignment (v5 at 6 proposed). THE HASH SIDE on ca3-v4-amend (tip 8c728ca3, read from the branch 14:0x UK; the hash lane's own report pending): 1748fd1d the PC 2 G1-only playbook; e1f48d63 the fud-ledger entry AP-F8-1 (the fault, Josh's ruling, the amendment, the split protection, the owed tests); d8859522 the G1 line (the eight fingerprints equal on the RTX 5090, self-test PASS) and the node lane's signal byte 5; 4aa0c665 the v4 unit test following the amendment; 965d9e96 igneum-pow taken from release-0.3.20's 3f1652bf (the ladder's chain_program_shadow with the reps argument, never on master) with the amendment re-applied, the seven packs re-exporting byte-identical; 8c728ca3 the source rule keyed on the class with the shadow's pass count set aside, so every ladder rung draws under it (the fork's ladder test). The shipper took this igneum-pow tree into release-0.3.20 (00249643, byte-equal); nothing after 8c728ca3 touches igneum-pow. THE VECTORS AND THE PACKS (read from the branch and its ledger entry, 14:1x UK): the seven amended v4 packs (v4-devnet-epoch0, v4-era-0 to 5) carry generator 4, sub-version 1, one program id 1a4230699a6b9c60 (the 2.0 one-id-per-seed rule across the eras; the old c120d7963abdcd96 pinned as must-differ); the v3 control mx8-devnet-epoch0 untouched (73bcbfe8ccf988f1, fingerprint 90f794dd556f7a3b); the seven 2^24 fingerprints, Metal equal to Apple OpenCL: 867dbc45cfb36b4d, 2146ecacc8c75a8e, fe52602393f6d3d4, 3b206471a13912b4, c3f03c4a5d7333aa, f1dfd7209f15bb97, 8c194da64fadf31d; the zip of the eight packs sha256 889ec99976d2728b4b5035bfa476032e5b6a13b928968fc45236d5f25084aa39; the per-pack vectors.json sha256 prefixes 756301bf (devnet epoch 0), 1b5f4568, d430cadc, 1a1b21d8, 460fff9e, 4a85d49d, f83a1196 (eras 0 to 5). G1 on the RTX 5090 (PC 2 job run-ca3-v4-amend-g1-pc2-20261007, 09:41:07 to 09:41:28Z, exit 0, the installed worker): every fingerprint equal to the Mac's (the seven above and the control), NVRTC 188 to 332 ms per pack, the 1 GiB build 38 to 49 ms. hash-gates.md's older table still lists the pre-amendment fingerprints (f410c731... and the eras), which no longer apply to the amended packs; the ledger entry is the record. THE FIRST GREEN (11:31 UK, the box): the kaspa-pow suite on release-0.3.20-node (dc141409 plus the proof archive aea0ca5c plus the object-5 change) against the hash lane's igneum-pow 8c728ca3: 17 passed, 0 failed; the amended devnet epoch-0 id 1a4230699a6b9c60 pinned equal and c120d7963abdcd96 differing, the ladder's rung test green under the rekeyed rule, the v3 control unchanged; the consensus-core and exec RPC suites follow, then the node line (commit, push, box build, the tip to the shipper), then the digest and mixed-version gates. CLOCK RE-CUT (the node lane, 13:0x UK): the node line now carries, beside the object-5 change and the vector test, the lane's 0.3.20 fixes from the day (isSynced from the hook's stamp, the lazy template snapshot, the weight-table cache, the submit path returning after the block task, the watchdog, the RPC fields), about 13:30 UK if the box suites are green; the shipper's fresh-join canary 60 to 100 minutes after the cut; PC 1 as its first machine about 16:00 UK at the earliest, approximate until the shipper names the cut; the earliest flip about 6 days 10 hours after the publish. BUILD-2 LINES (12:28 to 12:33 UK): consensus-core 123 passed (the 60x file test green with the ladder window and activation pinned), the behind test green, kaspa-pow 17 passed (the amended vectors, earlier on build-1), the exec RPC suite green, the flows and rpc-service checks green with the submit-path change; the 24-requester latency test's first run tripped an unrelated flapping-fork double insert (24 equal forks from one parent; the test now builds on the sink as a real miner does; the double insert owed to a small fork harness before it is called a bug); THE NODE LINE COMMITTED (13:1x UK): release-0.3.20-node = 8097d600 (dc141409 + the proof archive aea0ca5c + one commit) on the mirror, pairing igneum-pow 8c728ca3, the hash with the shipper; in it the amended class v4 as object 5 (CLASS_SIGNAL_V4 = 5, byte 4 never counts, the kaspa-pow vector test pinning 1a4230699a6b9c60 equal and c120d7963abdcd96 differing, the daemon's window line naming object 5 and sub-version 1) beside the day's fixes (isSynced from the hook's stamp, the weight-table cache, the lazy snapshot, the submit path, the 100 ms template wait); the suites green on build-2 (consensus-core 123, the exec RPC suite, the four finality tests including 24 requesters under 200 ms: the worst template 100 ms, the worst submit 102 ms) and kaspa-pow 17 on build-1. Next: igneumd and igneum-miner building from 8097d600 on build-1, then the two gate lines (the mixed-version Devnet 2 gate: the 8097d600 node mining beside the 5899f603 pair for ten minutes on the live file without the v4 fields, the old node accepting every block; the digest test: the thirteen-field file b18ed271 unchanged, the sixteen-field object re-read on the 8097d600 binary), expected about 13:30 UK; the shipper picks the cut point. THE DATE FIXED (the node lane, from the hub's live file, 13:3x UK): publish 2 of 6 October (22:49:45Z, digest eada4bda) already put BOTH v4 fields on the live devnet (floor 831,600, window 86,400), so the 0.3.17 fleet has stamped object byte 4 since 7 October 00:2x UK and the floor is live at about 13 October 09:00 UK, before any seven-window signal completes; a 0.3.17 node left on that file flips to the OLD v4 stream at epoch 231 whatever anyone signals, a 0.3.20 node to the amended stream at the same epoch, and the two never share an id, so each straggler forks alone there. REQUIREMENT for the 0.3.20 publish (with the shipper and main): a new file with the floor at the publish DAA + 604,800 rounded up (about 882,000 for a publish today), the digest moving, the one-sweep rollout replacing every 0.3.17 node before 13 October 09:00 UK; any node that misses the sweep is alone then; the earliest flip after that about 6 days 10 hours past the publish; plan section 6.6 amended today. IN THE 0.3.20 PLAN (the shipper, 13:4x UK): both requirements; the node pin by main's rule is the node lane's second commit (the claim floor, the listener watchdog, the claim RPCs, on top of 8097d600) if its suites, both gates and the fleet's 12 GB prover line are green by 15:30 UK, else 8097d600; igneum-pow 8c728ca3 either way; the digest read on whichever binary pins. THE LINE AT 13:5x UK: three commits on release-0.3.20-node, 8097d600 (the object-5 amended class v4 and the day's fixes), 6b94c823 (test-only: the stale PC 1 test from 500ddd66 inverted by the isSynced ruling; the FALLBACK pin, code byte-identical to 8097d600, so the module reads green whole) and 6a3432a3 (the app lane's key methods, the observer's claims, the settled claim floor, the listener watchdog); suites on build-2 on 6a3432a3's code (the whole finality module 25, the exec suite 29 with the watchdog test, the kaspad, flows and rpc-service checks; consensus-core 123 and kaspa-pow 17 earlier); the cut 6a3432a3 if its gates and the fleet's 12 GB settled-claim line are green by 15:30 UK, else 6b94c823; both binaries building on build-1, the two gates (the digest gate, then the ten-minute mixed-version gate beside the 5899f603 pair) on the 8097d600 build, lines about 14:05 UK. GATE NEWS (13:53 UK): on 6a3432a3's own digest gate the listener watchdog counted a bind failure (the four harness nodes share one exec JSON-RPC port) as a listener death and exited three of four nodes at 20 s, where 0.3.17 and 8097d600 only warn and live without the exec RPC; the digest facts came out first and stand (the thirteen-field file a89be8a7 on both binaries, the compat case; the sixteen-field object db9a85f9 refused with the mismatch line, the refusal case); the ten-minute gate on 6a3432a3 stopped as void for the same cause. The fix: a bind failure is a retry every poll, one line a minute, no death counted and never an exit, with a second watchdog test whose known-failed shape is the old rule's exit on a held port; the third commit and its build about 14:15 UK, its gates about 14:35 UK; the fallback 6b94c823's gates on build-1 on their own binary (no watchdog there), lines about 14:20 UK; ledger row N12 for the bind-failure class. A ROLL BLOCKER on every kept datadir (the node lane, 14:1x UK, ledger N13): the fleet started 6a3432a3 on a kept 0.3.17 datadir (pool-1's copy) and it died at start (virtual_state.rs:250, DeserializationError(UnexpectedEof)); the cause 10db4b61 on the 0.3.16 feature line added `silent: bool` to BlockRewardData under serde(default), which bincode ignores, so every build from 10db4b61 on (dc141409, 8097d600, 6b94c823, 6a3432a3, 09124180) reads a 0.3.17 node's virtual-state row short; no canary saw it because every canary wiped, and a one-box roll keeps datadirs, so it blocks the roll on every standing box, the hands and the hub whatever the pin. The fix on the line: the store reads the current layout first and on a deserialization error decodes the row as a v1 mirror, converts with silent false and rewrites it under the same key, with the known-failed test first; the fourth commit and build about 14:40 UK, the fleet's kept-datadir start on the fixed binary about 14:50 UK, its gates after. THE RULE IT ADDS for every node cut from now: a kept-datadir restart gate on a standing box's datadir copy beside the wiped canary. THE CANDIDATE PIN (14:2x UK): b7cc37e7 (8097d600, 6b94c823, 6a3432a3, 09124180, b7cc37e7; igneum-pow 8c728ca3): the N13 fix with its test green on build-2 at 14:04 UK and the kaspad check green, the build on build-1; the fallback 6b94c823 is no longer a pin for the one-box roll (it dies on a kept datadir like every build since 10db4b61): if b7cc37e7's gates are not green by 15:30 UK the honest fallback is 0.3.17's 5899f603 staying live. In flight on build-1: the earlier commits' gates, then b7cc37e7's own digest and ten-minute mixed-version gates on its binary with the read-back, lines about 15:05 UK; on the fleet the kept-datadir start on b7cc37e7 about 14:50 UK and the 12 GB settled-claim line 14:50 to 15:00 UK. Plan section 6.6 amended with the hard date (ca3-v4-node 9d763edd, merged to master); N12 and N13 on the ledger. THE GATES ON THE FALLBACK'S OWN BINARY (6b94c823, sha b1b7d47b, 13:56 to 14:08 UK; code byte-identical to 8097d600, so the amendment's node side): the digest gate, the thirteen-field file a89be8a7 on both binaries (the compat case, n0 peering n1 and n2) and the sixteen-field object db9a85f9 refused with the mismatch line (the refusal case); the mixed-version gate, ten minutes, one digest b0afb2ee on all five nodes, the 5899f603 hub accepting every block the amended node mined (146 new, 246 old, 0 rejected), plain header version 2 on the thirteen-field file, counts equal on all five through the two clean joins and the restart. Two FAILED checks, both the harness's own and fixed (36d3efdc): a refused peer's count read 1 with the reconnect in flight (now the minimum of five), and six address-in-use panics in the two old nodes because the second gate reused the first's ports the second they were sent SIGTERM (a 20 s gap now). CLOCK CORRECTION (the node lane, 12:12Z = 13:12 BST): every "UK" stamp it sent today was the box's CEST, an hour fast of BST; its lines read UTC from now. Restated: b7cc37e7's build about 12:15Z, its digest and mixed-version gates on that binary with the sha and string about 12:32Z (13:32 BST), the fleet's kept-datadir start on it about 12:25Z, its 12 GB settled-claim line 12:50 to 13:00Z; the shipper's checkpoint 14:30Z (15:30 BST), two hours of room. The 13 October date stands (derived from UTC DAA rates): the floor 831,600 about 08:00Z, 09:00 BST. b7cc37e7'S OWN LINES (binary sha256 bc28331abf21f4d5, the string read back on build-1 and on the fleet's pod): the digest gate 12:14:39Z to 12:16:18Z SUMMARY PASS (thirteen fields a89be8a7 on both binaries with the peers as the gate wants them; the sixteen-field object db9a85f9 refused with the line and no peer; the live file's digest eada4bda on the binary, unmoved); the kept-datadir start on the fleet's copy of pool-1's 0.3.17 datadir: the first start 12:17:12Z reads the v1 row through the mirror and rewrites it ("1 mergeset rewards"), the finality blob converts (1,747 locks), the node comes up on its ports with no panic; the second start 12:18:53Z reads first-try with no rewrite line and no panic; 6a3432a3's death on the same copy is the known-failed shape. The ten-minute mixed-version gate beside the 5899f603 pair runs on the same binary since 12:16:39Z, its line about 12:28Z; then the only line outstanding for the shipper's 14:30Z rule is the fleet's 12 GB settled-claim line, 12:50 to 13:00Z. AP-F8-1 RESIDUAL CLASS ON THE AMENDED STREAM (attack-pass lane 12:18Z on igneum-pow 8c728ca3, sub-version 1). F9 over 1,000,000 seeds: programs flagged (hot share at least 1 percent or 7 constant address bits) 1,871 (0.19 percent) against 11,696 (1.17 percent) unamended; worst hot share 9.66 percent against 17.3; mean 0.011 against 0.063 percent; 84 percent of the flagged programs and the whole or-saturation tail gone. F8 at 30 of 64 seeds: nine over 1.2x of the window model (p31 29.3x, p11 5.5x, p19 3.3x, p6 3.1x, p23 2.0x, the rest 1.3x to 1.6x); the 64-seed 1.2x gate is heading to FAIL on sub-version 1. Mechanism, confirmed on the two worst seeds: an all-ones load source (image 0x0ca59e4c under the era map) delivered through a writer the source rule counts as entropy-keeping, a rotate (rotl and rotr map all-ones to itself) or a load whose own source was saturated, with the saturation made one or more writes upstream by or. The rule looks one writer back; it must look through saturation-preserving writers or test the source's values. The ceiling has not moved: rule (c)'s 120-of-128 floor still caps any program at one saturated site, 6.25 percent of reads, a chip edge of at most 1.067x, and the residual (worst seed two sites at 0.53 and 0.56) sits inside it. THE SENTENCE "no lossy-sourced load by construction" IS HELD: it goes in no plan row and no ledger entry as true; sub-version 1 removes the or-source class and bounds the rest. MAIN'S RULING (13:2x UK): 0.3.20 ships object byte 5 on sub-version 1 as it stands, strictly better than the old stream the live floor flips to on 13 October; the fix is sub-version 2 on ca3-v4-amend (object byte 6 or whatever the v5 alignment leaves free) with both fixes: (F1) the static rule made transitive (rotates do not keep entropy; a load keeps entropy only if its own source did; one draw change, no attempts lost) and (F2) the dynamic source check (saturated load SOURCE values counted per site over the 64 units' 16,384 evaluations, rejected above 163 of 16,384, the same 1 percent the final-value rule uses; costs attempts on about 0.2 percent of seeds; rides with F1 because an or-written source is all-ones only (3/4)^32 of the time). Gate before sub-version 2 is proposed, run by the attack-pass lane and not by the hash lane: the full 64-seed census under 1.2x on every seed and the hot-set census. Hash lane's estimate about an hour its side (implement, re-export seven packs, vectors, crate suite, pairing, one G1 on PC 2) plus the node lane's vector re-pin and the attack-pass re-gate. The flip floor for sub-version 1 is expected to move (Josh's word) so the chain never flips to a stream that fails this gate. Also recorded: the crate suite at 8c728ca3 100 of 100 on the box (rc 0, 77 s); the pairing against the fork at dc141409 compiled and ran 15 of 16, the one failure the fork's own pre-amendment assertion (base equals v3's, igneum.rs:972), which 8097d600 on the release-0.3.20-node line turns into assert_ne; the pairing re-runs at b7cc37e7, its line to follow. CORRECTION (the attack-pass lane's own retraction, 13:3x UK): the F9 hot-set figures above (1,871 of 1,000,000, worst 9.66 percent, 84 percent removed, the two or-then-rotate listings) are WITHDRAWN: F9's harness draws through candidate_class with its own era class, outside candidate_from_words_class where the source rule lives, so it measured the old stream (the 8c728ca3 binary prints the identical program to the sub-version-0 binary for its worst seed). F8's 64-seed census on the chain path (pairing verified on 1a4230699a6b9c60) is the valid re-gate and STANDS: at 30 of 64 seeds, nine over 1.2x of the window model (p31 29.3x, p11 5.5x, p19 3.3x, p6 3.1x, p23 2.0x, p4 1.6x, p10 1.5x, p26 1.3x, p25 1.3x). The residual mechanism on the amended stream: a load-after-load chain (a saturated source reads one fixed word, which is the next load's address), admitted because a load injects; and the rotate-preserves-saturation path (generator.rs sets entropy_kept true for a rotate whatever it rotated), correct in code and a second admitted path if it occurs on the chain stream. Sub-version 2 must close both: dataflow freshness per register (a load fresh only if its source was fresh; add, sub, xor, mad, shfl fresh if either operand was; rotates only if the operand was; or, mul, mulhi never) plus the (c') count of saturated load sources per site as the backstop. The STOP holds on F8's evidence alone; the options and the 1.067x ceiling are unchanged. The sentence "no lossy-sourced load by construction" waits on the sub-version 2 census verdict and stays out of every public text until then. SUB-VERSION 2 IN BUILD (the hash lane, ca3-v4-amend, on the coordinator's direction, 13:4x UK): F1 (dataflow freshness per register, keyed on the class v4 shape on every draw path, era or not, so the candidate_class path and the chain path draw one stream) plus F2 (the (c') count of saturated load source values per site over the 64 units' 16,384 evaluations, rejected above 163, keyed on the same shape so v2 and v3 verdicts do not move); PROGRAM_SUBVERSION_V4 = 2, new ids, the seven packs re-exported, recheck.rs with 1a4230699a6b9c60 and c120d7963abdcd96 as the must-differ pair. Clock (UTC): the commit on the branch by 13:30; the crate suite on box 2 and the pairing against b7cc37e7 by about 13:50 (the pairing's vector test fails on the fork's sub-version-1 pin until the node lane re-pins; the compile and the other 15 are the pairing evidence); the G1 job on PC 2 under --cards-off by about 14:10, lock permitting; then the attack-pass lane's full 64-seed census and hot-set census on the chain path. Two consequences stated in the commit: the rule on every draw path moves the no-era sh256xN ladder packs' stream (packs-ca3-shadow's seven 256-block packs re-export with new fingerprints; the measured rates stand as the old stream's), and the class v5 lane's pinned string-seed packs move when it merges sub-version 2, so it re-exports them then. 0.3.20's sub-version-1 packs, ids and fingerprints untouched. OBJECT BYTES SETTLED (main, 13:5x UK): byte 5 = class v4 sub-version 1 (0.3.20), byte 6 = class v5 (pinned: class-v5 16afd0a0, class-v5-node 699db5a2, the flip case passed on 6,6,6; the v5 lane stopped), byte 7 = class v4 sub-version 2; the node and hash lanes told. b7cc37e7's MIXED-VERSION GATE: FAIL, the binary not the harness (12:16:39Z to 12:27:21Z, sha256 bc28331abf21f4d5, the string read back). Before the restart step everything held: one digest b0afb2ee on all five nodes, 268 new and 392 old blocks accepted, 0 rejected, header versions plain 2, counts equal on all five at 324 and 502 through both clean joins. At the new node's restart (12:24:19Z) it died at once on its own datadir ("IO error: While lock file: .../datadir/meta/LOCK: Resource temporarily unavailable", conn_builder.rs:167): the previous process was still shutting down, because the listener watchdog added on 6a3432a3 sleeps its whole 10 s poll before checking shutdown, so every node on the line since then takes up to 10 s longer to stop than 0.3.17 (the fleet saw the same shape as "a 12-second timeout does not stop the node"). Three of the four failed checks follow from that one death (counts, the restarted node's resync, the node it served frozen at 502). The fix on the line, one rule: the poll in 250 ms steps returning the moment shutdown is set, with a test that a shutdown returns within a second (the 10 s loop the known-failed shape); the exec suite on build-2, the fifth commit and its build about 12:45Z, its digest and ten-minute gates about 12:50 to 13:05Z, inside 14:30Z. b7cc37e7 is NOT the pin. The node-side re-pin for sub-version 2 (byte 7) once the hash lane's commit lands: the beside-the-fork igneum-pow copy archived from the commit, the two pinned ids moved in the kaspa-pow vector test (sub-version-2's epoch-0 id must-equal; sub-version-1's joins c120d7963abdcd96 as must-differ), CLASS_SIGNAL and tests for byte 7, the daemon's window line: about 20 minutes of edits plus one kaspa-pow suite run on build-2 (about 2 minutes). THE FIFTH COMMIT c4459193 on release-0.3.20-node (b7cc37e7's child, the watchdog poll returning on shutdown; the diff is the poll loop in rpc.rs alone), pairing igneum-pow 8c728ca3; its build on build-1 started 12:30:13Z, sha256 and string to follow. Line A, the shutdown test: rpc::watchdog_tests::a_shutdown_returns_within_a_second_whatever_the_poll green on build-2 at 12:29Z in the exec suite's 31 passed, beside the two other watchdog tests; its known-failed shape the old loop's 10 s stop. Line B, the kept-datadir start: b7cc37e7's fleet read carries to c4459193 since the store code is byte-identical between the two commits; the fleet re-reads on the c4459193 binary only if the shipper's rule wants the string on that line too. The digest gate and the ten-minute mixed-version gate on c4459193's own binary follow its build. THE SHIPPER'S CARRY RULING (14:1x UK): b7cc37e7's kept-datadir read stands as evidence that the store fix is right (the store code byte-identical) but is not the gate line for the pin, because the rule reads the binary, not the diff, and the binary changed (rpc.rs); the gate line is the kept read on c4459193's own binary with its string, which the fleet's canary already runs on c18-1 (wipe, then the kept read, then the restart) before the canary's restart step, at no extra cost; no re-read on p12-vast. THE PIN IS c4459193 pairing 8c728ca3 (object byte 5, sub-version 1); sub-version 2 (byte 7) is 0.3.21's, not 0.3.20's. The shipper's reading of main's F8 ruling: 0.3.20 ships object 5 as it stands because the live floor otherwise flips every node to the OLD stream on 13 October, and the 16:00 BST report tells Josh the floor move is now RECOMMENDED rather than optional, so the chain never flips to a stream that fails the 1.2x gate before sub-version 2 lands. THE FLEET'S CLOCK ON c4459193 (the fleet lane, 12:5x UTC): the kept read on pool-1's 0.3.17 datadir copy and the restart (the old process's stop time on the line) run on c18-1 before the wipe, a few minutes each, so both lines land before 14:30Z; the wipe canary (IBD from the pruning-point proof, 98 minutes on this pod class) starts when c18-1 is free of the 0.3.20 cases (about 13:00Z) and the binary is in hand, so its synced line lands about 14:40Z at the earliest, PAST the 14:30Z checkpoint; the 12 GB settled-claim line: c4459193 starts on p12-vast's kept copy of pool-1's datadir beside the 6a3432a3 IBD node on alternate ports the moment the binary lands, catches up from 129,398 blocks (15 to 20 minutes) and the 12 GB prover claims against it, the line on c4459193 itself. The binary not yet in the fleet's hand (build-1 building since 12:30:13Z); a wait armed on the sha and string, a report by 13:10Z if nothing. THE SHIPPER'S CALL ON THE CLOCK (14:2x UK): the wipe canary is the decisive read by the deploy rule; the pin never cuts without it and b7cc37e7's lineage does not stand in (the binary changed). The fleet rents a second one-shot pod of c18-1's class now and starts the wipe canary on c4459193's binary the moment the build lands, synced line about 14:15Z (15:15 BST), inside the checkpoint; c18-1 keeps the 0.3.20 cases and the pool window. If the wipe line slips past 15:30 BST the pin holds to it and main hears the clock (a slip is a report, not a cut). The set: the node lane's digest and mixed-version gates (12:50 to 13:05Z), the kept read and restart on the new pod, the wipe line on the new pod, the 12 GB settled-claim line on p12-vast. c4459193's BINARY IN THE FLEET'S HAND (12:34:54Z from build-1): igneumd sha256 45be9b02d1b002f5486d0f0108571c3b6042094113ad9da6f3d3d9ffc0072bba with the string c4459193 read back from the file, igneum-miner c7cfc40bc8b0e357. The wipe pod c19-1 (RunPod wpuke4tfu0vr49, RTX 3070 community, c18-1's class, USD 0.13/h, rented 12:37:03Z, one-shot; the day at USD 124 of work plus the 248 leak, 37 percent of the ceiling): the canary form (wipe, IBD from the pruning-point proof, synced, ten minutes mining with the exec poller, the hub read, the restart read) starts the moment the pod answers ssh; the kept read on pool-1's 0.3.17 copy armed behind its synced line on the same pod; the IBD start stamp its own line; synced about 14:20Z if the pod answers by 12:42Z (ten minutes inside the checkpoint), a slip reported the moment a poll shows it. CASES END on c18-1 at 12:37:18Z rc 0 (the relay and poison lines to the shipper); c18-1 and the two case pods destroyed by the run; the ten-member pool window rented its ten at 12:37:36Z. The 12 GB settled-claim line on p12-vast runs against a c4459193 node on the pod's kept copy, up since 12:36:35Z first-try, catching up. THE WIPE CANARY ON c19-1 STARTED: IBD at 12:38:55Z on c4459193 (sha256 45be9b02... asserted on the Mac before the put; the node's own line igneumd/2.1.0-c4459193 and digest eada4bda8aa8368c read back on the pod; a wiped datadir; IBD from the pruning-point proof with 4 peers at 12:39:26Z); synced about 14:17Z by the 98-minute class, thirteen minutes inside the checkpoint; the mining read, hub read, restart and kept read follow on the same pod, each its own line. c4459193's GATE LINES (the node lane): the binary built on build-1 at 12:33Z (1 m 07 s), sha256 45be9b02d1b002f5, the string read back from the binary (strings, two hits) and the worktree HEAD; igneum-miner beside it at /srv/builds/igneum-wt-ca3-v4-node/vendor/igneum-node-0318-release/target/release/. THE DIGEST GATE 12:33:27Z to 12:35:05Z SUMMARY PASS: the thirteen-field object a89be8a7 on both binaries, n0 peering n1 and n2 and the old node peering the new (the compat case); the sixteen-field object db9a85f9, n3 with no peer and the refusal line "consensus params digest mismatch, local db9a… remote a89b…" (the refusal case); the live file's digest on this binary eada4bda, as 5899f603 reads it. THE MIXED-VERSION GATE 12:35:26Z to 12:45:39Z SUMMARY PASS, beside the 5899f603 pair: one digest b0afb2ee on all five nodes; the 5899f603 hub accepted every block the c4459193 node mined, 215 new and 314 old, 0 rejected, no reject line in any log; header versions plain 2 on the thirteen-field file; counts equal on all five at 312 after mining, 441 after the clean join through the old hub and the clean join served by the new node, 529 at the end; the restart step passed: the new node restarted at 12:43:08Z on its own datadir and resynced to 529 with the others (where b7cc37e7 died on the database lock); no panic in any node log; every check green. The node side of the set is complete; the fleet's wipe, kept read, restart and settled-claim lines remain. A SLIP (the fleet lane, 12:5x UTC): the 0.3.20 cases rerun on c4459193 lands about 15:10Z, not 14:20Z: its target c20-1 catches up from pool-1's kept 1026 copy, 22,000 blocks behind a tip the line reaches headers-first (headers 137,405, blocks 129,398 at 12:50Z; the morning's poison pod on the same copy took 50 minutes before its blocks moved), synced about 13:50Z, the 79-minute form after; no faster path exists on a kept copy. The wipe canary on c19-1 holds its clock (29 percent of the headers at 12:47Z on dc141409's curve): synced about 14:17Z, the mining and hub reads to about 14:30Z, the restart and the kept read after; the 12 GB settled-claim line on p12-vast about 14:00 to 14:10Z. The kept read on the pinned binary is already in hand from c20-1's own start at 12:45:46Z (the rewrite line, no panic, sha 45be9b02 and the string read back), with the shipper. MAIN'S RULING WITH THE SHIPPER (14:5x UK): the cases rerun on the pin's own binary gates the cut; the cut word about 15:15Z (16:15 UK) on CASES END, the publish on green right after, the sweep from then with PC 1 first; 5899f603 the fallback until the word. The shipper's reason: the cases are a named gate and the morning's run was on dc141409 (the diff from dc141409 to c4459193 touches the class signal byte, in the cases' territory); the 16:00 BST report carries the clock and the full cut set; everything else staged so the publish is one step at that moment; nothing changes on the pods. THE INTEROP FACT stands from the void run: the 5899f603 hub accepted 235 object-byte-5 blocks from the 8097d600 node with 0 rejected, one digest on all five nodes on the live sixteen-field file. The gates: the digest test and the kaspa-pow vector test (the amended devnet epoch-0 id 1a4230699a6b9c60 must equal, c120d7963abdcd96 must differ, the v3 control unchanged) on the box; the mixed-version Devnet 2 gate (the amended 0.3.20 node beside a 5899f603 node for ten minutes on the live file without the v4 fields) after the Mac build; the fresh-join canary the 0.3.20 cut's | | Main's rulings (7 October, morning) | no generator change to v4 on the live devnet; the record's null is the window model with numbers, sent by the hash lane to the attack-pass lane so AP-F8-1 re-gates against it; a fault beyond the model (a low-entropy source at site 15) stops at the coordinator with the two options priced (a 0.3.19 class amendment before the flip, or the flip held at the floor), nothing shipping without Josh's word; the tighter tail, an acceptance bound on the hot-set share, is a CLASS V5 item (sent to the v5 lane a6410f3b8abefb762 with the 64-seed census as its gate; the bound's number follows from the model) | ### AP-F4-1, the weak-day MUL draw (the attack-pass lane, 7 October, morning): PASS against v4, a class v5 rule From 430edbebbe63c0125dc93f1d9666f915cf8cbebe Mon Sep 17 00:00:00 2001 From: igneum-josh <337424239+igneum-josh@users.noreply.github.com> Date: Wed, 7 Oct 2026 13:57:40 +0100 Subject: [PATCH 12/19] Counter ASIC 3.0 status: the F8 re-gate verdict on sub-version 1 (53 of 64 PASS, 11 FAIL, worst 29.27x), the three residual classes, the fixpoint requirement for sub-version 2 Co-Authored-By: Claude Fable 5.1 --- docs/plans/counter-asic-3-status.md | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/docs/plans/counter-asic-3-status.md b/docs/plans/counter-asic-3-status.md index 8a7f84ea6..349a75da0 100644 --- a/docs/plans/counter-asic-3-status.md +++ b/docs/plans/counter-asic-3-status.md @@ -338,7 +338,24 @@ Josh gave the go in advance for tonight: the shipper runs publish 1 on the 0.3.1 | THE ANALYSIS (the hash lane, ca3-v4-uniform 095f84a7, `docs/analysis/ca3-v4-uniform.md`, the tool on igneum-build-1) | the window model moves the null from 0.115 to 0.160 percent (1.39x, not 4.05x); the rest is a FAULT beyond it: site 15 reads a register last written by `or r6, r4`, so all-ones recurs at (3/4)^32 per read and the era map sends it to F8's hottest item exactly (the popcount model predicts 77,348 all-ones reads against 78,479; the top-0.1-percent share 0.58 against 0.52); it passes the acceptance rule because part (a) takes any write as a fresh source and part (c) counts saturation on final values only. The census of 1,024 chain-shaped v4 programs: 96.6 percent carry a lossy-sourced load (or, mul, mulhi as the last writer), 48.5 percent an or-sourced one (0.30 percent of all reads per site), 4.9 percent an or-of-or chain (4.6 percent of all reads on 0.1 percent of items); F8's 1.2x gate fails 96.6 percent of today's programs. Worth to a chip: 1.07 MB of SRAM ($0.25) serving 0.52 percent of a typical program's reads and 4.6 percent of the worst class's, at most 1.005x and 1.048x in rate; the ceiling under rule (c)'s 120-of-128 floor one site repeating its item in all 8 iterations, 6.25 percent of reads, 1.067x in 64 bytes; the 2x margin stands; the public line says "bounded at 1.067x", not "uniform" (the public text corrected) | | The two options, priced, STOPPED at the coordinator for Josh's word | A: a 0.3.19 class amendment before the flip (the generator draws a load's source from the registers whose last writer injects): a new program stream, new vectors, the seven gate packs re-exported, the six gates again (G1 to G3 and the verifier about an hour on the Mac and PC 2; G4 to G6 the node lane), every node before the flip under the one-box-at-a-time rule; the risk a node that misses the build splits the chain at the flip. B: hold the flip at the floor with v4 as it is; the bound documented; the source rule to class v5: a hot set worth up to 1.005x on about half the hours and 1.05x on 5 percent, 1.067x at the ceiling; no chain risk. The number: 1.067x at the ceiling against the 2x margin. The lane recommends B | | The v5 bound (sent to the v5 lane) | H = W_0.1 (the window term, 0.115 to 0.251 percent) + the sum over load sites of h(last writer) (or 0.30 percent, an or chain 4.5, mul 0.067, mulhi 0.049, an injecting op or a rotate 0), H at or under 1.2 x W_0.1, which is the static rule "every load's source was last written by an injecting op or a rotate"; as a rejection it costs 96.6 percent of candidates (about 30 attempts per seed), as a generator draw nothing; gate F8's 64-seed census with the saturated-source count | -| JOSH'S WORD (15:2x UK, 7 October): OPTION A, "do this but limit the testing, get it pushed" | the class v4 amendment: a load's source drawn only from registers whose last writer injects or is a rotate (the v5 rule applied now), a new program stream and vectors, the seven gate packs re-exported, the amended class with its own generator stamp; rides 0.3.20, the feature node (release-0.3.20-node = dc141409; 0.3.19 is an app-only cut with nothing of ours), on the shipper's line. The rollout arithmetic for the flip clock (the shipper): the standing fleet's one-box-at-a-time rollout took 32 minutes for 14 boxes (04:56 to 05:28Z, 7 October), the hands and the seed about 3 minutes after the miners, the Mac and the PCs within minutes of the publish; every 0.3.20 worker must accept the amended stamp before any flip. Owners: the hash lane (ca3-v4-amend: the generator, the vectors, the packs, the pairing on the box, one G1 run on PC 2, the ledger row), the node lane (release-0.3.20-node: the stamp agreed with the hash lane, the split-protection mechanism and the earliest flip time, the digest test, the mixed-version Devnet 2 gate), the attack-pass lane (the F8 census at 2^24 on the new stream, the gate 1.2x of the window model over 64 seeds), the shipper (the cut, the rollout order that sets the earliest flip). Testing limited to what prevents a split and proves the fix; G2, G3, the ladder re-measure and the rest of G4 to G6 OWED. THE STAMP agreed (the node and hash lanes, 7 October afternoon): generator 4 with sub-version 1 inside igneum-pow's id function, so the amended v4's program id for a seed differs from the old v4's (the old devnet epoch-0 id c120d7963abdcd96 pinned as the must-differ vector in kaspa-pow's test). SPLIT PROTECTION SETTLED (the node lane, plan section 6.6, ca3-v4-node fa5bc9e6; the node side on release-0.3.20-node): a fresh object byte. CLASS_SIGNAL_V4 is 5; the amended binary stamps 5 and the tally counts a block only at byte 5 or above; object 4 was stamped only by the unpublished dc141409 canary, so no published block carries it and a byte-4 block never counts; a node of the 6 October stream that sees byte 5 counts it as v4 (its rule is at least 4), flips to its own stream at the same epoch and forks ALONE (its blocks fail the amended id check, generator 4 sub-version 1 inside every id; the amended blocks fail its own), ours to upgrade in the sweep; object 6 is class v5's; the two holds already in the rule keep the window shut until every node is on 0.3.20 (a node stamps and tallies only with both v4 fields in its file; the fields publish only after the one-sweep rollout); a lagging worker refuses the amended pack at packcheck and mines nothing after the flip, costing that box, never the chain; no extra window hold: seven full day-windows are the hold. THE EARLIEST FLIP (approximate, measured 09:40Z: DAA 270,659, 1.095 DAA/s over 25 hours, 1.165 over 4; epoch 3,600, lead 600; seven windows 604,800 DAA wholly after the sweep's end D_s = T + about 40 minutes; the flip epoch the first e with 3600 e - 600 >= D_s + 604,800): T + 6 days 10 hours to T + 6 days 11 hours UK; for a publish at 12:00 UK on 7 October, 13 October between 22:20 and 23:10 UK (about 13:00 UK if the 4-hour rate holds). The floor as it stands (831,600, about 13 October 09:00 UK) would fire before any seven-window signal from a publish today completes, so it moves by the 0.3.16 rule to the publish DAA + 604,800 rounded up to the epoch boundary (882,000 for a 12:00 UK publish), firing about 30 minutes before the earliest signal flip: either way about 6 days 10 hours after the publish, never before every node has had the sweep plus a week. THE CLOCK (the node lane, 11:3x UK, after a Mac reboot moved its runs to the box): the 0.3.20 node line (dc141409 plus the proof archive aea0ca5c plus the amended v4 at object byte 5, igneum-pow at the hash lane's a0aaca92 beside the fork on the box) tested on the box, committed on release-0.3.20-node, pushed to the mirror and origin, igneumd and igneum-miner built, the tip to the shipper: about 12:00 UK; the mixed-version Devnet 2 gate (node-compat.mjs on the box, the amended node beside the 5899f603 pair for ten minutes) and the digest test (digest-compat.mjs): about 12:45 UK; the object-byte pin 5 unless the v5 lane answers both lanes with another assignment (v5 at 6 proposed). THE HASH SIDE on ca3-v4-amend (tip 8c728ca3, read from the branch 14:0x UK; the hash lane's own report pending): 1748fd1d the PC 2 G1-only playbook; e1f48d63 the fud-ledger entry AP-F8-1 (the fault, Josh's ruling, the amendment, the split protection, the owed tests); d8859522 the G1 line (the eight fingerprints equal on the RTX 5090, self-test PASS) and the node lane's signal byte 5; 4aa0c665 the v4 unit test following the amendment; 965d9e96 igneum-pow taken from release-0.3.20's 3f1652bf (the ladder's chain_program_shadow with the reps argument, never on master) with the amendment re-applied, the seven packs re-exporting byte-identical; 8c728ca3 the source rule keyed on the class with the shadow's pass count set aside, so every ladder rung draws under it (the fork's ladder test). The shipper took this igneum-pow tree into release-0.3.20 (00249643, byte-equal); nothing after 8c728ca3 touches igneum-pow. THE VECTORS AND THE PACKS (read from the branch and its ledger entry, 14:1x UK): the seven amended v4 packs (v4-devnet-epoch0, v4-era-0 to 5) carry generator 4, sub-version 1, one program id 1a4230699a6b9c60 (the 2.0 one-id-per-seed rule across the eras; the old c120d7963abdcd96 pinned as must-differ); the v3 control mx8-devnet-epoch0 untouched (73bcbfe8ccf988f1, fingerprint 90f794dd556f7a3b); the seven 2^24 fingerprints, Metal equal to Apple OpenCL: 867dbc45cfb36b4d, 2146ecacc8c75a8e, fe52602393f6d3d4, 3b206471a13912b4, c3f03c4a5d7333aa, f1dfd7209f15bb97, 8c194da64fadf31d; the zip of the eight packs sha256 889ec99976d2728b4b5035bfa476032e5b6a13b928968fc45236d5f25084aa39; the per-pack vectors.json sha256 prefixes 756301bf (devnet epoch 0), 1b5f4568, d430cadc, 1a1b21d8, 460fff9e, 4a85d49d, f83a1196 (eras 0 to 5). G1 on the RTX 5090 (PC 2 job run-ca3-v4-amend-g1-pc2-20261007, 09:41:07 to 09:41:28Z, exit 0, the installed worker): every fingerprint equal to the Mac's (the seven above and the control), NVRTC 188 to 332 ms per pack, the 1 GiB build 38 to 49 ms. hash-gates.md's older table still lists the pre-amendment fingerprints (f410c731... and the eras), which no longer apply to the amended packs; the ledger entry is the record. THE FIRST GREEN (11:31 UK, the box): the kaspa-pow suite on release-0.3.20-node (dc141409 plus the proof archive aea0ca5c plus the object-5 change) against the hash lane's igneum-pow 8c728ca3: 17 passed, 0 failed; the amended devnet epoch-0 id 1a4230699a6b9c60 pinned equal and c120d7963abdcd96 differing, the ladder's rung test green under the rekeyed rule, the v3 control unchanged; the consensus-core and exec RPC suites follow, then the node line (commit, push, box build, the tip to the shipper), then the digest and mixed-version gates. CLOCK RE-CUT (the node lane, 13:0x UK): the node line now carries, beside the object-5 change and the vector test, the lane's 0.3.20 fixes from the day (isSynced from the hook's stamp, the lazy template snapshot, the weight-table cache, the submit path returning after the block task, the watchdog, the RPC fields), about 13:30 UK if the box suites are green; the shipper's fresh-join canary 60 to 100 minutes after the cut; PC 1 as its first machine about 16:00 UK at the earliest, approximate until the shipper names the cut; the earliest flip about 6 days 10 hours after the publish. BUILD-2 LINES (12:28 to 12:33 UK): consensus-core 123 passed (the 60x file test green with the ladder window and activation pinned), the behind test green, kaspa-pow 17 passed (the amended vectors, earlier on build-1), the exec RPC suite green, the flows and rpc-service checks green with the submit-path change; the 24-requester latency test's first run tripped an unrelated flapping-fork double insert (24 equal forks from one parent; the test now builds on the sink as a real miner does; the double insert owed to a small fork harness before it is called a bug); THE NODE LINE COMMITTED (13:1x UK): release-0.3.20-node = 8097d600 (dc141409 + the proof archive aea0ca5c + one commit) on the mirror, pairing igneum-pow 8c728ca3, the hash with the shipper; in it the amended class v4 as object 5 (CLASS_SIGNAL_V4 = 5, byte 4 never counts, the kaspa-pow vector test pinning 1a4230699a6b9c60 equal and c120d7963abdcd96 differing, the daemon's window line naming object 5 and sub-version 1) beside the day's fixes (isSynced from the hook's stamp, the weight-table cache, the lazy snapshot, the submit path, the 100 ms template wait); the suites green on build-2 (consensus-core 123, the exec RPC suite, the four finality tests including 24 requesters under 200 ms: the worst template 100 ms, the worst submit 102 ms) and kaspa-pow 17 on build-1. Next: igneumd and igneum-miner building from 8097d600 on build-1, then the two gate lines (the mixed-version Devnet 2 gate: the 8097d600 node mining beside the 5899f603 pair for ten minutes on the live file without the v4 fields, the old node accepting every block; the digest test: the thirteen-field file b18ed271 unchanged, the sixteen-field object re-read on the 8097d600 binary), expected about 13:30 UK; the shipper picks the cut point. THE DATE FIXED (the node lane, from the hub's live file, 13:3x UK): publish 2 of 6 October (22:49:45Z, digest eada4bda) already put BOTH v4 fields on the live devnet (floor 831,600, window 86,400), so the 0.3.17 fleet has stamped object byte 4 since 7 October 00:2x UK and the floor is live at about 13 October 09:00 UK, before any seven-window signal completes; a 0.3.17 node left on that file flips to the OLD v4 stream at epoch 231 whatever anyone signals, a 0.3.20 node to the amended stream at the same epoch, and the two never share an id, so each straggler forks alone there. REQUIREMENT for the 0.3.20 publish (with the shipper and main): a new file with the floor at the publish DAA + 604,800 rounded up (about 882,000 for a publish today), the digest moving, the one-sweep rollout replacing every 0.3.17 node before 13 October 09:00 UK; any node that misses the sweep is alone then; the earliest flip after that about 6 days 10 hours past the publish; plan section 6.6 amended today. IN THE 0.3.20 PLAN (the shipper, 13:4x UK): both requirements; the node pin by main's rule is the node lane's second commit (the claim floor, the listener watchdog, the claim RPCs, on top of 8097d600) if its suites, both gates and the fleet's 12 GB prover line are green by 15:30 UK, else 8097d600; igneum-pow 8c728ca3 either way; the digest read on whichever binary pins. THE LINE AT 13:5x UK: three commits on release-0.3.20-node, 8097d600 (the object-5 amended class v4 and the day's fixes), 6b94c823 (test-only: the stale PC 1 test from 500ddd66 inverted by the isSynced ruling; the FALLBACK pin, code byte-identical to 8097d600, so the module reads green whole) and 6a3432a3 (the app lane's key methods, the observer's claims, the settled claim floor, the listener watchdog); suites on build-2 on 6a3432a3's code (the whole finality module 25, the exec suite 29 with the watchdog test, the kaspad, flows and rpc-service checks; consensus-core 123 and kaspa-pow 17 earlier); the cut 6a3432a3 if its gates and the fleet's 12 GB settled-claim line are green by 15:30 UK, else 6b94c823; both binaries building on build-1, the two gates (the digest gate, then the ten-minute mixed-version gate beside the 5899f603 pair) on the 8097d600 build, lines about 14:05 UK. GATE NEWS (13:53 UK): on 6a3432a3's own digest gate the listener watchdog counted a bind failure (the four harness nodes share one exec JSON-RPC port) as a listener death and exited three of four nodes at 20 s, where 0.3.17 and 8097d600 only warn and live without the exec RPC; the digest facts came out first and stand (the thirteen-field file a89be8a7 on both binaries, the compat case; the sixteen-field object db9a85f9 refused with the mismatch line, the refusal case); the ten-minute gate on 6a3432a3 stopped as void for the same cause. The fix: a bind failure is a retry every poll, one line a minute, no death counted and never an exit, with a second watchdog test whose known-failed shape is the old rule's exit on a held port; the third commit and its build about 14:15 UK, its gates about 14:35 UK; the fallback 6b94c823's gates on build-1 on their own binary (no watchdog there), lines about 14:20 UK; ledger row N12 for the bind-failure class. A ROLL BLOCKER on every kept datadir (the node lane, 14:1x UK, ledger N13): the fleet started 6a3432a3 on a kept 0.3.17 datadir (pool-1's copy) and it died at start (virtual_state.rs:250, DeserializationError(UnexpectedEof)); the cause 10db4b61 on the 0.3.16 feature line added `silent: bool` to BlockRewardData under serde(default), which bincode ignores, so every build from 10db4b61 on (dc141409, 8097d600, 6b94c823, 6a3432a3, 09124180) reads a 0.3.17 node's virtual-state row short; no canary saw it because every canary wiped, and a one-box roll keeps datadirs, so it blocks the roll on every standing box, the hands and the hub whatever the pin. The fix on the line: the store reads the current layout first and on a deserialization error decodes the row as a v1 mirror, converts with silent false and rewrites it under the same key, with the known-failed test first; the fourth commit and build about 14:40 UK, the fleet's kept-datadir start on the fixed binary about 14:50 UK, its gates after. THE RULE IT ADDS for every node cut from now: a kept-datadir restart gate on a standing box's datadir copy beside the wiped canary. THE CANDIDATE PIN (14:2x UK): b7cc37e7 (8097d600, 6b94c823, 6a3432a3, 09124180, b7cc37e7; igneum-pow 8c728ca3): the N13 fix with its test green on build-2 at 14:04 UK and the kaspad check green, the build on build-1; the fallback 6b94c823 is no longer a pin for the one-box roll (it dies on a kept datadir like every build since 10db4b61): if b7cc37e7's gates are not green by 15:30 UK the honest fallback is 0.3.17's 5899f603 staying live. In flight on build-1: the earlier commits' gates, then b7cc37e7's own digest and ten-minute mixed-version gates on its binary with the read-back, lines about 15:05 UK; on the fleet the kept-datadir start on b7cc37e7 about 14:50 UK and the 12 GB settled-claim line 14:50 to 15:00 UK. Plan section 6.6 amended with the hard date (ca3-v4-node 9d763edd, merged to master); N12 and N13 on the ledger. THE GATES ON THE FALLBACK'S OWN BINARY (6b94c823, sha b1b7d47b, 13:56 to 14:08 UK; code byte-identical to 8097d600, so the amendment's node side): the digest gate, the thirteen-field file a89be8a7 on both binaries (the compat case, n0 peering n1 and n2) and the sixteen-field object db9a85f9 refused with the mismatch line (the refusal case); the mixed-version gate, ten minutes, one digest b0afb2ee on all five nodes, the 5899f603 hub accepting every block the amended node mined (146 new, 246 old, 0 rejected), plain header version 2 on the thirteen-field file, counts equal on all five through the two clean joins and the restart. Two FAILED checks, both the harness's own and fixed (36d3efdc): a refused peer's count read 1 with the reconnect in flight (now the minimum of five), and six address-in-use panics in the two old nodes because the second gate reused the first's ports the second they were sent SIGTERM (a 20 s gap now). CLOCK CORRECTION (the node lane, 12:12Z = 13:12 BST): every "UK" stamp it sent today was the box's CEST, an hour fast of BST; its lines read UTC from now. Restated: b7cc37e7's build about 12:15Z, its digest and mixed-version gates on that binary with the sha and string about 12:32Z (13:32 BST), the fleet's kept-datadir start on it about 12:25Z, its 12 GB settled-claim line 12:50 to 13:00Z; the shipper's checkpoint 14:30Z (15:30 BST), two hours of room. The 13 October date stands (derived from UTC DAA rates): the floor 831,600 about 08:00Z, 09:00 BST. b7cc37e7'S OWN LINES (binary sha256 bc28331abf21f4d5, the string read back on build-1 and on the fleet's pod): the digest gate 12:14:39Z to 12:16:18Z SUMMARY PASS (thirteen fields a89be8a7 on both binaries with the peers as the gate wants them; the sixteen-field object db9a85f9 refused with the line and no peer; the live file's digest eada4bda on the binary, unmoved); the kept-datadir start on the fleet's copy of pool-1's 0.3.17 datadir: the first start 12:17:12Z reads the v1 row through the mirror and rewrites it ("1 mergeset rewards"), the finality blob converts (1,747 locks), the node comes up on its ports with no panic; the second start 12:18:53Z reads first-try with no rewrite line and no panic; 6a3432a3's death on the same copy is the known-failed shape. The ten-minute mixed-version gate beside the 5899f603 pair runs on the same binary since 12:16:39Z, its line about 12:28Z; then the only line outstanding for the shipper's 14:30Z rule is the fleet's 12 GB settled-claim line, 12:50 to 13:00Z. AP-F8-1 RESIDUAL CLASS ON THE AMENDED STREAM (attack-pass lane 12:18Z on igneum-pow 8c728ca3, sub-version 1). F9 over 1,000,000 seeds: programs flagged (hot share at least 1 percent or 7 constant address bits) 1,871 (0.19 percent) against 11,696 (1.17 percent) unamended; worst hot share 9.66 percent against 17.3; mean 0.011 against 0.063 percent; 84 percent of the flagged programs and the whole or-saturation tail gone. F8 at 30 of 64 seeds: nine over 1.2x of the window model (p31 29.3x, p11 5.5x, p19 3.3x, p6 3.1x, p23 2.0x, the rest 1.3x to 1.6x); the 64-seed 1.2x gate is heading to FAIL on sub-version 1. Mechanism, confirmed on the two worst seeds: an all-ones load source (image 0x0ca59e4c under the era map) delivered through a writer the source rule counts as entropy-keeping, a rotate (rotl and rotr map all-ones to itself) or a load whose own source was saturated, with the saturation made one or more writes upstream by or. The rule looks one writer back; it must look through saturation-preserving writers or test the source's values. The ceiling has not moved: rule (c)'s 120-of-128 floor still caps any program at one saturated site, 6.25 percent of reads, a chip edge of at most 1.067x, and the residual (worst seed two sites at 0.53 and 0.56) sits inside it. THE SENTENCE "no lossy-sourced load by construction" IS HELD: it goes in no plan row and no ledger entry as true; sub-version 1 removes the or-source class and bounds the rest. MAIN'S RULING (13:2x UK): 0.3.20 ships object byte 5 on sub-version 1 as it stands, strictly better than the old stream the live floor flips to on 13 October; the fix is sub-version 2 on ca3-v4-amend (object byte 6 or whatever the v5 alignment leaves free) with both fixes: (F1) the static rule made transitive (rotates do not keep entropy; a load keeps entropy only if its own source did; one draw change, no attempts lost) and (F2) the dynamic source check (saturated load SOURCE values counted per site over the 64 units' 16,384 evaluations, rejected above 163 of 16,384, the same 1 percent the final-value rule uses; costs attempts on about 0.2 percent of seeds; rides with F1 because an or-written source is all-ones only (3/4)^32 of the time). Gate before sub-version 2 is proposed, run by the attack-pass lane and not by the hash lane: the full 64-seed census under 1.2x on every seed and the hot-set census. Hash lane's estimate about an hour its side (implement, re-export seven packs, vectors, crate suite, pairing, one G1 on PC 2) plus the node lane's vector re-pin and the attack-pass re-gate. The flip floor for sub-version 1 is expected to move (Josh's word) so the chain never flips to a stream that fails this gate. Also recorded: the crate suite at 8c728ca3 100 of 100 on the box (rc 0, 77 s); the pairing against the fork at dc141409 compiled and ran 15 of 16, the one failure the fork's own pre-amendment assertion (base equals v3's, igneum.rs:972), which 8097d600 on the release-0.3.20-node line turns into assert_ne; the pairing re-runs at b7cc37e7, its line to follow. CORRECTION (the attack-pass lane's own retraction, 13:3x UK): the F9 hot-set figures above (1,871 of 1,000,000, worst 9.66 percent, 84 percent removed, the two or-then-rotate listings) are WITHDRAWN: F9's harness draws through candidate_class with its own era class, outside candidate_from_words_class where the source rule lives, so it measured the old stream (the 8c728ca3 binary prints the identical program to the sub-version-0 binary for its worst seed). F8's 64-seed census on the chain path (pairing verified on 1a4230699a6b9c60) is the valid re-gate and STANDS: at 30 of 64 seeds, nine over 1.2x of the window model (p31 29.3x, p11 5.5x, p19 3.3x, p6 3.1x, p23 2.0x, p4 1.6x, p10 1.5x, p26 1.3x, p25 1.3x). The residual mechanism on the amended stream: a load-after-load chain (a saturated source reads one fixed word, which is the next load's address), admitted because a load injects; and the rotate-preserves-saturation path (generator.rs sets entropy_kept true for a rotate whatever it rotated), correct in code and a second admitted path if it occurs on the chain stream. Sub-version 2 must close both: dataflow freshness per register (a load fresh only if its source was fresh; add, sub, xor, mad, shfl fresh if either operand was; rotates only if the operand was; or, mul, mulhi never) plus the (c') count of saturated load sources per site as the backstop. The STOP holds on F8's evidence alone; the options and the 1.067x ceiling are unchanged. The sentence "no lossy-sourced load by construction" waits on the sub-version 2 census verdict and stays out of every public text until then. SUB-VERSION 2 IN BUILD (the hash lane, ca3-v4-amend, on the coordinator's direction, 13:4x UK): F1 (dataflow freshness per register, keyed on the class v4 shape on every draw path, era or not, so the candidate_class path and the chain path draw one stream) plus F2 (the (c') count of saturated load source values per site over the 64 units' 16,384 evaluations, rejected above 163, keyed on the same shape so v2 and v3 verdicts do not move); PROGRAM_SUBVERSION_V4 = 2, new ids, the seven packs re-exported, recheck.rs with 1a4230699a6b9c60 and c120d7963abdcd96 as the must-differ pair. Clock (UTC): the commit on the branch by 13:30; the crate suite on box 2 and the pairing against b7cc37e7 by about 13:50 (the pairing's vector test fails on the fork's sub-version-1 pin until the node lane re-pins; the compile and the other 15 are the pairing evidence); the G1 job on PC 2 under --cards-off by about 14:10, lock permitting; then the attack-pass lane's full 64-seed census and hot-set census on the chain path. Two consequences stated in the commit: the rule on every draw path moves the no-era sh256xN ladder packs' stream (packs-ca3-shadow's seven 256-block packs re-export with new fingerprints; the measured rates stand as the old stream's), and the class v5 lane's pinned string-seed packs move when it merges sub-version 2, so it re-exports them then. 0.3.20's sub-version-1 packs, ids and fingerprints untouched. OBJECT BYTES SETTLED (main, 13:5x UK): byte 5 = class v4 sub-version 1 (0.3.20), byte 6 = class v5 (pinned: class-v5 16afd0a0, class-v5-node 699db5a2, the flip case passed on 6,6,6; the v5 lane stopped), byte 7 = class v4 sub-version 2; the node and hash lanes told. b7cc37e7's MIXED-VERSION GATE: FAIL, the binary not the harness (12:16:39Z to 12:27:21Z, sha256 bc28331abf21f4d5, the string read back). Before the restart step everything held: one digest b0afb2ee on all five nodes, 268 new and 392 old blocks accepted, 0 rejected, header versions plain 2, counts equal on all five at 324 and 502 through both clean joins. At the new node's restart (12:24:19Z) it died at once on its own datadir ("IO error: While lock file: .../datadir/meta/LOCK: Resource temporarily unavailable", conn_builder.rs:167): the previous process was still shutting down, because the listener watchdog added on 6a3432a3 sleeps its whole 10 s poll before checking shutdown, so every node on the line since then takes up to 10 s longer to stop than 0.3.17 (the fleet saw the same shape as "a 12-second timeout does not stop the node"). Three of the four failed checks follow from that one death (counts, the restarted node's resync, the node it served frozen at 502). The fix on the line, one rule: the poll in 250 ms steps returning the moment shutdown is set, with a test that a shutdown returns within a second (the 10 s loop the known-failed shape); the exec suite on build-2, the fifth commit and its build about 12:45Z, its digest and ten-minute gates about 12:50 to 13:05Z, inside 14:30Z. b7cc37e7 is NOT the pin. The node-side re-pin for sub-version 2 (byte 7) once the hash lane's commit lands: the beside-the-fork igneum-pow copy archived from the commit, the two pinned ids moved in the kaspa-pow vector test (sub-version-2's epoch-0 id must-equal; sub-version-1's joins c120d7963abdcd96 as must-differ), CLASS_SIGNAL and tests for byte 7, the daemon's window line: about 20 minutes of edits plus one kaspa-pow suite run on build-2 (about 2 minutes). THE FIFTH COMMIT c4459193 on release-0.3.20-node (b7cc37e7's child, the watchdog poll returning on shutdown; the diff is the poll loop in rpc.rs alone), pairing igneum-pow 8c728ca3; its build on build-1 started 12:30:13Z, sha256 and string to follow. Line A, the shutdown test: rpc::watchdog_tests::a_shutdown_returns_within_a_second_whatever_the_poll green on build-2 at 12:29Z in the exec suite's 31 passed, beside the two other watchdog tests; its known-failed shape the old loop's 10 s stop. Line B, the kept-datadir start: b7cc37e7's fleet read carries to c4459193 since the store code is byte-identical between the two commits; the fleet re-reads on the c4459193 binary only if the shipper's rule wants the string on that line too. The digest gate and the ten-minute mixed-version gate on c4459193's own binary follow its build. THE SHIPPER'S CARRY RULING (14:1x UK): b7cc37e7's kept-datadir read stands as evidence that the store fix is right (the store code byte-identical) but is not the gate line for the pin, because the rule reads the binary, not the diff, and the binary changed (rpc.rs); the gate line is the kept read on c4459193's own binary with its string, which the fleet's canary already runs on c18-1 (wipe, then the kept read, then the restart) before the canary's restart step, at no extra cost; no re-read on p12-vast. THE PIN IS c4459193 pairing 8c728ca3 (object byte 5, sub-version 1); sub-version 2 (byte 7) is 0.3.21's, not 0.3.20's. The shipper's reading of main's F8 ruling: 0.3.20 ships object 5 as it stands because the live floor otherwise flips every node to the OLD stream on 13 October, and the 16:00 BST report tells Josh the floor move is now RECOMMENDED rather than optional, so the chain never flips to a stream that fails the 1.2x gate before sub-version 2 lands. THE FLEET'S CLOCK ON c4459193 (the fleet lane, 12:5x UTC): the kept read on pool-1's 0.3.17 datadir copy and the restart (the old process's stop time on the line) run on c18-1 before the wipe, a few minutes each, so both lines land before 14:30Z; the wipe canary (IBD from the pruning-point proof, 98 minutes on this pod class) starts when c18-1 is free of the 0.3.20 cases (about 13:00Z) and the binary is in hand, so its synced line lands about 14:40Z at the earliest, PAST the 14:30Z checkpoint; the 12 GB settled-claim line: c4459193 starts on p12-vast's kept copy of pool-1's datadir beside the 6a3432a3 IBD node on alternate ports the moment the binary lands, catches up from 129,398 blocks (15 to 20 minutes) and the 12 GB prover claims against it, the line on c4459193 itself. The binary not yet in the fleet's hand (build-1 building since 12:30:13Z); a wait armed on the sha and string, a report by 13:10Z if nothing. THE SHIPPER'S CALL ON THE CLOCK (14:2x UK): the wipe canary is the decisive read by the deploy rule; the pin never cuts without it and b7cc37e7's lineage does not stand in (the binary changed). The fleet rents a second one-shot pod of c18-1's class now and starts the wipe canary on c4459193's binary the moment the build lands, synced line about 14:15Z (15:15 BST), inside the checkpoint; c18-1 keeps the 0.3.20 cases and the pool window. If the wipe line slips past 15:30 BST the pin holds to it and main hears the clock (a slip is a report, not a cut). The set: the node lane's digest and mixed-version gates (12:50 to 13:05Z), the kept read and restart on the new pod, the wipe line on the new pod, the 12 GB settled-claim line on p12-vast. c4459193's BINARY IN THE FLEET'S HAND (12:34:54Z from build-1): igneumd sha256 45be9b02d1b002f5486d0f0108571c3b6042094113ad9da6f3d3d9ffc0072bba with the string c4459193 read back from the file, igneum-miner c7cfc40bc8b0e357. The wipe pod c19-1 (RunPod wpuke4tfu0vr49, RTX 3070 community, c18-1's class, USD 0.13/h, rented 12:37:03Z, one-shot; the day at USD 124 of work plus the 248 leak, 37 percent of the ceiling): the canary form (wipe, IBD from the pruning-point proof, synced, ten minutes mining with the exec poller, the hub read, the restart read) starts the moment the pod answers ssh; the kept read on pool-1's 0.3.17 copy armed behind its synced line on the same pod; the IBD start stamp its own line; synced about 14:20Z if the pod answers by 12:42Z (ten minutes inside the checkpoint), a slip reported the moment a poll shows it. CASES END on c18-1 at 12:37:18Z rc 0 (the relay and poison lines to the shipper); c18-1 and the two case pods destroyed by the run; the ten-member pool window rented its ten at 12:37:36Z. The 12 GB settled-claim line on p12-vast runs against a c4459193 node on the pod's kept copy, up since 12:36:35Z first-try, catching up. THE WIPE CANARY ON c19-1 STARTED: IBD at 12:38:55Z on c4459193 (sha256 45be9b02... asserted on the Mac before the put; the node's own line igneumd/2.1.0-c4459193 and digest eada4bda8aa8368c read back on the pod; a wiped datadir; IBD from the pruning-point proof with 4 peers at 12:39:26Z); synced about 14:17Z by the 98-minute class, thirteen minutes inside the checkpoint; the mining read, hub read, restart and kept read follow on the same pod, each its own line. c4459193's GATE LINES (the node lane): the binary built on build-1 at 12:33Z (1 m 07 s), sha256 45be9b02d1b002f5, the string read back from the binary (strings, two hits) and the worktree HEAD; igneum-miner beside it at /srv/builds/igneum-wt-ca3-v4-node/vendor/igneum-node-0318-release/target/release/. THE DIGEST GATE 12:33:27Z to 12:35:05Z SUMMARY PASS: the thirteen-field object a89be8a7 on both binaries, n0 peering n1 and n2 and the old node peering the new (the compat case); the sixteen-field object db9a85f9, n3 with no peer and the refusal line "consensus params digest mismatch, local db9a… remote a89b…" (the refusal case); the live file's digest on this binary eada4bda, as 5899f603 reads it. THE MIXED-VERSION GATE 12:35:26Z to 12:45:39Z SUMMARY PASS, beside the 5899f603 pair: one digest b0afb2ee on all five nodes; the 5899f603 hub accepted every block the c4459193 node mined, 215 new and 314 old, 0 rejected, no reject line in any log; header versions plain 2 on the thirteen-field file; counts equal on all five at 312 after mining, 441 after the clean join through the old hub and the clean join served by the new node, 529 at the end; the restart step passed: the new node restarted at 12:43:08Z on its own datadir and resynced to 529 with the others (where b7cc37e7 died on the database lock); no panic in any node log; every check green. The node side of the set is complete; the fleet's wipe, kept read, restart and settled-claim lines remain. A SLIP (the fleet lane, 12:5x UTC): the 0.3.20 cases rerun on c4459193 lands about 15:10Z, not 14:20Z: its target c20-1 catches up from pool-1's kept 1026 copy, 22,000 blocks behind a tip the line reaches headers-first (headers 137,405, blocks 129,398 at 12:50Z; the morning's poison pod on the same copy took 50 minutes before its blocks moved), synced about 13:50Z, the 79-minute form after; no faster path exists on a kept copy. The wipe canary on c19-1 holds its clock (29 percent of the headers at 12:47Z on dc141409's curve): synced about 14:17Z, the mining and hub reads to about 14:30Z, the restart and the kept read after; the 12 GB settled-claim line on p12-vast about 14:00 to 14:10Z. The kept read on the pinned binary is already in hand from c20-1's own start at 12:45:46Z (the rewrite line, no panic, sha 45be9b02 and the string read back), with the shipper. MAIN'S RULING WITH THE SHIPPER (14:5x UK): the cases rerun on the pin's own binary gates the cut; the cut word about 15:15Z (16:15 UK) on CASES END, the publish on green right after, the sweep from then with PC 1 first; 5899f603 the fallback until the word. The shipper's reason: the cases are a named gate and the morning's run was on dc141409 (the diff from dc141409 to c4459193 touches the class signal byte, in the cases' territory); the 16:00 BST report carries the clock and the full cut set; everything else staged so the publish is one step at that moment; nothing changes on the pods. THE INTEROP FACT stands from the void run: the 5899f603 hub accepted 235 object-byte-5 blocks from the 8097d600 node with 0 rejected, one digest on all five nodes on the live sixteen-field file. The gates: the digest test and the kaspa-pow vector test (the amended devnet epoch-0 id 1a4230699a6b9c60 must equal, c120d7963abdcd96 must differ, the v3 control unchanged) on the box; the mixed-version Devnet 2 gate (the amended 0.3.20 node beside a 5899f603 node for ten minutes on the live file without the v4 fields) after the Mac build; the fresh-join canary the 0.3.20 cut's | +| JOSH'S WORD (15:2x UK, 7 October): OPTION A, "do this but limit the testing, get it pushed" | the class v4 amendment: a load's source drawn only from registers whose last writer injects or is a rotate (the v5 rule applied now), a new program stream and vectors, the seven gate packs re-exported, the amended class with its own generator stamp; rides 0.3.20, the feature node (release-0.3.20-node = dc141409; 0.3.19 is an app-only cut with nothing of ours), on the shipper's line. The rollout arithmetic for the flip clock (the shipper): the standing fleet's one-box-at-a-time rollout took 32 minutes for 14 boxes (04:56 to 05:28Z, 7 October), the hands and the seed about 3 minutes after the miners, the Mac and the PCs within minutes of the publish; every 0.3.20 worker must accept the amended stamp before any flip. Owners: the hash lane (ca3-v4-amend: the generator, the vectors, the packs, the pairing on the box, one G1 run on PC 2, the ledger row), the node lane (release-0.3.20-node: the stamp agreed with the hash lane, the split-protection mechanism and the earliest flip time, the digest test, the mixed-version Devnet 2 gate), the attack-pass lane (the F8 census at 2^24 on the new stream, the gate 1.2x of the window model over 64 seeds), the shipper (the cut, the rollout order that sets the earliest flip). Testing limited to what prevents a split and proves the fix; G2, G3, the ladder re-measure and the rest of G4 to G6 OWED. THE STAMP agreed (the node and hash lanes, 7 October afternoon): generator 4 with sub-version 1 inside igneum-pow's id function, so the amended v4's program id for a seed differs from the old v4's (the old devnet epoch-0 id c120d7963abdcd96 pinned as the must-differ vector in kaspa-pow's test). SPLIT PROTECTION SETTLED (the node lane, plan section 6.6, ca3-v4-node fa5bc9e6; the node side on release-0.3.20-node): a fresh object byte. CLASS_SIGNAL_V4 is 5; the amended binary stamps 5 and the tally counts a block only at byte 5 or above; object 4 was stamped only by the unpublished dc141409 canary, so no published block carries it and a byte-4 block never counts; a node of the 6 October stream that sees byte 5 counts it as v4 (its rule is at least 4), flips to its own stream at the same epoch and forks ALONE (its blocks fail the amended id check, generator 4 sub-version 1 inside every id; the amended blocks fail its own), ours to upgrade in the sweep; object 6 is class v5's; the two holds already in the rule keep the window shut until every node is on 0.3.20 (a node stamps and tallies only with both v4 fields in its file; the fields publish only after the one-sweep rollout); a lagging worker refuses the amended pack at packcheck and mines nothing after the flip, costing that box, never the chain; no extra window hold: seven full day-windows are the hold. THE EARLIEST FLIP (approximate, measured 09:40Z: DAA 270,659, 1.095 DAA/s over 25 hours, 1.165 over 4; epoch 3,600, lead 600; seven windows 604,800 DAA wholly after the sweep's end D_s = T + about 40 minutes; the flip epoch the first e with 3600 e - 600 >= D_s + 604,800): T + 6 days 10 hours to T + 6 days 11 hours UK; for a publish at 12:00 UK on 7 October, 13 October between 22:20 and 23:10 UK (about 13:00 UK if the 4-hour rate holds). The floor as it stands (831,600, about 13 October 09:00 UK) would fire before any seven-window signal from a publish today completes, so it moves by the 0.3.16 rule to the publish DAA + 604,800 rounded up to the epoch boundary (882,000 for a 12:00 UK publish), firing about 30 minutes before the earliest signal flip: either way about 6 days 10 hours after the publish, never before every node has had the sweep plus a week. THE CLOCK (the node lane, 11:3x UK, after a Mac reboot moved its runs to the box): the 0.3.20 node line (dc141409 plus the proof archive aea0ca5c plus the amended v4 at object byte 5, igneum-pow at the hash lane's a0aaca92 beside the fork on the box) tested on the box, committed on release-0.3.20-node, pushed to the mirror and origin, igneumd and igneum-miner built, the tip to the shipper: about 12:00 UK; the mixed-version Devnet 2 gate (node-compat.mjs on the box, the amended node beside the 5899f603 pair for ten minutes) and the digest test (digest-compat.mjs): about 12:45 UK; the object-byte pin 5 unless the v5 lane answers both lanes with another assignment (v5 at 6 proposed). THE HASH SIDE on ca3-v4-amend (tip 8c728ca3, read from the branch 14:0x UK; the hash lane's own report pending): 1748fd1d the PC 2 G1-only playbook; e1f48d63 the fud-ledger entry AP-F8-1 (the fault, Josh's ruling, the amendment, the split protection, the owed tests); d8859522 the G1 line (the eight fingerprints equal on the RTX 5090, self-test PASS) and the node lane's signal byte 5; 4aa0c665 the v4 unit test following the amendment; 965d9e96 igneum-pow taken from release-0.3.20's 3f1652bf (the ladder's chain_program_shadow with the reps argument, never on master) with the amendment re-applied, the seven packs re-exporting byte-identical; 8c728ca3 the source rule keyed on the class with the shadow's pass count set aside, so every ladder rung draws under it (the fork's ladder test). The shipper took this igneum-pow tree into release-0.3.20 (00249643, byte-equal); nothing after 8c728ca3 touches igneum-pow. THE VECTORS AND THE PACKS (read from the branch and its ledger entry, 14:1x UK): the seven amended v4 packs (v4-devnet-epoch0, v4-era-0 to 5) carry generator 4, sub-version 1, one program id 1a4230699a6b9c60 (the 2.0 one-id-per-seed rule across the eras; the old c120d7963abdcd96 pinned as must-differ); the v3 control mx8-devnet-epoch0 untouched (73bcbfe8ccf988f1, fingerprint 90f794dd556f7a3b); the seven 2^24 fingerprints, Metal equal to Apple OpenCL: 867dbc45cfb36b4d, 2146ecacc8c75a8e, fe52602393f6d3d4, 3b206471a13912b4, c3f03c4a5d7333aa, f1dfd7209f15bb97, 8c194da64fadf31d; the zip of the eight packs sha256 889ec99976d2728b4b5035bfa476032e5b6a13b928968fc45236d5f25084aa39; the per-pack vectors.json sha256 prefixes 756301bf (devnet epoch 0), 1b5f4568, d430cadc, 1a1b21d8, 460fff9e, 4a85d49d, f83a1196 (eras 0 to 5). G1 on the RTX 5090 (PC 2 job run-ca3-v4-amend-g1-pc2-20261007, 09:41:07 to 09:41:28Z, exit 0, the installed worker): every fingerprint equal to the Mac's (the seven above and the control), NVRTC 188 to 332 ms per pack, the 1 GiB build 38 to 49 ms. hash-gates.md's older table still lists the pre-amendment fingerprints (f410c731... and the eras), which no longer apply to the amended packs; the ledger entry is the record. THE FIRST GREEN (11:31 UK, the box): the kaspa-pow suite on release-0.3.20-node (dc141409 plus the proof archive aea0ca5c plus the object-5 change) against the hash lane's igneum-pow 8c728ca3: 17 passed, 0 failed; the amended devnet epoch-0 id 1a4230699a6b9c60 pinned equal and c120d7963abdcd96 differing, the ladder's rung test green under the rekeyed rule, the v3 control unchanged; the consensus-core and exec RPC suites follow, then the node line (commit, push, box build, the tip to the shipper), then the digest and mixed-version gates. CLOCK RE-CUT (the node lane, 13:0x UK): the node line now carries, beside the object-5 change and the vector test, the lane's 0.3.20 fixes from the day (isSynced from the hook's stamp, the lazy template snapshot, the weight-table cache, the submit path returning after the block task, the watchdog, the RPC fields), about 13:30 UK if the box suites are green; the shipper's fresh-join canary 60 to 100 minutes after the cut; PC 1 as its first machine about 16:00 UK at the earliest, approximate until the shipper names the cut; the earliest flip about 6 days 10 hours after the publish. BUILD-2 LINES (12:28 to 12:33 UK): consensus-core 123 passed (the 60x file test green with the ladder window and activation pinned), the behind test green, kaspa-pow 17 passed (the amended vectors, earlier on build-1), the exec RPC suite green, the flows and rpc-service checks green with the submit-path change; the 24-requester latency test's first run tripped an unrelated flapping-fork double insert (24 equal forks from one parent; the test now builds on the sink as a real miner does; the double insert owed to a small fork harness before it is called a bug); THE NODE LINE COMMITTED (13:1x UK): release-0.3.20-node = 8097d600 (dc141409 + the proof archive aea0ca5c + one commit) on the mirror, pairing igneum-pow 8c728ca3, the hash with the shipper; in it the amended class v4 as object 5 (CLASS_SIGNAL_V4 = 5, byte 4 never counts, the kaspa-pow vector test pinning 1a4230699a6b9c60 equal and c120d7963abdcd96 differing, the daemon's window line naming object 5 and sub-version 1) beside the day's fixes (isSynced from the hook's stamp, the weight-table cache, the lazy snapshot, the submit path, the 100 ms template wait); the suites green on build-2 (consensus-core 123, the exec RPC suite, the four finality tests including 24 requesters under 200 ms: the worst template 100 ms, the worst submit 102 ms) and kaspa-pow 17 on build-1. Next: igneumd and igneum-miner building from 8097d600 on build-1, then the two gate lines (the mixed-version Devnet 2 gate: the 8097d600 node mining beside the 5899f603 pair for ten minutes on the live file without the v4 fields, the old node accepting every block; the digest test: the thirteen-field file b18ed271 unchanged, the sixteen-field object re-read on the 8097d600 binary), expected about 13:30 UK; the shipper picks the cut point. THE DATE FIXED (the node lane, from the hub's live file, 13:3x UK): publish 2 of 6 October (22:49:45Z, digest eada4bda) already put BOTH v4 fields on the live devnet (floor 831,600, window 86,400), so the 0.3.17 fleet has stamped object byte 4 since 7 October 00:2x UK and the floor is live at about 13 October 09:00 UK, before any seven-window signal completes; a 0.3.17 node left on that file flips to the OLD v4 stream at epoch 231 whatever anyone signals, a 0.3.20 node to the amended stream at the same epoch, and the two never share an id, so each straggler forks alone there. REQUIREMENT for the 0.3.20 publish (with the shipper and main): a new file with the floor at the publish DAA + 604,800 rounded up (about 882,000 for a publish today), the digest moving, the one-sweep rollout replacing every 0.3.17 node before 13 October 09:00 UK; any node that misses the sweep is alone then; the earliest flip after that about 6 days 10 hours past the publish; plan section 6.6 amended today. IN THE 0.3.20 PLAN (the shipper, 13:4x UK): both requirements; the node pin by main's rule is the node lane's second commit (the claim floor, the listener watchdog, the claim RPCs, on top of 8097d600) if its suites, both gates and the fleet's 12 GB prover line are green by 15:30 UK, else 8097d600; igneum-pow 8c728ca3 either way; the digest read on whichever binary pins. THE LINE AT 13:5x UK: three commits on release-0.3.20-node, 8097d600 (the object-5 amended class v4 and the day's fixes), 6b94c823 (test-only: the stale PC 1 test from 500ddd66 inverted by the isSynced ruling; the FALLBACK pin, code byte-identical to 8097d600, so the module reads green whole) and 6a3432a3 (the app lane's key methods, the observer's claims, the settled claim floor, the listener watchdog); suites on build-2 on 6a3432a3's code (the whole finality module 25, the exec suite 29 with the watchdog test, the kaspad, flows and rpc-service checks; consensus-core 123 and kaspa-pow 17 earlier); the cut 6a3432a3 if its gates and the fleet's 12 GB settled-claim line are green by 15:30 UK, else 6b94c823; both binaries building on build-1, the two gates (the digest gate, then the ten-minute mixed-version gate beside the 5899f603 pair) on the 8097d600 build, lines about 14:05 UK. GATE NEWS (13:53 UK): on 6a3432a3's own digest gate the listener watchdog counted a bind failure (the four harness nodes share one exec JSON-RPC port) as a listener death and exited three of four nodes at 20 s, where 0.3.17 and 8097d600 only warn and live without the exec RPC; the digest facts came out first and stand (the thirteen-field file a89be8a7 on both binaries, the compat case; the sixteen-field object db9a85f9 refused with the mismatch line, the refusal case); the ten-minute gate on 6a3432a3 stopped as void for the same cause. The fix: a bind failure is a retry every poll, one line a minute, no death counted and never an exit, with a second watchdog test whose known-failed shape is the old rule's exit on a held port; the third commit and its build about 14:15 UK, its gates about 14:35 UK; the fallback 6b94c823's gates on build-1 on their own binary (no watchdog there), lines about 14:20 UK; ledger row N12 for the bind-failure class. A ROLL BLOCKER on every kept datadir (the node lane, 14:1x UK, ledger N13): the fleet started 6a3432a3 on a kept 0.3.17 datadir (pool-1's copy) and it died at start (virtual_state.rs:250, DeserializationError(UnexpectedEof)); the cause 10db4b61 on the 0.3.16 feature line added `silent: bool` to BlockRewardData under serde(default), which bincode ignores, so every build from 10db4b61 on (dc141409, 8097d600, 6b94c823, 6a3432a3, 09124180) reads a 0.3.17 node's virtual-state row short; no canary saw it because every canary wiped, and a one-box roll keeps datadirs, so it blocks the roll on every standing box, the hands and the hub whatever the pin. The fix on the line: the store reads the current layout first and on a deserialization error decodes the row as a v1 mirror, converts with silent false and rewrites it under the same key, with the known-failed test first; the fourth commit and build about 14:40 UK, the fleet's kept-datadir start on the fixed binary about 14:50 UK, its gates after. THE RULE IT ADDS for every node cut from now: a kept-datadir restart gate on a standing box's datadir copy beside the wiped canary. THE CANDIDATE PIN (14:2x UK): b7cc37e7 (8097d600, 6b94c823, 6a3432a3, 09124180, b7cc37e7; igneum-pow 8c728ca3): the N13 fix with its test green on build-2 at 14:04 UK and the kaspad check green, the build on build-1; the fallback 6b94c823 is no longer a pin for the one-box roll (it dies on a kept datadir like every build since 10db4b61): if b7cc37e7's gates are not green by 15:30 UK the honest fallback is 0.3.17's 5899f603 staying live. In flight on build-1: the earlier commits' gates, then b7cc37e7's own digest and ten-minute mixed-version gates on its binary with the read-back, lines about 15:05 UK; on the fleet the kept-datadir start on b7cc37e7 about 14:50 UK and the 12 GB settled-claim line 14:50 to 15:00 UK. Plan section 6.6 amended with the hard date (ca3-v4-node 9d763edd, merged to master); N12 and N13 on the ledger. THE GATES ON THE FALLBACK'S OWN BINARY (6b94c823, sha b1b7d47b, 13:56 to 14:08 UK; code byte-identical to 8097d600, so the amendment's node side): the digest gate, the thirteen-field file a89be8a7 on both binaries (the compat case, n0 peering n1 and n2) and the sixteen-field object db9a85f9 refused with the mismatch line (the refusal case); the mixed-version gate, ten minutes, one digest b0afb2ee on all five nodes, the 5899f603 hub accepting every block the amended node mined (146 new, 246 old, 0 rejected), plain header version 2 on the thirteen-field file, counts equal on all five through the two clean joins and the restart. Two FAILED checks, both the harness's own and fixed (36d3efdc): a refused peer's count read 1 with the reconnect in flight (now the minimum of five), and six address-in-use panics in the two old nodes because the second gate reused the first's ports the second they were sent SIGTERM (a 20 s gap now). CLOCK CORRECTION (the node lane, 12:12Z = 13:12 BST): every "UK" stamp it sent today was the box's CEST, an hour fast of BST; its lines read UTC from now. Restated: b7cc37e7's build about 12:15Z, its digest and mixed-version gates on that binary with the sha and string about 12:32Z (13:32 BST), the fleet's kept-datadir start on it about 12:25Z, its 12 GB settled-claim line 12:50 to 13:00Z; the shipper's checkpoint 14:30Z (15:30 BST), two hours of room. The 13 October date stands (derived from UTC DAA rates): the floor 831,600 about 08:00Z, 09:00 BST. b7cc37e7'S OWN LINES (binary sha256 bc28331abf21f4d5, the string read back on build-1 and on the fleet's pod): the digest gate 12:14:39Z to 12:16:18Z SUMMARY PASS (thirteen fields a89be8a7 on both binaries with the peers as the gate wants them; the sixteen-field object db9a85f9 refused with the line and no peer; the live file's digest eada4bda on the binary, unmoved); the kept-datadir start on the fleet's copy of pool-1's 0.3.17 datadir: the first start 12:17:12Z reads the v1 row through the mirror and rewrites it ("1 mergeset rewards"), the finality blob converts (1,747 locks), the node comes up on its ports with no panic; the second start 12:18:53Z reads first-try with no rewrite line and no panic; 6a3432a3's death on the same copy is the known-failed shape. The ten-minute mixed-version gate beside the 5899f603 pair runs on the same binary since 12:16:39Z, its line about 12:28Z; then the only line outstanding for the shipper's 14:30Z rule is the fleet's 12 GB settled-claim line, 12:50 to 13:00Z. AP-F8-1 RESIDUAL CLASS ON THE AMENDED STREAM (attack-pass lane 12:18Z on igneum-pow 8c728ca3, sub-version 1). F9 over 1,000,000 seeds: programs flagged (hot share at least 1 percent or 7 constant address bits) 1,871 (0.19 percent) against 11,696 (1.17 percent) unamended; worst hot share 9.66 percent against 17.3; mean 0.011 against 0.063 percent; 84 percent of the flagged programs and the whole or-saturation tail gone. F8 at 30 of 64 seeds: nine over 1.2x of the window model (p31 29.3x, p11 5.5x, p19 3.3x, p6 3.1x, p23 2.0x, the rest 1.3x to 1.6x); the 64-seed 1.2x gate is heading to FAIL on sub-version 1. Mechanism, confirmed on the two worst seeds: an all-ones load source (image 0x0ca59e4c under the era map) delivered through a writer the source rule counts as entropy-keeping, a rotate (rotl and rotr map all-ones to itself) or a load whose own source was saturated, with the saturation made one or more writes upstream by or. The rule looks one writer back; it must look through saturation-preserving writers or test the source's values. The ceiling has not moved: rule (c)'s 120-of-128 floor still caps any program at one saturated site, 6.25 percent of reads, a chip edge of at most 1.067x, and the residual (worst seed two sites at 0.53 and 0.56) sits inside it. THE SENTENCE "no lossy-sourced load by construction" IS HELD: it goes in no plan row and no ledger entry as true; sub-version 1 removes the or-source class and bounds the rest. MAIN'S RULING (13:2x UK): 0.3.20 ships object byte 5 on sub-version 1 as it stands, strictly better than the old stream the live floor flips to on 13 October; the fix is sub-version 2 on ca3-v4-amend (object byte 6 or whatever the v5 alignment leaves free) with both fixes: (F1) the static rule made transitive (rotates do not keep entropy; a load keeps entropy only if its own source did; one draw change, no attempts lost) and (F2) the dynamic source check (saturated load SOURCE values counted per site over the 64 units' 16,384 evaluations, rejected above 163 of 16,384, the same 1 percent the final-value rule uses; costs attempts on about 0.2 percent of seeds; rides with F1 because an or-written source is all-ones only (3/4)^32 of the time). Gate before sub-version 2 is proposed, run by the attack-pass lane and not by the hash lane: the full 64-seed census under 1.2x on every seed and the hot-set census. Hash lane's estimate about an hour its side (implement, re-export seven packs, vectors, crate suite, pairing, one G1 on PC 2) plus the node lane's vector re-pin and the attack-pass re-gate. The flip floor for sub-version 1 is expected to move (Josh's word) so the chain never flips to a stream that fails this gate. Also recorded: the crate suite at 8c728ca3 100 of 100 on the box (rc 0, 77 s); the pairing against the fork at dc141409 compiled and ran 15 of 16, the one failure the fork's own pre-amendment assertion (base equals v3's, igneum.rs:972), which 8097d600 on the release-0.3.20-node line turns into assert_ne; the pairing re-runs at b7cc37e7, its line to follow. CORRECTION (the attack-pass lane's own retraction, 13:3x UK): the F9 hot-set figures above (1,871 of 1,000,000, worst 9.66 percent, 84 percent removed, the two or-then-rotate listings) are WITHDRAWN: F9's harness draws through candidate_class with its own era class, outside candidate_from_words_class where the source rule lives, so it measured the old stream (the 8c728ca3 binary prints the identical program to the sub-version-0 binary for its worst seed). F8's 64-seed census on the chain path (pairing verified on 1a4230699a6b9c60) is the valid re-gate and STANDS: at 30 of 64 seeds, nine over 1.2x of the window model (p31 29.3x, p11 5.5x, p19 3.3x, p6 3.1x, p23 2.0x, p4 1.6x, p10 1.5x, p26 1.3x, p25 1.3x). The residual mechanism on the amended stream: a load-after-load chain (a saturated source reads one fixed word, which is the next load's address), admitted because a load injects; and the rotate-preserves-saturation path (generator.rs sets entropy_kept true for a rotate whatever it rotated), correct in code and a second admitted path if it occurs on the chain stream. Sub-version 2 must close both: dataflow freshness per register (a load fresh only if its source was fresh; add, sub, xor, mad, shfl fresh if either operand was; rotates only if the operand was; or, mul, mulhi never) plus the (c') count of saturated load sources per site as the backstop. The STOP holds on F8's evidence alone; the options and the 1.067x ceiling are unchanged. The sentence "no lossy-sourced load by construction" waits on the sub-version 2 census verdict and stays out of every public text until then. SUB-VERSION 2 IN BUILD (the hash lane, ca3-v4-amend, on the coordinator's direction, 13:4x UK): F1 (dataflow freshness per register, keyed on the class v4 shape on every draw path, era or not, so the candidate_class path and the chain path draw one stream) plus F2 (the (c') count of saturated load source values per site over the 64 units' 16,384 evaluations, rejected above 163, keyed on the same shape so v2 and v3 verdicts do not move); PROGRAM_SUBVERSION_V4 = 2, new ids, the seven packs re-exported, recheck.rs with 1a4230699a6b9c60 and c120d7963abdcd96 as the must-differ pair. Clock (UTC): the commit on the branch by 13:30; the crate suite on box 2 and the pairing against b7cc37e7 by about 13:50 (the pairing's vector test fails on the fork's sub-version-1 pin until the node lane re-pins; the compile and the other 15 are the pairing evidence); the G1 job on PC 2 under --cards-off by about 14:10, lock permitting; then the attack-pass lane's full 64-seed census and hot-set census on the chain path. Two consequences stated in the commit: the rule on every draw path moves the no-era sh256xN ladder packs' stream (packs-ca3-shadow's seven 256-block packs re-export with new fingerprints; the measured rates stand as the old stream's), and the class v5 lane's pinned string-seed packs move when it merges sub-version 2, so it re-exports them then. 0.3.20's sub-version-1 packs, ids and fingerprints untouched. OBJECT BYTES SETTLED (main, 13:5x UK): byte 5 = class v4 sub-version 1 (0.3.20), byte 6 = class v5 (pinned: class-v5 16afd0a0, class-v5-node 699db5a2, the flip case passed on 6,6,6; the v5 lane stopped), byte 7 = class v4 sub-version 2; the node and hash lanes told. b7cc37e7's MIXED-VERSION GATE: FAIL, the binary not the harness (12:16:39Z to 12:27:21Z, sha256 bc28331abf21f4d5, the string read back). Before the restart step everything held: one digest b0afb2ee on all five nodes, 268 new and 392 old blocks accepted, 0 rejected, header versions plain 2, counts equal on all five at 324 and 502 through both clean joins. At the new node's restart (12:24:19Z) it died at once on its own datadir ("IO error: While lock file: .../datadir/meta/LOCK: Resource temporarily unavailable", conn_builder.rs:167): the previous process was still shutting down, because the listener watchdog added on 6a3432a3 sleeps its whole 10 s poll before checking shutdown, so every node on the line since then takes up to 10 s longer to stop than 0.3.17 (the fleet saw the same shape as "a 12-second timeout does not stop the node"). Three of the four failed checks follow from that one death (counts, the restarted node's resync, the node it served frozen at 502). The fix on the line, one rule: the poll in 250 ms steps returning the moment shutdown is set, with a test that a shutdown returns within a second (the 10 s loop the known-failed shape); the exec suite on build-2, the fifth commit and its build about 12:45Z, its digest and ten-minute gates about 12:50 to 13:05Z, inside 14:30Z. b7cc37e7 is NOT the pin. The node-side re-pin for sub-version 2 (byte 7) once the hash lane's commit lands: the beside-the-fork igneum-pow copy archived from the commit, the two pinned ids moved in the kaspa-pow vector test (sub-version-2's epoch-0 id must-equal; sub-version-1's joins c120d7963abdcd96 as must-differ), CLASS_SIGNAL and tests for byte 7, the daemon's window line: about 20 minutes of edits plus one kaspa-pow suite run on build-2 (about 2 minutes). THE FIFTH COMMIT c4459193 on release-0.3.20-node (b7cc37e7's child, the watchdog poll returning on shutdown; the diff is the poll loop in rpc.rs alone), pairing igneum-pow 8c728ca3; its build on build-1 started 12:30:13Z, sha256 and string to follow. Line A, the shutdown test: rpc::watchdog_tests::a_shutdown_returns_within_a_second_whatever_the_poll green on build-2 at 12:29Z in the exec suite's 31 passed, beside the two other watchdog tests; its known-failed shape the old loop's 10 s stop. Line B, the kept-datadir start: b7cc37e7's fleet read carries to c4459193 since the store code is byte-identical between the two commits; the fleet re-reads on the c4459193 binary only if the shipper's rule wants the string on that line too. The digest gate and the ten-minute mixed-version gate on c4459193's own binary follow its build. THE SHIPPER'S CARRY RULING (14:1x UK): b7cc37e7's kept-datadir read stands as evidence that the store fix is right (the store code byte-identical) but is not the gate line for the pin, because the rule reads the binary, not the diff, and the binary changed (rpc.rs); the gate line is the kept read on c4459193's own binary with its string, which the fleet's canary already runs on c18-1 (wipe, then the kept read, then the restart) before the canary's restart step, at no extra cost; no re-read on p12-vast. THE PIN IS c4459193 pairing 8c728ca3 (object byte 5, sub-version 1); sub-version 2 (byte 7) is 0.3.21's, not 0.3.20's. The shipper's reading of main's F8 ruling: 0.3.20 ships object 5 as it stands because the live floor otherwise flips every node to the OLD stream on 13 October, and the 16:00 BST report tells Josh the floor move is now RECOMMENDED rather than optional, so the chain never flips to a stream that fails the 1.2x gate before sub-version 2 lands. THE FLEET'S CLOCK ON c4459193 (the fleet lane, 12:5x UTC): the kept read on pool-1's 0.3.17 datadir copy and the restart (the old process's stop time on the line) run on c18-1 before the wipe, a few minutes each, so both lines land before 14:30Z; the wipe canary (IBD from the pruning-point proof, 98 minutes on this pod class) starts when c18-1 is free of the 0.3.20 cases (about 13:00Z) and the binary is in hand, so its synced line lands about 14:40Z at the earliest, PAST the 14:30Z checkpoint; the 12 GB settled-claim line: c4459193 starts on p12-vast's kept copy of pool-1's datadir beside the 6a3432a3 IBD node on alternate ports the moment the binary lands, catches up from 129,398 blocks (15 to 20 minutes) and the 12 GB prover claims against it, the line on c4459193 itself. The binary not yet in the fleet's hand (build-1 building since 12:30:13Z); a wait armed on the sha and string, a report by 13:10Z if nothing. THE SHIPPER'S CALL ON THE CLOCK (14:2x UK): the wipe canary is the decisive read by the deploy rule; the pin never cuts without it and b7cc37e7's lineage does not stand in (the binary changed). The fleet rents a second one-shot pod of c18-1's class now and starts the wipe canary on c4459193's binary the moment the build lands, synced line about 14:15Z (15:15 BST), inside the checkpoint; c18-1 keeps the 0.3.20 cases and the pool window. If the wipe line slips past 15:30 BST the pin holds to it and main hears the clock (a slip is a report, not a cut). The set: the node lane's digest and mixed-version gates (12:50 to 13:05Z), the kept read and restart on the new pod, the wipe line on the new pod, the 12 GB settled-claim line on p12-vast. c4459193's BINARY IN THE FLEET'S HAND (12:34:54Z from build-1): igneumd sha256 45be9b02d1b002f5486d0f0108571c3b6042094113ad9da6f3d3d9ffc0072bba with the string c4459193 read back from the file, igneum-miner c7cfc40bc8b0e357. The wipe pod c19-1 (RunPod wpuke4tfu0vr49, RTX 3070 community, c18-1's class, USD 0.13/h, rented 12:37:03Z, one-shot; the day at USD 124 of work plus the 248 leak, 37 percent of the ceiling): the canary form (wipe, IBD from the pruning-point proof, synced, ten minutes mining with the exec poller, the hub read, the restart read) starts the moment the pod answers ssh; the kept read on pool-1's 0.3.17 copy armed behind its synced line on the same pod; the IBD start stamp its own line; synced about 14:20Z if the pod answers by 12:42Z (ten minutes inside the checkpoint), a slip reported the moment a poll shows it. CASES END on c18-1 at 12:37:18Z rc 0 (the relay and poison lines to the shipper); c18-1 and the two case pods destroyed by the run; the ten-member pool window rented its ten at 12:37:36Z. The 12 GB settled-claim line on p12-vast runs against a c4459193 node on the pod's kept copy, up since 12:36:35Z first-try, catching up. THE WIPE CANARY ON c19-1 STARTED: IBD at 12:38:55Z on c4459193 (sha256 45be9b02... asserted on the Mac before the put; the node's own line igneumd/2.1.0-c4459193 and digest eada4bda8aa8368c read back on the pod; a wiped datadir; IBD from the pruning-point proof with 4 peers at 12:39:26Z); synced about 14:17Z by the 98-minute class, thirteen minutes inside the checkpoint; the mining read, hub read, restart and kept read follow on the same pod, each its own line. c4459193's GATE LINES (the node lane): the binary built on build-1 at 12:33Z (1 m 07 s), sha256 45be9b02d1b002f5, the string read back from the binary (strings, two hits) and the worktree HEAD; igneum-miner beside it at /srv/builds/igneum-wt-ca3-v4-node/vendor/igneum-node-0318-release/target/release/. THE DIGEST GATE 12:33:27Z to 12:35:05Z SUMMARY PASS: the thirteen-field object a89be8a7 on both binaries, n0 peering n1 and n2 and the old node peering the new (the compat case); the sixteen-field object db9a85f9, n3 with no peer and the refusal line "consensus params digest mismatch, local db9a… remote a89b…" (the refusal case); the live file's digest on this binary eada4bda, as 5899f603 reads it. THE MIXED-VERSION GATE 12:35:26Z to 12:45:39Z SUMMARY PASS, beside the 5899f603 pair: one digest b0afb2ee on all five nodes; the 5899f603 hub accepted every block the c4459193 node mined, 215 new and 314 old, 0 rejected, no reject line in any log; header versions plain 2 on the thirteen-field file; counts equal on all five at 312 after mining, 441 after the clean join through the old hub and the clean join served by the new node, 529 at the end; the restart step passed: the new node restarted at 12:43:08Z on its own datadir and resynced to 529 with the others (where b7cc37e7 died on the database lock); no panic in any node log; every check green. The node side of the set is complete; the fleet's wipe, kept read, restart and settled-claim lines remain. A SLIP (the fleet lane, 12:5x UTC): the 0.3.20 cases rerun on c4459193 lands about 15:10Z, not 14:20Z: its target c20-1 catches up from pool-1's kept 1026 copy, 22,000 blocks behind a tip the line reaches headers-first (headers 137,405, blocks 129,398 at 12:50Z; the morning's poison pod on the same copy took 50 minutes before its blocks moved), synced about 13:50Z, the 79-minute form after; no faster path exists on a kept copy. The wipe canary on c19-1 holds its clock (29 percent of the headers at 12:47Z on dc141409's curve): synced about 14:17Z, the mining and hub reads to about 14:30Z, the restart and the kept read after; the 12 GB settled-claim line on p12-vast about 14:00 to 14:10Z. The kept read on the pinned binary is already in hand from c20-1's own start at 12:45:46Z (the rewrite line, no panic, sha 45be9b02 and the string read back), with the shipper. MAIN'S RULING WITH THE SHIPPER (14:5x UK): the cases rerun on the pin's own binary gates the cut; the cut word about 15:15Z (16:15 UK) on CASES END, the publish on green right after, the sweep from then with PC 1 first; 5899f603 the fallback until the word. The shipper's reason: the cases are a named gate and the morning's run was on dc141409 (the diff from dc141409 to c4459193 touches the class signal byte, in the cases' territory); the 16:00 BST report carries the clock and the full cut set; everything else staged so the publish is one step at that moment; nothing changes on the pods. AP-F8-1 RE-GATE VERDICT ON SUB-VERSION 1 (the attack-pass lane, census ended 12:55:55Z; igneum-pow 8c728ca3 paired with release-0.3.20-node 8097d600, pairing id 1a4230699a6b9c60 verified by the harness; 64 seeds p2 to p65 at 2^24 nonces each, chain path with era, window-model control, box 2; log /srv/builds/igneum-wt-attack-regate/attack-f8-regate/log/regate-census-64x2e24.log): FAIL the pass line, 53 of 64 PASS, 11 FAIL. + +| Seed | Ratio to the window model | Hottest item's predicted source | +|---|---|---| +| p31 | 29.27x | 0x74e2b8, 5,365,527 reads, site 4 r4 all-ones, last writer rotl at 3 | +| p11 | 5.45x | 0x0eec66, site 1 r7 all-ones, last writer or at 63 of the previous iteration | +| p45 | 4.55x | 0x400000, site 1 r4 zero, last writer mulhi at 59 | +| p19 | 3.32x | 0x400000, site 37 r5 zero, last writer load at 32 | +| p6 | 3.11x | 0x3bf40d, site 13 r0 all-ones, last writer load at 12 | +| p23 | 2.04x | site 16 r7 all-ones, last writer load at 14 | +| p4 | 1.57x | | +| p34 | 1.51x | 0x400000, site 23 r6 zero, last writer rotr at 12 | +| p10 | 1.50x | | +| p26 | 1.30x | 0x000000, site 10 r1 zero, last writer rotl at 2 | +| p25 | 1.28x | | +| the 53 passing | 0.9915x to 1.16x | no predicted source | + +Three residual classes, all a constant delivered through a writer the rule admits: (1) saturation or zero preserved through rotl, rotr, load or mad (p31, p6, p23, p26, p34); (2) zero from mulhi (p45) and zero preserved by rotates; (3) the iteration boundary, the rule's writer state starting fresh at instruction 0 so an or at 63 feeds a load at 1 (p11). Sub-version 2's dataflow-freshness rule closes all three IF the freshness is computed as a fixpoint over the loop (the state after instruction 63 feeds instruction 0 of the next iteration), with the dynamic (c') count on load sources as the backstop; sent to the hash lane. "No lossy-sourced load by construction" is not true of sub-version 1 and stays held. Chip consequence on sub-version 1 by the 1.4 arithmetic: the hot set is still one item at one site, under 1 percent of rate for a chip caching it, so the ship is safe on the rate side; the auditor's flag is what sub-version 2 removes. F9's hot-set harness cannot be the second re-gate (its metric counts the era's designed half and quarter windows as hot; its chain-path 8.3 percent on sub-version 1 is the window model, verified on its worst seed); F8's census is the single re-gate instrument, re-run on sub-version 2 within the hour of its commit. THE INTEROP FACT stands from the void run: the 5899f603 hub accepted 235 object-byte-5 blocks from the 8097d600 node with 0 rejected, one digest on all five nodes on the live sixteen-field file. The gates: the digest test and the kaspa-pow vector test (the amended devnet epoch-0 id 1a4230699a6b9c60 must equal, c120d7963abdcd96 must differ, the v3 control unchanged) on the box; the mixed-version Devnet 2 gate (the amended 0.3.20 node beside a 5899f603 node for ten minutes on the live file without the v4 fields) after the Mac build; the fresh-join canary the 0.3.20 cut's | | Main's rulings (7 October, morning) | no generator change to v4 on the live devnet; the record's null is the window model with numbers, sent by the hash lane to the attack-pass lane so AP-F8-1 re-gates against it; a fault beyond the model (a low-entropy source at site 15) stops at the coordinator with the two options priced (a 0.3.19 class amendment before the flip, or the flip held at the floor), nothing shipping without Josh's word; the tighter tail, an acceptance bound on the hot-set share, is a CLASS V5 item (sent to the v5 lane a6410f3b8abefb762 with the 64-seed census as its gate; the bound's number follows from the model) | ### AP-F4-1, the weak-day MUL draw (the attack-pass lane, 7 October, morning): PASS against v4, a class v5 rule From d267c2683d58be7e7c48922f84629715fcd02efa Mon Sep 17 00:00:00 2001 From: igneum-josh <337424239+igneum-josh@users.noreply.github.com> Date: Wed, 7 Oct 2026 14:03:19 +0100 Subject: [PATCH 13/19] Counter ASIC 3.0 status: sub-version 2 committed (07a809a7, id a788661687db4bb3, the fixpoint rule, seven fingerprints, packs sha256) Co-Authored-By: Claude Fable 5.1 --- docs/plans/counter-asic-3-status.md | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/docs/plans/counter-asic-3-status.md b/docs/plans/counter-asic-3-status.md index 349a75da0..2014050bd 100644 --- a/docs/plans/counter-asic-3-status.md +++ b/docs/plans/counter-asic-3-status.md @@ -355,7 +355,19 @@ Josh gave the go in advance for tonight: the shipper runs publish 1 on the 0.3.1 | p25 | 1.28x | | | the 53 passing | 0.9915x to 1.16x | no predicted source | -Three residual classes, all a constant delivered through a writer the rule admits: (1) saturation or zero preserved through rotl, rotr, load or mad (p31, p6, p23, p26, p34); (2) zero from mulhi (p45) and zero preserved by rotates; (3) the iteration boundary, the rule's writer state starting fresh at instruction 0 so an or at 63 feeds a load at 1 (p11). Sub-version 2's dataflow-freshness rule closes all three IF the freshness is computed as a fixpoint over the loop (the state after instruction 63 feeds instruction 0 of the next iteration), with the dynamic (c') count on load sources as the backstop; sent to the hash lane. "No lossy-sourced load by construction" is not true of sub-version 1 and stays held. Chip consequence on sub-version 1 by the 1.4 arithmetic: the hot set is still one item at one site, under 1 percent of rate for a chip caching it, so the ship is safe on the rate side; the auditor's flag is what sub-version 2 removes. F9's hot-set harness cannot be the second re-gate (its metric counts the era's designed half and quarter windows as hot; its chain-path 8.3 percent on sub-version 1 is the window model, verified on its worst seed); F8's census is the single re-gate instrument, re-run on sub-version 2 within the hour of its commit. THE INTEROP FACT stands from the void run: the 5899f603 hub accepted 235 object-byte-5 blocks from the 8097d600 node with 0 rejected, one digest on all five nodes on the live sixteen-field file. The gates: the digest test and the kaspa-pow vector test (the amended devnet epoch-0 id 1a4230699a6b9c60 must equal, c120d7963abdcd96 must differ, the v3 control unchanged) on the box; the mixed-version Devnet 2 gate (the amended 0.3.20 node beside a 5899f603 node for ten minutes on the live file without the v4 fields) after the Mac build; the fresh-join canary the 0.3.20 cut's | +Three residual classes, all a constant delivered through a writer the rule admits: (1) saturation or zero preserved through rotl, rotr, load or mad (p31, p6, p23, p26, p34); (2) zero from mulhi (p45) and zero preserved by rotates; (3) the iteration boundary, the rule's writer state starting fresh at instruction 0 so an or at 63 feeds a load at 1 (p11). Sub-version 2's dataflow-freshness rule closes all three IF the freshness is computed as a fixpoint over the loop (the state after instruction 63 feeds instruction 0 of the next iteration), with the dynamic (c') count on load sources as the backstop; sent to the hash lane. "No lossy-sourced load by construction" is not true of sub-version 1 and stays held. Chip consequence on sub-version 1 by the 1.4 arithmetic: the hot set is still one item at one site, under 1 percent of rate for a chip caching it, so the ship is safe on the rate side; the auditor's flag is what sub-version 2 removes. F9's hot-set harness cannot be the second re-gate (its metric counts the era's designed half and quarter windows as hot; its chain-path 8.3 percent on sub-version 1 is the window model, verified on its worst seed); F8's census is the single re-gate instrument, re-run on sub-version 2 within the hour of its commit. SUB-VERSION 2 COMMITTED: ca3-v4-amend 07a809a7, 13:01Z (origin and build), the string with the attack-pass lane. The loop fixpoint is in as rule (a') in accept.rs (the freshness run to its fixpoint over base then shadow block; every load's source fresh in the steady state, else the candidate rejected and the next attempt drawn; it closes the iteration boundary the draw's fallback cannot see); (c') counts zero and all-ones alike (v == 0 or v == MAX) per load site over the 16,384 evaluations, rejected at 164 or more; both and the draw rule keyed on the class v4 shape on every draw path, so v2 and v3 do not move; mulhi never fresh. Epoch-0 id a788661687db4bb3 (the devnet seed's attempt 0 rejected by the new rules, attempt 1 accepted); must-differ c120d7963abdcd96 and 1a4230699a6b9c60 pinned; object byte 7 in recheck.rs. The seven fingerprints (Metal = Apple OpenCL on the M5 Max, 13:01:17 to 13:01:49Z, the control 90f794dd556f7a3b unchanged): + +| Pack | Fingerprint | +|---|---| +| v4-devnet-epoch0 | e370fb2080b7dbb1 | +| era-0 | b7237555d31fc3cf | +| era-1 | b6b167fa15dfe2c9 | +| era-2 | 28bdf65eff33f2c4 | +| era-3 | e26d38c46f3f1b16 | +| era-4 | dd8fdf6ff4f59eed | +| era-5 | 8bf40f5cb858d835 | + +Packs zip (eight packs, packs-ca3-v4-sub2) sha256 69c36772cd79e44e2ddd589466d9c64a94a13c9e970e9f27bd76feabb9b4581b. The suite re-runs through master's build-remote on box 2 (the worktree's own script predates --box; the first run died on the flag), line to follow; G1 on PC 2 under --cards-off after it. The sub-version-2 pairing waits on the node lane's re-pin to a788661687db4bb3 and byte 7. For the record, sub-version 1's pairing: igneum-pow 8c728ca3 against b7cc37e7 (8097d600's assert_ne in) 17 passed, 0 failed, rc 0, 12:21Z. THE INTEROP FACT stands from the void run: the 5899f603 hub accepted 235 object-byte-5 blocks from the 8097d600 node with 0 rejected, one digest on all five nodes on the live sixteen-field file. The gates: the digest test and the kaspa-pow vector test (the amended devnet epoch-0 id 1a4230699a6b9c60 must equal, c120d7963abdcd96 must differ, the v3 control unchanged) on the box; the mixed-version Devnet 2 gate (the amended 0.3.20 node beside a 5899f603 node for ten minutes on the live file without the v4 fields) after the Mac build; the fresh-join canary the 0.3.20 cut's | | Main's rulings (7 October, morning) | no generator change to v4 on the live devnet; the record's null is the window model with numbers, sent by the hash lane to the attack-pass lane so AP-F8-1 re-gates against it; a fault beyond the model (a low-entropy source at site 15) stops at the coordinator with the two options priced (a 0.3.19 class amendment before the flip, or the flip held at the floor), nothing shipping without Josh's word; the tighter tail, an acceptance bound on the hot-set share, is a CLASS V5 item (sent to the v5 lane a6410f3b8abefb762 with the 64-seed census as its gate; the bound's number follows from the model) | ### AP-F4-1, the weak-day MUL draw (the attack-pass lane, 7 October, morning): PASS against v4, a class v5 rule From b28f808b67206374c55477589d14dcb302533fd2 Mon Sep 17 00:00:00 2001 From: igneum-josh <337424239+igneum-josh@users.noreply.github.com> Date: Wed, 7 Oct 2026 14:08:19 +0100 Subject: [PATCH 14/19] Build boxes: the class router is a preference with spill-over (a held or overloaded box hands the job to the other one); build-2 gets a third slot and every run there is bounded on its own 32-core band; the spill decision in the first route line, the slot label and the JSONL row Josh, 7 October 2026 15:02 UK: build-1 at load 139 / 114 / 90 with both slots held and a 1 h 40 min queue while build-2 read 4.5 with free slots, because the class router pinned each class to its box. Now lib.sh bs_route_spill reads the preferred box (free slots, 1-minute load) with one ssh and hands the job to the other box when the preferred one has no free slot or sits above load 64 and the other qualifies; neither qualifying queues on the class's own box. The decision travels as BR_ROUTE_* into the JSONL "route" object for the dashboard. build-2's slots file reads 3; everything on box 2 runs at nice 10 / 32 cores / -j 32, and a bounded run takes the band its slot owns so three never share a core. Self-test tools/ci/route-spill-check.sh (thirteen cases) in the gate. Co-Authored-By: Claude Fable 5.1 --- docs/plans/build-server.md | 20 ++++++++++++++ infra/build-server/lib.sh | 47 ++++++++++++++++++++++++++++++-- infra/build-server/provision.sh | 3 +- infra/build-server/remote-run.sh | 11 +++++++- tools/build-remote.sh | 20 +++++++++----- tools/ci/pre-push.sh | 1 + tools/ci/route-spill-check.sh | 37 +++++++++++++++++++++++++ 7 files changed, 128 insertions(+), 11 deletions(-) create mode 100755 tools/ci/route-spill-check.sh diff --git a/docs/plans/build-server.md b/docs/plans/build-server.md index d32940a3e..ee4f8d6c1 100644 --- a/docs/plans/build-server.md +++ b/docs/plans/build-server.md @@ -357,3 +357,23 @@ service. The layer tracks the repo branch `master`; until this work merges, the tree, so install writes a drop-in pinning `CAP_REPO_BRANCH=box-capacity` and removes it once `master` carries `infra/build-server/capacity/run.sh` (self-healing after the merge). `--no-start` enables without starting; `--smoke ` installs then runs one job's 10-minute smoke and prints the summary. + +## 7. Spill-over between the boxes (7 October 2026, 15:0x UK) + +Josh's reading at 15:02 UK: build-1 at load 139 / 114 / 90 with both slots held and a queue (the horizon lane waited 1 h 40 min) +while build-2 read 4.5 / 27 / 46 with both slots free. The class router (section 6) pinned each class to its box with no +spill-over. Now (lib.sh `bs_route_spill`, master from this commit): + +- The class is a PREFERENCE: a build, check or gate prefers box 1, a suite, bench or attack row box 2, a proving crate box 3. +- Before a run, the preferred box is read with one ssh (free slots of its slot count, 1-minute load). It takes the job when it + has a free slot and its load is at or under 64 (`BS_SPILL_LOAD`). Otherwise the other box (1 and 2 swap; 3 falls to 1) takes it + when THAT one qualifies; when neither does, the job queues on its own box. A box without a host file is never chosen; an + unreachable box reads as "down" and is skipped. +- The decision is the first route line of the run ("route: class suite prefers box 2; box 2 (free=0 slots=3 load1=70) is full or + over load 64: spilled to box 1 (free=1 slots=2 load1=20)"), the slot label carries "; spilled from box N", and the JSONL row + carries `"route": {"preferred", "box", "spilled", "reason"}` for the dashboard's job card. +- build-2 has THREE slots (its `slots` file reads 3 since 14:0x UK; provision.sh defaults a `-2` hostname to 3). Everything that + lands on box 2 runs at the bounded class, nice 10 on a 32-core band with -j 32, builds and gates included, so a suite beside + them keeps its number; since this commit a bounded run takes the band its slot owns (slot 0 the last 32 cores, slot 1 the 32 + below, slot 2 the 32 below that), so three bounded runs never share a core. A gate still takes its slot ahead of queued suites. +- `--box N` still pins. Self-test: tools/ci/route-spill-check.sh (thirteen cases through `BS_ROUTE_STATE_`, no ssh), in the gate. diff --git a/infra/build-server/lib.sh b/infra/build-server/lib.sh index bb754b796..70e9158ea 100755 --- a/infra/build-server/lib.sh +++ b/infra/build-server/lib.sh @@ -22,13 +22,55 @@ BS_HOST_FILE="${IGNEUM_BUILD_HOST_FILE:-$HOME/.config/igneum/build-server}" # # caller passes --box: gates, builds, checks, cross-builds, the workers, the hands and the observer stay on box 1; suites, benches and # the attack rows go to box 2; proving and aggregation CPU work, the second prover's shadow runner and the pool's fast-time NETWORK go # to box 3. A class whose box has no host file yet falls back to box 1, and the log line says so. No box mines, ever (README.md). +# Since 7 October 2026 15:xx UK the class is a preference with spill-over (bs_route_spill below): a full or overloaded box hands +# the job to the other one. bs_box_file() { case "${1:-1}" in 1) echo "$BS_HOST_FILE" ;; *) echo "${BS_HOST_FILE}-$1" ;; esac; } -bs_route() { # -> the box number, falling back to 1 +bs_route() { # -> the PREFERRED box number, falling back to 1 local want=1 case "$1" in suite|bench|attack) want=2 ;; prove|shadow|fasttime) want=3 ;; esac - if [ "$want" != 1 ] && [ ! -s "$(bs_box_file "$want")" ]; then bs_log "class $1 routes to box $want, which has no host file yet ($(bs_box_file "$want")): box 1"; want=1; fi + if [ "$want" != 1 ] && [ ! -s "$(bs_box_file "$want")" ]; then bs_log "class $1 prefers box $want, which has no host file yet ($(bs_box_file "$want")): box 1"; want=1; fi echo "$want" } +# Spill-over (Josh, 7 October 2026, 15:02 UK: build-1 at load 139 with a queue of 1 h 40 min while build-2 read 4.5 with both +# slots free). The class is a PREFERENCE, not a pin: a job goes to its class's box unless that box has no free slot or its 1-minute +# load is above BS_SPILL_LOAD (64), in which case it goes to the other box when THAT one has a free slot under the same load +# line; when neither qualifies it queues on its own box. The alternate of box 1 is box 2, of box 2 box 1, of box 3 box 1; a box +# without a host file is never chosen. The decision is one line on the Mac (bs_log) and travels to the box in BR_ROUTE_* for the +# JSONL row ("route": preferred, box, spilled, reason), so the dashboard shows it per job. A box is read with one ssh +# (bs_box_state: free slots of the slot count, load1); BS_ROUTE_STATE_ in the environment replaces the ssh for the self-test +# (tools/ci/route-spill-check.sh), "down" standing for an unreachable box. +BS_SPILL_LOAD="${BS_SPILL_LOAD:-64}" +bs_box_state() { # -> "free= slots= load1=" | "absent" | "down" + local b="$1" v f h + v=$(eval "printf '%s' \"\${BS_ROUTE_STATE_$b:-}\""); if [ -n "$v" ]; then printf '%s' "$v"; return 0; fi + f=$(bs_box_file "$b"); [ -s "$f" ] || { printf 'absent'; return 0; } + h="$(head -1 "$f" | tr -d '[:space:]')" + ssh "${BS_SSH_OPTS[@]}" -o ConnectTimeout=8 "$h" 'd=/srv/builds/_locks; n=$(cat $d/slots 2>/dev/null || echo 1); free=0; k=0; while [ $k -lt $n ]; do exec 9>>$d/build-$k; if flock -n 9; then free=$((free+1)); fi; exec 9>&-; k=$((k+1)); done; printf "free=%s slots=%s load1=%s" $free $n "$(cut -d" " -f1 /proc/loadavg)"' 2>/dev/null || printf 'down' +} +bs_state_ok() { # -> 0 when the box can take a job now (a free slot, load1 at or under the line) + local st="$1" free load + case "$st" in free=*) ;; *) return 1 ;; esac + free=${st#free=}; free=${free%% *}; load=${st##*load1=} + [ "$free" -gt 0 ] 2>/dev/null || return 1 + awk -v l="$load" -v m="$BS_SPILL_LOAD" 'BEGIN { exit !(l + 0 <= m + 0) }' +} +bs_route_spill() { # [priority] -> the box number; sets BS_ROUTE_PREF, BS_ROUTE_BOX, BS_ROUTE_SPILLED, BS_ROUTE_REASON + local class="$1" pref alt ps as + pref=$(bs_route "$class" 2>/dev/null) + case "$pref" in 1) alt=2 ;; 2) alt=1 ;; *) alt=1 ;; esac + BS_ROUTE_PREF=$pref; BS_ROUTE_BOX=$pref; BS_ROUTE_SPILLED=0 + ps=$(bs_box_state "$pref") + if bs_state_ok "$ps"; then BS_ROUTE_REASON="box $pref ($ps) takes it" + else + as=$(bs_box_state "$alt") + if bs_state_ok "$as"; then BS_ROUTE_BOX=$alt; BS_ROUTE_SPILLED=1; BS_ROUTE_REASON="box $pref ($ps) is full or over load $BS_SPILL_LOAD: spilled to box $alt ($as)" + else BS_ROUTE_REASON="box $pref ($ps) and box $alt ($as) are both full or over load $BS_SPILL_LOAD: queued on box $pref"; fi + fi + bs_log "route: class $class prefers box $pref; $BS_ROUTE_REASON" + BR_ROUTE_PREF=$BS_ROUTE_PREF BR_ROUTE_BOX=$BS_ROUTE_BOX BR_ROUTE_SPILLED=$BS_ROUTE_SPILLED BR_ROUTE_REASON=$BS_ROUTE_REASON + export BR_ROUTE_PREF BR_ROUTE_BOX BR_ROUTE_SPILLED BR_ROUTE_REASON + echo "$BS_ROUTE_BOX" +} BS_ROOT_REMOTE=/srv/builds BS_MIRROR_REPO=/srv/igneum.git BS_MIRROR_NODE=/srv/igneum-node.git @@ -296,6 +338,7 @@ bs_remote_run() { BR_BRANCH="$BS_BRANCH" BR_SHA="$BS_SHA" BR_AGENT="$agent" BR_KIND="${BR_KIND:-other}" BR_COMMAND="${BR_COMMAND:-}" \ BR_TARGET="${BR_TARGET:-}" BR_ARTEFACTS="${BR_ARTEFACTS:-}" BR_SDE="${BR_SDE:-}" BR_PAIRS_WITH="${BR_PAIRS_WITH:-}" \ BR_NICE="${BR_NICE:-0}" BR_CORES="${BR_CORES:-0}" BR_JOBS_CAP="${BR_JOBS_CAP:-0}" BR_PRIORITY="${BR_PRIORITY:-normal}" \ + BR_ROUTE_PREF="${BR_ROUTE_PREF:-}" BR_ROUTE_BOX="${BR_ROUTE_BOX:-}" BR_ROUTE_SPILLED="${BR_ROUTE_SPILLED:-0}" BR_ROUTE_REASON="${BR_ROUTE_REASON:-}" \ bash -c ' for v in BR_DIR BR_LABEL BR_CMD BR_TOOL BR_WT BR_CRATE BR_BRANCH BR_SHA BR_AGENT BR_KIND BR_COMMAND BR_TARGET BR_ARTEFACTS BR_SDE BR_PAIRS_WITH BR_NICE BR_CORES BR_JOBS_CAP BR_PRIORITY; do printf "export %s=%q\n" "$v" "${!v}" diff --git a/infra/build-server/provision.sh b/infra/build-server/provision.sh index 7ad923adb..754851298 100755 --- a/infra/build-server/provision.sh +++ b/infra/build-server/provision.sh @@ -53,9 +53,10 @@ SCCACHE_GB="${SCCACHE_GB:-100}" SCCACHE_VERSION="${SCCACHE_VERSION:-}" NODE_MAJOR="${NODE_MAJOR:-22}" WORKTREES="${WORKTREES:-}" -SLOTS="${SLOTS:-2}" # 2 since main's ruling of 6 October 2026 (20:3x UK); remote-run.sh gives 90 jobs alone, 45 beside another +SLOTS_GIVEN="${SLOTS:-}"; SLOTS="${SLOTS:-2}" # 2 since main's ruling of 6 October 2026 (20:3x UK); remote-run.sh gives 90 jobs alone, 45 beside another P2P_PORTS="${P2P_PORTS:-26611 26811}" BOX_HOSTNAME="${BOX_HOSTNAME:-igneum-build-1}" +case "$BOX_HOSTNAME" in *-2) [ -n "$SLOTS_GIVEN" ] || SLOTS=3 ;; esac # build-2: three slots (main, 7 Oct 2026; the bounded runs take one 32-core band each) WORKERS_HOST="${WORKERS_HOST:-build.igneum.network}" # the dashboard feed's HTTPS name (A record in deSEC, 6 Oct 2026) SSH_PUBKEY="${SSH_PUBKEY:-}" BUILD_USER=build diff --git a/infra/build-server/remote-run.sh b/infra/build-server/remote-run.sh index f3b2451e1..1a8c72fe9 100755 --- a/infra/build-server/remote-run.sh +++ b/infra/build-server/remote-run.sh @@ -255,6 +255,8 @@ d = { "source_date_epoch": num(e.get('BR_SDE')), "pairs_with": e.get('BR_PAIRS_WITH') or None, "nice": num(e.get('BR_NICE')) or 0, "cores": (num(e.get('BR_CORES')) or 0) or os.cpu_count(), "priority": e.get('BR_PRIORITY') or "normal", "class": e.get('BR_CLASS') or None, "run_log": e.get('BR_RUN_LOG') or None, + "route": ({"preferred": num(e.get('BR_ROUTE_PREF')), "box": num(e.get('BR_ROUTE_BOX')), "spilled": e.get('BR_ROUTE_SPILLED') == '1', + "reason": e.get('BR_ROUTE_REASON') or ""} if e.get('BR_ROUTE_BOX') else None), } sc = {k: num(e[v]) for k, v in (("hits", "BR_HITS"), ("misses", "BR_MISSES"), ("hits_total", "BR_HITS_T"), ("misses_total", "BR_MISSES_T"))} sc = {k: v for k, v in sc.items() if v is not None} @@ -446,8 +448,15 @@ RUN_LOG_DIR="$LOG_DIR/runs"; mkdir -p "$RUN_LOG_DIR" BR_RUN_LOG="$RUN_LOG_DIR/$BR_HOST-$BR_T0-$BR_PID.log"; export BR_RUN_LOG # the class's nice and core set apply to the command's subshell and everything it starts (renice and taskset on the subshell's own # pid, BASHPID; cores are the LAST N of the box's set, so gates and builds keep the first ones to themselves) +# (since the third slot on build-2, 7 Oct 2026: a bounded run takes the band its SLOT owns, counted from the top: slot 0 the last N +# cores, slot 1 the N below, slot 2 the N below that, so three bounded runs never share a core; a band below core 0 falls back to +# the last N) ncpu=$(nproc); cores_str="0-$((ncpu - 1))" -if [ "${BR_CORES:-0}" -gt 0 ] && [ "${BR_CORES}" -lt "$ncpu" ]; then cores_str="$((ncpu - BR_CORES))-$((ncpu - 1))"; fi +if [ "${BR_CORES:-0}" -gt 0 ] && [ "${BR_CORES}" -lt "$ncpu" ]; then + band=0; case "${got:-}" in ''|measure) ;; *) band=$got ;; esac + lo=$((ncpu - BR_CORES * (band + 1))); [ "$lo" -ge 0 ] || lo=$((ncpu - BR_CORES)) + cores_str="$lo-$((lo + BR_CORES - 1))" +fi ( [ "${BR_NICE:-0}" -gt 0 ] && renice -n "$BR_NICE" -p $BASHPID >/dev/null 2>&1; [ "$cores_str" != "0-$((ncpu - 1))" ] && taskset -cp "$cores_str" $BASHPID >/dev/null 2>&1; eval "$BR_CMD" ) > >(tee -a "$BR_RUN_LOG") 2> >(tee -a "$BR_RUN_LOG" >&2) rc=$? # the keeper stops BEFORE the bare `wait` (which flushes the two tees): a bare wait also waits for the keeper, and the keeper waits diff --git a/tools/build-remote.sh b/tools/build-remote.sh index 9618ec3d5..fc5e4ea75 100755 --- a/tools/build-remote.sh +++ b/tools/build-remote.sh @@ -121,15 +121,20 @@ if [ "$PLAN" = 1 ]; then exit 0 fi -# the box: --box N, else the route by class (suite and bench to box 2, prove to box 3, the rest to box 1; lib.sh bs_route) -if [ -z "$BOX" ]; then - case "$SCHED_CLASS:$PRIORITY" in *:gate) BOX=1 ;; suite:*|bench:*) BOX=$(bs_route "$SCHED_CLASS") ;; *) BOX=1 ;; esac -fi +# the box: --box N pins it; else the class's PREFERRED box with spill-over (lib.sh bs_route_spill, Josh 7 Oct 2026: a build or gate +# prefers box 1, a suite or bench box 2, a proving crate box 3; a preferred box with no free slot or a 1-minute load above 64 hands +# the job to the other box when that one qualifies; the decision line is printed here and lands in the JSONL row as "route") +ROUTE_CLASS="$SCHED_CLASS"; [ "$PRIORITY" = gate ] && ROUTE_CLASS=gate +if [ -z "$BOX" ]; then bs_route_spill "$ROUTE_CLASS"; BOX=$BS_ROUTE_BOX; else BR_ROUTE_PREF=$BOX BR_ROUTE_BOX=$BOX BR_ROUTE_SPILLED=0 BR_ROUTE_REASON="box $BOX by --box"; export BR_ROUTE_PREF BR_ROUTE_BOX BR_ROUTE_SPILLED BR_ROUTE_REASON; fi bs_host "$BOX" bs_context -# a proving crate routes to box 3 unless the caller chose (its builds and suites alike) -if [ "$BS_CRATE_REL" = proving/igneum-prove ] && [ -z "${BOX_GIVEN:-}" ] && [ "$PRIORITY" != gate ]; then b=$(bs_route prove); [ "$b" != "$BOX" ] && { BOX=$b; bs_host "$BOX"; }; fi -bs_log "box $BOX ($BS_HOST) for class $SCHED_CLASS, priority $PRIORITY" +# a proving crate prefers box 3 unless the caller chose (its builds and suites alike; the same spill-over) +if [ "$BS_CRATE_REL" = proving/igneum-prove ] && [ -z "${BOX_GIVEN:-}" ] && [ "$PRIORITY" != gate ]; then bs_route_spill prove; [ "$BS_ROUTE_BOX" != "$BOX" ] && { BOX=$BS_ROUTE_BOX; bs_host "$BOX"; }; fi +# box 2 keeps the suites' numbers: everything that lands there runs at the bounded class (nice 10, a 32-core band, -j 32), builds +# and gates included (main, 7 Oct 2026); a gate still takes its slot ahead of queued suites +if [ "$BOX" = 2 ] && [ "$BR_CORES" = 0 ]; then BR_NICE=10; BR_CORES=32; BR_JOBS_CAP=32; export BR_NICE BR_CORES BR_JOBS_CAP; bs_log "bounded on box 2 (nice 10, a 32-core band, -j 32) so a suite beside it keeps its number"; fi +if [ "$BR_JOBS_CAP" -gt 0 ] && [ -n "$JOBS" ] && [ "$JOBS" -gt "$BR_JOBS_CAP" ]; then bs_log "--jobs $JOBS clamped to $BR_JOBS_CAP on box $BOX"; JOBS=$BR_JOBS_CAP; fi +bs_log "box $BOX ($BS_HOST) for class $SCHED_CLASS, priority $PRIORITY$( [ "${BR_ROUTE_SPILLED:-0}" = 1 ] && echo ", SPILLED from box $BR_ROUTE_PREF")" if [ "$SELFTEST" = 1 ]; then [ "$BS_KIND" = node ] || bs_die "--self-test-repro runs from a fork worktree (igneum-miner and kaspad live there)" @@ -223,6 +228,7 @@ BR_KIND=$(bs_kind build-remote "$( [ "${CARGO_ARGS[0]}" = zigbuild ] && echo bui [ "$SCHED_CLASS" = bench ] && BR_KIND=bench [ "$PRIORITY" = gate ] && BR_KIND=gate label="$label; kind=$BR_KIND nice=$BR_NICE cores=$( [ "$BR_CORES" = 0 ] && echo 96 || echo "$BR_CORES")" +[ "${BR_ROUTE_SPILLED:-0}" = 1 ] && label="$label; spilled from box $BR_ROUTE_PREF" for ((i = 0; i < ${#CARGO_ARGS[@]}; i++)); do [ "${CARGO_ARGS[$i]}" = --target ] && BR_TARGET="${CARGO_ARGS[$((i + 1))]:-}"; done BR_ARTEFACTS=""; [ "$FETCH" = 1 ] && BR_ARTEFACTS="$ARTEFACTS" export BR_KIND BR_COMMAND BR_TARGET BR_ARTEFACTS diff --git a/tools/ci/pre-push.sh b/tools/ci/pre-push.sh index 659e98396..58ab6ce7c 100755 --- a/tools/ci/pre-push.sh +++ b/tools/ci/pre-push.sh @@ -77,6 +77,7 @@ tree_checks() { run "the remote checkout's clean spares a lane's scratch (.igneum-scratch-spare, the fixed prefixes, never -x; the lost-scratch class)" bash -c 'bash tools/ci/scratch-spare-check.sh --self-test && bash tools/ci/scratch-spare-check.sh' run "long-running tools keep their body in one parsed block (the edited-while-running class)" bash -c 'bash tools/ci/whole-body-check.sh --self-test && bash tools/ci/whole-body-check.sh' run "build-remote without a priority flag bounds suites and benches (nice 10, 32 cores); a gate runs unbounded" bash tools/ci/build-kind-default-check.sh + run "the class router is a preference with spill-over (a held or overloaded box hands the job to the other one)" bash tools/ci/route-spill-check.sh run "no shell assignment hides behind a trailing comment (the swallowed-defaults class)" bash -c 'bash tools/ci/defaults-line-check.sh --self-test && bash tools/ci/defaults-line-check.sh' run "no script kills or finds a process by a plain name or a file name (pgrep/pkill -f literals, ps | grep)" bash -c 'bash tools/ci/kill-by-name-check.sh --self-test && bash tools/ci/kill-by-name-check.sh' run "the identity check's own self-test (excluded research path passes, exported leak fails)" bash tools/ci/identity-check.sh --self-test diff --git a/tools/ci/route-spill-check.sh b/tools/ci/route-spill-check.sh new file mode 100755 index 000000000..480b5d217 --- /dev/null +++ b/tools/ci/route-spill-check.sh @@ -0,0 +1,37 @@ +#!/usr/bin/env bash +# The spill-over router of tools/build-remote.sh (lib.sh bs_route_spill; Josh, 7 October 2026, 15:02 UK: build-1 at load 139 with a +# queue of 1 h 40 min while build-2 sat at 4.5 with free slots). The class is a preference: a job goes to its class's box unless +# that box has no free slot or its 1-minute load is above 64, in which case it goes to the other box when that one qualifies, else +# it queues on its own box. This check feeds the router fixed box states through BS_ROUTE_STATE_ (no ssh) and host files in a +# scratch directory, and compares the chosen box and the spilled flag for the known cases: a held build-1 selects build-2, a free +# build-1 selects build-1, an overloaded build-1 spills, a held build-2 sends a suite to build-1, two full boxes queue on the +# class's own box, a box without a host file is never chosen, a build-1 that is down spills. +# +# tools/ci/route-spill-check.sh # exit 1 with the case that resolved wrongly (the check IS its self-test) +set -euo pipefail +cd "$(dirname "$0")/../.." +t=$(mktemp -d); trap 'rm -rf "$t"' EXIT +printf 'build@10.0.0.1\n' > "$t/hosts"; printf 'build@10.0.0.2\n' > "$t/hosts-2" # box 3 absent on purpose +export IGNEUM_BUILD_HOST_FILE="$t/hosts" +fail=0 +expect() { # ; the states come from the environment + local name="$1" class="$2" wbox="$3" wsp="$4" out + out=$(bash -c '. infra/build-server/lib.sh; bs_route_spill "$1" >/dev/null 2>&1; printf "%s %s" "$BS_ROUTE_BOX" "$BS_ROUTE_SPILLED"' _ "$class" 2>/dev/null) + if [ "$out" = "$wbox $wsp" ]; then echo "route-spill: $name: $class -> box $wbox spilled=$wsp" + else echo "route-spill: $name: $class resolved to '$out', expected 'box $wbox spilled=$wsp'" >&2; fail=1; fi +} +BS_ROUTE_STATE_1="free=0 slots=2 load1=30" BS_ROUTE_STATE_2="free=3 slots=3 load1=5" expect "a held build-1 selects build-2" build 2 1 +BS_ROUTE_STATE_1="free=1 slots=2 load1=20" BS_ROUTE_STATE_2="free=3 slots=3 load1=5" expect "a free build-1 selects build-1" build 1 0 +BS_ROUTE_STATE_1="free=2 slots=2 load1=70" BS_ROUTE_STATE_2="free=3 slots=3 load1=5" expect "an overloaded build-1 spills" build 2 1 +BS_ROUTE_STATE_1="free=0 slots=2 load1=30" BS_ROUTE_STATE_2="free=3 slots=3 load1=5" expect "a gate spills like a build" gate 2 1 +BS_ROUTE_STATE_1="free=1 slots=2 load1=5" BS_ROUTE_STATE_2="free=0 slots=3 load1=10" expect "a held build-2 sends a suite to build-1" suite 1 1 +BS_ROUTE_STATE_1="free=1 slots=2 load1=5" BS_ROUTE_STATE_2="free=1 slots=3 load1=90" expect "an overloaded build-2 sends a bench away" bench 1 1 +BS_ROUTE_STATE_1="free=2 slots=2 load1=5" BS_ROUTE_STATE_2="free=2 slots=3 load1=10" expect "a free build-2 keeps its suite" suite 2 0 +BS_ROUTE_STATE_1="free=0 slots=2 load1=80" BS_ROUTE_STATE_2="free=0 slots=3 load1=90" expect "two full boxes queue a build on build-1" build 1 0 +BS_ROUTE_STATE_1="free=0 slots=2 load1=80" BS_ROUTE_STATE_2="free=0 slots=3 load1=90" expect "two full boxes queue a suite on build-2" suite 2 0 +BS_ROUTE_STATE_1="down" BS_ROUTE_STATE_2="free=3 slots=3 load1=5" expect "a build-1 that is down spills" build 2 1 +BS_ROUTE_STATE_1="free=1 slots=2 load1=5" BS_ROUTE_STATE_2="free=3 slots=3 load1=5" expect "a proving class with no box 3 prefers box 1" prove 1 0 +BS_ROUTE_STATE_1="free=0 slots=2 load1=5" BS_ROUTE_STATE_2="free=3 slots=3 load1=5" expect "a proving class spills to box 2 when box 1 is held" prove 2 1 +BS_ROUTE_STATE_1="free=1 slots=2 load1=64" BS_ROUTE_STATE_2="free=3 slots=3 load1=5" expect "load exactly 64 is under the line" build 1 0 +[ "$fail" = 0 ] && echo "route-spill: the class is a preference; a full or overloaded box hands the job to the other one" +exit $fail From 275859cecfec1dacecf1771d6e62c10499d05d6f Mon Sep 17 00:00:00 2001 From: igneum-josh <337424239+igneum-josh@users.noreply.github.com> Date: Wed, 7 Oct 2026 14:09:04 +0100 Subject: [PATCH 15/19] CI gate: the feature-branch hook runs the never-push classes (no-secrets, identity grep) beside the structural checks; harness summaries write keys through a redacting writer with its own check The class (7 October 2026, 11:26 to 12:47 UK): three fork-gate summaries on ca3-v4-node carried the miners' vote-key hashes under "key" and eight CI runs went red on "no secret file names and no 64-hex secrets in the tree" while the pushing lanes saw nothing: the light gate ran only conflict markers and Windows paths. - tools/ci/pre-push.sh: never_push_checks() (identity grep, no-secrets) runs on every ref from --hook, and inside the full gate where the identity grep already sat; the self-test asserts the wiring; the light gate is about 20 s on the Mac. - infra/fast-time/lib/redact-keys.mjs: writeSummary() shortens every 64-hex value under a key-shaped field to 8 hex and an ellipsis and refuses a text the no-secrets rule would flag (line named); --self-test and --check; the gate runs the self-test. fork-gate.mjs adopts it on ca3-v4-node. Co-Authored-By: Claude Fable 5.1 --- infra/fast-time/lib/redact-keys.mjs | 132 ++++++++++++++++++++++++++++ tools/ci/pre-push.sh | 32 +++++-- 2 files changed, 155 insertions(+), 9 deletions(-) create mode 100644 infra/fast-time/lib/redact-keys.mjs diff --git a/infra/fast-time/lib/redact-keys.mjs b/infra/fast-time/lib/redact-keys.mjs new file mode 100644 index 000000000..8b38c6514 --- /dev/null +++ b/infra/fast-time/lib/redact-keys.mjs @@ -0,0 +1,132 @@ +#!/usr/bin/env node +// Harness summaries never carry a raw key. Every fast-time runner that writes a summary JSON writes it through +// writeSummary(): a 64-hex value under a key-shaped field (a name ending in key, keys, token, secret, password or +// passphrase, or anything nested under one) is shortened to its first 8 hex characters and an ellipsis, and the +// serialised text is then checked with the same rule as tools/ci/no-secrets-check.sh before it touches the disk. +// A summary that would fail the no-secrets gate is refused here, at the source, with the line named. +// +// The class (7 October 2026, 11:26 to 12:47 UK): fork-gate.mjs wrote the two miners' vote-key hashes into +// joint_sinks.*.key and split_sinks.*.key of three gate summaries under docs/plans/counter-asic-3-gate; eight CI runs +// on ca3-v4-node went red on "no secret file names and no 64-hex secrets in the tree" and no pushing lane saw it, +// because the feature-branch hook ran only the structural checks and the red watcher posted master and release-* only. +// +// import { writeSummary } from './lib/redact-keys.mjs'; writeSummary(OUT, summary); +// node infra/fast-time/lib/redact-keys.mjs --self-test a key field is shortened, a hash field is left alone, +// a raw key in the text fails the writer's own check +// node infra/fast-time/lib/redact-keys.mjs --check ... exit 1 if any file carries a raw key line (the hits named) +import { mkdirSync, writeFileSync, readFileSync, existsSync, rmSync, mkdtempSync } from 'node:fs'; +import { dirname, join } from 'node:path'; +import { tmpdir } from 'node:os'; + +// the content rule of tools/ci/no-secrets-check.sh, verbatim in spirit: a 64-hex value (0x optional) assigned to a name +// ending in token, key, secret, password or passphrase +export const RAW_KEY_LINE = /(token|key|secret|password|passphrase)["']?\s*[:=]\s*["']?(0x)?[0-9a-fA-F]{64}(?![0-9a-fA-F])/i; +export const KEY_FIELD = /(key|keys|token|secret|password|passphrase)$/i; +const HEX64 = /^(0x)?[0-9a-fA-F]{64}$/; + +export function shortHex(v) { + if (typeof v !== 'string' || !HEX64.test(v)) return v; + const head = v.startsWith('0x') ? 10 : 8; + return v.slice(0, head) + '…'; +} + +// A copy of `value` with every 64-hex string under a key-shaped field shortened. Nothing else changes: hashes, digests +// and ids under other names stay whole. The input object is never mutated (the runner keeps comparing live keys). +export function redactKeys(value, underKeyField = false) { + if (Array.isArray(value)) return value.map((v) => redactKeys(v, underKeyField)); + if (value && typeof value === 'object') { + const out = {}; + for (const [k, v] of Object.entries(value)) out[k] = redactKeys(v, underKeyField || KEY_FIELD.test(k)); + return out; + } + return underKeyField ? shortHex(value) : value; +} + +// The line numbers (1-based) of `text` that the no-secrets gate would flag. +export function rawKeyLines(text) { + return text.split('\n').map((l, i) => (RAW_KEY_LINE.test(l) ? i + 1 : 0)).filter(Boolean); +} + +// The text a summary is written as: redacted, then checked. Throws when a raw key survives (a key inside a free-text +// field such as a quoted log line), so the runner fails before the tree does. +export function summaryText(summary) { + const text = JSON.stringify(redactKeys(summary), null, 2); + const lines = rawKeyLines(text); + if (lines.length) throw new Error(`summary carries a raw 64-hex key at line${lines.length > 1 ? 's' : ''} ${lines.join(', ')}: the no-secrets gate would refuse it; shorten it with redactKeys or drop the field`); + return text; +} + +export function writeSummary(file, summary) { + mkdirSync(dirname(file), { recursive: true }); + const text = summaryText(summary); + writeFileSync(file, text); + return text; +} + +const hex = (c) => c.repeat(64); + +function selfTest() { + const fails = []; + const summary = { + pass: true, keys: { a: hex('a'), b: hex('b') }, + joint_sinks: { a: { hash: hex('c'), blocks: 1, key: hex('a') }, b: { hash: hex('d'), blocks: 2, key: '0x' + hex('b') } }, + samples: [{ t: 1, a: { sink: hex('c').slice(0, 16), key: hex('a') } }], + vote_key: hex('e'), signingKey: hex('f'), a_token: hex('1'), digest: hex('2'), exec_restart_hash: hex('3'), id32: 'a'.repeat(32), + }; + const before = JSON.stringify(summary); + const out = redactKeys(summary); + if (JSON.stringify(summary) !== before) fails.push('redactKeys mutated its input'); + if (out.keys.a !== 'aaaaaaaa…' || out.keys.b !== 'bbbbbbbb…') fails.push(`keys.* not shortened: ${out.keys.a} ${out.keys.b}`); + if (out.joint_sinks.a.key !== 'aaaaaaaa…') fails.push(`joint_sinks.a.key not shortened: ${out.joint_sinks.a.key}`); + if (out.joint_sinks.b.key !== '0xbbbbbbbb…') fails.push(`a 0x key kept its prefix wrong: ${out.joint_sinks.b.key}`); + if (out.samples[0].a.key !== 'aaaaaaaa…') fails.push('a key inside an array element was not shortened'); + if (out.vote_key !== 'eeeeeeee…' || out.signingKey !== 'ffffffff…' || out.a_token !== '11111111…') fails.push('a name ending in key/Key/token was not shortened'); + if (out.joint_sinks.a.hash !== hex('c') || out.digest !== hex('2') || out.exec_restart_hash !== hex('3')) fails.push('a hash, digest or *_hash field was changed'); + if (out.id32 !== 'a'.repeat(32) || out.joint_sinks.a.blocks !== 1) fails.push('a non-key value was changed'); + let text; + try { text = summaryText(summary); } catch (e) { fails.push(`summaryText refused a redactable summary: ${e.message}`); } + if (text && /[0-9a-f]{64}/.test(text.replace(new RegExp(`"(hash|digest|exec_restart_hash)": "(0x)?[0-9a-f]{64}"`, 'g'), ''))) fails.push('a raw 64-hex key survived in the written text'); + if (text && rawKeyLines(text).length) fails.push('the written text would fail the no-secrets rule'); + // the writer's own check: a raw key line in the text fails, under each shape the gate catches + for (const t of [`{\n "key": "${hex('9')}"\n}`, `KEY=0x${hex('8')}`, `x-igneum-key: ${hex('7')}`, `const signingKey = "${hex('6')}";`]) { + if (!rawKeyLines(t).length) fails.push(`rawKeyLines missed: ${t.slice(0, 30)}`); + } + if (rawKeyLines(`{\n "hash": "${hex('5')}",\n "id": "${'4'.repeat(32)}"\n}`).length) fails.push('rawKeyLines flagged a hash or a 32-hex id'); + // a key hiding in free text under a field the redactor does not know: summaryText refuses it, and names the line + let refused = false; + try { summaryText({ ok: true, refusal_example: `Fork choice: refused block by key: ${hex('9')}` }); } catch (e) { refused = /line 3/.test(e.message); } + if (!refused) fails.push('summaryText did not refuse (or did not name the line of) a raw key inside a free-text field'); + // writeSummary writes the redacted text, and --check on a raw file fails + const dir = mkdtempSync(join(tmpdir(), 'redact-keys-')); + try { + const good = join(dir, 'nested', 'good.json'); writeSummary(good, summary); + if (!existsSync(good) || rawKeyLines(readFileSync(good, 'utf8')).length) fails.push('writeSummary wrote a raw key or nothing'); + if (JSON.parse(readFileSync(good, 'utf8')).keys.a !== 'aaaaaaaa…') fails.push('the written file does not parse back to the shortened key'); + const bad = join(dir, 'bad.json'); writeFileSync(bad, JSON.stringify({ keys: { a: hex('a') }, sink: { key: hex('a') } }, null, 2)); + if (checkFiles([good]).length) fails.push('--check flagged the redacted file'); + const hits = checkFiles([bad]); + if (hits.length !== 1 || !/bad\.json:\d+/.test(hits[0])) fails.push(`--check did not name the raw file and line: ${hits.join(' | ')}`); + if (hits.some((h) => /[0-9a-f]{64}/.test(h))) fails.push('--check printed a 64-hex value'); + } finally { rmSync(dir, { recursive: true, force: true }); } + if (fails.length) { for (const f of fails) console.error(`self-test failed: ${f}`); process.exit(1); } + console.log('self-test passed: key-shaped fields shorten to 8 hex and an ellipsis, hashes stay whole, the input is not mutated, a raw key in the text fails the writer\'s own check with its line, --check names a raw file without printing the key'); +} + +export function checkFiles(files) { + const hits = []; + for (const f of files) { + if (!existsSync(f)) { hits.push(`${f}: missing`); continue; } + for (const n of rawKeyLines(readFileSync(f, 'utf8'))) hits.push(`${f}:${n}: a raw 64-hex key under a key-shaped field`); + } + return hits; +} + +if (import.meta.url === `file://${process.argv[1]}`) { + const args = process.argv.slice(2); + if (args[0] === '--self-test') selfTest(); + else if (args[0] === '--check') { + const hits = checkFiles(args.slice(1)); + if (hits.length) { for (const h of hits) console.error(h); process.exit(1); } + console.log(`redact-keys: ${args.length - 1} file(s), no raw key`); + } else { console.error('usage: redact-keys.mjs --self-test | --check ...'); process.exit(2); } +} diff --git a/tools/ci/pre-push.sh b/tools/ci/pre-push.sh index 58ab6ce7c..016baca3b 100755 --- a/tools/ci/pre-push.sh +++ b/tools/ci/pre-push.sh @@ -5,10 +5,11 @@ # # tools/ci/pre-push.sh # the full gate over this working tree (any worktree; reads the tree, writes nothing in it) # tools/ci/pre-push.sh --ci # the same, with the site built in place (a CI checkout is disposable) -# tools/ci/pre-push.sh --hook # from .git/hooks/pre-push: full gate for master and release-*, the two structural -# # checks (conflict markers, Windows paths) for every other ref -# tools/ci/pre-push.sh --self-test # the runner fires on a known failure, passes a known success, and the hook picks the -# # right gate from the ref lines +# tools/ci/pre-push.sh --hook # from .git/hooks/pre-push: full gate for master and release-*; the light gate for every +# # other ref: the two structural checks (conflict markers, Windows paths) and the two +# # never-push classes (the no-secrets check, the identity grep), about 20 s on the Mac +# tools/ci/pre-push.sh --self-test # the runner fires on a known failure, passes a known success, the hook picks the +# # right gate from the ref lines, and the light gate carries the never-push classes # tools/ci/pre-push.sh --list # the check names, one per line # # What is NOT here, on purpose: the three compile-or-compute jobs (igneum-pow tests, igneum-census, the simulators) and @@ -51,12 +52,20 @@ structural_checks() { run "every tracked path is valid on Windows (colon, trailing dot, reserved names, length)" bash tools/ci/windows-paths-check.sh } +never_push_checks() { + # The two never-push classes, on EVERY ref (7 October 2026: three gate summaries on ca3-v4-node carried a 64-hex key + # through eight red CI runs in 80 minutes; the feature-branch hook ran only the structural checks, so no lane saw it). + # A secret or an identity leak must not reach the remote on any branch; together about 20 s on the Mac. + run "identity grep of the public export list and the served site" bash tools/ci/identity-check.sh + run "no secret file names and no 64-hex secrets in the tree" bash -c 'bash tools/ci/no-secrets-check.sh --self-test && bash tools/ci/no-secrets-check.sh' +} + tree_checks() { run "site build (in a temporary copy locally, in place in CI)" site_build run "internal link check of site/*.html" node tools/ci/link-check.mjs run "every served page carries the full header (six items, Download, burger)" node tools/ci/site-nav-check.mjs run "ledger sentences present verbatim on their public pages" node tools/ci/ledger-text-check.mjs - run "identity grep of the public export list and the served site" bash tools/ci/identity-check.sh + never_push_checks run "shell inside .github/workflows parses (bash -n, the PowerShell 5.1 rule)" node tools/ci/check-workflow-shell.mjs run "PowerShell drive-reference check (\$name: in a double-quoted string)" bash tools/ci/ps-drive-ref-check.sh run "copied sources are re-stamped before a build" bash tools/ci/copied-sources-check.sh @@ -90,10 +99,10 @@ tree_checks() { run "ship tool self-test" node tools/ship-app.mjs --self-test run "relay unit tests" node --test relay/test/parse.test.mjs relay/test/auth.test.mjs relay/test/wake.test.mjs relay/test/ember.test.mjs run "miner app notice strip and update card tests" node --test app/igneum-app/ui/notices.test.mjs app/igneum-app/ui/update-card.test.mjs app/igneum-app/ui/view.test.mjs app/igneum-app/ui/tune-line.test.mjs - run "no secret file names and no 64-hex secrets in the tree" bash -c 'bash tools/ci/no-secrets-check.sh --self-test && bash tools/ci/no-secrets-check.sh' run "launch gates: every row with its check, the handoff text clean (self-test, then the tree)" bash -c 'node tools/ci/launch-gates-check.mjs --self-test && node tools/ci/launch-gates-check.mjs' run "income per tier: the public table equals its inputs, the schedule arithmetic" bash -c 'node tools/launch/income-tiers.mjs --check && node --test tools/launch/income-tiers.test.mjs' run "hash-origin report: a known-finished day and a known-failed day" node --test tools/observer/hash-origin.test.mjs + run "harness summaries never carry a raw 64-hex key (the writer's own redaction and check)" node infra/fast-time/lib/redact-keys.mjs --self-test } gated_refs() { @@ -126,7 +135,12 @@ case "$MODE" in [ "$(printf 'refs/heads/x 1 refs/heads/release-0.3.15 2\n' | gated_refs)" = full ] || { echo "self-test failed: a push to release-0.3.15 did not select the full gate"; fails=1; } [ "$(printf 'refs/heads/x 1 refs/heads/x 2\n' | gated_refs)" = light ] || { echo "self-test failed: a push to a feature branch selected the full gate"; fails=1; } [ "$(printf '' | gated_refs)" = light ] || { echo "self-test failed: a push with no refs selected the full gate"; fails=1; } - [ "$fails" = 0 ] && echo "self-test passed: a failing check is RED and fails the gate, a passing one is ok; master and release-* select the full gate, other refs the light one" + # the light gate carries the two never-push classes beside the structural checks, and the full gate runs them too + declare -f never_push_checks | grep -q 'tools/ci/no-secrets-check.sh' || { echo "self-test failed: the never-push checks do not run the no-secrets check"; fails=1; } + declare -f never_push_checks | grep -q 'tools/ci/identity-check.sh' || { echo "self-test failed: the never-push checks do not run the identity grep"; fails=1; } + grep -qE '^\s+structural_checks; never_push_checks; finish "feature branch"' "$0" || { echo "self-test failed: the hook's light gate does not run the never-push checks"; fails=1; } + declare -f tree_checks | grep -q 'never_push_checks' || { echo "self-test failed: the full gate does not run the never-push checks"; fails=1; } + [ "$fails" = 0 ] && echo "self-test passed: a failing check is RED and fails the gate, a passing one is ok; master and release-* select the full gate, other refs the light one (structural checks, no-secrets, identity grep)" exit $fails ;; list) grep -E '^\s+run "' "$0" | sed -E 's/^\s+run "([^"]+)".*/\1/' ;; @@ -136,8 +150,8 @@ case "$MODE" in echo "pre-push gate: a push to master or release-*, the full gate (the same checks CI runs):" structural_checks; tree_checks; finish "push to master or release-*" else - echo "pre-push gate: a feature branch, the two structural checks:" - structural_checks; finish "feature branch" + echo "pre-push gate: a feature branch, the light gate (the two structural checks, the no-secrets check, the identity grep):" + structural_checks; never_push_checks; finish "feature branch" fi ;; ci|local) [ "$MODE" = ci ] && echo "pre-push gate in CI (the same script as the local hook):" || echo "pre-push gate over this working tree:" From 5e28845d0215481ea35207d83169210ca278b8f5 Mon Sep 17 00:00:00 2001 From: igneum-josh <337424239+igneum-josh@users.noreply.github.com> Date: Wed, 7 Oct 2026 14:09:04 +0100 Subject: [PATCH 16/19] CI red watcher: every branch, one line per failed run naming the branch, the commit, the red check and the pushing author The red job's condition drops the master/release-* clause; record() keeps GITHUB_ACTOR and the head commit's author name (RED_WATCH_AUTHOR from the workflow) and formatLine prints "pushed by (commit by )" before the failed job and step. The self-test covers a feature-branch run and the author in the line. Same updates channel, same box file, same one-line-per-run idempotence. Co-Authored-By: Claude Fable 5.1 --- .github/workflows/ci.yml | 16 +++++++++------- tools/ci/red-watch.mjs | 22 +++++++++++++++++----- 2 files changed, 26 insertions(+), 12 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2f0805968..47d816738 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -11,9 +11,10 @@ # Where it runs: `pow` and `sims` go to the box's runner (igneum-build-1, rustc pinned, sccache read-only, 48 jobs) # when the repository variable IGNEUM_CI_RUNNER is `box`, else to ubuntu-latest (docs/plans/ci-self-hosted.md; GitHub # has no fallback in runs-on, the variable is the switch). The `site` job stays on GitHub's machines. The `red` job -# runs on the box after any failed master or release-* run and records the failure for the watcher -# (tools/ci/red-watch.mjs; infra/build-server/ci-red): one line per run to the hidden updates channel and to -# /srv/ci-red/red.jsonl, so nobody opens the Actions page to learn master is red. +# runs on the box after any failed run on ANY branch and records the failure for the watcher +# (tools/ci/red-watch.mjs; infra/build-server/ci-red): one line per run, naming the branch, the commit, the red check +# and the pushing author, to the hidden updates channel and to /srv/ci-red/red.jsonl, so nobody opens the Actions page +# to learn a branch is red (master and release-* only until 7 October 2026, when eight red runs on ca3-v4-node went unseen). # # What does not run, on purpose: the node fork (vendor/igneum-node*, a rusty-kaspa fork of about 500 crates with # rocksdb, blst and the execution layer) is gitignored here and too big for the free runners today (a cold build is @@ -77,14 +78,14 @@ jobs: run: node tools/ci/public-api-check.mjs https://igneum.network red: - # Runs only when a master or release-* run has a failed job, on the box's own runner (not a GitHub-hosted machine: + # Runs when a run on any branch has a failed job, on the box's own runner (not a GitHub-hosted machine: # the billing block of 6 October 2026, 18:37Z to 20:10Z, failed every hosted job at start and nobody was told). # tools/ci/red-watch.mjs record appends ONE line for this run to /srv/ci-red/red.jsonl (idempotent per run attempt); # the box's igneum-ci-red.timer posts each new line once to the hidden updates channel. Never blocks a release: # it reads the run, writes one line, and ends. - name: red watcher (master and release-* only; one line per failed run to the updates channel and the box file) + name: red watcher (every branch; one line per failed run, with the branch, commit, red check and pushing author, to the updates channel and the box file) needs: [pow, sims, site] - if: ${{ failure() && (github.ref == 'refs/heads/master' || startsWith(github.ref, 'refs/heads/release-')) }} + if: ${{ failure() }} runs-on: [self-hosted, linux, x64, igneum-build-1] timeout-minutes: 5 permissions: @@ -94,8 +95,9 @@ jobs: - uses: actions/checkout@v4 with: sparse-checkout: tools/ci - - name: record this run (one line, the failed jobs and their first failed step, from the run's own API) + - name: record this run (one line, the branch, the commit, the failed jobs and their first failed step from the run's own API, the pushing author) env: GITHUB_TOKEN: ${{ github.token }} RED_WATCH_TITLE: ${{ github.event.head_commit.message }} + RED_WATCH_AUTHOR: ${{ github.event.head_commit.author.name }} run: node tools/ci/red-watch.mjs record --file /srv/ci-red/red.jsonl diff --git a/tools/ci/red-watch.mjs b/tools/ci/red-watch.mjs index 3f367735a..ca932d9e6 100755 --- a/tools/ci/red-watch.mjs +++ b/tools/ci/red-watch.mjs @@ -1,5 +1,7 @@ #!/usr/bin/env node -// The red-master watcher. One line per failed master or release-* run, so nobody opens the Actions page to learn CI is red. +// The red watcher. One line per failed run on ANY branch (master and release-* only until 7 October 2026: eight red runs on +// ca3-v4-node went unseen that morning), naming the branch, the commit, the red check and the pushing author, so nobody +// opens the Actions page to learn a branch is red. // Node 22, standard library only. // // node tools/ci/red-watch.mjs record --file in the workflow's `red` job (runs on igneum-build-1 after a @@ -41,7 +43,7 @@ const STATE_FILE = process.env.IGNEUM_CI_RED_STATE || path.join(os.homedir(), '. const WEBHOOK_KEY = 'DISCORD_WEBHOOK_UPDATES'; // what stops each class now (named in the digest so the line teaches, not just counts); docs/analysis/ci-failures-2026-10-06.md export const GUARDS = { - 'ci': 'the pre-push gate (tools/ci/pre-push.sh, the same checks CI runs, before any push to master or release-*)', + 'ci': 'the pre-push gate (tools/ci/pre-push.sh: the full gate before a push to master or release-*, the never-push checks before a push to any branch)', 'instant': 'pre-flight in remote-run.sh (manifest, -p package, feature, subcommand checked in a second) and the kept run log', 'preflight-manifest': 'refused before the slot: the manifest did not parse', 'preflight-package': 'refused before the slot: the -p package does not exist', @@ -68,6 +70,7 @@ export function runFromEnv(env = process.env) { return { run_id: String(env.GITHUB_RUN_ID), attempt: Number(env.GITHUB_RUN_ATTEMPT || 1), workflow: env.GITHUB_WORKFLOW, branch: env.GITHUB_REF_NAME, sha: env.GITHUB_SHA.slice(0, 7), event: env.GITHUB_EVENT_NAME || '', + actor: env.GITHUB_ACTOR || '', author: env.RED_WATCH_AUTHOR || '', // who pushed (the GitHub login), who the head commit names url: `${server}/${env.GITHUB_REPOSITORY}/actions/runs/${env.GITHUB_RUN_ID}`, at: new Date().toISOString(), }; } @@ -115,7 +118,8 @@ export async function record(file, env = process.env, fetchImpl = fetch, title = export function formatLine(l) { const where = l.failed.length ? l.failed.map((f) => `${f.job.replace(/,.*$/, '')} at "${f.step}"`).join('; ') : (l.note || 'no step detail'); const title = l.title ? ` "${l.title}"` : ''; - return `CI red: ${l.workflow} on ${l.branch} @${l.sha}${title}: ${where} ${l.url}`; + const who = l.actor ? ` pushed by ${l.actor}${l.author && l.author !== l.actor ? ` (commit by ${l.author})` : ''};` : ''; + return `CI red: ${l.workflow} on ${l.branch} @${l.sha}${title}:${who} ${where} ${l.url}`; } function readCredentials(file) { @@ -208,7 +212,8 @@ async function selfTest() { const dir = fs.mkdtempSync(path.join(os.tmpdir(), 'red-watch-')); const file = path.join(dir, 'red.jsonl'); const stateFile = path.join(dir, 'posted.json'); const credFile = path.join(dir, 'discord'); const env = { GITHUB_RUN_ID: '424242', GITHUB_RUN_ATTEMPT: '1', GITHUB_REPOSITORY: 'igneum-network/igneum', GITHUB_REF_NAME: 'master', - GITHUB_SHA: '0f0abc6deadbeef', GITHUB_WORKFLOW: 'ci', GITHUB_TOKEN: 'x', RED_WATCH_TITLE: 'Merge box-work 2bd3bec: the repro script re-stamps its clones' }; + GITHUB_SHA: '0f0abc6deadbeef', GITHUB_WORKFLOW: 'ci', GITHUB_TOKEN: 'x', RED_WATCH_TITLE: 'Merge box-work 2bd3bec: the repro script re-stamps its clones', + GITHUB_ACTOR: 'igneum-labs', RED_WATCH_AUTHOR: 'igneum-josh' }; const jobs = { jobs: [ { name: 'site build, link check, identity grep', conclusion: 'failure', steps: [{ name: 'site build', conclusion: 'success' }, { name: 'identity grep of the public export list', conclusion: 'failure' }] }, { name: 'igneum-pow tests, igneum-census build', conclusion: 'success', steps: [] }, @@ -226,6 +231,13 @@ async function selfTest() { if (lines[0].failed[1].step !== '(job never started: runner or billing)') fails.push('record: a job with no steps was not named as never started'); const text = formatLine(lines[0]); if (!/^CI red: ci on master @0f0abc6 "Merge box-work/.test(text) || !text.includes('actions/runs/424242')) fails.push(`format: ${text}`); + if (!text.includes('pushed by igneum-labs (commit by igneum-josh);') || !text.includes('site build at "identity grep of the public export list"')) fails.push(`format: the line does not name the pushing author and the red check: ${text}`); + // a feature branch is recorded and formatted like master (every branch since 7 October 2026) + const envFeature = { ...env, GITHUB_RUN_ID: '424299', GITHUB_REF_NAME: 'ca3-v4-node', RED_WATCH_AUTHOR: 'igneum-labs' }; + const fileFeature = path.join(dir, 'feature.jsonl'); + await record(fileFeature, envFeature, fakeFetch); + const textFeature = formatLine(readLines(fileFeature)[0]); + if (!/^CI red: ci on ca3-v4-node @0f0abc6 "Merge box-work[^"]*": pushed by igneum-labs; site build at/.test(textFeature)) fails.push(`format on a feature branch: ${textFeature}`); // post, dry run: prints, sends nothing, marks nothing let printed = []; const log = (s) => printed.push(s); const sends = []; const hookFetch = async (url, init) => { sends.push({ url, body: JSON.parse(init.body) }); return { ok: true, status: 204 }; }; @@ -274,7 +286,7 @@ async function selfTest() { if (!d3.sent) fails.push('digest: not sent the next day'); fs.rmSync(dir, { recursive: true, force: true }); if (fails.length) { for (const f of fails) console.error(`self-test failed: ${f}`); process.exit(1); } - console.log('self-test passed: one line per run however often record runs; the dry run sends nothing; a missing key is named, never a URL; one live send per run; a webhook error keeps the run pending; a box row is counted, never posted alone; the digest goes once per London day, at or after 09:00'); + console.log('self-test passed: one line per run however often record runs, on any branch, naming the pushing author; the dry run sends nothing; a missing key is named, never a URL; one live send per run; a webhook error keeps the run pending; a box row is counted, never posted alone; the digest goes once per London day, at or after 09:00'); } const cmd = args[0]; From 36e08c800bdfb6a8357b518043009e5dc65ade6b Mon Sep 17 00:00:00 2001 From: igneum-josh <337424239+igneum-josh@users.noreply.github.com> Date: Wed, 7 Oct 2026 14:09:04 +0100 Subject: [PATCH 17/19] CLAUDE.md: after every push the pushing lane reads its CI conclusion and owns any red before its next push; a red on any branch goes to main at once Co-Authored-By: Claude Fable 5.1 --- CLAUDE.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CLAUDE.md b/CLAUDE.md index 70e2feea3..d69e89184 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -129,7 +129,8 @@ The Mac crashed and rebooted under agent load (about twenty lanes, local cargo t ## CI red is stop-the-line (standing rule, 6 October 2026, 22:0x UK) - Whoever's merge turns master or a release-* branch red owns the fix inside 15 minutes or reverts the merge; the red watcher posts every failed run to the hidden updates channel and to /srv/ci-red/red.jsonl on the box (tools/ci/red-watch.mjs); the box's own red builds land in the same file with a class (remote-run.sh pre-flight, kept run logs) and the 09:00 UK digest counts them per class with each class's guard. -- The pre-push gate is the same script CI runs: `tools/ci/pre-push.sh` (installed by `tools/ci/install-hooks.sh`; `--hook` before a push to master or release-*, `--ci` in the workflow). A check is added there, never only in ci.yml. +- The pre-push gate is the same script CI runs: `tools/ci/pre-push.sh` (installed by `tools/ci/install-hooks.sh`; `--hook` before a push to master or release-*, `--ci` in the workflow). A check is added there, never only in ci.yml. On a feature branch the hook runs the light gate: the two structural checks plus the two never-push classes, the no-secrets check and the identity grep (7 October 2026). +- After every push, the pushing lane reads its CI conclusion (`gh run list --branch --limit 1` until it is not in progress, then `gh run view --log-failed` on a red) and owns any red before its next push; a red on any branch is reported to main the moment it is seen. The red watcher posts every failed run on every branch (branch, commit, red check, pushing author). Record: 7 October 2026, 11:26 to 12:47 UK, eight red runs on ca3-v4-node over three gate summaries carrying a 64-hex key, read by nobody. - Research and operations documents live outside the public export list: name them in `tools/ci/export-exclude.txt` (read by the identity check and by the mirror's sync.sh). What stays in the list is read by the public and must pass the identity grep. - A path Windows cannot hold (colon, trailing dot or space, reserved name, over 240 characters) never enters a commit: the pre-commit hook runs `tools/ci/windows-paths-check.sh --staged`. - Record: docs/analysis/ci-failures-2026-10-06.md (168 non-green runs in three days classified; 126 on master; all but two classes were tree checks that the gate now runs locally first). From 8dc58cebcd472a15f2b566ac85e7402bd040e235 Mon Sep 17 00:00:00 2001 From: igneum-josh <337424239+igneum-josh@users.noreply.github.com> Date: Wed, 7 Oct 2026 14:11:22 +0100 Subject: [PATCH 18/19] Counter ASIC 3.0 status: 0.3.20's cut set as it stands, 0.3.21's clock and the byte-5 fallback, the CI queue note Co-Authored-By: Claude Fable 5.1 --- docs/plans/counter-asic-3-status.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/plans/counter-asic-3-status.md b/docs/plans/counter-asic-3-status.md index 2014050bd..87b6b0e94 100644 --- a/docs/plans/counter-asic-3-status.md +++ b/docs/plans/counter-asic-3-status.md @@ -367,7 +367,7 @@ Three residual classes, all a constant delivered through a writer the rule admit | era-4 | dd8fdf6ff4f59eed | | era-5 | 8bf40f5cb858d835 | -Packs zip (eight packs, packs-ca3-v4-sub2) sha256 69c36772cd79e44e2ddd589466d9c64a94a13c9e970e9f27bd76feabb9b4581b. The suite re-runs through master's build-remote on box 2 (the worktree's own script predates --box; the first run died on the flag), line to follow; G1 on PC 2 under --cards-off after it. The sub-version-2 pairing waits on the node lane's re-pin to a788661687db4bb3 and byte 7. For the record, sub-version 1's pairing: igneum-pow 8c728ca3 against b7cc37e7 (8097d600's assert_ne in) 17 passed, 0 failed, rc 0, 12:21Z. THE INTEROP FACT stands from the void run: the 5899f603 hub accepted 235 object-byte-5 blocks from the 8097d600 node with 0 rejected, one digest on all five nodes on the live sixteen-field file. The gates: the digest test and the kaspa-pow vector test (the amended devnet epoch-0 id 1a4230699a6b9c60 must equal, c120d7963abdcd96 must differ, the v3 control unchanged) on the box; the mixed-version Devnet 2 gate (the amended 0.3.20 node beside a 5899f603 node for ten minutes on the live file without the v4 fields) after the Mac build; the fresh-join canary the 0.3.20 cut's | +Packs zip (eight packs, packs-ca3-v4-sub2) sha256 69c36772cd79e44e2ddd589466d9c64a94a13c9e970e9f27bd76feabb9b4581b. The suite re-runs through master's build-remote on box 2 (the worktree's own script predates --box; the first run died on the flag), line to follow; G1 on PC 2 under --cards-off after it. The sub-version-2 pairing waits on the node lane's re-pin to a788661687db4bb3 and byte 7. For the record, sub-version 1's pairing: igneum-pow 8c728ca3 against b7cc37e7 (8097d600's assert_ne in) 17 passed, 0 failed, rc 0, 12:21Z. 0.3.20's CUT SET AS IT STANDS (the shipper, 14:1x UK): pin c4459193, igneum-pow 8c728ca3 at object byte 5 (sub-version 1), the floor-moved file publishing with it (Josh's word; the floor from the live DAA at the publish plus 604,800, the digest read on c4459193), publish about 15:15Z (16:15 BST) on CASES END, the sweep from then with PC 1 first. 0.3.21's clock tonight: the node lane stages release-0.3.21-node at the shipper's sweep-end word (about 15:45Z, 16:45 BST) with the sub-version-2 re-pin (07a809a7, byte 7, id a788661687db4bb3) as its own commit, held pending the F8 census on 07a809a7; the census's clock about 14:00Z (15:00 BST) by the attack-pass lane's within-the-hour line from 13:01Z; the pass line every one of the 64 seeds under 1.2x of the window model on the chain path. If the census fails or slips past 19:00Z (20:00 BST), main's standing ruling applies (nothing on sub-version 2 is proposed until the census is green): 0.3.21's node ships byte 5 again with the re-pin dropped and the rest of its line kept. CI NOTE (13:1x UTC): master's ci runs since 12dc5c97 (nineteen of mine) sit queued behind one self-hosted runner (igneum-build-1, busy; 31 queued across branches, one in progress); the last completed master runs (439a233f to 5f990a09) are success; no red exists, the conclusions are unread until the queue drains. THE INTEROP FACT stands from the void run: the 5899f603 hub accepted 235 object-byte-5 blocks from the 8097d600 node with 0 rejected, one digest on all five nodes on the live sixteen-field file. The gates: the digest test and the kaspa-pow vector test (the amended devnet epoch-0 id 1a4230699a6b9c60 must equal, c120d7963abdcd96 must differ, the v3 control unchanged) on the box; the mixed-version Devnet 2 gate (the amended 0.3.20 node beside a 5899f603 node for ten minutes on the live file without the v4 fields) after the Mac build; the fresh-join canary the 0.3.20 cut's | | Main's rulings (7 October, morning) | no generator change to v4 on the live devnet; the record's null is the window model with numbers, sent by the hash lane to the attack-pass lane so AP-F8-1 re-gates against it; a fault beyond the model (a low-entropy source at site 15) stops at the coordinator with the two options priced (a 0.3.19 class amendment before the flip, or the flip held at the floor), nothing shipping without Josh's word; the tighter tail, an acceptance bound on the hot-set share, is a CLASS V5 item (sent to the v5 lane a6410f3b8abefb762 with the 64-seed census as its gate; the bound's number follows from the model) | ### AP-F4-1, the weak-day MUL draw (the attack-pass lane, 7 October, morning): PASS against v4, a class v5 rule From 8e1153b17861f0c453526a9365fde7a4ff4d6894 Mon Sep 17 00:00:00 2001 From: igneum-josh <337424239+igneum-josh@users.noreply.github.com> Date: Wed, 7 Oct 2026 14:13:02 +0100 Subject: [PATCH 19/19] Counter ASIC 3.0 status: main's word on the floor move, the CI lever and the rule's reading Co-Authored-By: Claude Fable 5.1 --- docs/plans/counter-asic-3-status.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/plans/counter-asic-3-status.md b/docs/plans/counter-asic-3-status.md index 87b6b0e94..781e591ca 100644 --- a/docs/plans/counter-asic-3-status.md +++ b/docs/plans/counter-asic-3-status.md @@ -367,7 +367,7 @@ Three residual classes, all a constant delivered through a writer the rule admit | era-4 | dd8fdf6ff4f59eed | | era-5 | 8bf40f5cb858d835 | -Packs zip (eight packs, packs-ca3-v4-sub2) sha256 69c36772cd79e44e2ddd589466d9c64a94a13c9e970e9f27bd76feabb9b4581b. The suite re-runs through master's build-remote on box 2 (the worktree's own script predates --box; the first run died on the flag), line to follow; G1 on PC 2 under --cards-off after it. The sub-version-2 pairing waits on the node lane's re-pin to a788661687db4bb3 and byte 7. For the record, sub-version 1's pairing: igneum-pow 8c728ca3 against b7cc37e7 (8097d600's assert_ne in) 17 passed, 0 failed, rc 0, 12:21Z. 0.3.20's CUT SET AS IT STANDS (the shipper, 14:1x UK): pin c4459193, igneum-pow 8c728ca3 at object byte 5 (sub-version 1), the floor-moved file publishing with it (Josh's word; the floor from the live DAA at the publish plus 604,800, the digest read on c4459193), publish about 15:15Z (16:15 BST) on CASES END, the sweep from then with PC 1 first. 0.3.21's clock tonight: the node lane stages release-0.3.21-node at the shipper's sweep-end word (about 15:45Z, 16:45 BST) with the sub-version-2 re-pin (07a809a7, byte 7, id a788661687db4bb3) as its own commit, held pending the F8 census on 07a809a7; the census's clock about 14:00Z (15:00 BST) by the attack-pass lane's within-the-hour line from 13:01Z; the pass line every one of the 64 seeds under 1.2x of the window model on the chain path. If the census fails or slips past 19:00Z (20:00 BST), main's standing ruling applies (nothing on sub-version 2 is proposed until the census is green): 0.3.21's node ships byte 5 again with the re-pin dropped and the rest of its line kept. CI NOTE (13:1x UTC): master's ci runs since 12dc5c97 (nineteen of mine) sit queued behind one self-hosted runner (igneum-build-1, busy; 31 queued across branches, one in progress); the last completed master runs (439a233f to 5f990a09) are success; no red exists, the conclusions are unread until the queue drains. THE INTEROP FACT stands from the void run: the 5899f603 hub accepted 235 object-byte-5 blocks from the 8097d600 node with 0 rejected, one digest on all five nodes on the live sixteen-field file. The gates: the digest test and the kaspa-pow vector test (the amended devnet epoch-0 id 1a4230699a6b9c60 must equal, c120d7963abdcd96 must differ, the v3 control unchanged) on the box; the mixed-version Devnet 2 gate (the amended 0.3.20 node beside a 5899f603 node for ten minutes on the live file without the v4 fields) after the Mac build; the fresh-join canary the 0.3.20 cut's | +Packs zip (eight packs, packs-ca3-v4-sub2) sha256 69c36772cd79e44e2ddd589466d9c64a94a13c9e970e9f27bd76feabb9b4581b. The suite re-runs through master's build-remote on box 2 (the worktree's own script predates --box; the first run died on the flag), line to follow; G1 on PC 2 under --cards-off after it. The sub-version-2 pairing waits on the node lane's re-pin to a788661687db4bb3 and byte 7. For the record, sub-version 1's pairing: igneum-pow 8c728ca3 against b7cc37e7 (8097d600's assert_ne in) 17 passed, 0 failed, rc 0, 12:21Z. 0.3.20's CUT SET AS IT STANDS (the shipper, 14:1x UK): pin c4459193, igneum-pow 8c728ca3 at object byte 5 (sub-version 1), the floor-moved file publishing with it (Josh's word; the floor from the live DAA at the publish plus 604,800, the digest read on c4459193), publish about 15:15Z (16:15 BST) on CASES END, the sweep from then with PC 1 first. 0.3.21's clock tonight: the node lane stages release-0.3.21-node at the shipper's sweep-end word (about 15:45Z, 16:45 BST) with the sub-version-2 re-pin (07a809a7, byte 7, id a788661687db4bb3) as its own commit, held pending the F8 census on 07a809a7; the census's clock about 14:00Z (15:00 BST) by the attack-pass lane's within-the-hour line from 13:01Z; the pass line every one of the 64 seeds under 1.2x of the window model on the chain path. If the census fails or slips past 19:00Z (20:00 BST), main's standing ruling applies (nothing on sub-version 2 is proposed until the census is green): 0.3.21's node ships byte 5 again with the re-pin dropped and the rest of its line kept. CI NOTE (13:1x UTC): master's ci runs since 12dc5c97 (nineteen of mine) sit queued behind one self-hosted runner (igneum-build-1, busy; 31 queued across branches, one in progress); the last completed master runs (439a233f to 5f990a09) are success; no red exists, the conclusions are unread until the queue drains. MAIN'S WORD (14:2x UK): the floor move is Josh's word already and ships with 0.3.20 at the cut; the CI lever is a second self-hosted runner on build-2 plus ubuntu-latest for docs-only pushes, ordered to the CI lane; the rule reads "own a red when the conclusion lands", never holding pushes; the census verdict about 14:00Z (15:00 UK) decides 0.3.21's byte. THE INTEROP FACT stands from the void run: the 5899f603 hub accepted 235 object-byte-5 blocks from the 8097d600 node with 0 rejected, one digest on all five nodes on the live sixteen-field file. The gates: the digest test and the kaspa-pow vector test (the amended devnet epoch-0 id 1a4230699a6b9c60 must equal, c120d7963abdcd96 must differ, the v3 control unchanged) on the box; the mixed-version Devnet 2 gate (the amended 0.3.20 node beside a 5899f603 node for ten minutes on the live file without the v4 fields) after the Mac build; the fresh-join canary the 0.3.20 cut's | | Main's rulings (7 October, morning) | no generator change to v4 on the live devnet; the record's null is the window model with numbers, sent by the hash lane to the attack-pass lane so AP-F8-1 re-gates against it; a fault beyond the model (a low-entropy source at site 15) stops at the coordinator with the two options priced (a 0.3.19 class amendment before the flip, or the flip held at the floor), nothing shipping without Josh's word; the tighter tail, an acceptance bound on the hot-set share, is a CLASS V5 item (sent to the v5 lane a6410f3b8abefb762 with the 64-seed census as its gate; the bound's number follows from the model) | ### AP-F4-1, the weak-day MUL draw (the attack-pass lane, 7 October, morning): PASS against v4, a class v5 rule