Merge remote-tracking branch 'box/master' into same-work-harness

# Conflicts:
#	docs/plans/igneum-2.0-test-registry.json
#	tools/ci/batches/same-work-20261008-02.json
This commit is contained in:
igneum-labs 2026-10-08 21:51:48 +00:00
commit d4718b2df7
44 changed files with 2196 additions and 495 deletions

View file

@ -378,6 +378,23 @@ The pairing, read back (20:3x BST, the igneum-pow CLI built from the ac86d7910 t
VERDICT (21:1x BST, to the coordinator and the hash lane; the mirror's sha of this landing is read back before any line says so): PASS on the acceptance's side on the frozen object's draw and acceptance (ac86d7910 = b24dfc162's, the packs' draw read back equal on both ids), under the full rule AND under the crate's own predicate, which now agree: 0 exhausted in 6,000 eras, the floors at 0 to 0.5 percent of reaching candidates, no hot set and nothing over 1.2x on the mirror-valid subset at 2^20, the bit-R class at its 6.11 level (the fold's half). The two things that stand outside this row: the live-dataset census on the fold and the 64-register window on the exact object is the kernel path's (Review B's F06, the census hand's instrument on the rented cards), and a later V6-02 commit on class-v6 (0266c9ec0, the executed load count routed into the acceptance) moved the reg64 verdicts and the re-exported id (0x1626c5853aa84261 at 43f1b1581 against the object's 0x4de7b836cc40a4ea), which the hash lane reported and is reverting; this section's rows are on ac86d7910, before it, and bind only that tree.
### 6.13 The chain-seed draw through the acceptance (class-v6 1a938abe4, the generator the chain runs; the coordinator's order of 21:3x BST; build-6, 21:49 to 21:54 BST)
The object: the one program the chain draws at genesis from the generator at 1a938abe4 (the final class-v6 tree, both of this lane's predicate findings in), class `mx8+sh256x27+state+reg64c+fold+rw`, epoch seed af89be5d..., day 20730. Two era inputs were in circulation at 21:4x BST and both are read back here, labelled; the engine's own era input is the one that binds, and the verdict line names it. The harness: the family harness ported onto 1a938abe4 (`logs/harness-v6-1a938abe4.diff`, 513 lines, the same port as 6.12's with the era taken from `IGNEUM_FG_EPOCH_HEX` and `IGNEUM_FG_ERA_HEX` when set, so the row is the chain's program and not a drawn one), one era per row, the full rule and the crate's own predicate (`IGNEUM_FG_CHAIN_PREDICATE=1`) at width 4 (the pinned genesis width) and at width 1; attack-f8 given a program-0 hex mode (`logs/attack-f8-program0-1a938abe4.diff`, 25 lines: `--programs 0..0` takes the same two hex inputs) on the mirror-valid subset `mx8+sh256x27+rw` at 2^20 nonces. The binary of every census row is a3c1da3b (the `bin/v6-1a938abe4...` test binary; `bin/v6-fin` is the same file by sha256).
The pairing, read back (the igneum-pow CLI built from the 1a938abe4 tree on build-6, `show` with the state file node1-state.igsd1, sha256 abb58003): input A, era `0:af89be5d...` (the pack hl-v6-all-chainseed's `program.json`: era_seed_bytes af89be5d..., id 0x442a1691b3e3507f) draws generator 6, era label 93a14ac6, attempt 0, program id 442a1691b3e3507f, equal to the pack; input B, era `0:edc4fa84...` (the genesis form the hash lane's 21:4x message carries) draws generator 6, era label d810f22d, attempt 0, program id 2a1d6caab4c24564, equal to the hash lane's read. The ids differ because the era input differs, not the tree: one CLI, one epoch, one state file.
| Row | Input A, era 0:af89be5d (id 442a1691b3e3507f) | Input B, era 0:edc4fa84 (id 2a1d6caab4c24564) |
|---|---|---|
| The era draw the harness reads (stride M, rotation R, windows) | M 5ea34e0b, R 12, windows [0, 1, 10, 15] at width 4, [10, 11, 13, 14] at width 1; weights add 16, xor 14, mul 4, mad 12, shfl 4, rotl 11, sub 10, mulhi 2, rotr 10, or 0 | M 9ad30d99, R 29, windows [0, 1, 6, 8] at width 4, [0, 2, 12, 13] at width 1; the same weight table |
| The full rule, width 4 | attempt 0, 1 candidate, every part 0: accepted first draw; minimum ratio 0.99994 at site 8 (floor 0.995); largest bucket 2.375 of the mean, +5.50 sigma at site 4 (the +8 line not reached); `logs/chainseed-w4-*` | attempt 0, 1 candidate, every part 0; minimum ratio 0.99991 at site 4; largest bucket 2.312 of the mean, +5.25 sigma at site 4; `logs/chainseed-gen-w4-*` |
| The crate's own predicate, width 4 | identical row (`logs/chainseed-w4-chainpred-*`): the two predicates agree on the chain's program as they did on 6.12's 1,500 | identical row (`logs/chainseed-gen-w4-chainpred-*`) |
| The full rule and the crate's predicate, width 1 | attempt 0, 1 candidate, every part 0; minimum ratio 0.99993 at site 3; bucket 2.250, +5.00 sigma at site 0; both predicates identical; `logs/chainseed-w1-*` | attempt 0, 1 candidate, every part 0; minimum ratio 0.99991 at site 6; bucket 2.375, +5.50 sigma at site 7; both predicates identical; `logs/chainseed-gen-w1-*` |
| The per-site index-bit read (the bit-R class of 6.2 and 6.12: 21.4 percent of width-4 eras over 6 sigma at one site, 74 percent of those at bit R) | width 4: bit 12 = R at site 2, window 1, z = minus 18.33: the chain's program at this era IS in the bit-R class, in the 6-to-100 sigma band (not the minus 512 mechanism of 6.2; the fold is on); width 1: bit 18, z = minus 3.40, clean | width 4: bit 4 at site 1, z = +3.82, clean of the class; width 1: bit 20, z = minus 3.39, clean |
| attack-f8, program 0 at 2^20 nonces, the mirror-valid subset `mx8+sh256x27+rw` (the fold, reg64c and state are the kernel path's, as in 6.12) | 6-sigma windowed clear, hot set clear, hottest item 34 reads of 2^20 (0.0000 percent), verdict PASS; lines per hash 1014 to 1024 of 1024 (925,106 nonces at 1024), items per hash 127 or 128 (494 at 127); `logs/f8-chainseed.log`, `logs/f8-chainseed-distinct.txt`, `logs/f8-chainseed-positions.txt` | 6-sigma windowed clear, hot set clear, verdict PASS; lines per hash 1014 to 1024 (925,441 at 1024), items per hash 127 or 128 (590 at 127); `logs/f8-chainseed-gen.log`, `logs/f8-chainseed-gen-distinct.txt`, `logs/f8-chainseed-gen-positions.txt` |
VERDICT (21:5x BST, to the node lane, the steward and the coordinator; the mirror's sha of this landing is read back before any line says so): PASS on the acceptance's side for the chain's program at 1a938abe4 under BOTH era inputs, under the full rule and under the crate's own predicate (which agree row for row): accepted at attempt 0 at both widths, every acceptance part 0, the (c''') ratio 0.9999 against the 0.995 floor, no bucket at the +8 line, no hot set and nothing over the 6-sigma window on the mirror-valid subset at 2^20. The one reading that differs between the inputs and is NOT an acceptance part: at width 4 the input-A program (era 0:af89be5d) sits in the bit-R class (bit 12 at site 2, 18 sigma), which 6.12 measured in 21 percent of width-4 eras on this tree and which the rule does not test; the input-B program (era 0:edc4fa84) is clean of it. If the engine's era input is A, the genesis program carries that known class at the measured level and the lane's standing line on it holds (the fold halves the class and leaves half; a per-era test on the index bits is the ring-B item the rule does not yet have); if B, it does not. RULING (the hash lane, 22:00 BST, closed by the coordinator; relayed by the node lane 22:1x): F0's pairing id is 2a1d6caab4c24564 on (epoch af89be5d, era edc4fa84, day 20730, node1 state abb58003), so input B's column is the signing object's and its verdict is the one that binds: PASS, clean of the bit-R class. Input A's era is the block hash used as the era, a different input and void for F0; its column stays landed as the pack hl-v6-all-chainseed's reproduction (442a1691b3e3507f read back equal) and the bit-R observation is recorded against that program only, not against the signing object.
## 7. The 16:30 BST report (the founder's clock, pulled from 09:00; a partial carries its count)
1. DONE 13:2x BST: the lossy-share curve per shape (section 6.4) and the last-resort scan's verdicts on every exhausted era.
@ -390,6 +407,7 @@ VERDICT (21:1x BST, to the coordinator and the hash lane; the mirror's sha of th
8. DONE 19:0x BST, section 6.10: the hash lane's layer-8-off draw (`+nowin`, class-v6 542cd7028) through the acceptance against the same-crate windowed control: PASS, the draw a third cheaper and the width-4 floor cost down from 13 to 2 percent of reaching candidates, 0 hot sets at 2^20, the bit-R mechanism unchanged (the fold the lever).
9. DONE 20:1x BST, section 6.11: the post-review object (class-v6 04442d9ca, the full class string) through the acceptance: PASS under the full rule; the second predicate finding (a width-4 class is not the class v4 shape to the crate's own predicate because of `mix`, so the chain's path runs the v2 parts only), a freeze condition; the registry batch `tools/ci/batches/family-gate-20261008.json` maps the harness to POW-02, ROT-07 and ROT-08 as partial coverage.
10. DONE 21:1x BST, section 6.12: the final tree (class-v6 ac86d7910, the packs' draw read back equal on both ids) through the acceptance under both predicates, which agree: PASS; the registry batches `tools/ci/batches/family-gate-20261008.json` (the CI steward's landing of the cell) and `family-gate-20261008b.json` (this landing, so the rows move with their evidence) at manifest ac86d7910, method native, status NOT RUN in the registry's vocabulary (partial coverage).
11. DONE 21:5x BST, section 6.13: the chain-seed draw at 1a938abe4 (the program the chain runs, read back at both era inputs in circulation: 442a1691b3e3507f at era 0:af89be5d, 2a1d6caab4c24564 at era 0:edc4fa84) through the acceptance under both predicates at widths 4 and 1 and through attack-f8 on the mirror-valid subset: PASS under both inputs; by the hash lane's 22:00 ruling the era-0:edc4fa84 column (2a1d6caab4c24564, clean of the bit-R class) is the signing object's, and the era-0:af89be5d column is the pack's reproduction (the block hash used as the era, void for F0), where alone the bit-R read sits.
11. Not in this report: the mixer ladder re-run at m = 4 and 16 (adv-mixer-3's harness rows; the per-family rows of section 4), the F8 census at D = 29 (the stand-in gap row), the 10^5-program verifier census at the top corner (F6 per family): each a named per-family row with its hours in section 4.1.
## 8. Sources

View file

@ -0,0 +1,11 @@
binary a3c1da3b180d9bd6 commit v6-fin test family_gate_era_census from 0 seeds 1 threads 4 start 2026-10-08T20:54:10Z
lease: holding 4 pool cores (8,9,10,11, waited 0 s, class release, mem 8 GB): family gate: family_gate_era_census chainseed-gen-w1-chainpred seeds 0+1
running 1 test
test accept::tests::family_gate_era_census ... family_gate_era_census: 1 eras 0..1 in 5 s on 4 threads -> /srv/builds/_adv-family-gate/logs/chainseed-gen-w1-chainpred-family_gate_era_census-0-1.tsv
ok
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 81 filtered out; finished in 4.61s
lease: released 4 pool cores after 4 s, exit 0
end 2026-10-08T20:54:14Z rc 0

View file

@ -0,0 +1,2 @@
k shape reps mixer width R M pos w_add w_xor w_mul w_mad w_shfl w_rotl w_sub w_mulhi w_rotr w_or attempt candidates a_prime a b c_const c_lane c_sat c_bias c_distinct c1_sat_source c2_low_entropy c3_hot_item c_other min_ratio min_site top_count_max bucket_ratio_max bucket_z_max bucket_site bucket_win bit_z_max bit_site bit_win bit last_resort_k c3_ratios secs
0 256 27 8 1 29 9ad30d99 [0, 2, 12, 13] 16 14 4 12 4 11 10 2 10 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0.99991 6 3 2.375 5.50 7 0 -3.39 6 2 20 4.6
1 k shape reps mixer width R M pos w_add w_xor w_mul w_mad w_shfl w_rotl w_sub w_mulhi w_rotr w_or attempt candidates a_prime a b c_const c_lane c_sat c_bias c_distinct c1_sat_source c2_low_entropy c3_hot_item c_other min_ratio min_site top_count_max bucket_ratio_max bucket_z_max bucket_site bucket_win bit_z_max bit_site bit_win bit last_resort_k c3_ratios secs
2 0 256 27 8 1 29 9ad30d99 [0, 2, 12, 13] 16 14 4 12 4 11 10 2 10 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0.99991 6 3 2.375 5.50 7 0 -3.39 6 2 20 4.6

View file

@ -0,0 +1,11 @@
binary a3c1da3b180d9bd6 commit v6-fin test family_gate_era_census from 0 seeds 1 threads 4 start 2026-10-08T20:54:05Z
lease: holding 4 pool cores (8,9,10,11, waited 0 s, class release, mem 8 GB): family gate: family_gate_era_census chainseed-gen-w1 seeds 0+1
running 1 test
test accept::tests::family_gate_era_census ... family_gate_era_census: 1 eras 0..1 in 5 s on 4 threads -> /srv/builds/_adv-family-gate/logs/chainseed-gen-w1-family_gate_era_census-0-1.tsv
ok
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 81 filtered out; finished in 4.59s
lease: released 4 pool cores after 5 s, exit 0
end 2026-10-08T20:54:10Z rc 0

View file

@ -0,0 +1,2 @@
k shape reps mixer width R M pos w_add w_xor w_mul w_mad w_shfl w_rotl w_sub w_mulhi w_rotr w_or attempt candidates a_prime a b c_const c_lane c_sat c_bias c_distinct c1_sat_source c2_low_entropy c3_hot_item c_other min_ratio min_site top_count_max bucket_ratio_max bucket_z_max bucket_site bucket_win bit_z_max bit_site bit_win bit last_resort_k c3_ratios secs
0 256 27 8 1 29 9ad30d99 [0, 2, 12, 13] 16 14 4 12 4 11 10 2 10 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0.99991 6 3 2.375 5.50 7 0 -3.39 6 2 20 4.6
1 k shape reps mixer width R M pos w_add w_xor w_mul w_mad w_shfl w_rotl w_sub w_mulhi w_rotr w_or attempt candidates a_prime a b c_const c_lane c_sat c_bias c_distinct c1_sat_source c2_low_entropy c3_hot_item c_other min_ratio min_site top_count_max bucket_ratio_max bucket_z_max bucket_site bucket_win bit_z_max bit_site bit_win bit last_resort_k c3_ratios secs
2 0 256 27 8 1 29 9ad30d99 [0, 2, 12, 13] 16 14 4 12 4 11 10 2 10 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0.99991 6 3 2.375 5.50 7 0 -3.39 6 2 20 4.6

View file

@ -0,0 +1,11 @@
binary a3c1da3b180d9bd6 commit v6-fin test family_gate_era_census from 0 seeds 1 threads 4 start 2026-10-08T20:54:19Z
lease: holding 4 pool cores (8,9,10,11, waited 1 s, class release, mem 8 GB): family gate: family_gate_era_census chainseed-gen-w4-chainpred seeds 0+1
running 1 test
test accept::tests::family_gate_era_census ... family_gate_era_census: 1 eras 0..1 in 5 s on 4 threads -> /srv/builds/_adv-family-gate/logs/chainseed-gen-w4-chainpred-family_gate_era_census-0-1.tsv
ok
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 81 filtered out; finished in 4.84s
lease: released 4 pool cores after 6 s, exit 0
end 2026-10-08T20:54:25Z rc 0

View file

@ -0,0 +1,2 @@
k shape reps mixer width R M pos w_add w_xor w_mul w_mad w_shfl w_rotl w_sub w_mulhi w_rotr w_or attempt candidates a_prime a b c_const c_lane c_sat c_bias c_distinct c1_sat_source c2_low_entropy c3_hot_item c_other min_ratio min_site top_count_max bucket_ratio_max bucket_z_max bucket_site bucket_win bit_z_max bit_site bit_win bit last_resort_k c3_ratios secs
0 256 27 8 4 29 9ad30d99 [0, 1, 6, 8] 16 14 4 12 4 11 10 2 10 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0.99991 4 4 2.312 5.25 4 0 3.82 1 1 4 4.8
1 k shape reps mixer width R M pos w_add w_xor w_mul w_mad w_shfl w_rotl w_sub w_mulhi w_rotr w_or attempt candidates a_prime a b c_const c_lane c_sat c_bias c_distinct c1_sat_source c2_low_entropy c3_hot_item c_other min_ratio min_site top_count_max bucket_ratio_max bucket_z_max bucket_site bucket_win bit_z_max bit_site bit_win bit last_resort_k c3_ratios secs
2 0 256 27 8 4 29 9ad30d99 [0, 1, 6, 8] 16 14 4 12 4 11 10 2 10 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0.99991 4 4 2.312 5.25 4 0 3.82 1 1 4 4.8

View file

@ -0,0 +1,11 @@
binary a3c1da3b180d9bd6 commit v6-fin test family_gate_era_census from 0 seeds 1 threads 4 start 2026-10-08T20:54:14Z
lease: holding 4 pool cores (8,9,10,11, waited 1 s, class release, mem 8 GB): family gate: family_gate_era_census chainseed-gen-w4 seeds 0+1
running 1 test
test accept::tests::family_gate_era_census ... family_gate_era_census: 1 eras 0..1 in 5 s on 4 threads -> /srv/builds/_adv-family-gate/logs/chainseed-gen-w4-family_gate_era_census-0-1.tsv
ok
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 81 filtered out; finished in 4.79s
lease: released 4 pool cores after 5 s, exit 0
end 2026-10-08T20:54:19Z rc 0

View file

@ -0,0 +1,2 @@
k shape reps mixer width R M pos w_add w_xor w_mul w_mad w_shfl w_rotl w_sub w_mulhi w_rotr w_or attempt candidates a_prime a b c_const c_lane c_sat c_bias c_distinct c1_sat_source c2_low_entropy c3_hot_item c_other min_ratio min_site top_count_max bucket_ratio_max bucket_z_max bucket_site bucket_win bit_z_max bit_site bit_win bit last_resort_k c3_ratios secs
0 256 27 8 4 29 9ad30d99 [0, 1, 6, 8] 16 14 4 12 4 11 10 2 10 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0.99991 4 4 2.312 5.25 4 0 3.82 1 1 4 4.8
1 k shape reps mixer width R M pos w_add w_xor w_mul w_mad w_shfl w_rotl w_sub w_mulhi w_rotr w_or attempt candidates a_prime a b c_const c_lane c_sat c_bias c_distinct c1_sat_source c2_low_entropy c3_hot_item c_other min_ratio min_site top_count_max bucket_ratio_max bucket_z_max bucket_site bucket_win bit_z_max bit_site bit_win bit last_resort_k c3_ratios secs
2 0 256 27 8 4 29 9ad30d99 [0, 1, 6, 8] 16 14 4 12 4 11 10 2 10 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0.99991 4 4 2.312 5.25 4 0 3.82 1 1 4 4.8

View file

@ -0,0 +1,11 @@
binary a3c1da3b180d9bd6 commit v6-fin test family_gate_era_census from 0 seeds 1 threads 4 start 2026-10-08T20:49:36Z
lease: holding 4 pool cores (8,9,10,11, waited 0 s, class release, mem 8 GB): family gate: family_gate_era_census chainseed-w1-chainpred seeds 0+1
running 1 test
test accept::tests::family_gate_era_census ... family_gate_era_census: 1 eras 0..1 in 5 s on 4 threads -> /srv/builds/_adv-family-gate/logs/chainseed-w1-chainpred-family_gate_era_census-0-1.tsv
ok
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 81 filtered out; finished in 4.67s
lease: released 4 pool cores after 4 s, exit 0
end 2026-10-08T20:49:40Z rc 0

View file

@ -0,0 +1,2 @@
k shape reps mixer width R M pos w_add w_xor w_mul w_mad w_shfl w_rotl w_sub w_mulhi w_rotr w_or attempt candidates a_prime a b c_const c_lane c_sat c_bias c_distinct c1_sat_source c2_low_entropy c3_hot_item c_other min_ratio min_site top_count_max bucket_ratio_max bucket_z_max bucket_site bucket_win bit_z_max bit_site bit_win bit last_resort_k c3_ratios secs
0 256 27 8 1 12 5ea34e0b [10, 11, 13, 14] 16 14 4 12 4 11 10 2 10 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0.99993 3 4 2.250 5.00 0 0 -3.40 8 1 18 4.7
1 k shape reps mixer width R M pos w_add w_xor w_mul w_mad w_shfl w_rotl w_sub w_mulhi w_rotr w_or attempt candidates a_prime a b c_const c_lane c_sat c_bias c_distinct c1_sat_source c2_low_entropy c3_hot_item c_other min_ratio min_site top_count_max bucket_ratio_max bucket_z_max bucket_site bucket_win bit_z_max bit_site bit_win bit last_resort_k c3_ratios secs
2 0 256 27 8 1 12 5ea34e0b [10, 11, 13, 14] 16 14 4 12 4 11 10 2 10 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0.99993 3 4 2.250 5.00 0 0 -3.40 8 1 18 4.7

View file

@ -0,0 +1,11 @@
binary a3c1da3b180d9bd6 commit v6-fin test family_gate_era_census from 0 seeds 1 threads 4 start 2026-10-08T20:49:30Z
lease: holding 4 pool cores (8,9,10,11, waited 0 s, class release, mem 8 GB): family gate: family_gate_era_census chainseed-w1 seeds 0+1
running 1 test
test accept::tests::family_gate_era_census ... family_gate_era_census: 1 eras 0..1 in 5 s on 4 threads -> /srv/builds/_adv-family-gate/logs/chainseed-w1-family_gate_era_census-0-1.tsv
ok
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 81 filtered out; finished in 4.80s
lease: released 4 pool cores after 5 s, exit 0
end 2026-10-08T20:49:36Z rc 0

View file

@ -0,0 +1,2 @@
k shape reps mixer width R M pos w_add w_xor w_mul w_mad w_shfl w_rotl w_sub w_mulhi w_rotr w_or attempt candidates a_prime a b c_const c_lane c_sat c_bias c_distinct c1_sat_source c2_low_entropy c3_hot_item c_other min_ratio min_site top_count_max bucket_ratio_max bucket_z_max bucket_site bucket_win bit_z_max bit_site bit_win bit last_resort_k c3_ratios secs
0 256 27 8 1 12 5ea34e0b [10, 11, 13, 14] 16 14 4 12 4 11 10 2 10 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0.99993 3 4 2.250 5.00 0 0 -3.40 8 1 18 4.8
1 k shape reps mixer width R M pos w_add w_xor w_mul w_mad w_shfl w_rotl w_sub w_mulhi w_rotr w_or attempt candidates a_prime a b c_const c_lane c_sat c_bias c_distinct c1_sat_source c2_low_entropy c3_hot_item c_other min_ratio min_site top_count_max bucket_ratio_max bucket_z_max bucket_site bucket_win bit_z_max bit_site bit_win bit last_resort_k c3_ratios secs
2 0 256 27 8 1 12 5ea34e0b [10, 11, 13, 14] 16 14 4 12 4 11 10 2 10 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0.99993 3 4 2.250 5.00 0 0 -3.40 8 1 18 4.8

View file

@ -0,0 +1,11 @@
binary a3c1da3b180d9bd6 commit v6-fin test family_gate_era_census from 0 seeds 1 threads 4 start 2026-10-08T20:49:45Z
lease: holding 4 pool cores (8,9,10,11, waited 1 s, class release, mem 8 GB): family gate: family_gate_era_census chainseed-w4-chainpred seeds 0+1
running 1 test
test accept::tests::family_gate_era_census ... family_gate_era_census: 1 eras 0..1 in 5 s on 4 threads -> /srv/builds/_adv-family-gate/logs/chainseed-w4-chainpred-family_gate_era_census-0-1.tsv
ok
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 81 filtered out; finished in 4.80s
lease: released 4 pool cores after 5 s, exit 0
end 2026-10-08T20:49:50Z rc 0

View file

@ -0,0 +1,2 @@
k shape reps mixer width R M pos w_add w_xor w_mul w_mad w_shfl w_rotl w_sub w_mulhi w_rotr w_or attempt candidates a_prime a b c_const c_lane c_sat c_bias c_distinct c1_sat_source c2_low_entropy c3_hot_item c_other min_ratio min_site top_count_max bucket_ratio_max bucket_z_max bucket_site bucket_win bit_z_max bit_site bit_win bit last_resort_k c3_ratios secs
0 256 27 8 4 12 5ea34e0b [0, 1, 10, 15] 16 14 4 12 4 11 10 2 10 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0.99994 8 5 2.375 5.50 4 0 -18.33 2 1 12 4.8
1 k shape reps mixer width R M pos w_add w_xor w_mul w_mad w_shfl w_rotl w_sub w_mulhi w_rotr w_or attempt candidates a_prime a b c_const c_lane c_sat c_bias c_distinct c1_sat_source c2_low_entropy c3_hot_item c_other min_ratio min_site top_count_max bucket_ratio_max bucket_z_max bucket_site bucket_win bit_z_max bit_site bit_win bit last_resort_k c3_ratios secs
2 0 256 27 8 4 12 5ea34e0b [0, 1, 10, 15] 16 14 4 12 4 11 10 2 10 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0.99994 8 5 2.375 5.50 4 0 -18.33 2 1 12 4.8

View file

@ -0,0 +1,11 @@
binary a3c1da3b180d9bd6 commit v6-fin test family_gate_era_census from 0 seeds 1 threads 4 start 2026-10-08T20:49:40Z
lease: holding 4 pool cores (8,9,10,11, waited 1 s, class release, mem 8 GB): family gate: family_gate_era_census chainseed-w4 seeds 0+1
running 1 test
test accept::tests::family_gate_era_census ... family_gate_era_census: 1 eras 0..1 in 5 s on 4 threads -> /srv/builds/_adv-family-gate/logs/chainseed-w4-family_gate_era_census-0-1.tsv
ok
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 81 filtered out; finished in 4.82s
lease: released 4 pool cores after 5 s, exit 0
end 2026-10-08T20:49:45Z rc 0

View file

@ -0,0 +1,2 @@
k shape reps mixer width R M pos w_add w_xor w_mul w_mad w_shfl w_rotl w_sub w_mulhi w_rotr w_or attempt candidates a_prime a b c_const c_lane c_sat c_bias c_distinct c1_sat_source c2_low_entropy c3_hot_item c_other min_ratio min_site top_count_max bucket_ratio_max bucket_z_max bucket_site bucket_win bit_z_max bit_site bit_win bit last_resort_k c3_ratios secs
0 256 27 8 4 12 5ea34e0b [0, 1, 10, 15] 16 14 4 12 4 11 10 2 10 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0.99994 8 5 2.375 5.50 4 0 -18.33 2 1 12 4.8
1 k shape reps mixer width R M pos w_add w_xor w_mul w_mad w_shfl w_rotl w_sub w_mulhi w_rotr w_or attempt candidates a_prime a b c_const c_lane c_sat c_bias c_distinct c1_sat_source c2_low_entropy c3_hot_item c_other min_ratio min_site top_count_max bucket_ratio_max bucket_z_max bucket_site bucket_win bit_z_max bit_site bit_win bit last_resort_k c3_ratios secs
2 0 256 27 8 4 12 5ea34e0b [0, 1, 10, 15] 16 14 4 12 4 11 10 2 10 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0.99994 8 5 2.375 5.50 4 0 -18.33 2 1 12 4.8

View file

@ -0,0 +1,119 @@
# distinct lines_hash: value count
lines_hash 1014 3
lines_hash 1015 50
lines_hash 1016 441
lines_hash 1020 9
lines_hash 1021 264
lines_hash 1022 7191
lines_hash 1023 115512
lines_hash 1024 925106
# distinct items_hash: value count
items_hash 127 494
items_hash 128 1048082
# distinct lines_warp: value count
lines_warp 32579 1
lines_warp 32581 1
lines_warp 32583 1
lines_warp 32584 1
lines_warp 32586 1
lines_warp 32587 1
lines_warp 32588 3
lines_warp 32589 2
lines_warp 32590 3
lines_warp 32591 4
lines_warp 32592 8
lines_warp 32593 3
lines_warp 32594 10
lines_warp 32595 12
lines_warp 32596 16
lines_warp 32597 12
lines_warp 32598 15
lines_warp 32599 23
lines_warp 32600 15
lines_warp 32601 34
lines_warp 32602 45
lines_warp 32603 40
lines_warp 32604 52
lines_warp 32605 61
lines_warp 32606 62
lines_warp 32607 87
lines_warp 32608 103
lines_warp 32609 120
lines_warp 32610 106
lines_warp 32611 134
lines_warp 32612 171
lines_warp 32613 158
lines_warp 32614 208
lines_warp 32615 251
lines_warp 32616 280
lines_warp 32617 306
lines_warp 32618 337
lines_warp 32619 400
lines_warp 32620 427
lines_warp 32621 445
lines_warp 32622 523
lines_warp 32623 559
lines_warp 32624 612
lines_warp 32625 660
lines_warp 32626 722
lines_warp 32627 695
lines_warp 32628 793
lines_warp 32629 850
lines_warp 32630 921
lines_warp 32631 894
lines_warp 32632 907
lines_warp 32633 967
lines_warp 32634 1050
lines_warp 32635 1067
lines_warp 32636 1058
lines_warp 32637 1044
lines_warp 32638 1066
lines_warp 32639 995
lines_warp 32640 1046
lines_warp 32641 995
lines_warp 32642 980
lines_warp 32643 902
lines_warp 32644 868
lines_warp 32645 863
lines_warp 32646 803
lines_warp 32647 744
lines_warp 32648 729
lines_warp 32649 680
lines_warp 32650 606
lines_warp 32651 608
lines_warp 32652 514
lines_warp 32653 423
lines_warp 32654 408
lines_warp 32655 372
lines_warp 32656 308
lines_warp 32657 266
lines_warp 32658 239
lines_warp 32659 197
lines_warp 32660 148
lines_warp 32661 133
lines_warp 32662 121
lines_warp 32663 96
lines_warp 32664 88
lines_warp 32665 68
lines_warp 32666 54
lines_warp 32667 42
lines_warp 32668 34
lines_warp 32669 18
lines_warp 32670 23
lines_warp 32671 14
lines_warp 32672 10
lines_warp 32673 5
lines_warp 32674 9
lines_warp 32675 3
lines_warp 32676 3
lines_warp 32680 1
lines_warp 32681 3
lines_warp 32682 1
lines_warp 32692 1
# distinct items_warp: value count
items_warp 4091 14
items_warp 4092 64
items_warp 4093 454
items_warp 4094 2535
items_warp 4095 10170
items_warp 4096 19531

View file

@ -0,0 +1,122 @@
# distinct lines_hash: value count
lines_hash 1014 7
lines_hash 1015 58
lines_hash 1016 525
lines_hash 1020 11
lines_hash 1021 302
lines_hash 1022 7094
lines_hash 1023 115138
lines_hash 1024 925441
# distinct items_hash: value count
items_hash 127 590
items_hash 128 1047986
# distinct lines_warp: value count
lines_warp 32575 1
lines_warp 32580 2
lines_warp 32581 2
lines_warp 32583 3
lines_warp 32585 1
lines_warp 32586 4
lines_warp 32587 2
lines_warp 32588 4
lines_warp 32589 8
lines_warp 32590 3
lines_warp 32591 7
lines_warp 32592 9
lines_warp 32593 8
lines_warp 32594 8
lines_warp 32595 8
lines_warp 32596 12
lines_warp 32597 11
lines_warp 32598 21
lines_warp 32599 32
lines_warp 32600 37
lines_warp 32601 32
lines_warp 32602 50
lines_warp 32603 37
lines_warp 32604 61
lines_warp 32605 74
lines_warp 32606 82
lines_warp 32607 89
lines_warp 32608 115
lines_warp 32609 134
lines_warp 32610 158
lines_warp 32611 165
lines_warp 32612 197
lines_warp 32613 216
lines_warp 32614 244
lines_warp 32615 250
lines_warp 32616 279
lines_warp 32617 357
lines_warp 32618 379
lines_warp 32619 404
lines_warp 32620 428
lines_warp 32621 465
lines_warp 32622 544
lines_warp 32623 630
lines_warp 32624 647
lines_warp 32625 638
lines_warp 32626 750
lines_warp 32627 792
lines_warp 32628 807
lines_warp 32629 840
lines_warp 32630 860
lines_warp 32631 890
lines_warp 32632 977
lines_warp 32633 975
lines_warp 32634 949
lines_warp 32635 1014
lines_warp 32636 1029
lines_warp 32637 1024
lines_warp 32638 973
lines_warp 32639 1056
lines_warp 32640 1006
lines_warp 32641 929
lines_warp 32642 1006
lines_warp 32643 975
lines_warp 32644 825
lines_warp 32645 853
lines_warp 32646 783
lines_warp 32647 713
lines_warp 32648 679
lines_warp 32649 637
lines_warp 32650 604
lines_warp 32651 564
lines_warp 32652 461
lines_warp 32653 443
lines_warp 32654 374
lines_warp 32655 373
lines_warp 32656 280
lines_warp 32657 253
lines_warp 32658 202
lines_warp 32659 197
lines_warp 32660 133
lines_warp 32661 132
lines_warp 32662 119
lines_warp 32663 93
lines_warp 32664 76
lines_warp 32665 70
lines_warp 32666 39
lines_warp 32667 32
lines_warp 32668 30
lines_warp 32669 26
lines_warp 32670 15
lines_warp 32671 12
lines_warp 32672 9
lines_warp 32673 7
lines_warp 32674 5
lines_warp 32675 2
lines_warp 32676 7
lines_warp 32677 4
lines_warp 32678 2
lines_warp 32679 2
lines_warp 32682 1
lines_warp 32687 1
# distinct items_warp: value count
items_warp 4090 1
items_warp 4091 16
items_warp 4092 85
items_warp 4093 633
items_warp 4094 3157
items_warp 4095 10682
items_warp 4096 18194

View file

@ -0,0 +1,129 @@
# position iteration site instr max_hi16_bucket_share saturated_share
0 0 0 1 0.000032 0.000000
1 0 1 15 0.000096 0.000000
2 0 2 27 0.000034 0.000000
3 0 3 28 0.000092 0.000000
4 0 4 30 0.000058 0.000000
5 0 5 32 0.000034 0.000000
6 0 6 33 0.000054 0.000000
7 0 7 42 0.000031 0.000000
8 0 8 48 0.000053 0.000000
9 0 9 52 0.000033 0.000000
10 0 10 55 0.000038 0.000000
11 0 11 56 0.000055 0.000000
12 0 12 58 0.000054 0.000000
13 0 13 59 0.000036 0.000000
14 0 14 60 0.000033 0.000000
15 0 15 62 0.000096 0.000000
16 1 0 1 0.000033 0.000000
17 1 1 15 0.000092 0.000000
18 1 2 27 0.000033 0.000000
19 1 3 28 0.000092 0.000000
20 1 4 30 0.000053 0.000000
21 1 5 32 0.000034 0.000000
22 1 6 33 0.000054 0.000000
23 1 7 42 0.000032 0.000000
24 1 8 48 0.000055 0.000000
25 1 9 52 0.000033 0.000000
26 1 10 55 0.000033 0.000000
27 1 11 56 0.000054 0.000000
28 1 12 58 0.000053 0.000000
29 1 13 59 0.000033 0.000000
30 1 14 60 0.000035 0.000000
31 1 15 62 0.000096 0.000000
32 2 0 1 0.000037 0.000000
33 2 1 15 0.000092 0.000000
34 2 2 27 0.000032 0.000000
35 2 3 28 0.000093 0.000000
36 2 4 30 0.000055 0.000000
37 2 5 32 0.000033 0.000000
38 2 6 33 0.000056 0.000000
39 2 7 42 0.000035 0.000000
40 2 8 48 0.000052 0.000000
41 2 9 52 0.000032 0.000000
42 2 10 55 0.000034 0.000000
43 2 11 56 0.000055 0.000000
44 2 12 58 0.000054 0.000000
45 2 13 59 0.000032 0.000000
46 2 14 60 0.000033 0.000000
47 2 15 62 0.000091 0.000000
48 3 0 1 0.000032 0.000000
49 3 1 15 0.000092 0.000000
50 3 2 27 0.000039 0.000000
51 3 3 28 0.000092 0.000000
52 3 4 30 0.000056 0.000000
53 3 5 32 0.000032 0.000000
54 3 6 33 0.000054 0.000000
55 3 7 42 0.000034 0.000000
56 3 8 48 0.000055 0.000000
57 3 9 52 0.000034 0.000000
58 3 10 55 0.000036 0.000000
59 3 11 56 0.000055 0.000000
60 3 12 58 0.000054 0.000000
61 3 13 59 0.000034 0.000000
62 3 14 60 0.000033 0.000000
63 3 15 62 0.000097 0.000000
64 4 0 1 0.000034 0.000000
65 4 1 15 0.000093 0.000000
66 4 2 27 0.000033 0.000000
67 4 3 28 0.000097 0.000000
68 4 4 30 0.000057 0.000000
69 4 5 32 0.000032 0.000000
70 4 6 33 0.000054 0.000000
71 4 7 42 0.000031 0.000000
72 4 8 48 0.000057 0.000000
73 4 9 52 0.000033 0.000000
74 4 10 55 0.000035 0.000000
75 4 11 56 0.000055 0.000000
76 4 12 58 0.000055 0.000000
77 4 13 59 0.000033 0.000000
78 4 14 60 0.000034 0.000000
79 4 15 62 0.000093 0.000000
80 5 0 1 0.000032 0.000000
81 5 1 15 0.000091 0.000000
82 5 2 27 0.000034 0.000000
83 5 3 28 0.000091 0.000000
84 5 4 30 0.000057 0.000000
85 5 5 32 0.000035 0.000000
86 5 6 33 0.000056 0.000000
87 5 7 42 0.000034 0.000000
88 5 8 48 0.000053 0.000000
89 5 9 52 0.000033 0.000000
90 5 10 55 0.000033 0.000000
91 5 11 56 0.000055 0.000000
92 5 12 58 0.000054 0.000000
93 5 13 59 0.000034 0.000000
94 5 14 60 0.000032 0.000000
95 5 15 62 0.000102 0.000000
96 6 0 1 0.000032 0.000000
97 6 1 15 0.000099 0.000000
98 6 2 27 0.000032 0.000000
99 6 3 28 0.000097 0.000000
100 6 4 30 0.000052 0.000000
101 6 5 32 0.000032 0.000000
102 6 6 33 0.000055 0.000000
103 6 7 42 0.000033 0.000000
104 6 8 48 0.000052 0.000000
105 6 9 52 0.000038 0.000000
106 6 10 55 0.000034 0.000000
107 6 11 56 0.000056 0.000000
108 6 12 58 0.000057 0.000000
109 6 13 59 0.000033 0.000000
110 6 14 60 0.000033 0.000000
111 6 15 62 0.000095 0.000000
112 7 0 1 0.000034 0.000000
113 7 1 15 0.000094 0.000000
114 7 2 27 0.000033 0.000000
115 7 3 28 0.000093 0.000000
116 7 4 30 0.000054 0.000000
117 7 5 32 0.000034 0.000000
118 7 6 33 0.000054 0.000000
119 7 7 42 0.000033 0.000000
120 7 8 48 0.000052 0.000000
121 7 9 52 0.000037 0.000000
122 7 10 55 0.000034 0.000000
123 7 11 56 0.000055 0.000000
124 7 12 58 0.000054 0.000000
125 7 13 59 0.000035 0.000000
126 7 14 60 0.000034 0.000000
127 7 15 62 0.000092 0.000000

View file

@ -0,0 +1,76 @@
lease: holding 8 pool cores (8,9,10,11,28,29,30,31, waited 0 s, class measure, mem 8 GB): family gate: 6.13, f8 census 2^20 on program 0 (the chain seed, genesis era) at mx8+sh256x27+rw, 1a938abe4
[2026-10-08T20:53:12Z] attack-f8 0.1.0 (igneum-pow 4); args ["census", "--programs", "0..0", "--nonces", "1048576", "--control", "window", "--by-site", "--threads", "8", "--out", "f8-chainseed-gen"]
[2026-10-08T20:53:12Z] census warps: programs [0] day 20730 nonces 1048576 threads 8 plant none validate all check_every 997 diag true
[2026-10-08T20:53:12Z] day 20730: cache filled in 0.41 s, fnv 448274a57f508cbc
[2026-10-08T20:53:22Z] table: 16777216 items derived with their 8 lines in 9.2 s; library comparison all (0 mismatches)
[2026-10-08T20:53:24Z] program p0-chain-seed: epoch seed af89be5ddbadb6f6b4aee28ac8f249713be5d4c12621e3cea7f83ceada3c66b3 era seed edc4fa844da9dc98d37e965176f6558a31560e40502ab3ae5491b21aaaabfb07 id 28d2180ecbb83984 attempt 0 class mx8-erad810f22d+sh256x27 op mix load=16 rotl=7 add=6 mad=6 shfl=6 sub=6 mulhi=5 rotr=5 mul=3 xor=3 or=1; era stride mul 0x9ad30d99 rot 29 interleave [0, 2, 12, 13] windows 1:0:0 15:2:2 27:0:0 28:2:2 30:1:1 32:0:0 33:1:1 42:0:0 48:1:1 52:0:0 55:0:0 56:1:1 58:1:1 59:0:0 60:0:0 62:2:1
[2026-10-08T20:53:24Z] load site instr 1: src r2 win 0 off 0; last base writer add at 0; writers back to the last injecting one: add@0; shadow writes of r2 per rep: add=4 mad=2 mulhi=2 rotl=3 rotr=1 shfl=2 sub=2 xor=4
[2026-10-08T20:53:24Z] load site instr 15: src r2 win 2 off 2; last base writer rotl at 3; writers back to the last injecting one: rotl@3 add@0; shadow writes of r2 per rep: add=4 mad=2 mulhi=2 rotl=3 rotr=1 shfl=2 sub=2 xor=4
[2026-10-08T20:53:24Z] load site instr 27: src r6 win 0 off 0; last base writer mad at 25; writers back to the last injecting one: mad@25; shadow writes of r6 per rep: add=4 mad=3 mul=3 mulhi=3 rotl=5 rotr=3 shfl=2 sub=3 xor=3
[2026-10-08T20:53:24Z] load site instr 28: src r2 win 2 off 2; last base writer sub at 24; writers back to the last injecting one: sub@24; shadow writes of r2 per rep: add=4 mad=2 mulhi=2 rotl=3 rotr=1 shfl=2 sub=2 xor=4
[2026-10-08T20:53:24Z] load site instr 30: src r1 win 1 off 1; last base writer sub at 26; writers back to the last injecting one: sub@26; shadow writes of r1 per rep: add=10 mad=3 mul=4 mulhi=3 or=2 rotl=1 rotr=1 shfl=5 sub=5 xor=2
[2026-10-08T20:53:24Z] load site instr 32: src r4 win 0 off 0; last base writer load at 30; writers back to the last injecting one: load@30; shadow writes of r4 per rep: add=1 mad=3 mul=3 mulhi=3 or=4 rotl=1 rotr=3 shfl=3 sub=3 xor=5
[2026-10-08T20:53:24Z] load site instr 33: src r3 win 1 off 1; last base writer sub at 21; writers back to the last injecting one: sub@21; shadow writes of r3 per rep: add=3 mad=4 mul=3 mulhi=3 or=2 rotl=4 rotr=3 shfl=3 sub=2 xor=3
[2026-10-08T20:53:24Z] load site instr 42: src r2 win 0 off 0; last base writer shfl at 41; writers back to the last injecting one: shfl@41; shadow writes of r2 per rep: add=4 mad=2 mulhi=2 rotl=3 rotr=1 shfl=2 sub=2 xor=4
[2026-10-08T20:53:24Z] load site instr 48: src r5 win 1 off 1; last base writer load at 32; writers back to the last injecting one: load@32; shadow writes of r5 per rep: add=4 mad=4 mul=2 mulhi=1 or=7 rotl=3 rotr=4 shfl=8 sub=4 xor=6
[2026-10-08T20:53:24Z] load site instr 52: src r3 win 0 off 0; last base writer mad at 51; writers back to the last injecting one: mad@51; shadow writes of r3 per rep: add=3 mad=4 mul=3 mulhi=3 or=2 rotl=4 rotr=3 shfl=3 sub=2 xor=3
[2026-10-08T20:53:24Z] load site instr 55: src r7 win 0 off 0; last base writer rotl at 54; writers back to the last injecting one: rotl@54 add@43; shadow writes of r7 per rep: add=10 mad=6 mul=4 mulhi=6 rotl=4 rotr=3 shfl=3 sub=5 xor=3
[2026-10-08T20:53:24Z] load site instr 56: src r2 win 1 off 1; last base writer rotl at 53; writers back to the last injecting one: rotl@53 shfl@41; shadow writes of r2 per rep: add=4 mad=2 mulhi=2 rotl=3 rotr=1 shfl=2 sub=2 xor=4
[2026-10-08T20:53:24Z] load site instr 58: src r4 win 1 off 1; last base writer rotr at 46; writers back to the last injecting one: rotr@46 load@42; shadow writes of r4 per rep: add=1 mad=3 mul=3 mulhi=3 or=4 rotl=1 rotr=3 shfl=3 sub=3 xor=5
[2026-10-08T20:53:24Z] load site instr 59: src r3 win 0 off 0; last base writer load at 58; writers back to the last injecting one: load@58; shadow writes of r3 per rep: add=3 mad=4 mul=3 mulhi=3 or=2 rotl=4 rotr=3 shfl=3 sub=2 xor=3
[2026-10-08T20:53:24Z] load site instr 60: src r0 win 0 off 0; last base writer load at 56; writers back to the last injecting one: load@56; shadow writes of r0 per rep: add=2 mad=3 mulhi=3 or=3 rotl=2 rotr=2 shfl=3 sub=2 xor=5
[2026-10-08T20:53:24Z] load site instr 62: src r5 win 2 off 1; last base writer load at 59; writers back to the last injecting one: load@59; shadow writes of r5 per rep: add=4 mad=4 mul=2 mulhi=1 or=7 rotl=3 rotr=4 shfl=8 sub=4 xor=6
[2026-10-08T20:53:24Z] window layer: site item windows (first, items) (0x0,2^24) (0x800000,2^22) (0x0,2^24) (0x800000,2^22) (0x800000,2^23) (0x0,2^24) (0x800000,2^23) (0x0,2^24) (0x800000,2^23) (0x0,2^24) (0x0,2^24) (0x800000,2^23) (0x800000,2^23) (0x0,2^24) (0x0,2^24) (0x400000,2^22); expected reads per item by quarter 4.000 6.000 13.000 9.000 (flat uniform 8.000)
[2026-10-08T20:53:34Z] 32768 warps (1048576 nonces) interpreted in 10.1 s (2.464 ms per warp per thread); Epoch::hash_warp agreement on 96 warps: 0 mismatches
[2026-10-08T20:53:34Z] p0-chain-seed distinct lines per hash: n 1048576 min 1014 p1 1023 median 1024 p99 1024 max 1024 mean 1023.8712
[2026-10-08T20:53:34Z] p0-chain-seed distinct items per hash: n 1048576 min 127 p1 128 median 128 p99 128 max 128 mean 127.9994
[2026-10-08T20:53:34Z] p0-chain-seed distinct lines per warp: n 32768 min 32575 p1 32604 median 32636 p99 32664 max 32687 mean 32635.6756
[2026-10-08T20:53:34Z] p0-chain-seed distinct items per warp: n 32768 min 4090 p1 4093 median 4096 p99 4096 max 4096 mean 4095.4104
[2026-10-08T20:53:34Z] uniform expectation: distinct lines per hash 1023.875 of 1024 reads, per warp 32640.3 of 32768 reads (2^22 lines); distinct items per hash 127.9995 of 128, per warp 4095.50 of 4096 (2^24 items)
[2026-10-08T20:53:34Z] positions: largest hi16-bucket (256 items) share 0.0102% at p95 (iteration 5, site 15, instr 62); windowed expectation 0.0061%; largest saturated-source share 0.0000% at p0 (site 0, instr 1)
[2026-10-08T20:53:34Z] acceptance-style (2,048 evaluations, the rule's sample size): the most repeated address at one position 2 of 2048 at p113 (site 1, instr 15); saturated sources at one position 0 of 2048 at p0 (site 0, instr 1); uniform expectation: repeats 1 to 2, saturated 0
[2026-10-08T20:53:34Z] p0-chain-seed item histogram (flat): bins 16777216 reads 134217728 mean 8.000 sigma 2.828 max 36 (bin 9945705) z_max +9.90 min 0 z_min -2.83 chi2/dof 2.43771 chi2_z +4164.06 top0.1% 0.31129% top0.5% 1.40443% top1% 2.67125%
[2026-10-08T20:53:35Z] p0-chain-seed item histogram against the window density: full 2^24 chi2/dof 1.00037 largest 18 (item 0x30ba0b) at +7.00 sigma smallest at -3.61; buckets64 chi2/dof 1.00289 largest 327 (bucket 63988) at +4.44 sigma smallest at -4.31
[2026-10-08T20:53:35Z] p0-chain-seed WINDOWED CONTROL item histogram (flat): bins 16777216 reads 134217728 mean 8.000 sigma 2.828 max 36 (bin 10342311) z_max +9.90 min 0 z_min -2.83 chi2/dof 2.43685 chi2_z +4161.57 top0.1% 0.31147% top0.5% 1.40444% top1% 2.67128%
[2026-10-08T20:53:35Z] p0-chain-seed WINDOWED CONTROL against the window density: full chi2/dof 0.99984 largest +6.53 sigma; buckets64 chi2/dof 1.00277 largest +4.65 smallest -4.51
[2026-10-08T20:53:35Z] 6-sigma p0-chain-seed items buckets64 against the window density: largest bucket +4.44 sigma, smallest -4.31 -> within 6 sigma
[2026-10-08T20:53:35Z] hot-set p0-chain-seed items (windowed control): f 0.1% S_f 0.31129% E_f(control) 0.31147% X_f -0.00018% X_f/f -0.0018 -> no hot set
[2026-10-08T20:53:35Z] hot-set p0-chain-seed items (windowed control): f 0.5% S_f 1.40443% E_f(control) 1.40444% X_f -0.00001% X_f/f -0.0000 -> no hot set
[2026-10-08T20:53:35Z] hot-set p0-chain-seed items (windowed control): f 1.0% S_f 2.67125% E_f(control) 2.67128% X_f -0.00004% X_f/f -0.0000 -> no hot set
[2026-10-08T20:53:35Z] hot-set p0-chain-seed items (windowed control): verdict clear
[2026-10-08T20:53:36Z] p0-chain-seed FLAT CONTROL item histogram: bins 16777216 reads 134217728 mean 8.000 sigma 2.828 max 27 (bin 12354048) z_max +6.72 min 0 z_min -2.83 chi2/dof 1.00026 chi2_z +0.76 top0.1% 0.23808% top0.5% 1.07965% top1% 2.05746%
[2026-10-08T20:53:36Z] hot-set p0-chain-seed items (flat control, the auditor's first view): f 0.1% S_f 0.31129% E_f(control) 0.23808% X_f +0.07321% X_f/f +0.7321 -> no hot set
[2026-10-08T20:53:36Z] hot-set p0-chain-seed items (flat control, the auditor's first view): f 0.5% S_f 1.40443% E_f(control) 1.07965% X_f +0.32479% X_f/f +0.6496 -> no hot set
[2026-10-08T20:53:36Z] hot-set p0-chain-seed items (flat control, the auditor's first view): f 1.0% S_f 2.67125% E_f(control) 2.05746% X_f +0.61379% X_f/f +0.6138 -> no hot set
[2026-10-08T20:53:36Z] hot-set p0-chain-seed items (flat control, the auditor's first view): verdict clear
[2026-10-08T20:53:36Z] ratio p0-chain-seed: top 0.1% / 0.5% / 1% share over the WINDOW-MODEL control 0.9994x / 1.0000x / 1.0000x (gate 1.2x at 0.1%: within); over the FLAT control 1.3075x / 1.3008x / 1.2983x
[2026-10-08T20:53:37Z] attribution: hot threshold count >= 23 marks 31851 items (0.1898% of items) holding 764508 reads (0.5696% of reads); top 8 items t=0x97c269:36 t=0x9b6345:35 t=0x8e0894:34 t=0xbb6e8d:33 t=0xaead92:33 t=0xacf907:33 t=0xaac459:33 t=0xa72ee7:33
[2026-10-08T20:53:41Z] attribution: reads on hot items per position (flat expectation 0.1898% of each position's 1048576 reads); the 24 largest: p33(it2 s1)=1.410% p67(it4 s3)=1.407% p81(it5 s1)=1.406% p65(it4 s1)=1.404% p19(it1 s3)=1.402% p51(it3 s3)=1.400% p83(it5 s3)=1.399% p35(it2 s3)=1.398% p99(it6 s3)=1.397% p49(it3 s1)=1.397% p17(it1 s1)=1.393% p3(it0 s3)=1.391% p97(it6 s1)=1.383% p1(it0 s1)=1.374% p113(it7 s1)=1.368% p115(it7 s3)=1.361% p28(it1 s12)=0.717% p40(it2 s8)=0.717% p52(it3 s4)=0.713% p102(it6 s6)=0.711% p6(it0 s6)=0.710% p68(it4 s4)=0.710% p36(it2 s4)=0.710% p24(it1 s8)=0.710%
[2026-10-08T20:53:41Z] attribution: hot reads by iteration it0=0.570% it1=0.570% it2=0.574% it3=0.570% it4=0.571% it5=0.568% it6=0.569% it7=0.566% ; by site s0=0.355% s1=1.392% s2=0.351% s3=1.394% s4=0.705% s5=0.351% s6=0.701% s7=0.351% s8=0.704% s9=0.351% s10=0.352% s11=0.699% s12=0.703% s13=0.351% s14=0.355% s15=0.000%
[2026-10-08T20:53:41Z] site 0 (instr 1, src r2, k_off 0 offset 0, window 2^24 items): share of its reads into the top 0.1% 0.3546% (flat expectation 0.1898%); index entropy 15.994 bits of 16 uniform-on-window; saturated source 0.0000%; largest 256-item bucket 0.0022% (window expectation 0.0015%)
[2026-10-08T20:53:41Z] site 1 (instr 15, src r2, k_off 2 offset 2, window 2^22 items): share of its reads into the top 0.1% 1.3917% (flat expectation 0.1898%); index entropy 13.999 bits of 14 uniform-on-window; saturated source 0.0000%; largest 256-item bucket 0.0072% (window expectation 0.0061%)
[2026-10-08T20:53:41Z] site 2 (instr 27, src r6, k_off 0 offset 0, window 2^24 items): share of its reads into the top 0.1% 0.3512% (flat expectation 0.1898%); index entropy 15.994 bits of 16 uniform-on-window; saturated source 0.0000%; largest 256-item bucket 0.0021% (window expectation 0.0015%)
[2026-10-08T20:53:41Z] site 3 (instr 28, src r2, k_off 2 offset 2, window 2^22 items): share of its reads into the top 0.1% 1.3943% (flat expectation 0.1898%); index entropy 13.999 bits of 14 uniform-on-window; saturated source 0.0000%; largest 256-item bucket 0.0072% (window expectation 0.0061%)
[2026-10-08T20:53:41Z] site 4 (instr 30, src r1, k_off 1 offset 1, window 2^23 items): share of its reads into the top 0.1% 0.7053% (flat expectation 0.1898%); index entropy 14.997 bits of 15 uniform-on-window; saturated source 0.0000%; largest 256-item bucket 0.0039% (window expectation 0.0031%)
[2026-10-08T20:53:41Z] site 5 (instr 32, src r4, k_off 0 offset 0, window 2^24 items): share of its reads into the top 0.1% 0.3509% (flat expectation 0.1898%); index entropy 15.994 bits of 16 uniform-on-window; saturated source 0.0000%; largest 256-item bucket 0.0022% (window expectation 0.0015%)
[2026-10-08T20:53:41Z] site 6 (instr 33, src r3, k_off 1 offset 1, window 2^23 items): share of its reads into the top 0.1% 0.7012% (flat expectation 0.1898%); index entropy 14.997 bits of 15 uniform-on-window; saturated source 0.0000%; largest 256-item bucket 0.0039% (window expectation 0.0031%)
[2026-10-08T20:53:41Z] site 7 (instr 42, src r2, k_off 0 offset 0, window 2^24 items): share of its reads into the top 0.1% 0.3509% (flat expectation 0.1898%); index entropy 15.994 bits of 16 uniform-on-window; saturated source 0.0000%; largest 256-item bucket 0.0022% (window expectation 0.0015%)
[2026-10-08T20:53:41Z] site 8 (instr 48, src r5, k_off 1 offset 1, window 2^23 items): share of its reads into the top 0.1% 0.7037% (flat expectation 0.1898%); index entropy 14.997 bits of 15 uniform-on-window; saturated source 0.0000%; largest 256-item bucket 0.0038% (window expectation 0.0031%)
[2026-10-08T20:53:41Z] site 9 (instr 52, src r3, k_off 0 offset 0, window 2^24 items): share of its reads into the top 0.1% 0.3505% (flat expectation 0.1898%); index entropy 15.994 bits of 16 uniform-on-window; saturated source 0.0000%; largest 256-item bucket 0.0021% (window expectation 0.0015%)
[2026-10-08T20:53:41Z] site 10 (instr 55, src r7, k_off 0 offset 0, window 2^24 items): share of its reads into the top 0.1% 0.3516% (flat expectation 0.1898%); index entropy 15.994 bits of 16 uniform-on-window; saturated source 0.0000%; largest 256-item bucket 0.0021% (window expectation 0.0015%)
[2026-10-08T20:53:41Z] site 11 (instr 56, src r2, k_off 1 offset 1, window 2^23 items): share of its reads into the top 0.1% 0.6992% (flat expectation 0.1898%); index entropy 14.997 bits of 15 uniform-on-window; saturated source 0.0000%; largest 256-item bucket 0.0039% (window expectation 0.0031%)
[2026-10-08T20:53:41Z] site 12 (instr 58, src r4, k_off 1 offset 1, window 2^23 items): share of its reads into the top 0.1% 0.7026% (flat expectation 0.1898%); index entropy 14.997 bits of 15 uniform-on-window; saturated source 0.0000%; largest 256-item bucket 0.0038% (window expectation 0.0031%)
[2026-10-08T20:53:41Z] site 13 (instr 59, src r3, k_off 0 offset 0, window 2^24 items): share of its reads into the top 0.1% 0.3514% (flat expectation 0.1898%); index entropy 15.994 bits of 16 uniform-on-window; saturated source 0.0000%; largest 256-item bucket 0.0021% (window expectation 0.0015%)
[2026-10-08T20:53:41Z] site 14 (instr 60, src r0, k_off 0 offset 0, window 2^24 items): share of its reads into the top 0.1% 0.3547% (flat expectation 0.1898%); index entropy 15.994 bits of 16 uniform-on-window; saturated source 0.0000%; largest 256-item bucket 0.0021% (window expectation 0.0015%)
[2026-10-08T20:53:41Z] site 15 (instr 62, src r5, k_off 2 offset 1, window 2^22 items): share of its reads into the top 0.1% 0.0000% (flat expectation 0.1898%); index entropy 13.999 bits of 14 uniform-on-window; saturated source 0.0000%; largest 256-item bucket 0.0072% (window expectation 0.0061%)
[2026-10-08T20:53:41Z] attribution: item 0x97c269 (36 reads) read from positions p8(it0 s8)x2 p17(it1 s1)x2 p35(it2 s3)x2 p51(it3 s3)x2 p92(it5 s12)x2 p108(it6 s12)x2 p120(it7 s8)x2 p2(it0 s2)x1 p5(it0 s5)x1 p22(it1 s6)x1 p23(it1 s7)x1 p24(it1 s8)x1
[2026-10-08T20:53:41Z] attribution: item 0x9b6345 (35 reads) read from positions p3(it0 s3)x3 p49(it3 s1)x2 p72(it4 s8)x2 p120(it7 s8)x2 p6(it0 s6)x1 p8(it0 s8)x1 p12(it0 s12)x1 p21(it1 s5)x1 p22(it1 s6)x1 p25(it1 s9)x1 p28(it1 s12)x1 p33(it2 s1)x1
[2026-10-08T20:53:41Z] attribution: item 0x8e0894 (34 reads) read from positions p11(it0 s11)x3 p92(it5 s12)x3 p1(it0 s1)x2 p35(it2 s3)x2 p51(it3 s3)x2 p52(it3 s4)x2 p3(it0 s3)x1 p13(it0 s13)x1 p19(it1 s3)x1 p27(it1 s11)x1 p33(it2 s1)x1 p38(it2 s6)x1
[2026-10-08T20:53:41Z] attribution: item 0xbb6e8d (33 reads) read from positions p35(it2 s3)x4 p113(it7 s1)x3 p33(it2 s1)x2 p1(it0 s1)x1 p2(it0 s2)x1 p6(it0 s6)x1 p19(it1 s3)x1 p30(it1 s14)x1 p34(it2 s2)x1 p38(it2 s6)x1 p41(it2 s9)x1 p46(it2 s14)x1
[2026-10-08T20:53:41Z] attribution: item 0xaead92 (33 reads) read from positions p3(it0 s3)x2 p17(it1 s1)x2 p49(it3 s1)x2 p53(it3 s5)x2 p83(it5 s3)x2 p113(it7 s1)x2 p115(it7 s3)x2 p8(it0 s8)x1 p10(it0 s10)x1 p22(it1 s6)x1 p23(it1 s7)x1 p27(it1 s11)x1
[2026-10-08T20:53:41Z] attribution: item 0xacf907 (33 reads) read from positions p3(it0 s3)x3 p86(it5 s6)x2 p115(it7 s3)x2 p124(it7 s12)x2 p8(it0 s8)x1 p11(it0 s11)x1 p23(it1 s7)x1 p24(it1 s8)x1 p33(it2 s1)x1 p35(it2 s3)x1 p40(it2 s8)x1 p43(it2 s11)x1
[2026-10-08T20:53:41Z] attribution: item 0xaac459 (33 reads) read from positions p4(it0 s4)x2 p12(it0 s12)x2 p41(it2 s9)x2 p84(it5 s4)x2 p3(it0 s3)x1 p6(it0 s6)x1 p19(it1 s3)x1 p22(it1 s6)x1 p24(it1 s8)x1 p28(it1 s12)x1 p32(it2 s0)x1 p36(it2 s4)x1
[2026-10-08T20:53:41Z] attribution: item 0xa72ee7 (33 reads) read from positions p44(it2 s12)x3 p6(it0 s6)x2 p57(it3 s9)x2 p97(it6 s1)x2 p114(it7 s2)x2 p0(it0 s0)x1 p1(it0 s1)x1 p8(it0 s8)x1 p11(it0 s11)x1 p16(it1 s0)x1 p27(it1 s11)x1 p32(it2 s0)x1
[2026-10-08T20:53:41Z] hottest item p0-chain-seed (0x97c269): 36 reads (0.0000% of all); predicted source none
[2026-10-08T20:53:41Z] program p0-chain-seed DONE: 1048576 nonces; 6-sigma (windowed) clear; hot-set clear; verdict PASS (no test fired)
lease: released 8 pool cores after 29 s, exit 0

View file

@ -0,0 +1,129 @@
# position iteration site instr max_hi16_bucket_share saturated_share
0 0 0 1 0.000032 0.000000
1 0 1 15 0.000053 0.000000
2 0 2 27 0.000093 0.000000
3 0 3 28 0.000034 0.000000
4 0 4 30 0.000053 0.000000
5 0 5 32 0.000053 0.000000
6 0 6 33 0.000091 0.000000
7 0 7 42 0.000034 0.000000
8 0 8 48 0.000055 0.000000
9 0 9 52 0.000034 0.000000
10 0 10 55 0.000092 0.000000
11 0 11 56 0.000037 0.000000
12 0 12 58 0.000053 0.000000
13 0 13 59 0.000032 0.000000
14 0 14 60 0.000055 0.000000
15 0 15 62 0.000054 0.000000
16 1 0 1 0.000036 0.000000
17 1 1 15 0.000054 0.000000
18 1 2 27 0.000092 0.000000
19 1 3 28 0.000034 0.000000
20 1 4 30 0.000055 0.000000
21 1 5 32 0.000056 0.000000
22 1 6 33 0.000095 0.000000
23 1 7 42 0.000033 0.000000
24 1 8 48 0.000054 0.000000
25 1 9 52 0.000032 0.000000
26 1 10 55 0.000097 0.000000
27 1 11 56 0.000032 0.000000
28 1 12 58 0.000053 0.000000
29 1 13 59 0.000033 0.000000
30 1 14 60 0.000055 0.000000
31 1 15 62 0.000055 0.000000
32 2 0 1 0.000032 0.000000
33 2 1 15 0.000060 0.000000
34 2 2 27 0.000094 0.000000
35 2 3 28 0.000035 0.000000
36 2 4 30 0.000053 0.000000
37 2 5 32 0.000055 0.000000
38 2 6 33 0.000096 0.000000
39 2 7 42 0.000033 0.000000
40 2 8 48 0.000053 0.000000
41 2 9 52 0.000032 0.000000
42 2 10 55 0.000092 0.000000
43 2 11 56 0.000034 0.000000
44 2 12 58 0.000054 0.000000
45 2 13 59 0.000032 0.000000
46 2 14 60 0.000056 0.000000
47 2 15 62 0.000053 0.000000
48 3 0 1 0.000037 0.000000
49 3 1 15 0.000056 0.000000
50 3 2 27 0.000093 0.000000
51 3 3 28 0.000034 0.000000
52 3 4 30 0.000058 0.000000
53 3 5 32 0.000054 0.000000
54 3 6 33 0.000093 0.000000
55 3 7 42 0.000032 0.000000
56 3 8 48 0.000058 0.000000
57 3 9 52 0.000034 0.000000
58 3 10 55 0.000093 0.000000
59 3 11 56 0.000034 0.000000
60 3 12 58 0.000053 0.000000
61 3 13 59 0.000037 0.000000
62 3 14 60 0.000056 0.000000
63 3 15 62 0.000054 0.000000
64 4 0 1 0.000034 0.000000
65 4 1 15 0.000054 0.000000
66 4 2 27 0.000098 0.000000
67 4 3 28 0.000032 0.000000
68 4 4 30 0.000060 0.000000
69 4 5 32 0.000057 0.000000
70 4 6 33 0.000097 0.000000
71 4 7 42 0.000036 0.000000
72 4 8 48 0.000055 0.000000
73 4 9 52 0.000033 0.000000
74 4 10 55 0.000093 0.000000
75 4 11 56 0.000033 0.000000
76 4 12 58 0.000055 0.000000
77 4 13 59 0.000037 0.000000
78 4 14 60 0.000054 0.000000
79 4 15 62 0.000058 0.000000
80 5 0 1 0.000033 0.000000
81 5 1 15 0.000056 0.000000
82 5 2 27 0.000094 0.000000
83 5 3 28 0.000034 0.000000
84 5 4 30 0.000053 0.000000
85 5 5 32 0.000054 0.000000
86 5 6 33 0.000099 0.000000
87 5 7 42 0.000033 0.000000
88 5 8 48 0.000055 0.000000
89 5 9 52 0.000034 0.000000
90 5 10 55 0.000094 0.000000
91 5 11 56 0.000032 0.000000
92 5 12 58 0.000055 0.000000
93 5 13 59 0.000037 0.000000
94 5 14 60 0.000054 0.000000
95 5 15 62 0.000054 0.000000
96 6 0 1 0.000033 0.000000
97 6 1 15 0.000055 0.000000
98 6 2 27 0.000091 0.000000
99 6 3 28 0.000035 0.000000
100 6 4 30 0.000054 0.000000
101 6 5 32 0.000055 0.000000
102 6 6 33 0.000094 0.000000
103 6 7 42 0.000033 0.000000
104 6 8 48 0.000054 0.000000
105 6 9 52 0.000034 0.000000
106 6 10 55 0.000092 0.000000
107 6 11 56 0.000039 0.000000
108 6 12 58 0.000055 0.000000
109 6 13 59 0.000033 0.000000
110 6 14 60 0.000055 0.000000
111 6 15 62 0.000057 0.000000
112 7 0 1 0.000037 0.000000
113 7 1 15 0.000054 0.000000
114 7 2 27 0.000090 0.000000
115 7 3 28 0.000035 0.000000
116 7 4 30 0.000053 0.000000
117 7 5 32 0.000053 0.000000
118 7 6 33 0.000102 0.000000
119 7 7 42 0.000034 0.000000
120 7 8 48 0.000059 0.000000
121 7 9 52 0.000032 0.000000
122 7 10 55 0.000093 0.000000
123 7 11 56 0.000036 0.000000
124 7 12 58 0.000052 0.000000
125 7 13 59 0.000032 0.000000
126 7 14 60 0.000051 0.000000
127 7 15 62 0.000055 0.000000

View file

@ -0,0 +1,76 @@
lease: holding 8 pool cores (8,9,10,11,28,29,30,31, waited 1 s, class release, mem 8 GB): family gate: 6.13, f8 census 2^20 on program 0 (the chain seed) at the mirror-valid subset mx8+sh256x27+rw, 1a938abe4
[2026-10-08T20:49:51Z] attack-f8 0.1.0 (igneum-pow 4); args ["census", "--programs", "0..0", "--nonces", "1048576", "--control", "window", "--by-site", "--threads", "8", "--out", "f8-chainseed"]
[2026-10-08T20:49:51Z] census warps: programs [0] day 20730 nonces 1048576 threads 8 plant none validate all check_every 997 diag true
[2026-10-08T20:49:51Z] day 20730: cache filled in 0.41 s, fnv 448274a57f508cbc
[2026-10-08T20:50:01Z] table: 16777216 items derived with their 8 lines in 9.2 s; library comparison all (0 mismatches)
[2026-10-08T20:50:03Z] program p0-chain-seed: epoch seed af89be5ddbadb6f6b4aee28ac8f249713be5d4c12621e3cea7f83ceada3c66b3 era seed af89be5ddbadb6f6b4aee28ac8f249713be5d4c12621e3cea7f83ceada3c66b3 id dcf3a6b79172f3b1 attempt 0 class mx8-era93a14ac6+sh256x27+rw op mix load=16 add=10 shfl=8 rotl=5 rotr=5 xor=5 mad=4 mul=4 sub=4 mulhi=3; era stride mul 0x5ea34e0b rot 12 interleave [10, 11, 13, 14] windows 1:0:0 15:1:0 27:2:1 28:0:0 30:1:1 32:1:0 33:2:3 42:0:0 48:1:0 52:0:0 55:2:2 56:0:0 58:1:1 59:0:0 60:1:0 62:1:0
[2026-10-08T20:50:03Z] load site instr 1: src r7 win 0 off 0; last base writer mad at 0; writers back to the last injecting one: mad@0; shadow writes of r7 per rep: add=4 mad=5 mul=2 rotl=5 rotr=6 shfl=1 sub=4 xor=6
[2026-10-08T20:50:03Z] load site instr 15: src r0 win 1 off 0; last base writer xor at 11; writers back to the last injecting one: xor@11; shadow writes of r0 per rep: add=8 mad=7 mul=1 mulhi=2 rotl=4 rotr=6 sub=3 xor=6
[2026-10-08T20:50:03Z] load site instr 27: src r7 win 2 off 1; last base writer sub at 12; writers back to the last injecting one: sub@12; shadow writes of r7 per rep: add=4 mad=5 mul=2 rotl=5 rotr=6 shfl=1 sub=4 xor=6
[2026-10-08T20:50:03Z] load site instr 28: src r0 win 0 off 0; last base writer xor at 25; writers back to the last injecting one: xor@25; shadow writes of r0 per rep: add=8 mad=7 mul=1 mulhi=2 rotl=4 rotr=6 sub=3 xor=6
[2026-10-08T20:50:03Z] load site instr 30: src r4 win 1 off 1; last base writer add at 20; writers back to the last injecting one: add@20; shadow writes of r4 per rep: add=6 mad=2 mul=2 rotl=5 rotr=3 shfl=1 sub=4 xor=5
[2026-10-08T20:50:03Z] load site instr 32: src r1 win 1 off 0; last base writer add at 31; writers back to the last injecting one: add@31; shadow writes of r1 per rep: add=4 mad=5 mul=1 mulhi=1 rotl=1 rotr=7 shfl=2 sub=2 xor=4
[2026-10-08T20:50:03Z] load site instr 33: src r2 win 2 off 3; last base writer load at 32; writers back to the last injecting one: load@32; shadow writes of r2 per rep: add=6 mad=4 mul=2 mulhi=2 rotl=2 rotr=3 shfl=4 sub=4 xor=4
[2026-10-08T20:50:03Z] load site instr 42: src r2 win 0 off 0; last base writer add at 41; writers back to the last injecting one: add@41; shadow writes of r2 per rep: add=6 mad=4 mul=2 mulhi=2 rotl=2 rotr=3 shfl=4 sub=4 xor=4
[2026-10-08T20:50:03Z] load site instr 48: src r6 win 1 off 0; last base writer shfl at 44; writers back to the last injecting one: shfl@44; shadow writes of r6 per rep: add=8 mad=5 mul=5 mulhi=1 rotl=5 rotr=5 sub=2 xor=9
[2026-10-08T20:50:03Z] load site instr 52: src r0 win 0 off 0; last base writer sub at 51; writers back to the last injecting one: sub@51; shadow writes of r0 per rep: add=8 mad=7 mul=1 mulhi=2 rotl=4 rotr=6 sub=3 xor=6
[2026-10-08T20:50:03Z] load site instr 55: src r5 win 2 off 2; last base writer sub at 49; writers back to the last injecting one: sub@49; shadow writes of r5 per rep: add=7 mad=4 mul=3 rotl=3 rotr=3 shfl=2 sub=5 xor=2
[2026-10-08T20:50:03Z] load site instr 56: src r4 win 0 off 0; last base writer shfl at 54; writers back to the last injecting one: shfl@54; shadow writes of r4 per rep: add=6 mad=2 mul=2 rotl=5 rotr=3 shfl=1 sub=4 xor=5
[2026-10-08T20:50:03Z] load site instr 58: src r5 win 1 off 1; last base writer shfl at 57; writers back to the last injecting one: shfl@57; shadow writes of r5 per rep: add=7 mad=4 mul=3 rotl=3 rotr=3 shfl=2 sub=5 xor=2
[2026-10-08T20:50:03Z] load site instr 59: src r7 win 0 off 0; last base writer xor at 43; writers back to the last injecting one: xor@43; shadow writes of r7 per rep: add=4 mad=5 mul=2 rotl=5 rotr=6 shfl=1 sub=4 xor=6
[2026-10-08T20:50:03Z] load site instr 60: src r1 win 1 off 0; last base writer load at 58; writers back to the last injecting one: load@58; shadow writes of r1 per rep: add=4 mad=5 mul=1 mulhi=1 rotl=1 rotr=7 shfl=2 sub=2 xor=4
[2026-10-08T20:50:03Z] load site instr 62: src r2 win 1 off 0; last base writer load at 60; writers back to the last injecting one: load@60; shadow writes of r2 per rep: add=6 mad=4 mul=2 mulhi=2 rotl=2 rotr=3 shfl=4 sub=4 xor=4
[2026-10-08T20:50:03Z] window layer: site item windows (first, items) (0x0,2^24) (0x0,2^23) (0x400000,2^22) (0x0,2^24) (0x800000,2^23) (0x0,2^23) (0xc00000,2^22) (0x0,2^24) (0x0,2^23) (0x0,2^24) (0x800000,2^22) (0x0,2^24) (0x800000,2^23) (0x0,2^24) (0x0,2^23) (0x0,2^23); expected reads per item by quarter 8.000 10.000 7.000 7.000 (flat uniform 8.000)
[2026-10-08T20:50:12Z] 32768 warps (1048576 nonces) interpreted in 9.6 s (2.341 ms per warp per thread); Epoch::hash_warp agreement on 96 warps: 0 mismatches
[2026-10-08T20:50:12Z] p0-chain-seed distinct lines per hash: n 1048576 min 1014 p1 1023 median 1024 p99 1024 max 1024 mean 1023.8715
[2026-10-08T20:50:12Z] p0-chain-seed distinct items per hash: n 1048576 min 127 p1 128 median 128 p99 128 max 128 mean 127.9995
[2026-10-08T20:50:12Z] p0-chain-seed distinct lines per warp: n 32768 min 32579 p1 32605 median 32637 p99 32664 max 32692 mean 32636.2978
[2026-10-08T20:50:12Z] p0-chain-seed distinct items per warp: n 32768 min 4091 p1 4093 median 4096 p99 4096 max 4096 mean 4095.4834
[2026-10-08T20:50:12Z] uniform expectation: distinct lines per hash 1023.875 of 1024 reads, per warp 32640.3 of 32768 reads (2^22 lines); distinct items per hash 127.9995 of 128, per warp 4095.50 of 4096 (2^24 items)
[2026-10-08T20:50:12Z] positions: largest hi16-bucket (256 items) share 0.0102% at p118 (iteration 7, site 6, instr 33); windowed expectation 0.0061%; largest saturated-source share 0.0000% at p0 (site 0, instr 1)
[2026-10-08T20:50:12Z] acceptance-style (2,048 evaluations, the rule's sample size): the most repeated address at one position 1 of 2048 at p0 (site 0, instr 1); saturated sources at one position 0 of 2048 at p0 (site 0, instr 1); uniform expectation: repeats 1 to 2, saturated 0
[2026-10-08T20:50:12Z] p0-chain-seed item histogram (flat): bins 16777216 reads 134217728 mean 8.000 sigma 2.828 max 34 (bin 4901318) z_max +9.19 min 0 z_min -2.83 chi2/dof 1.18766 chi2_z +543.52 top0.1% 0.25876% top0.5% 1.16072% top1% 2.20026%
[2026-10-08T20:50:12Z] p0-chain-seed item histogram against the window density: full 2^24 chi2/dof 1.00013 largest 34 (item 0x4ac9c6) at +7.59 sigma smallest at -3.16; buckets64 chi2/dof 1.00317 largest 546 (bucket 212024) at +4.63 sigma smallest at -4.58
[2026-10-08T20:50:13Z] p0-chain-seed WINDOWED CONTROL item histogram (flat): bins 16777216 reads 134217728 mean 8.000 sigma 2.828 max 29 (bin 4487742) z_max +7.42 min 0 z_min -2.83 chi2/dof 1.18810 chi2_z +544.79 top0.1% 0.25891% top0.5% 1.16133% top1% 2.20120%
[2026-10-08T20:50:13Z] p0-chain-seed WINDOWED CONTROL against the window density: full chi2/dof 1.00038 largest +6.80 sigma; buckets64 chi2/dof 1.00364 largest +4.77 smallest -4.68
[2026-10-08T20:50:13Z] 6-sigma p0-chain-seed items buckets64 against the window density: largest bucket +4.63 sigma, smallest -4.58 -> within 6 sigma
[2026-10-08T20:50:13Z] hot-set p0-chain-seed items (windowed control): f 0.1% S_f 0.25876% E_f(control) 0.25891% X_f -0.00015% X_f/f -0.0015 -> no hot set
[2026-10-08T20:50:13Z] hot-set p0-chain-seed items (windowed control): f 0.5% S_f 1.16072% E_f(control) 1.16133% X_f -0.00061% X_f/f -0.0012 -> no hot set
[2026-10-08T20:50:13Z] hot-set p0-chain-seed items (windowed control): f 1.0% S_f 2.20026% E_f(control) 2.20120% X_f -0.00094% X_f/f -0.0009 -> no hot set
[2026-10-08T20:50:13Z] hot-set p0-chain-seed items (windowed control): verdict clear
[2026-10-08T20:50:13Z] p0-chain-seed FLAT CONTROL item histogram: bins 16777216 reads 134217728 mean 8.000 sigma 2.828 max 27 (bin 12354048) z_max +6.72 min 0 z_min -2.83 chi2/dof 1.00026 chi2_z +0.76 top0.1% 0.23808% top0.5% 1.07965% top1% 2.05746%
[2026-10-08T20:50:13Z] hot-set p0-chain-seed items (flat control, the auditor's first view): f 0.1% S_f 0.25876% E_f(control) 0.23808% X_f +0.02068% X_f/f +0.2068 -> no hot set
[2026-10-08T20:50:13Z] hot-set p0-chain-seed items (flat control, the auditor's first view): f 0.5% S_f 1.16072% E_f(control) 1.07965% X_f +0.08107% X_f/f +0.1621 -> no hot set
[2026-10-08T20:50:13Z] hot-set p0-chain-seed items (flat control, the auditor's first view): f 1.0% S_f 2.20026% E_f(control) 2.05746% X_f +0.14281% X_f/f +0.1428 -> no hot set
[2026-10-08T20:50:13Z] hot-set p0-chain-seed items (flat control, the auditor's first view): verdict clear
[2026-10-08T20:50:13Z] ratio p0-chain-seed: top 0.1% / 0.5% / 1% share over the WINDOW-MODEL control 0.9994x / 0.9995x / 0.9996x (gate 1.2x at 0.1%: within); over the FLAT control 1.0869x / 1.0751x / 1.0694x
[2026-10-08T20:50:14Z] attribution: hot threshold count >= 19 marks 33871 items (0.2019% of items) holding 672094 reads (0.5007% of reads); top 8 items t=0x4ac9c6:34 t=0x6aa2ef:31 t=0x4246e0:29 t=0x79e507:28 t=0x74b686:28 t=0x741c68:28 t=0x662ae7:28 t=0x553866:28
[2026-10-08T20:50:19Z] attribution: reads on hot items per position (flat expectation 0.2019% of each position's 1048576 reads); the 24 largest: p2(it0 s2)=1.434% p114(it7 s2)=1.433% p50(it3 s2)=1.433% p82(it5 s2)=1.431% p98(it6 s2)=1.426% p34(it2 s2)=1.424% p18(it1 s2)=1.420% p66(it4 s2)=1.408% p78(it4 s14)=0.822% p126(it7 s14)=0.811% p8(it0 s8)=0.808% p33(it2 s1)=0.808% p24(it1 s8)=0.807% p14(it0 s14)=0.805% p94(it5 s14)=0.805% p111(it6 s15)=0.802% p117(it7 s5)=0.801% p40(it2 s8)=0.797% p37(it2 s5)=0.796% p88(it5 s8)=0.795% p15(it0 s15)=0.795% p31(it1 s15)=0.795% p110(it6 s14)=0.795% p72(it4 s8)=0.794%
[2026-10-08T20:50:19Z] attribution: hot reads by iteration it0=0.503% it1=0.503% it2=0.499% it3=0.499% it4=0.498% it5=0.503% it6=0.500% it7=0.501% ; by site s0=0.414% s1=0.789% s2=1.426% s3=0.411% s4=0.036% s5=0.789% s6=0.038% s7=0.415% s8=0.795% s9=0.412% s10=0.035% s11=0.412% s12=0.036% s13=0.410% s14=0.801% s15=0.791%
[2026-10-08T20:50:19Z] site 0 (instr 1, src r7, k_off 0 offset 0, window 2^24 items): share of its reads into the top 0.1% 0.4140% (flat expectation 0.2019%); index entropy 15.994 bits of 16 uniform-on-window; saturated source 0.0000%; largest 256-item bucket 0.0021% (window expectation 0.0015%)
[2026-10-08T20:50:19Z] site 1 (instr 15, src r0, k_off 1 offset 0, window 2^23 items): share of its reads into the top 0.1% 0.7891% (flat expectation 0.2019%); index entropy 14.997 bits of 15 uniform-on-window; saturated source 0.0000%; largest 256-item bucket 0.0039% (window expectation 0.0031%)
[2026-10-08T20:50:19Z] site 2 (instr 27, src r7, k_off 2 offset 1, window 2^22 items): share of its reads into the top 0.1% 1.4262% (flat expectation 0.2019%); index entropy 13.999 bits of 14 uniform-on-window; saturated source 0.0000%; largest 256-item bucket 0.0072% (window expectation 0.0061%)
[2026-10-08T20:50:19Z] site 3 (instr 28, src r0, k_off 0 offset 0, window 2^24 items): share of its reads into the top 0.1% 0.4115% (flat expectation 0.2019%); index entropy 15.994 bits of 16 uniform-on-window; saturated source 0.0000%; largest 256-item bucket 0.0021% (window expectation 0.0015%)
[2026-10-08T20:50:19Z] site 4 (instr 30, src r4, k_off 1 offset 1, window 2^23 items): share of its reads into the top 0.1% 0.0360% (flat expectation 0.2019%); index entropy 14.997 bits of 15 uniform-on-window; saturated source 0.0000%; largest 256-item bucket 0.0039% (window expectation 0.0031%)
[2026-10-08T20:50:19Z] site 5 (instr 32, src r1, k_off 1 offset 0, window 2^23 items): share of its reads into the top 0.1% 0.7895% (flat expectation 0.2019%); index entropy 14.997 bits of 15 uniform-on-window; saturated source 0.0000%; largest 256-item bucket 0.0038% (window expectation 0.0031%)
[2026-10-08T20:50:19Z] site 6 (instr 33, src r2, k_off 2 offset 3, window 2^22 items): share of its reads into the top 0.1% 0.0380% (flat expectation 0.2019%); index entropy 13.999 bits of 14 uniform-on-window; saturated source 0.0000%; largest 256-item bucket 0.0071% (window expectation 0.0061%)
[2026-10-08T20:50:19Z] site 7 (instr 42, src r2, k_off 0 offset 0, window 2^24 items): share of its reads into the top 0.1% 0.4152% (flat expectation 0.2019%); index entropy 15.994 bits of 16 uniform-on-window; saturated source 0.0000%; largest 256-item bucket 0.0021% (window expectation 0.0015%)
[2026-10-08T20:50:19Z] site 8 (instr 48, src r6, k_off 1 offset 0, window 2^23 items): share of its reads into the top 0.1% 0.7949% (flat expectation 0.2019%); index entropy 14.997 bits of 15 uniform-on-window; saturated source 0.0000%; largest 256-item bucket 0.0038% (window expectation 0.0031%)
[2026-10-08T20:50:19Z] site 9 (instr 52, src r0, k_off 0 offset 0, window 2^24 items): share of its reads into the top 0.1% 0.4120% (flat expectation 0.2019%); index entropy 15.994 bits of 16 uniform-on-window; saturated source 0.0000%; largest 256-item bucket 0.0021% (window expectation 0.0015%)
[2026-10-08T20:50:19Z] site 10 (instr 55, src r5, k_off 2 offset 2, window 2^22 items): share of its reads into the top 0.1% 0.0348% (flat expectation 0.2019%); index entropy 13.999 bits of 14 uniform-on-window; saturated source 0.0000%; largest 256-item bucket 0.0074% (window expectation 0.0061%)
[2026-10-08T20:50:19Z] site 11 (instr 56, src r4, k_off 0 offset 0, window 2^24 items): share of its reads into the top 0.1% 0.4124% (flat expectation 0.2019%); index entropy 15.994 bits of 16 uniform-on-window; saturated source 0.0000%; largest 256-item bucket 0.0021% (window expectation 0.0015%)
[2026-10-08T20:50:19Z] site 12 (instr 58, src r5, k_off 1 offset 1, window 2^23 items): share of its reads into the top 0.1% 0.0361% (flat expectation 0.2019%); index entropy 14.997 bits of 15 uniform-on-window; saturated source 0.0000%; largest 256-item bucket 0.0038% (window expectation 0.0031%)
[2026-10-08T20:50:19Z] site 13 (instr 59, src r7, k_off 0 offset 0, window 2^24 items): share of its reads into the top 0.1% 0.4105% (flat expectation 0.2019%); index entropy 15.994 bits of 16 uniform-on-window; saturated source 0.0000%; largest 256-item bucket 0.0023% (window expectation 0.0015%)
[2026-10-08T20:50:19Z] site 14 (instr 60, src r1, k_off 1 offset 0, window 2^23 items): share of its reads into the top 0.1% 0.8010% (flat expectation 0.2019%); index entropy 14.997 bits of 15 uniform-on-window; saturated source 0.0000%; largest 256-item bucket 0.0038% (window expectation 0.0031%)
[2026-10-08T20:50:19Z] site 15 (instr 62, src r2, k_off 1 offset 0, window 2^23 items): share of its reads into the top 0.1% 0.7909% (flat expectation 0.2019%); index entropy 14.997 bits of 15 uniform-on-window; saturated source 0.0000%; largest 256-item bucket 0.0038% (window expectation 0.0031%)
[2026-10-08T20:50:19Z] attribution: item 0x4ac9c6 (34 reads) read from positions p5(it0 s5)x3 p15(it0 s15)x2 p33(it2 s1)x2 p63(it3 s15)x2 p69(it4 s5)x2 p79(it4 s15)x2 p1(it0 s1)x1 p18(it1 s2)x1 p21(it1 s5)x1 p24(it1 s8)x1 p31(it1 s15)x1 p45(it2 s13)x1
[2026-10-08T20:50:19Z] attribution: item 0x6aa2ef (31 reads) read from positions p2(it0 s2)x2 p18(it1 s2)x2 p19(it1 s3)x2 p109(it6 s13)x2 p114(it7 s2)x2 p119(it7 s7)x2 p8(it0 s8)x1 p9(it0 s9)x1 p30(it1 s14)x1 p43(it2 s11)x1 p53(it3 s5)x1 p65(it4 s1)x1
[2026-10-08T20:50:19Z] attribution: item 0x4246e0 (29 reads) read from positions p50(it3 s2)x3 p110(it6 s14)x2 p114(it7 s2)x2 p16(it1 s0)x1 p18(it1 s2)x1 p29(it1 s13)x1 p30(it1 s14)x1 p35(it2 s3)x1 p41(it2 s9)x1 p43(it2 s11)x1 p53(it3 s5)x1 p55(it3 s7)x1
[2026-10-08T20:50:19Z] attribution: item 0x79e507 (28 reads) read from positions p2(it0 s2)x2 p62(it3 s14)x2 p63(it3 s15)x2 p0(it0 s0)x1 p8(it0 s8)x1 p14(it0 s14)x1 p18(it1 s2)x1 p24(it1 s8)x1 p29(it1 s13)x1 p30(it1 s14)x1 p33(it2 s1)x1 p34(it2 s2)x1
[2026-10-08T20:50:19Z] attribution: item 0x74b686 (28 reads) read from positions p72(it4 s8)x2 p79(it4 s15)x2 p85(it5 s5)x2 p121(it7 s9)x2 p2(it0 s2)x1 p5(it0 s5)x1 p13(it0 s13)x1 p14(it0 s14)x1 p17(it1 s1)x1 p24(it1 s8)x1 p30(it1 s14)x1 p31(it1 s15)x1
[2026-10-08T20:50:19Z] attribution: item 0x741c68 (28 reads) read from positions p82(it5 s2)x3 p24(it1 s8)x2 p34(it2 s2)x2 p50(it3 s2)x2 p109(it6 s13)x2 p114(it7 s2)x2 p2(it0 s2)x1 p3(it0 s3)x1 p5(it0 s5)x1 p14(it0 s14)x1 p21(it1 s5)x1 p41(it2 s9)x1
[2026-10-08T20:50:19Z] attribution: item 0x662ae7 (28 reads) read from positions p18(it1 s2)x2 p104(it6 s8)x2 p1(it0 s1)x1 p2(it0 s2)x1 p3(it0 s3)x1 p9(it0 s9)x1 p14(it0 s14)x1 p15(it0 s15)x1 p24(it1 s8)x1 p32(it2 s0)x1 p37(it2 s5)x1 p39(it2 s7)x1
[2026-10-08T20:50:19Z] attribution: item 0x553866 (28 reads) read from positions p1(it0 s1)x2 p34(it2 s2)x2 p65(it4 s1)x2 p79(it4 s15)x2 p7(it0 s7)x1 p17(it1 s1)x1 p21(it1 s5)x1 p24(it1 s8)x1 p40(it2 s8)x1 p50(it3 s2)x1 p53(it3 s5)x1 p56(it3 s8)x1
[2026-10-08T20:50:19Z] hottest item p0-chain-seed (0x4ac9c6): 34 reads (0.0000% of all); predicted source none
[2026-10-08T20:50:19Z] program p0-chain-seed DONE: 1048576 nonces; 6-sigma (windowed) clear; hot-set clear; verdict PASS (no test fired)
lease: released 8 pool cores after 29 s, exit 0

View file

@ -0,0 +1,513 @@
diff --git a/igneum-pow/src/accept.rs b/igneum-pow/src/accept.rs
--- a/igneum-pow/src/accept.rs
+++ b/igneum-pow/src/accept.rs
@@ -365,7 +365,88 @@ pub struct SiteIndexStats {
/// The window of a load site in words at the rule's dataset: `2^28 >> min(win, 2)`.
pub fn site_window_words(ins: &Instr) -> u64 {
- (1u64 << ACCEPT_DATASET_LOG2) >> (ins.win as u64).min(2)
+ // a load of `width` words reads an aligned address, so its index space is the window over `width` (1 on every
+ // shipped class; the class v6 family-gate harness draws 4 and the expectation must follow, 8 October 2026)
+ ((1u64 << ACCEPT_DATASET_LOG2) >> (ins.win as u64).min(2)) / (ins.width.max(1) as u64)
+}
+
+/// Class v6 family-gate harness: what one load site's indices look like beyond [`SiteIndexStats`]: the largest
+/// 256-item bucket (4,096 words, the bucket of the F8 tail attribution of 8 October 2026) as a ratio to the window's
+/// expectation and in sigma of it, and the largest index-bit one-count excess in sigma over the window's free bits
+/// (adv-cache-2's value-level read: a product's low bits placed at address bit R and up).
+#[derive(Clone, Copy, Debug, PartialEq)]
+pub struct FamilySiteStats {
+ pub base: SiteIndexStats,
+ pub bucket_ratio: f64,
+ pub bucket_z: f64,
+ pub bucket_id: u32,
+ /// the site's window draw `k_off` (0 the dataset, 1 a half, 2 a quarter)
+ pub win: u8,
+ pub bit_z: f64,
+ pub bit: u8,
+}
+
+/// The same run as [`site_index_stats`] with the two extra statistics per site.
+pub fn family_site_stats(p: &Program, units: usize) -> Result<Vec<FamilySiteStats>, Reject> {
+ let mut indices = site_indices(p, units)?;
+ let load_instrs: Vec<&Instr> = p.instrs.iter().filter(|i| i.op.is_load()).collect();
+ let mut out = Vec::with_capacity(indices.len());
+ for (site, ix) in indices.iter_mut().enumerate() {
+ let ins = load_instrs[site];
+ let n = ix.len() as f64;
+ let k = (ins.win as u32).min(2);
+ let free_bits = ACCEPT_DATASET_LOG2 - k;
+ let mut ones = [0u64; 32];
+ let mut buckets = vec![0u32; 1usize << (ACCEPT_DATASET_LOG2 - 12)];
+ for &x in ix.iter() {
+ buckets[(x >> 12) as usize] += 1;
+ let mut v = x;
+ let mut b = 0;
+ while v != 0 {
+ ones[b] += (v & 1) as u64;
+ v >>= 1;
+ b += 1;
+ }
+ }
+ let width = ins.width.max(1) as u32;
+ let align_bits = width.trailing_zeros();
+ let (mut bit_z, mut bit) = (0.0f64, 0u8);
+ for b in align_bits..free_bits {
+ let z = (ones[b as usize] as f64 - n / 2.0) / (n / 4.0).sqrt();
+ if z.abs() > bit_z.abs() {
+ bit_z = z;
+ bit = b as u8;
+ }
+ }
+ let window_buckets = (site_window_words(ins) * width as u64) >> 12;
+ let expect = n / window_buckets as f64;
+ let (mut bmax, mut bid) = (0u32, 0u32);
+ for (i, &c) in buckets.iter().enumerate() {
+ if c > bmax {
+ bmax = c;
+ bid = i as u32;
+ }
+ }
+ ix.sort_unstable();
+ let mut st = SiteIndexStats { distinct: 0, pairs: 0, top_index: 0, top_count: 0 };
+ let mut i = 0;
+ while i < ix.len() {
+ let mut j = i + 1;
+ while j < ix.len() && ix[j] == ix[i] {
+ j += 1;
+ }
+ let run = (j - i) as u32;
+ st.distinct += 1;
+ st.pairs += (run as u64) * (run as u64 - 1) / 2;
+ if run > st.top_count {
+ st.top_count = run;
+ st.top_index = ix[i];
+ }
+ i = j;
+ }
+ out.push(FamilySiteStats { base: st, bucket_ratio: bmax as f64 / expect, bucket_z: (bmax as f64 - expect) / expect.sqrt(), bucket_id: bid, win: k as u8, bit_z, bit });
+ }
+ Ok(out)
}
/// One interpreter run over `units` units of the seed's acceptance stream with every load site's word indices kept,
@@ -485,6 +566,11 @@ pub fn check_indices_v5(p: &Program) -> Result<(), Reject> {
/// Whether `class` is the class v4 shape (the 256-instruction shadow block over the class v3 base, the pass count and
/// the era set aside): the shape the sub-version 2 rules (a') and (c') apply to, on every draw path.
pub fn is_class_v4_shape(class: &LoadClass) -> bool {
+ // IGNEUM_FG_CHAIN_PREDICATE: the harness runs but the shape predicate stays the crate's own, so a row reads the
+ // verdicts the chain would give (the 6.11 comparison of 8 October 2026)
+ if family_gate_on() && std::env::var_os("IGNEUM_FG_CHAIN_PREDICATE").is_none() {
+ return is_family_shape(class);
+ }
matches!(class.shadow, Some(ShadowClass { instrs: V4_SHADOW_INSTRS, .. }))
// class v5 (docs/design/class-v5-stored-state.md) is judged under the same rules: its state flag is set aside;
// class v6 lane 1's index fold and re-weight table are set aside too (the address path and the op table are
@@ -496,6 +582,31 @@ pub fn is_class_v4_shape(class: &LoadClass) -> bool {
&& LoadClass { era: None, shadow: None, state: false, fold: false, rw: 0, nowin: false, reg64: false, reg64_chain: false, mix: V4_CLASS.mix, ..*class } == LoadClass { shadow: None, ..V4_CLASS }
}
+/// Class v6 family-gate harness (8 October 2026, `docs/analysis/class-v6/family-gate.md`): the acceptance keyed on the
+/// FAMILY's shapes instead of the one class v4 shape, on when `IGNEUM_FAMILY_GATE` is set in the environment of a
+/// harness run and never on a chain path. The family: the shadow block in {64, 128, 256} instructions at the same
+/// 6,912 instructions per iteration, the mixer multiplier in {4, 8, 16}, the read width the era's draw over {1, 4}
+/// words (the mix one-hot on the drawn width), the rest the class v4 base with the state flag, the class v6 fold and
+/// the re-weight table set aside (as the class's own predicate sets them aside).
+pub fn is_family_shape(class: &LoadClass) -> bool {
+ let sh = match class.shadow {
+ Some(s) => s,
+ None => return false,
+ };
+ if !matches!(sh.instrs, 64 | 128 | 256) || sh.instrs as usize * sh.reps as usize != V4_SHADOW_INSTRS as usize * crate::generator::V4_SHADOW_REPS as usize {
+ return false;
+ }
+ if !matches!(class.mixer_mult, 4 | 8 | 16) {
+ return false;
+ }
+ LoadClass { era: None, shadow: None, state: false, fold: false, rw: 0, nowin: false, reg64: false, reg64_chain: false, mixer_mult: 8, mix: V4_CLASS.mix, ..*class } == LoadClass { shadow: None, ..V4_CLASS }
+}
+
+fn family_gate_on() -> bool {
+ static ON: std::sync::OnceLock<bool> = std::sync::OnceLock::new();
+ *ON.get_or_init(|| std::env::var_os("IGNEUM_FAMILY_GATE").is_some())
+}
+
/// One pass of the dataflow freshness over the base program then the shadow block (the order of one iteration),
/// from `fresh`; `check` reports the first load that reads a register that is not fresh. The rule (AP-F8-1,
/// `docs/analysis/ca3-v4-uniform.md`): a load leaves its destination fresh only if its source was (a saturated
@@ -1408,4 +1519,247 @@ mod tests {
assert!(check(&generate(s)).is_ok());
}
}
+ /// Class v6 family-gate harness (8 October 2026, `docs/analysis/class-v6/family-gate.md`): one drawn era per seed of a
+ /// label space, every parameter of the family drawn from the era's own stream (the shadow block shape in {64, 128,
+ /// 256}, the mixer multiplier in {4, 8, 16}, the read width over {1, 4} words through the era draw, the ten non-load
+ /// weights perturbed within B points with shuffle and mulhi never raised), the chain draw of that era's epoch
+ /// through the real rule with the first failing part of every candidate, then on the accepted program the per-site
+ /// statistics at the rule's own 2^20 sample: the (c'') ratio, the largest 256-item bucket, the index-bit bias.
+ /// One TSV row per era to `IGNEUM_FG_OUT`. Pins for the strata: `IGNEUM_FG_SHAPE`, `IGNEUM_FG_MIXER`,
+ /// `IGNEUM_FG_WIDTH`, `IGNEUM_FG_B` (default 4), `IGNEUM_FG_LOSSY_CAP` (or, mul and mulhi at +B: the lossy corner),
+ /// `IGNEUM_FG_LABEL` (default `igneum-family-gate`). Requires `IGNEUM_FAMILY_GATE=1` in the environment.
+ #[test]
+ #[ignore]
+ fn family_gate_era_census() {
+ use crate::generator::{set_family_weights, LoadClass, ShadowClass, NONLOAD_WEIGHTS, V5_CLASS, MAX_ATTEMPTS_V4};
+ use crate::seed::seed_words_from_bytes;
+ use std::io::Write;
+ use std::sync::atomic::{AtomicU32, Ordering};
+ use std::sync::Mutex;
+ assert!(family_gate_on(), "IGNEUM_FAMILY_GATE=1 is required");
+ let env_u = |k: &str, d: u32| std::env::var(k).ok().and_then(|v| v.parse().ok()).unwrap_or(d);
+ let seeds = env_u("IGNEUM_FG_SEEDS", 1000);
+ let from = env_u("IGNEUM_FG_FROM", 0);
+ let threads = env_u("IGNEUM_FG_THREADS", 32) as usize;
+ let b_pts = env_u("IGNEUM_FG_B", 4) as i64;
+ let label = std::env::var("IGNEUM_FG_LABEL").unwrap_or_else(|_| "igneum-family-gate".to_string());
+ let pin_shape = std::env::var("IGNEUM_FG_SHAPE").ok().and_then(|v| v.parse::<u16>().ok());
+ let pin_mixer = std::env::var("IGNEUM_FG_MIXER").ok().and_then(|v| v.parse::<u8>().ok());
+ let pin_width = std::env::var("IGNEUM_FG_WIDTH").ok().and_then(|v| v.parse::<u8>().ok());
+ let lossy_cap = std::env::var_os("IGNEUM_FG_LOSSY_CAP").is_some();
+ // the proposed band after the 12:00 BST reading of 8 October: B on the injecting families only, the three lossy
+ // families (or, mul, mulhi) never raised above their base
+ let lossy_base = std::env::var_os("IGNEUM_FG_LOSSY_BASE").is_some();
+ // the lossy-share curve (the full report's item 3): or, mul and mulhi each at exactly +n points
+ let lossy_plus: Option<i64> = std::env::var("IGNEUM_FG_LOSSY_PLUS").ok().and_then(|v| v.parse().ok());
+ let out_path = std::env::var("IGNEUM_FG_OUT").unwrap_or_else(|_| "family-gate.tsv".to_string());
+ let out = Mutex::new(std::fs::File::create(&out_path).expect("IGNEUM_FG_OUT"));
+ let wnames: Vec<String> = NONLOAD_WEIGHTS.iter().map(|(o, _)| format!("w_{o:?}").to_lowercase()).collect();
+ writeln!(out.lock().unwrap(), "k\tshape\treps\tmixer\twidth\tR\tM\tpos\t{}\tattempt\tcandidates\ta_prime\ta\tb\tc_const\tc_lane\tc_sat\tc_bias\tc_distinct\tc1_sat_source\tc2_low_entropy\tc3_hot_item\tc_other\tmin_ratio\tmin_site\ttop_count_max\tbucket_ratio_max\tbucket_z_max\tbucket_site\tbucket_win\tbit_z_max\tbit_site\tbit_win\tbit\tlast_resort_k\tc3_ratios\tsecs", wnames.join("\t")).unwrap();
+ let part_ix = |r: &Reject| -> usize {
+ match r {
+ Reject::UnfreshLoadSource { .. } => 0,
+ Reject::StaleLoadSource { .. } => 1,
+ Reject::NoInjectingWrite { .. } => 2,
+ Reject::ConstantBit { .. } => 3,
+ Reject::LaneConstantSite { .. } => 4,
+ Reject::Saturated { .. } => 5,
+ Reject::OutputBias { .. } => 6,
+ Reject::DistinctAddresses { .. } => 7,
+ Reject::SaturatedSource { .. } => 8,
+ Reject::LowEntropySite { .. } | Reject::RepeatedSource { .. } => 9,
+ Reject::HotItemSite { .. } => 10,
+ _ => 11,
+ }
+ };
+ let next = AtomicU32::new(from);
+ let t0 = std::time::Instant::now();
+ let done = AtomicU32::new(0);
+ std::thread::scope(|sc| {
+ for _ in 0..threads {
+ sc.spawn(|| loop {
+ let k = next.fetch_add(1, Ordering::Relaxed);
+ if k >= from + seeds {
+ break;
+ }
+ let ts = std::time::Instant::now();
+ let w = |s: String| -> Vec<u8> { seed_words_from_bytes(s.as_bytes()).iter().flat_map(|x| x.to_le_bytes()).collect() };
+ let (epoch, era) = match (std::env::var("IGNEUM_FG_EPOCH_HEX"), std::env::var("IGNEUM_FG_ERA_HEX")) {
+ (Ok(e), Ok(r)) => (crate::bind::unhex(&e).expect("IGNEUM_FG_EPOCH_HEX"), crate::bind::unhex(&r).expect("IGNEUM_FG_ERA_HEX")),
+ _ => (w(format!("{label}/program/{k}")), w(format!("{label}/era/{k}"))),
+ };
+ // the family's draws from the era's own stream, in a fixed order, each consumed whether pinned or not
+ let dw = seed_words_from_bytes(&[b"igneum-family-gate/draw/".as_slice(), era.as_slice()].concat());
+ let mut rng = SplitMix64::new(dw[0] as u64 | ((dw[1] as u64) << 32));
+ let shapes = [64u16, 128, 256];
+ let shape = pin_shape.unwrap_or(shapes[rng.below(3) as usize]);
+ let mixers = [4u8, 8, 16];
+ let mixer = pin_mixer.unwrap_or(mixers[rng.below(3) as usize]);
+ // the base table: NONLOAD_WEIGHTS, or IGNEUM_FG_WEIGHTS when set (a fixed genesis table under test
+ // with B = 0, the research lane's close of 15:3x BST on 8 October)
+ let base_weights = crate::generator::family_weights_env_table();
+ let mut weights = base_weights;
+ let mut raw = [0i64; 10];
+ for (i, (op, wgt)) in base_weights.iter().enumerate() {
+ let mut d = rng.below((2 * b_pts + 1) as u64) as i64 - b_pts;
+ if matches!(op, Op::Shfl | Op::MulHi) && d > 0 {
+ d = 0;
+ }
+ if lossy_cap && matches!(op, Op::Or | Op::Mul | Op::MulHi) {
+ d = b_pts;
+ }
+ if lossy_base && matches!(op, Op::Or | Op::Mul | Op::MulHi) && d > 0 {
+ d = 0;
+ }
+ if let Some(n) = lossy_plus {
+ if matches!(op, Op::Or | Op::Mul | Op::MulHi) {
+ d = n;
+ }
+ }
+ // a drawn table keeps every family at one point or more; a fixed table under test (B = 0 with
+ // IGNEUM_FG_WEIGHTS) is taken as given, a zero weight included (the first run of the best-mix
+ // table floored `or` at 1 of 75 by this line; the record names both)
+ raw[i] = (*wgt as i64 + d).max(if b_pts == 0 { 0 } else { 1 });
+ }
+ // renormalise to 75 by largest remainder
+ let total: i64 = raw.iter().sum();
+ let mut floors = [0u64; 10];
+ let mut rems: Vec<(i64, usize)> = Vec::new();
+ let mut sum = 0u64;
+ for i in 0..10 {
+ floors[i] = ((raw[i] * 75) / total) as u64;
+ rems.push((((raw[i] * 75) % total), i));
+ sum += floors[i];
+ }
+ rems.sort_by(|x, y| y.0.cmp(&x.0).then(x.1.cmp(&y.1)));
+ let mut short = 75 - sum;
+ for &(_, i) in &rems {
+ if short == 0 {
+ break;
+ }
+ floors[i] += 1;
+ short -= 1;
+ }
+ for i in 0..10 {
+ weights[i].1 = floors[i];
+ }
+ if std::env::var_os("IGNEUM_FG_CLASS").is_none() || std::env::var_os("IGNEUM_FG_WEIGHTS").is_some() {
+ set_family_weights(Some(weights));
+ } else {
+ weights = *LoadClass::parse(&std::env::var("IGNEUM_FG_CLASS").unwrap()).expect("IGNEUM_FG_CLASS parses").nonload_weights().0;
+ }
+ let reps = (V4_SHADOW_INSTRS as u32 * crate::generator::V4_SHADOW_REPS as u32 / shape as u32) as u16;
+ let mut base = match std::env::var("IGNEUM_FG_CLASS") {
+ Ok(s) => LoadClass { era: None, ..LoadClass::parse(&s).expect("IGNEUM_FG_CLASS parses") },
+ Err(_) => LoadClass { shadow: Some(ShadowClass { instrs: shape, reps }), mixer_mult: mixer, ..V5_CLASS },
+ };
+ if std::env::var_os("IGNEUM_FG_NOWIN").is_some() {
+ base = base.with_nowin();
+ }
+ // a one-entry set is the pinned-width path of LoadClass::era (the mix stays the base's and the draw is
+ // redrawn to the base's widest, 1 word) and the set must be strictly ascending, so a pinned width is
+ // built by hand: the era drawn over the one-entry set and the mix one-hot on that width, as the
+ // drawn-set path does
+ let class = match pin_width {
+ Some(w) if w == 1 || w == 4 => {
+ let mut c = base;
+ let i = crate::generator::WIDTH_WORDS.iter().position(|&x| x == w).unwrap();
+ c.mix = [0, 0, 0];
+ c.mix[i] = 100;
+ c.era = Some(crate::generator::era_draw(&era, &[w]));
+ c
+ }
+ _ => LoadClass::era(base, &era, &[1, 4]),
+ };
+ let e = class.era.unwrap();
+ let lbl = f8_label(&epoch);
+ let mut parts = [0u32; 12];
+ let mut accepted: Option<(u32, Program)> = None;
+ // the ratios of the candidates the two floors refused (the pre-floor spread per width: the full
+ // report's per-width calibration), as "c2:<milli>" or "c3:<milli>" per refusal
+ let mut c3_ratios: Vec<String> = Vec::new();
+ for attempt in 0..MAX_ATTEMPTS_V4 {
+ let c = candidate_class(&lbl, &epoch, attempt, class);
+ match check(&c) {
+ Ok(_) => {
+ accepted = Some((attempt, c));
+ break;
+ }
+ Err(r) => {
+ match &r {
+ Reject::HotItemSite { ratio_milli, .. } => c3_ratios.push(format!("c3:{ratio_milli}")),
+ Reject::LowEntropySite { ratio_milli, .. } => c3_ratios.push(format!("c2:{ratio_milli}")),
+ _ => {}
+ }
+ parts[part_ix(&r)] += 1
+ }
+ }
+ }
+ // an exhausted era takes class v5's last resort: the scan of 256 more candidates past the cap, each
+ // rewritten (or, mul, mulhi to xor) and its stale loads re-sourced, the first that passes the whole
+ // rule; the column records that k (cap + i), or "fallback" when none of the 256 passed
+ let last_resort_k: String = if accepted.is_none() {
+ use crate::generator::{last_resort_v4, repair_stale_loads, LAST_RESORT_SCAN};
+ let mut found = String::from("fallback");
+ for kk in MAX_ATTEMPTS_V4..MAX_ATTEMPTS_V4 + LAST_RESORT_SCAN {
+ let q = repair_stale_loads(last_resort_v4(candidate_class(&lbl, &epoch, kk, class)));
+ if check(&q).is_ok() {
+ found = kk.to_string();
+ break;
+ }
+ }
+ found
+ } else {
+ String::new()
+ };
+ set_family_weights(None);
+ let candidates: u32 = parts.iter().sum::<u32>() + accepted.is_some() as u32;
+ let (attempt, stats_row) = match &accepted {
+ Some((att, p)) => {
+ let st = family_site_stats(p, ACCEPT_UNITS_DISTINCT_V4).expect("the accepted program runs");
+ let n = (ACCEPT_UNITS_DISTINCT_V4 * LANES * ITERATIONS) as f64;
+ let loads: Vec<&Instr> = p.instrs.iter().filter(|i| i.op.is_load()).collect();
+ let (mut min_r, mut min_s) = (f64::MAX, 0usize);
+ let (mut bmax, mut bz, mut bsite, mut bwin) = (0.0f64, 0.0f64, 0usize, 0u8);
+ let (mut zmax, mut zsite, mut zbit, mut zwin) = (0.0f64, 0usize, 0u8, 0u8);
+ let mut top = 0u32;
+ for (s, fs) in st.iter().enumerate() {
+ let r = site_ratio(fs.base.distinct, n, site_window_words(loads[s]));
+ if r < min_r {
+ min_r = r;
+ min_s = s;
+ }
+ if fs.bucket_z > bz {
+ bmax = fs.bucket_ratio;
+ bz = fs.bucket_z;
+ bsite = s;
+ bwin = fs.win;
+ }
+ if fs.bit_z.abs() > zmax.abs() {
+ zmax = fs.bit_z;
+ zsite = s;
+ zbit = fs.bit;
+ zwin = fs.win;
+ }
+ top = top.max(fs.base.top_count);
+ }
+ (*att as i64, format!("{min_r:.5}\t{min_s}\t{top}\t{bmax:.3}\t{bz:.2}\t{bsite}\t{bwin}\t{zmax:.2}\t{zsite}\t{zwin}\t{zbit}"))
+ }
+ None => (-1, "\t\t\t\t\t\t\t\t\t\t".to_string()),
+ };
+ let wcols: Vec<String> = weights.iter().map(|(_, x)| x.to_string()).collect();
+ let pcols: Vec<String> = parts.iter().map(|x| x.to_string()).collect();
+ let row = format!("{k}\t{shape}\t{reps}\t{mixer}\t{}\t{}\t{:08x}\t{:?}\t{}\t{attempt}\t{candidates}\t{}\t{stats_row}\t{last_resort_k}\t{}\t{:.1}", e.width_words, e.stride_rot, e.stride_mul, e.pos, wcols.join("\t"), pcols.join("\t"), c3_ratios.join(","), ts.elapsed().as_secs_f64());
+ writeln!(out.lock().unwrap(), "{row}").unwrap();
+ let d = done.fetch_add(1, Ordering::Relaxed) + 1;
+ if d % 100 == 0 {
+ println!("family_gate_era_census: {d} eras in {:.0} s", t0.elapsed().as_secs_f64());
+ out.lock().unwrap().flush().unwrap();
+ }
+ });
+ }
+ });
+ out.lock().unwrap().flush().unwrap();
+ println!("family_gate_era_census: {} eras {from}..{} in {:.0} s on {threads} threads -> {out_path}", done.load(Ordering::Relaxed), from + seeds, t0.elapsed().as_secs_f64());
+ }
}
diff --git a/igneum-pow/src/generator.rs b/igneum-pow/src/generator.rs
--- a/igneum-pow/src/generator.rs
+++ b/igneum-pow/src/generator.rs
@@ -474,7 +474,8 @@ impl LoadClass {
/// width that mix can draw.
pub fn era(base: LoadClass, era_bytes: &[u8], allowed: &[u8]) -> LoadClass {
let mut e = era_draw(era_bytes, allowed);
- let mut c = base;
+ // class v6 family-gate harness: the shape and nowin hooks on every era class (under IGNEUM_FAMILY_GATE only)
+ let mut c = family_shape_of(base);
if allowed.len() > 1 {
let i = WIDTH_WORDS.iter().position(|&w| w == e.width_words).unwrap();
c.mix = [0, 0, 0];
@@ -657,6 +658,9 @@ impl LoadClass {
/// The non-load op table this class draws from, in draw order, and its sum (the roll's range). The plain table
/// for every class without the re-weight flag, so their streams are byte for byte what they were.
pub fn nonload_weights(&self) -> (&'static [(Op, u64); 10], u64) {
+ if let Some(o) = family_weights_override() {
+ return o;
+ }
match self.rw {
1 => (&NONLOAD_WEIGHTS_RW, NONLOAD_WEIGHTS_RW_SUM),
2 => (&NONLOAD_WEIGHTS_RW2, NONLOAD_WEIGHTS_RW2_SUM),
@@ -1098,14 +1102,38 @@ pub fn generate_era_generator(seed_string: &str, seed_bytes: &[u8], base: LoadCl
p
}
+/// Class v6 family-gate harness: `base` with the shadow block shape from `IGNEUM_FG_SHAPE` (64, 128 or 256 at 6,912 per
+/// iteration) under `IGNEUM_FAMILY_GATE`, so an unmodified harness runs the family's shape; `base` otherwise.
+fn family_shape_of(base: LoadClass) -> LoadClass {
+ let mut c = base;
+ if std::env::var_os("IGNEUM_FAMILY_GATE").is_some() {
+ // a whole class string under test (the post-review object's "mx8+sh256x27+state+reg64c+nowin+fold+rw"):
+ // the parsed class, era-less, replaces the base; the era is composed by the caller as before
+ if let Ok(s) = std::env::var("IGNEUM_FG_CLASS") {
+ let parsed = LoadClass::parse(&s).unwrap_or_else(|| panic!("IGNEUM_FG_CLASS: {s} does not parse"));
+ c = LoadClass { era: None, ..parsed };
+ }
+ if let Some(n) = std::env::var("IGNEUM_FG_SHAPE").ok().and_then(|v| v.parse::<u16>().ok()) {
+ assert!(matches!(n, 64 | 128 | 256), "IGNEUM_FG_SHAPE is 64, 128 or 256");
+ let reps = (V4_SHADOW_INSTRS as u32 * V4_SHADOW_REPS as u32 / n as u32) as u16;
+ c = LoadClass { shadow: Some(ShadowClass { instrs: n, reps }), ..c };
+ }
+ // the hash lane's layer-8-off experiment (8 October 2026, 18:1x BST): the "+nowin" flag on the harness's draws
+ if std::env::var_os("IGNEUM_FG_NOWIN").is_some() {
+ c = c.with_nowin();
+ }
+ }
+ c
+}
+
impl ProgramClass {
/// The load class this program class draws from.
pub fn load_class(&self) -> LoadClass {
match self {
ProgramClass::V2 => LoadClass::V2,
ProgramClass::V3 => V3_CLASS,
- ProgramClass::V4 => V4_CLASS,
- ProgramClass::V5 => V5_CLASS,
+ ProgramClass::V4 => family_shape_of(V4_CLASS),
+ ProgramClass::V5 => family_shape_of(V5_CLASS),
ProgramClass::V6 => V6_CLASS,
}
}
@@ -1583,6 +1611,51 @@ pub const NONLOAD_WEIGHTS: [(Op, u64); 10] = [
/// Class v6 lane 1, the re-weight table behind the index fold (`+rw`): the k lane's optimiser split in draw order,
/// sum [`NONLOAD_WEIGHTS_RW_SUM`] (83). Shuffle stays at 4 (a shuffle-heavy draw is the worst thing the class can do
/// on the chip side, k 0.021 routed) and `or` is never drawn. The roll ranges over the table's own sum.
+thread_local! {
+ static FAMILY_WEIGHTS: std::cell::Cell<Option<&'static [(Op, u64); 10]>> = const { std::cell::Cell::new(None) };
+}
+/// Class v6 family-gate harness (8 October 2026): the ten non-load weights this thread's draws use when set (a leaked
+/// table per era, so [`LoadClass::nonload_weights`] keeps its static signature), else the process-wide table. Set only
+/// by the harness census (`accept::tests::family_gate_era_census`), never on a chain path.
+pub fn set_family_weights(w: Option<[(Op, u64); 10]>) {
+ FAMILY_WEIGHTS.with(|c| c.set(w.map(|t| &*Box::leak(Box::new(t)))));
+}
+pub fn family_weights() -> [(Op, u64); 10] {
+ FAMILY_WEIGHTS.with(|c| c.get()).map(|t| *t).unwrap_or_else(family_weights_env_table)
+}
+/// The family override for a draw, when the harness set one: the table and its sum.
+fn family_weights_override() -> Option<(&'static [(Op, u64); 10], u64)> {
+ if std::env::var_os("IGNEUM_FAMILY_GATE").is_none() {
+ return None;
+ }
+ let t: &'static [(Op, u64); 10] = match FAMILY_WEIGHTS.with(|c| c.get()) {
+ Some(t) => t,
+ None if std::env::var_os("IGNEUM_FG_WEIGHTS").is_some() => FAMILY_WEIGHTS_ENV.get_or_init(family_weights_env),
+ None => return None,
+ };
+ Some((t, t.iter().map(|w| w.1).sum()))
+}
+static FAMILY_WEIGHTS_ENV: std::sync::OnceLock<[(Op, u64); 10]> = std::sync::OnceLock::new();
+/// The process-wide table (`IGNEUM_FG_WEIGHTS` under `IGNEUM_FAMILY_GATE`, else [`NONLOAD_WEIGHTS`]).
+pub fn family_weights_env_table() -> [(Op, u64); 10] {
+ *FAMILY_WEIGHTS_ENV.get_or_init(family_weights_env)
+}
+/// The harness's process-wide weight table: `IGNEUM_FG_WEIGHTS=w0,..,w9` (sum 75, the order of [`NONLOAD_WEIGHTS`]),
+/// read only with `IGNEUM_FAMILY_GATE` set (an unmodified harness such as attack-f8 then draws the family's weights).
+fn family_weights_env() -> [(Op, u64); 10] {
+ let mut w = NONLOAD_WEIGHTS;
+ if std::env::var_os("IGNEUM_FAMILY_GATE").is_some() {
+ if let Ok(s) = std::env::var("IGNEUM_FG_WEIGHTS") {
+ let v: Vec<u64> = s.split(',').filter_map(|x| x.trim().parse().ok()).collect();
+ assert!(v.len() == 10 && v.iter().sum::<u64>() == 75, "IGNEUM_FG_WEIGHTS: ten weights summing to 75");
+ for (i, x) in v.into_iter().enumerate() {
+ w[i].1 = x;
+ }
+ }
+ }
+ w
+}
+
pub const NONLOAD_WEIGHTS_RW: [(Op, u64); 10] = [
(Op::Add, 16),
(Op::Xor, 14),
@@ -1752,8 +1825,9 @@ pub fn candidate_from_words_class(
// class v5 (docs/design/class-v5-stored-state.md) draws under the same rule: its state flag is set aside here too
// class v6 lane 1: the index fold and the re-weight table are set aside too (the address path and the table are not
// the shape; a +fold or +rw program draws its sources under the same rule)
- let source_rule_v4 = matches!(class.shadow, Some(ShadowClass { instrs: V4_SHADOW_INSTRS, .. }))
- && LoadClass { era: None, shadow: None, state: false, fold: false, rw: 0, nowin: false, reg64: false, reg64_chain: false, mix: V4_CLASS.mix, ..class } == LoadClass { shadow: None, ..V4_CLASS };
+ // class v6 family-gate harness (8 October 2026): the same predicate as the acceptance's, generalised to the
+ // family's shapes only when IGNEUM_FAMILY_GATE is set (never on a chain path; see accept::is_family_shape)
+ let source_rule_v4 = crate::accept::is_class_v4_shape(&class);
// the op table and the roll's range: the plain table at 75 for every class without the re-weight flag
let (weights, weights_sum) = class.nonload_weights();
let mut fresh = [false; 8];

View file

@ -0,0 +1,35 @@
# Key succession on the live object: the H and W proposal (Phase 1 item d, 8 to 9 October 2026)
For the founder's word in the 08:00 UK read-back. The mechanism is docs/design/key-succession.md (`proving_key_succession_daa` H, `proving_key_succession_window_daa` W, `proving_next_shard_program_id` and `proving_next_aggregator_id` the next pair; both pairs verify for H <= d < H + W, only the next from H + W). Nothing here activates anything: the pin tool is on master, the real pin and the object's fields move on the founder's word.
## 1. The proposal
| Field | Proposed | Why |
|---|---|---|
| W, the window | one epoch of the live object: 3,600 DAA (`POW_EPOCH_BLOCKS`, consensus/core/src/igneum.rs; one hour at one block per second) | the coordinator's word (W one epoch). A prover on the old host keeps earning for the whole epoch it started in; the verdict cache's epoch key (`a_verdict_cached_in_the_window_is_not_valid_after_it`) and the fast-time runs below show both pairs verifying across a window and the right refusal on each side of it. The object's default of 86,400 (one day) is the mainnet clock; on the devnet a day of two pairs is a day of two hosts to keep, with no gain the runs could show. |
| H, the height | the first epoch boundary (a multiple of 3,600 DAA) at least one epoch after the end of a clean 24-hour run of the live chain on the 2.0.2 line: no finality pause, no reorg over depth 3, every fleet node on the cut; named as a DAA score in the object, never a clock | the coordinator's word (H after the chain's clean run). An epoch boundary so the window is one whole epoch of one seed; a full epoch of notice so every prover host has moved before the window opens (the fleet's hosts move with the kit, the app's with its update). |
| The next pair | pin C: shard 0x51cd8cba314a32b60fac393949a4571714da6d6656717d286011601b2a163fe7, aggregator 0x05b395ec238f67406084f8a449d400f64c87dc62151daebf66695864727ded8a (branch p22-stage-2-pin, b5b82c958; manifest source_commit c45db4420, guest input format 3; deterministic across three builds) | docs/analysis/v6-10-guest-repin-2026-10-08.md |
| The prior pair | the served pair 0x2b1a81cb… / 0x474678f3… (devnet-4's pinned pair) | the 2.0.1 kits embed it; the 17:58 UK pair 0x282dcfce… never activated and is skipped |
Consequences, stated: for a home prover on the app, the old host earns through the hour of the window and the app's update carries the new pair before it; for a fleet box, the kit's host moves at the cut, before H; for a pool, the pool's verifier accepts both pairs in the window and only the next after (the pool lane's rows). A record under the old pair carried after H + W pays nothing (the after-window row below); a record under the new pair carried before H pays nothing (the below-H row).
## 2. The evidence (fast time, three local nodes, the live pair as prior and the 17:58 pair as next, one real proof under each)
Every run on the verdict-cache fix node 3f672661 (review B F01/F02), build-8, 8 October 2026. The harness is infra/fast-time/proving-enforcement.mjs in succession mode; a chain at about one DAA per second with 60-DAA epochs; the attacker A carries what its pool holds, H1 and H2 refuse with the verifier in consensus. Every record carried in every run was refused on the right ground and nothing was ever paid; the runs differ only in how many of the six records the harness managed to get carried (its attacker's one-record-per-carrier shape, fixed over the evening).
| Run (UK) | H, W | Below H | In the window | After H + W | Paid | Verdict |
|---|---|---|---|---|---|---|
| 20:29 to 20:38 (vcache-2) | 240, 120 | next pair refused on its pair | prior pair accepted on its pair, refused on its statement | prior pair refused on its pair | none | the three carried records right; one record per phase carried (harness) |
| 20:42 to 20:55 (vcache-3) | 240, 120 | both refused on their statements: the second record's carrier landed after H (window too short for two records) | prior pair refused on its pair (its carrier past H + W) | prior pair refused on its pair | none | every refusal right for the carrier's DAA; the harness's clocks wrong |
| 20:56 to 21:14 (vcache-4) | 360, 300 | next pair on its pair, prior pair on its statement | both on their statements, none on a pair | prior pair on its pair; the next-pair record went unread (the attacker did not rejoin in 150 s) | none | five of six right |
| 21:15 to 21:33 (vcache-5) | 360, 300 | with the attacker's miner paused for the rejoin, A never rejoined (300 s, twice) | | | none | a harness fault, reverted |
| 21:34 to 22:04 (vcache-7) | 360, 300 | next pair on its pair, prior pair on its statement | both on their statements, none on a pair | prior pair on its pair, next pair on its statement | none | PASS: all six right; registry batch enforced-proving-20261008-02 |
What the rows establish for the live schedule: the pair accepted is decided by the carrier's DAA against H and H + W, not by when the record was made (vcache-3's second records, forged below H and carried after it, were judged at their carriers); both pairs verify inside the window and a verified proof is answered from its facts at each carrier, never from a stale refusal (the F01 shape of the 19:49 run is gone on the fix node); a window of two harness epochs held every record the attacker managed to carry inside it. None of this measures a live epoch: the harness's epoch is 60 DAA, the live object's 3,600, so W of one live epoch is 60 times the harness's smallest passing window relative to the record's lifetime (RECORD_WINDOW_CHAIN_BLOCKS), which is the margin the proposal rests on.
## 3. What the founder's word moves
1. The object's four fields on the 2.0.2 line's override and digest (the node lane's digest move, the start check accepting both pairs: the 291ee6ae check refuses an elf/ whose top pair is not the object's, so the pin and the fields move in one cut).
2. proving/igneum-prove/elf/ on master to pin C with the served pair as prior (p22-stage-2-pin), site/release-manifest.json's proof_guests and succession blocks (the steward's signed manifest with the sha256s 0ce9e351… / 3ef25e3f… elf and 0dbb6605… / 074eb906… vk).
3. The fleet's prover kit on the new host before H; the app's host in its next update before H.
4. The fast-time succession case rerun on the cut's node with pin C as next (the harness takes `--next-ids` and a `--next-proof` under pin C: one compressed proof of a devnet-4 block under the new host, about 100 s on a box CPU).

View file

@ -336,8 +336,8 @@ Rule: a case maps to a cell only where the cell's tests visibly answer it; cover
### bench:amd-intel-energy
- Command: `the AMD-and-Intel energy lane jobs on the signed-jobs channel: run-ae-pc2-b580-energy-20261008 (PC 2, Arc B580, the class v6 kit worker --memprobe and --bench-pack on hl-v6-foldrw and hl-v6-all, Level Zero energy counter) and run-ae-pc1-7600-energy-20261008 (the project's own rig, RX 7600, the same with ADLX watts at stock, plimit -30, gmax -500 + plimit -30); scripts in docs/analysis/class-v6/amd-intel-energy/`
- Box class: the project's own rig and PC 2 bench (OpenCL)
- Command: `the AMD-and-Intel energy lane jobs on the signed-jobs channel: run-ae-pc2-b580-energy-20261008 (the project's second rig, Arc B580, the class v6 kit worker --memprobe and --bench-pack on hl-v6-foldrw and hl-v6-all, Level Zero energy counter) and run-ae-pc1-7600-energy-20261008 (the project's own rig, RX 7600, the same with ADLX watts at stock, plimit -30, gmax -500 + plimit -30); scripts in docs/analysis/class-v6/amd-intel-energy/`
- Box class: the project's two rigs' bench (OpenCL)
- Fixtures: F0, F1
- Cases:
- GPU-03 Measure the real 64-register GPU cost: partial: the 64-register window on AMD and Intel, rate per unit of work (RX 7600 0 percent, Arc B580 -0.3 percent, kernel throughput, quiet) with the B580 fingerprints equal on both packs and the offline RDNA allocation (160 VGPRs, no spill); energy owed (the 7600 job queued, the B580 counter unsupported unelevated); team-run, not under the standard's paired protocol or a wall meter
@ -367,7 +367,7 @@ Rule: a case maps to a cell only where the cell's tests visibly answer it; cover
### pc:install-update
- Command: `signed jobs and relay runs on the project's own rig (ae432dc7) and PC 2 (1ccfe586): the installer over the running app (rule 14: installed versions, the process set, the first upload), the OTA path (update-now, the update-return read-back line), and the no-click resume after the install (relay run mining-on-after-200.ps1)`
- Command: `signed jobs and relay runs on the project's two rigs (ae432dc7 and 1ccfe586): the installer over the running app (rule 14: installed versions, the process set, the first upload), the OTA path (update-now, the update-return read-back line), and the no-click resume after the install (relay run mining-on-after-200.ps1)`
- Box class: PC (the two Windows PCs; nothing on the Mac)
- Fixtures: F2
- Cases:
@ -410,8 +410,8 @@ Rule: a case maps to a cell only where the cell's tests visibly answer it; cover
### kit:class-v6-fingerprints
- Command: `KITS_BOX_SCRIPT=kits-v6-on-box.sh tools/class-v5/kits-remote.sh --box 1 (the kit zip with its emulation check), then the kit's workers on every platform: the box's CPU emulation (--check, 96 of 96 vector lanes), the fleet's CUDA 4090 (--check and --bench at 2^24, base nonce 0), the Mac's Metal (proto-metal/packbench.swift --pack) and Apple OpenCL (proto-opencl/host.c --pack --bench-pack), PC 1's RTX 5090 and RX 7600 (tools/class-v5/pc1-v6-bench.ps1), PC 2's Arc B580 (tools/class-v5/arc-v6-bench.ps1); the fingerprint of the 2^24 outputs at base nonce 0 equal on every platform for the all pack and for its known-failed partner, the two distinct`
- Box class: build box + pods + Mac + PC 1 + PC 2
- Command: `KITS_BOX_SCRIPT=kits-v6-on-box.sh tools/class-v5/kits-remote.sh --box 1 (the kit zip with its emulation check), then the kit's workers on every platform: the box's CPU emulation (--check, 96 of 96 vector lanes), the fleet's CUDA 4090 (--check and --bench at 2^24, base nonce 0), the Mac's Metal (proto-metal/packbench.swift --pack) and Apple OpenCL (proto-opencl/host.c --pack --bench-pack), the project's first rig's RTX 5090 and RX 7600 (tools/class-v5/pc1-v6-bench.ps1), the project's second rig's Arc B580 (tools/class-v5/arc-v6-bench.ps1); the fingerprint of the 2^24 outputs at base nonce 0 equal on every platform for the all pack and for its known-failed partner, the two distinct`
- Box class: build box + pods + Mac + the project's two rigs
- Fixtures: F0, F2
- Cases:
- R2-F03-R02 Same job context produces identical accepted work in node, CPU reference, CUDA, Metal, OpenCL and pool.: partial: the worker half (CPU reference, CUDA, Metal, OpenCL) on the same program packs; the node's and the pool's accepted work on the same job context are the CI steward's and the pool lane's cells; PASS only when every listed platform reads one fingerprint and the node and pool halves are green

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,248 @@
{
"case": "succession-360-window-300",
"floor": "240",
"expect": "refuse",
"phases": {
"below": {
"daaAtForge": 121,
"forge": {
"block": 105,
"hash": "0x87fe67d16fda7174b0706fedd4bdafcbabbb2f808897944d7ec687570b6fb91f",
"second": {
"block": 254,
"hash": "0x110d897b880b165caa6c40478cc3238b58926576260882198210889954ee199f"
},
"shapes": [
{
"shape": "p-prior-pair-proof",
"accepted": true,
"new": true,
"reason": "accepted"
},
{
"shape": "n-next-pair-proof",
"accepted": true,
"new": true,
"reason": "accepted"
}
]
},
"observed": {
"paid": [],
"carried": []
},
"refusals": {
"H1": {
"invalid": 2,
"dropped": 0,
"pair": 1,
"statement": 1,
"garbage": 0,
"reasons": [
"a carried proof record's proof does not verify: shard record block 105 shard 0 by 1bb65de716c3b466cd45a85b3ceddf7bcb9873e1821209ee76ec9ed1b21bd53d (proof 92de5638f248a5c1): shard record block 105 shard 0 by 1bb65de716c3b466cd45a85b3ceddf7bcb9873e1821209ee76ec9",
"a carried proof record's proof does not verify: shard record block 254 shard 0 by 990b90ac727bef6244fbbce29abcb47796dd1d197b2c4301aa92609d7c4943ba (proof 52f5ebdcc116da9f): shard record block 254 shard 0 by 990b90ac727bef6244fbbce29abcb47796dd1d197b2c4301aa926"
]
},
"H2": {
"invalid": 2,
"dropped": 0,
"pair": 1,
"statement": 1,
"garbage": 0,
"reasons": [
"a carried proof record's proof does not verify: shard record block 105 shard 0 by 1bb65de716c3b466cd45a85b3ceddf7bcb9873e1821209ee76ec9ed1b21bd53d (proof 92de5638f248a5c1): shard record block 105 shard 0 by 1bb65de716c3b466cd45a85b3ceddf7bcb9873e1821209ee76ec9",
"a carried proof record's proof does not verify: shard record block 254 shard 0 by 990b90ac727bef6244fbbce29abcb47796dd1d197b2c4301aa92609d7c4943ba (proof 52f5ebdcc116da9f): shard record block 254 shard 0 by 990b90ac727bef6244fbbce29abcb47796dd1d197b2c4301aa926"
]
}
}
},
"atFloor": {
"daaAtForge": 288,
"forge": {
"block": 374,
"hash": "0x8ce7a062860107fc4eb0596c0c28e22fa61fbc0ff5287730c78fae69226dd792",
"second": {
"block": 511,
"hash": "0xba04be731e0ae6b637820c5ffef1901b7985349579b4c1a3ad795d67a710ffea"
},
"shapes": [
{
"shape": "p-prior-pair-proof",
"accepted": true,
"new": true,
"reason": "accepted"
},
{
"shape": "n-next-pair-proof",
"accepted": true,
"new": true,
"reason": "accepted"
}
]
},
"observed": {
"paid": [],
"carried": []
},
"refusalsBefore": {
"H1": {
"invalid": 2,
"dropped": 0,
"pair": 1,
"statement": 1,
"garbage": 0,
"reasons": [
"a carried proof record's proof does not verify: shard record block 105 shard 0 by 1bb65de716c3b466cd45a85b3ceddf7bcb9873e1821209ee76ec9ed1b21bd53d (proof 92de5638f248a5c1): shard record block 105 shard 0 by 1bb65de716c3b466cd45a85b3ceddf7bcb9873e1821209ee76ec9",
"a carried proof record's proof does not verify: shard record block 254 shard 0 by 990b90ac727bef6244fbbce29abcb47796dd1d197b2c4301aa92609d7c4943ba (proof 52f5ebdcc116da9f): shard record block 254 shard 0 by 990b90ac727bef6244fbbce29abcb47796dd1d197b2c4301aa926"
]
},
"H2": {
"invalid": 2,
"dropped": 0,
"pair": 1,
"statement": 1,
"garbage": 0,
"reasons": [
"a carried proof record's proof does not verify: shard record block 105 shard 0 by 1bb65de716c3b466cd45a85b3ceddf7bcb9873e1821209ee76ec9ed1b21bd53d (proof 92de5638f248a5c1): shard record block 105 shard 0 by 1bb65de716c3b466cd45a85b3ceddf7bcb9873e1821209ee76ec9",
"a carried proof record's proof does not verify: shard record block 254 shard 0 by 990b90ac727bef6244fbbce29abcb47796dd1d197b2c4301aa92609d7c4943ba (proof 52f5ebdcc116da9f): shard record block 254 shard 0 by 990b90ac727bef6244fbbce29abcb47796dd1d197b2c4301aa926"
]
}
},
"refusalsAfter": {
"H1": {
"invalid": 4,
"dropped": 0,
"pair": 1,
"statement": 3,
"garbage": 0,
"reasons": [
"a carried proof record's proof does not verify: shard record block 105 shard 0 by 1bb65de716c3b466cd45a85b3ceddf7bcb9873e1821209ee76ec9ed1b21bd53d (proof 92de5638f248a5c1): shard record block 105 shard 0 by 1bb65de716c3b466cd45a85b3ceddf7bcb9873e1821209ee76ec9",
"a carried proof record's proof does not verify: shard record block 254 shard 0 by 990b90ac727bef6244fbbce29abcb47796dd1d197b2c4301aa92609d7c4943ba (proof 52f5ebdcc116da9f): shard record block 254 shard 0 by 990b90ac727bef6244fbbce29abcb47796dd1d197b2c4301aa926",
"a carried proof record's proof does not verify: shard record block 374 shard 0 by 1bb65de716c3b466cd45a85b3ceddf7bcb9873e1821209ee76ec9ed1b21bd53d (proof 92de5638f248a5c1): shard record block 374 shard 0 by 1bb65de716c3b466cd45a85b3ceddf7bcb9873e1821209ee76ec9",
"a carried proof record's proof does not verify: shard record block 511 shard 0 by 990b90ac727bef6244fbbce29abcb47796dd1d197b2c4301aa92609d7c4943ba (proof 52f5ebdcc116da9f): shard record block 511 shard 0 by 990b90ac727bef6244fbbce29abcb47796dd1d197b2c4301aa926"
]
},
"H2": {
"invalid": 4,
"dropped": 0,
"pair": 1,
"statement": 3,
"garbage": 0,
"reasons": [
"a carried proof record's proof does not verify: shard record block 105 shard 0 by 1bb65de716c3b466cd45a85b3ceddf7bcb9873e1821209ee76ec9ed1b21bd53d (proof 92de5638f248a5c1): shard record block 105 shard 0 by 1bb65de716c3b466cd45a85b3ceddf7bcb9873e1821209ee76ec9",
"a carried proof record's proof does not verify: shard record block 254 shard 0 by 990b90ac727bef6244fbbce29abcb47796dd1d197b2c4301aa92609d7c4943ba (proof 52f5ebdcc116da9f): shard record block 254 shard 0 by 990b90ac727bef6244fbbce29abcb47796dd1d197b2c4301aa926",
"a carried proof record's proof does not verify: shard record block 374 shard 0 by 1bb65de716c3b466cd45a85b3ceddf7bcb9873e1821209ee76ec9ed1b21bd53d (proof 92de5638f248a5c1): shard record block 374 shard 0 by 1bb65de716c3b466cd45a85b3ceddf7bcb9873e1821209ee76ec9",
"a carried proof record's proof does not verify: shard record block 511 shard 0 by 990b90ac727bef6244fbbce29abcb47796dd1d197b2c4301aa92609d7c4943ba (proof 52f5ebdcc116da9f): shard record block 511 shard 0 by 990b90ac727bef6244fbbce29abcb47796dd1d197b2c4301aa926"
]
}
}
},
"afterWindow": {
"daaAtForge": 675,
"forge": {
"block": 657,
"hash": "0xddb37d774fe5b5c0711a27984b6d25f7c2908ed58c14d00a69f9576274f41b46",
"second": {
"block": 786,
"hash": "0x525c035698dd1d756825d76b92019184023a6b5a3ef1221a51825bcc968a278f"
},
"shapes": [
{
"shape": "p-prior-pair-proof",
"accepted": true,
"new": true,
"reason": "accepted"
},
{
"shape": "n-next-pair-proof",
"accepted": true,
"new": true,
"reason": "accepted"
}
]
},
"observed": {
"paid": [],
"carried": []
},
"refusalsBefore": {
"H1": {
"invalid": 4,
"dropped": 0,
"pair": 1,
"statement": 3,
"garbage": 0,
"reasons": [
"a carried proof record's proof does not verify: shard record block 105 shard 0 by 1bb65de716c3b466cd45a85b3ceddf7bcb9873e1821209ee76ec9ed1b21bd53d (proof 92de5638f248a5c1): shard record block 105 shard 0 by 1bb65de716c3b466cd45a85b3ceddf7bcb9873e1821209ee76ec9",
"a carried proof record's proof does not verify: shard record block 254 shard 0 by 990b90ac727bef6244fbbce29abcb47796dd1d197b2c4301aa92609d7c4943ba (proof 52f5ebdcc116da9f): shard record block 254 shard 0 by 990b90ac727bef6244fbbce29abcb47796dd1d197b2c4301aa926",
"a carried proof record's proof does not verify: shard record block 374 shard 0 by 1bb65de716c3b466cd45a85b3ceddf7bcb9873e1821209ee76ec9ed1b21bd53d (proof 92de5638f248a5c1): shard record block 374 shard 0 by 1bb65de716c3b466cd45a85b3ceddf7bcb9873e1821209ee76ec9",
"a carried proof record's proof does not verify: shard record block 511 shard 0 by 990b90ac727bef6244fbbce29abcb47796dd1d197b2c4301aa92609d7c4943ba (proof 52f5ebdcc116da9f): shard record block 511 shard 0 by 990b90ac727bef6244fbbce29abcb47796dd1d197b2c4301aa926"
]
},
"H2": {
"invalid": 4,
"dropped": 0,
"pair": 1,
"statement": 3,
"garbage": 0,
"reasons": [
"a carried proof record's proof does not verify: shard record block 105 shard 0 by 1bb65de716c3b466cd45a85b3ceddf7bcb9873e1821209ee76ec9ed1b21bd53d (proof 92de5638f248a5c1): shard record block 105 shard 0 by 1bb65de716c3b466cd45a85b3ceddf7bcb9873e1821209ee76ec9",
"a carried proof record's proof does not verify: shard record block 254 shard 0 by 990b90ac727bef6244fbbce29abcb47796dd1d197b2c4301aa92609d7c4943ba (proof 52f5ebdcc116da9f): shard record block 254 shard 0 by 990b90ac727bef6244fbbce29abcb47796dd1d197b2c4301aa926",
"a carried proof record's proof does not verify: shard record block 374 shard 0 by 1bb65de716c3b466cd45a85b3ceddf7bcb9873e1821209ee76ec9ed1b21bd53d (proof 92de5638f248a5c1): shard record block 374 shard 0 by 1bb65de716c3b466cd45a85b3ceddf7bcb9873e1821209ee76ec9",
"a carried proof record's proof does not verify: shard record block 511 shard 0 by 990b90ac727bef6244fbbce29abcb47796dd1d197b2c4301aa92609d7c4943ba (proof 52f5ebdcc116da9f): shard record block 511 shard 0 by 990b90ac727bef6244fbbce29abcb47796dd1d197b2c4301aa926"
]
}
},
"refusalsAfter": {
"H1": {
"invalid": 6,
"dropped": 0,
"pair": 2,
"statement": 4,
"garbage": 0,
"reasons": [
"a carried proof record's proof does not verify: shard record block 105 shard 0 by 1bb65de716c3b466cd45a85b3ceddf7bcb9873e1821209ee76ec9ed1b21bd53d (proof 92de5638f248a5c1): shard record block 105 shard 0 by 1bb65de716c3b466cd45a85b3ceddf7bcb9873e1821209ee76ec9",
"a carried proof record's proof does not verify: shard record block 254 shard 0 by 990b90ac727bef6244fbbce29abcb47796dd1d197b2c4301aa92609d7c4943ba (proof 52f5ebdcc116da9f): shard record block 254 shard 0 by 990b90ac727bef6244fbbce29abcb47796dd1d197b2c4301aa926",
"a carried proof record's proof does not verify: shard record block 374 shard 0 by 1bb65de716c3b466cd45a85b3ceddf7bcb9873e1821209ee76ec9ed1b21bd53d (proof 92de5638f248a5c1): shard record block 374 shard 0 by 1bb65de716c3b466cd45a85b3ceddf7bcb9873e1821209ee76ec9",
"a carried proof record's proof does not verify: shard record block 511 shard 0 by 990b90ac727bef6244fbbce29abcb47796dd1d197b2c4301aa92609d7c4943ba (proof 52f5ebdcc116da9f): shard record block 511 shard 0 by 990b90ac727bef6244fbbce29abcb47796dd1d197b2c4301aa926",
"a carried proof record's proof does not verify: shard record block 657 shard 0 by 1bb65de716c3b466cd45a85b3ceddf7bcb9873e1821209ee76ec9ed1b21bd53d (proof 92de5638f248a5c1): shard record block 657 shard 0 by 1bb65de716c3b466cd45a85b3ceddf7bcb9873e1821209ee76ec9",
"a carried proof record's proof does not verify: shard record block 786 shard 0 by 990b90ac727bef6244fbbce29abcb47796dd1d197b2c4301aa92609d7c4943ba (proof 52f5ebdcc116da9f): shard record block 786 shard 0 by 990b90ac727bef6244fbbce29abcb47796dd1d197b2c4301aa926"
]
},
"H2": {
"invalid": 6,
"dropped": 0,
"pair": 2,
"statement": 4,
"garbage": 0,
"reasons": [
"a carried proof record's proof does not verify: shard record block 105 shard 0 by 1bb65de716c3b466cd45a85b3ceddf7bcb9873e1821209ee76ec9ed1b21bd53d (proof 92de5638f248a5c1): shard record block 105 shard 0 by 1bb65de716c3b466cd45a85b3ceddf7bcb9873e1821209ee76ec9",
"a carried proof record's proof does not verify: shard record block 254 shard 0 by 990b90ac727bef6244fbbce29abcb47796dd1d197b2c4301aa92609d7c4943ba (proof 52f5ebdcc116da9f): shard record block 254 shard 0 by 990b90ac727bef6244fbbce29abcb47796dd1d197b2c4301aa926",
"a carried proof record's proof does not verify: shard record block 374 shard 0 by 1bb65de716c3b466cd45a85b3ceddf7bcb9873e1821209ee76ec9ed1b21bd53d (proof 92de5638f248a5c1): shard record block 374 shard 0 by 1bb65de716c3b466cd45a85b3ceddf7bcb9873e1821209ee76ec9",
"a carried proof record's proof does not verify: shard record block 511 shard 0 by 990b90ac727bef6244fbbce29abcb47796dd1d197b2c4301aa92609d7c4943ba (proof 52f5ebdcc116da9f): shard record block 511 shard 0 by 990b90ac727bef6244fbbce29abcb47796dd1d197b2c4301aa926",
"a carried proof record's proof does not verify: shard record block 657 shard 0 by 1bb65de716c3b466cd45a85b3ceddf7bcb9873e1821209ee76ec9ed1b21bd53d (proof 92de5638f248a5c1): shard record block 657 shard 0 by 1bb65de716c3b466cd45a85b3ceddf7bcb9873e1821209ee76ec9",
"a carried proof record's proof does not verify: shard record block 786 shard 0 by 990b90ac727bef6244fbbce29abcb47796dd1d197b2c4301aa92609d7c4943ba (proof 52f5ebdcc116da9f): shard record block 786 shard 0 by 990b90ac727bef6244fbbce29abcb47796dd1d197b2c4301aa926"
]
}
}
}
},
"node": "/srv/builds/igneum-wt-vcache/vendor/igneum-node/target/release/igneumd",
"slot": 0,
"ports": {
"base": 30890,
"suffix": 985
},
"startedAt": "2026-10-08T20:49:30.024Z",
"verdict": {
"pairBelow": 1,
"stmtBelow": 1,
"pairWindow": 0,
"stmtWindow": 2,
"pairAfter": 1,
"stmtAfter": 1,
"nothingPaid": true,
"pass": true
},
"endedAt": "2026-10-08T21:04:37.315Z"
}

View file

@ -54,7 +54,10 @@ _slots_env="${IGNEUM_BUILD_SLOTS_DIR:-}"; _log_env="${IGNEUM_BUILD_LOG_DIR:-}"
# What the clean spares beyond target dirs and stamps: a lane's scratch. The fixed prefixes, plus every glob in the mirror-local
# file `.igneum-scratch-spare` (one per line, # comments; the file itself is spared). spare_args <dir> fills SPARE_ARGS with
# the `-e <glob>` arguments; it is never empty (the fixed list), so bash 3.2's unbound-empty-array rule cannot bite the self-test.
SPARE_FIXED=('attack-*' 'scratch-*' 'target-attack-*' '.build-remote.log' '.igneum-scratch-spare')
# vendor/ is spared (8 Oct 2026, the enforced lane's read on build-9): the vendor repos (vendor/igneum-node, vendor/igneum-node-exec)
# are separate repositories, untracked in the main mirror and checked out by their own bs_push_and_checkout only when the run's
# crate is under vendor, so a main-repo crate run on the same worktree took the whole node tree and its target with it
SPARE_FIXED=('attack-*' 'scratch-*' 'target-attack-*' '.build-remote.log' '.igneum-scratch-spare' 'vendor')
spare_args() {
local p
SPARE_ARGS=()

View file

@ -63,6 +63,9 @@ const WINDOW = sflag('window', '120');
const NEXT_PROOF = sflag('next-proof');
const PRIOR_IDS = sflag('prior-ids'); // "0x<shard>,0x<agg>" of the prior pair, default the manifest's
const NEXT_IDS = sflag('next-ids'); // "0x<shard>,0x<agg>" of the next pair
// --drop-keys k1,k2: keys the 60x file lists that the node line under test does not know yet (OverrideParams refuses an
// unknown field); a node line behind master's file drops them
const DROP_KEYS = (sflag('drop-keys', '') || '').split(',').filter(Boolean);
const EXPECT = sflag('expect', FLOOR === 'never' ? 'pay' : 'refuse');
const GENESIS_BITS = flag('genesis-bits', 0x1f010000);
const CASE = sflag('case') || (SUCCESSION ? `succession-${SUCCESSION}-window-${WINDOW}` : `floor-${FLOOR}-expect-${EXPECT}`);
@ -94,7 +97,7 @@ await sleep(1000);
rmSync(TMP, { recursive: true, force: true }); mkdirSync(TMP, { recursive: true });
const track = (proc) => { started.push(proc); try { appendFileSync(PIDS, `${proc.pid}\n`); } catch { } };
const baseText = readFileSync(FILE, 'utf8');
let baseText = readFileSync(FILE, 'utf8');
const field = (name) => { const m = new RegExp(`"${name}":\\s*([0-9]+)`).exec(baseText); return m ? +m[1] : undefined; };
function mergeOverrideText(text, fields) {
let out = text;
@ -102,13 +105,14 @@ function mergeOverrideText(text, fields) {
const extra = Object.entries(fields).map(([k, v]) => `"${k}": ${typeof v === 'string' && !/^\d+$/.test(v) && v !== 'true' && v !== 'false' ? JSON.stringify(v) : v}`).join(', ');
return out.replace(/,?\s*}\s*$/, `,\n ${extra}\n}\n`);
}
for (const k of DROP_KEYS) baseText = baseText.replace(new RegExp(`\\s*"${k}":\\s*[^,}\\n]+,?`), '');
const DAY_MS = field('pow_day_ms');
const manifest = JSON.parse(readFileSync(MANIFEST, 'utf8'));
const override = `${TMP}/override.json`;
writeFileSync(override, mergeOverrideText(baseText, {
genesis_bits: GENESIS_BITS, skip_proof_of_work: false,
proving_v0_activation_daa: '0',
proving_consensus_verify_daa: FLOOR === 'never' ? NEVER : FLOOR,
proving_consensus_verify_daa: SUCCESSION ? '0' : (FLOOR === 'never' ? NEVER : FLOOR),
proving_shard_program_id: PRIOR_IDS ? PRIOR_IDS.split(',')[0] : manifest.shard.program_id, proving_aggregator_id: PRIOR_IDS ? PRIOR_IDS.split(',')[1] : manifest.aggregator.program_id,
verifier_in_consensus: 'false',
proving_key_succession_daa: SUCCESSION || NEVER, proving_key_succession_window_daa: WINDOW,
@ -182,8 +186,39 @@ const PAYOUT_A = '0x' + 'a1'.repeat(20), PAYOUT_B = '0x' + 'b2'.repeat(20);
async function daa(node) { const s = await node.exec('igneum_getExecStatus', []); return Number(s.executedTipDaa ?? 0); }
async function tipNumber(node) { const s = await node.exec('igneum_getExecStatus', []); return Number(s.executedTip ?? 0); }
async function sameTip(a, h) {
try { const x = await a.exec('igneum_getExecStatus', []); const y = await h.exec('igneum_getExecStatus', []); return x.executedTipHash && x.executedTipHash === y.executedTipHash; } catch { return false; }
}
/// Succession mode: the attacker's carrier is refused by the honest nodes and its chain dies with it; before the next
/// forge the attacker must be back on the honest tip (it follows the heavier honest chain), so the carrier it builds is
/// one the honest nodes will read.
async function rejoin(a, h, label) {
// 21:33 UK: pausing A's miner made the rejoin fail every time (A did not adopt H's chain in 300 s twice; with its
// miner running the rejoin took 15 to 130 s and failed once at 150 s), so the miner stays up and the wait is 600 s
for (let k = 0; k < 120; k++) { if (await sameTip(a, h)) { log(`${label}: A is on H1's tip (${k * 5} s)`); return true; } await sleep(5000); }
log(`${label}: A did not rejoin H1's tip in 600 s`); return false;
}
/// The seven shapes for shard 0 of A's chain block `n` (a block A has executed); returns what A's own pool answered.
async function forge(n, phase) {
/// The clocks that fit this shape (read from the 20:42 UK run on build-8, DAA about one per second): a rejoin after a
/// refused carrier took up to 100 s, so the second record of a phase lands 60 to 130 DAA after the first; the floor and
/// the window must leave room: --succession 360 --window 300 (below: records at about 100 and 230; window: about 370 and
/// 500 of 660; after: from 665), never --succession 240 --window 120, whose window closed on the second record.
/// Succession mode, one record per carrier (8 October 2026, 20:4x UK, read from the fix node's run: the attacker's
/// carrier dies with its refusal, so of two records forged on one block only the first is ever carried; the 18:49 run
/// on the pre-fix node read the other half for the same reason): the two shapes go on two blocks with a rejoin between.
async function forgeSuccession(phase, waitMs) {
let tip = await tipNumber(A);
const fa = await forge(Math.max(1, tip - 15), phase, 'p');
await sleep(waitMs / 2);
await rejoin(A, H1, `${phase}: before the second shape`);
tip = await tipNumber(A);
const fb = await forge(Math.max(1, tip - 15), phase, 'n');
await sleep(waitMs); // the second record's carrier and its refusal need the full wait (20:55 UK: a 60 s half missed the after-window one)
return { block: fa.block, hash: fa.hash, second: { block: fb.block, hash: fb.hash }, shapes: [...fa.shapes, ...fb.shapes] };
}
async function forge(n, phase, which = 'pn') {
const plan = await A.exec('igneum_getShardPlan', ['0x' + n.toString(16), PAYOUT_A]);
const block = plan.hash, statement = plan.shards[0].statement;
const planB = await A.exec('igneum_getShardPlan', ['0x' + n.toString(16), PAYOUT_B]);
@ -196,6 +231,19 @@ async function forge(n, phase) {
log(`${phase} ${name}: A's pool ${out.accepted ? 'accepted' : 'refused'} (${out.reason || ''})`);
return out;
};
if (SUCCESSION) {
// the real proof under each pair, each with A's native statement: refused on its pair where the epoch does not
// accept it, on its statement (another chain's) where it does
if (which.includes('p') && REAL_PROOF && existsSync(REAL_PROOF)) {
const real = readFileSync(REAL_PROOF);
await submit('p-prior-pair-proof', signRecord('forger-p', CHAIN, block, n, 0, PAYOUT_A, statement, '0x' + sha256(real)).record, hex(real));
}
if (which.includes('n') && NEXT_PROOF && existsSync(NEXT_PROOF)) {
const nextp = readFileSync(NEXT_PROOF);
await submit('n-next-pair-proof', signRecord('forger-n', CHAIN, block, n, 0, PAYOUT_B, statementB, '0x' + sha256(nextp)).record, hex(nextp));
}
return { block: n, hash: block, shapes };
}
const empty = Buffer.alloc(0), wrong = randomBytes(1024);
// (a) no proof bytes
await submit('a-no-proof', signRecord('forger-a', CHAIN, block, n, 0, PAYOUT_A, statement, '0x' + sha256(empty)).record, '0x');
@ -235,8 +283,10 @@ async function observe(n) {
}
const refusals = (node) => {
const t = node.logText();
return { invalid: (t.match(/IgneumInvalidProofRecord|invalid proof record|proof record .* does not verify|REFUSED/gi) || []).length, dropped: (t.match(/carried proofs did not arrive|did not deliver its carried proofs/g) || []).length,
pair: (t.match(/epoch does not accept|does not embed/g) || []).length, statement: (t.match(/public values hash to/g) || []).length };
const reasons = t.match(/a carried proof record's proof does not verify: [^\n]*/g) || [];
return { invalid: (t.match(/consensus verify of [^\n]*REFUSED/g) || []).length, dropped: (t.match(/carried proofs did not arrive|did not deliver its carried proofs/g) || []).length,
pair: reasons.filter(r => /does not accept|does not embed/.test(r)).length, statement: reasons.filter(r => /public values hash to/.test(r)).length,
garbage: reasons.filter(r => /not a bincode SP1 proof|not a compressed SP1 proof/.test(r)).length, reasons: reasons.map(r => r.slice(0, 260)) };
};
try {
@ -250,9 +300,9 @@ try {
log(`A at DAA ${d}, chain block ${tip}`);
if (d >= floor) log(`WARNING: the floor ${floor} was crossed before the first forge (DAA ${d}); lengthen --floor`);
// outside the 10-DAA exclusive window, where anyone may claim the shard (spec 07 7.2 item 4)
const n1 = Math.max(1, tip - 15);
const f1 = await forge(n1, 'below');
await sleep(45000);
const f1 = SUCCESSION ? await forgeSuccession('below', 45000) : await forge(Math.max(1, tip - 15), 'below');
const n1 = f1.block;
if (!SUCCESSION) await sleep(45000);
const o1 = await observe(n1);
result.phases.below = { daaAtForge: d, forge: f1, observed: o1, refusals: { H1: refusals(H1), H2: refusals(H2) } };
log(`below: H1 paid ${JSON.stringify(o1.paid)}; carried ${JSON.stringify(o1.carried)}`);
@ -260,11 +310,12 @@ try {
if (floor !== Infinity) {
while ((d = await daa(A)) < floor + 5) { log(`waiting for the floor: DAA ${d} of ${floor}`); await sleep(10000); }
} else await sleep(AFTER * 1000 / 2);
if (SUCCESSION) await rejoin(A, H1, 'before the window forge');
tip = await tipNumber(A);
const n2 = Math.max(1, tip - 15);
const beforeRefusals = { H1: refusals(H1), H2: refusals(H2) };
const f2 = await forge(n2, 'at-floor');
await sleep(AFTER * 1000);
const f2 = SUCCESSION ? await forgeSuccession('at-floor', AFTER * 1000) : await forge(Math.max(1, tip - 15), 'at-floor');
const n2 = f2.block;
if (!SUCCESSION) await sleep(AFTER * 1000);
const o2 = await observe(n2);
const afterRefusals = { H1: refusals(H1), H2: refusals(H2) };
result.phases.atFloor = { daaAtForge: d, forge: f2, observed: o2, refusalsBefore: beforeRefusals, refusalsAfter: afterRefusals };
@ -273,28 +324,27 @@ try {
if (SUCCESSION) {
const h = Number(SUCCESSION), w = Number(WINDOW);
while ((d = await daa(A)) < h + w + 5) { log(`waiting for the window's end: DAA ${d} of ${h + w}`); await sleep(10000); }
await rejoin(A, H1, 'before the after-window forge');
tip = await tipNumber(A);
const n3 = Math.max(1, tip - 15);
const r2 = { H1: refusals(H1), H2: refusals(H2) };
const f3 = await forge(n3, 'after-window');
await sleep(AFTER * 1000);
const f3 = await forgeSuccession('after-window', AFTER * 1000);
const n3 = f3.block;
const o3 = await observe(n3);
const r3 = { H1: refusals(H1), H2: refusals(H2) };
result.phases.afterWindow = { daaAtForge: d, forge: f3, observed: o3, refusalsBefore: r2, refusalsAfter: r3 };
const rb = result.phases.below.refusals, rw = afterRefusals;
// below H: the next-pair proof refused on its pair; in the window: no new pair refusal, both on statements;
// after H+W: the prior-pair proof refused on its pair
const pairBelow = rb.H1.pair > 0;
const pairWindow = rw.H1.pair - rb.H1.pair;
const stmtWindow = rw.H1.statement - rb.H1.statement;
const pairAfter = r3.H1.pair - r2.H1.pair;
// below H: the next-pair proof refused on its pair, the prior-pair proof on its statement (another chain's);
// in the window: both on their statements, none on a pair; after H+W: the prior-pair proof on its pair
const pairBelow = rb.H1.pair, stmtBelow = rb.H1.statement;
const pairWindow = rw.H1.pair - rb.H1.pair, stmtWindow = rw.H1.statement - rb.H1.statement;
const pairAfter = r3.H1.pair - r2.H1.pair, stmtAfter = r3.H1.statement - r2.H1.statement;
const nothingPaid = (o1.paid || []).length === 0 && (o2.paid || []).length === 0 && (o3.paid || []).length === 0;
const pass = pairBelow && pairWindow === 0 && stmtWindow > 0 && pairAfter > 0 && nothingPaid;
result.verdict = { pairBelow, pairWindow, stmtWindow, pairAfter, nothingPaid, pass };
const pass = pairBelow >= 1 && stmtBelow >= 1 && pairWindow === 0 && stmtWindow >= 2 && pairAfter >= 1 && stmtAfter >= 1 && nothingPaid;
result.verdict = { pairBelow, stmtBelow, pairWindow, stmtWindow, pairAfter, stmtAfter, nothingPaid, pass };
result.endedAt = new Date().toISOString();
mkdirSync(OUT.replace(/\/[^/]+$/, ''), { recursive: true });
writeFileSync(OUT, JSON.stringify(result, null, 2));
log(`RESULT ${pass ? 'PASS' : 'FAIL'}: below H pair refusals=${rb.H1.pair}; window new pair refusals=${pairWindow}, new statement refusals=${stmtWindow}; after H+W new pair refusals=${pairAfter}; nothing paid=${nothingPaid}; ${OUT}`);
log(`RESULT ${pass ? 'PASS' : 'FAIL'}: below H pair=${pairBelow} statement=${stmtBelow}; window pair=${pairWindow} statement=${stmtWindow}; after H+W pair=${pairAfter} statement=${stmtAfter}; nothing paid=${nothingPaid}; ${OUT}`);
await stopAll();
process.exit(pass ? 0 : 1);
}

View file

@ -1,15 +1,16 @@
{
"run_id": "amd-intel-energy-20261008-01",
"manifest_sha": "c245d50b9",
"evidence_dir": "docs/analysis/class-v6/amd-intel-energy",
"cells": [
{
"cell": "bench:amd-intel-energy",
"status": "NOT RUN",
"evidence": "docs/analysis/class-v6/amd-intel-energy.md",
"note": "GPU-03 AMD and Intel cells: the window costs the RX 7600 0 percent and the Arc B580 -0.3 percent of rate per unit of work (measured, kernel throughput, quiet); B580 fingerprints equal on hl-v6-foldrw and hl-v6-all; energy owed (RX 7600 ADLX job queued behind a held PC 1 runner; the B580 Level Zero energy counter unsupported unelevated); RUNNING, not PASS: team-run, no paired 30-minute protocol, no wall meter",
"method": "GPU",
"in_progress": true
}
]
"run_id": "amd-intel-energy-20261008-01",
"manifest_sha": "c245d50b9",
"evidence_dir": "docs/analysis/class-v6/amd-intel-energy",
"cells": [
{
"cell": "bench:amd-intel-energy",
"status": "NOT RUN",
"evidence": "docs/analysis/class-v6/amd-intel-energy.md",
"note": "GPU-03 AMD and Intel cells: the window costs the RX 7600 0 percent and the Arc B580 -0.3 percent of rate per unit of work (measured, kernel throughput, quiet); B580 fingerprints equal on hl-v6-foldrw and hl-v6-all; energy owed (RX 7600 ADLX job queued behind a held the project's first rig runner; the B580 Level Zero energy counter unsupported unelevated); RUNNING, not PASS: team-run, no paired 30-minute protocol, no wall meter",
"method": "GPU",
"in_progress": true
}
],
"note": " (rig names scrubbed for the served registry at 22:2x UK, the steward's identity landing.)"
}

View file

@ -3,9 +3,16 @@
"manifest_sha": "7cfa422a",
"evidence_dir": "docs/release/evidence",
"cells": [
{"cell": "suite:miner", "cases": ["UX-06"], "status": "PASS", "method": "team-reported",
"evidence": "docs/release/evidence/ux-shipper-2026-10-08.md",
"note": "the fixed miner 7cfa422a on build-1's seed, 20:05:11 to 20:06:11 BST: 49 templates taken in 60 s, no template error, no amount-high-word refusal, no NODE SLOW; MINER SUMMARY 0.006 MH/s (cpu), VOTER votes 20 of 20; lp-4090-11 on the kit from 20:31: zero refusals, 186 blocks accepted in 320 s; the whole fleet's miners on it by 21:48",
"claim_impact": "the miner takes every template the network gives it, including coinbases above a u64"}
{
"cell": "suite:miner",
"cases": [
"UX-06"
],
"status": "PASS",
"method": "team-reported",
"evidence": "docs/release/evidence/ux-shipper-2026-10-08.md",
"note": "the fixed miner 7cfa422a on build-1's seed, 20:05:11 to 20:06:11 UK: 49 templates taken in 60 s, no template error, no amount-high-word refusal, no NODE SLOW; MINER SUMMARY 0.006 MH/s (cpu), VOTER votes 20 of 20; lp-4090-11 on the kit from 20:31: zero refusals, 186 blocks accepted in 320 s; the whole fleet's miners on it by 21:48",
"claim_impact": "the miner takes every template the network gives it, including coinbases above a u64"
}
]
}

View file

@ -0,0 +1,17 @@
{
"run_id": "enforced-proving-20261008-02",
"manifest_sha": "3f672661",
"evidence_dir": "docs/plans/proving-enforcement",
"boxes": [
"build-8"
],
"method": "native",
"cells": [
{
"cell": "harness:proving-enforcement",
"status": "PASS",
"evidence": "docs/plans/proving-enforcement/succession-360-window-300-vcache-7.json"
}
],
"note": "Key succession across a boundary on the review B F01/F02 fix node 3f672661 (harness-unsafe build, both pairs embedded): six refusals on the right ground (below H the next pair on its pair and the prior on its statement; in the window both on their statements, none on a pair; after H+W the prior on its pair and the next on its statement), nothing paid; 21:34 to 22:04 UK, floor 360, window 300, two records per phase."
}

View file

@ -0,0 +1,17 @@
{
"run_id": "family-gate-20261008c",
"manifest_sha": "1a938abe4",
"method": "native",
"cut_tip": "class-v6 1a938abe4 (section 6.13: the chain-seed draw through the acceptance at both era inputs; by the hash lane's 22:00 UK ruling the era-edc4fa84 column, id 2a1d6caab4c24564, is the signing object's and passes, clean of the bit-R class; the era-af89be5d column is the pack hl-v6-all-chainseed's reproduction, void for F0); ac86d7910 for 6.12 and before (family-gate-20261008b)",
"evidence_dir": "docs/analysis/class-v6/logs",
"boxes": [
"build-6"
],
"cells": [
{
"cell": "harness:family-gate",
"status": "NOT RUN",
"evidence": "docs/analysis/class-v6/family-gate.md"
}
]
}

View file

@ -3,9 +3,16 @@
"manifest_sha": "4cdcc488",
"evidence_dir": "docs/release/evidence",
"cells": [
{"cell": "suite:miner", "cases": ["UX-06"], "status": "FAIL", "method": "team-reported",
"evidence": "docs/release/evidence/ux-shipper-2026-10-08.md",
"note": "the shipped miner (4cdcc488, ef0f2ed8) refused every block template whose coinbase exceeded a u64 (rpc/core/src/error.rs:131; the base unit installed only for `inspect`); the fleet fell to a two-key branch, 0 blocks per minute at 19:54 BST",
"claim_impact": "no miner could take the work templates the network gave it above 18.4 IGN of merged subsidy"}
{
"cell": "suite:miner",
"cases": [
"UX-06"
],
"status": "FAIL",
"method": "team-reported",
"evidence": "docs/release/evidence/ux-shipper-2026-10-08.md",
"note": "the shipped miner (4cdcc488, ef0f2ed8) refused every block template whose coinbase exceeded a u64 (rpc/core/src/error.rs:131; the base unit installed only for `inspect`); the fleet fell to a two-key branch, 0 blocks per minute at 19:54 UK",
"claim_impact": "no miner could take the work templates the network gave it above 18.4 IGN of merged subsidy"
}
]
}

View file

@ -24,5 +24,5 @@
"evidence": "build-1:/srv/artefacts/p01/p01-20261008-01/cuda-5090-hl-v5-win.json; build-1:/srv/artefacts/p01/p01-20261008-01/cuda-4090-hl-v5-win.json; build-1:/srv/artefacts/p01/p01-20261008-01/cuda-3090-hl-v5-win.json; build-1:/srv/artefacts/p01/p01-20261008-01/cuda-5090-hl-v6-all.json; build-1:/srv/artefacts/p01/p01-20261008-01/cuda-4090-hl-v6-all.json; build-1:/srv/artefacts/p01/p01-20261008-01/cuda-3090-hl-v6-all.json; build-1:/srv/artefacts/p01/p01-20261008-01/cuda-5090-hl-v6-foldrw.json; build-1:/srv/artefacts/p01/p01-20261008-01/cuda-4090-hl-v6-foldrw.json; build-1:/srv/artefacts/p01/p01-20261008-01/cuda-3090-hl-v6-foldrw.json; build-1:/srv/artefacts/p01/p01-20261008-01/cuda-5090-hl-v6-all-nowin.json; build-1:/srv/artefacts/p01/p01-20261008-01/cuda-4090-hl-v6-all-nowin.json; build-1:/srv/artefacts/p01/p01-20261008-01/cuda-3090-hl-v6-all-nowin.json"
}
],
"note": "P01 part A, the CUDA half, complete at 20:41 UK: four packs (hl-v5-win e3da3669 id 0x6554474f410f36f3 gen 5; hl-v6-all 6df3d430 id 0x4de7b836cc40a4ea gen 6; hl-v6-foldrw f0dc3428 id 0xd7eba30115d26dd4; hl-v6-all-nowin 67ceec05 id 0xbe1d6f48928cef4a) on three CUDA cards (RTX 5090 sm_120, 4090 sm_89, 3090 sm_86), twelve runs, every one driver exit 0, answered 1,000,000, agree 1,000,000, disagree 0, missing 0, 41 to 50 s per million; the kit worker 9bfcf728 for gen 5, the generator-6 worker 804a6f7f for gen 6; the twelve JSONs parsed on build-1 with their sha256s. Remaining for PASS: OpenCL (PC 1's RX 7600, the hash lane; no rented AMD card exists tonight) and Metal (the mini, the morning); the case stays NOT RUN in progress until then."
"note": "P01 part A, the CUDA half, complete at 20:41 UK: four packs (hl-v5-win e3da3669 id 0x6554474f410f36f3 gen 5; hl-v6-all 6df3d430 id 0x4de7b836cc40a4ea gen 6; hl-v6-foldrw f0dc3428 id 0xd7eba30115d26dd4; hl-v6-all-nowin 67ceec05 id 0xbe1d6f48928cef4a) on three CUDA cards (RTX 5090 sm_120, 4090 sm_89, 3090 sm_86), twelve runs, every one driver exit 0, answered 1,000,000, agree 1,000,000, disagree 0, missing 0, 41 to 50 s per million; the kit worker 9bfcf728 for gen 5, the generator-6 worker 804a6f7f for gen 6; the twelve JSONs parsed on build-1 with their sha256s. Remaining for PASS: OpenCL (the project's first rig's RX 7600, the hash lane; no rented AMD card exists tonight) and Metal (the mini, the morning); the case stays NOT RUN in progress until then. (rig names scrubbed for the served registry at 22:2x UK, the steward's identity landing.)"
}

View file

@ -15,8 +15,9 @@
"cell": "bench:fleet-pods",
"status": "NOT RUN",
"evidence": "build-1:/srv/artefacts/tas/p02-rows/p02-rows.txt",
"note": "six CUDA retail cells measured (2080 Ti, 3060 12 GB, 3070 8 GB, 4060 8 GB, 4070 12 GB, 4070 Ti): hl-v5-win, hl-v6-all, hl-v6-foldrw rate and board power, every check PASS on the kit fingerprints; RUNNING not PASS because the AMD cells are PC 1 only (no rented AMD listed), the 1080 Ti cell is open, the 1300 MHz lock did not take inside RunPod containers, the 4060 host reports no power, and the v6 rows predate the 04442d9c pack re-export (program id only)"
"note": "six CUDA retail cells measured (2080 Ti, 3060 12 GB, 3070 8 GB, 4060 8 GB, 4070 12 GB, 4070 Ti): hl-v5-win, hl-v6-all, hl-v6-foldrw rate and board power, every check PASS on the kit fingerprints; RUNNING not PASS because the AMD cells are the project's first rig only (no rented AMD listed), the 1080 Ti cell is open, the 1300 MHz lock did not take inside RunPod containers, the 4060 host reports no power, and the v6 rows predate the 04442d9c pack re-export (program id only)"
}
],
"method": "GPU"
"method": "GPU",
"note": " (rig names scrubbed for the served registry at 22:2x UK, the steward's identity landing.)"
}

View file

@ -43,6 +43,7 @@ docs/design/app-audit-2026-10-08.md
docs/ledger-public-pre-2.0.md
# 8 October 2026: the Devnet 3 proving pipeline record (the fleet lane: box names, the operations record, the external review quoted)
docs/analysis/proving-pipeline-2026-10-08.md
docs/design/key-succession-schedule.md
docs/analysis/v6-10-guest-repin-2026-10-08.md
docs/analysis/class-v6/coexistence-model.md
docs/analysis/class-v6/operator-simulation.md

View file

@ -34,7 +34,12 @@ if [ "${1:-}" = "--self-test" ]; then
# a served site file carrying a pattern: must fail, unscrubbed
printf '<p>a home path /Users/someone/x</p>\n' > "$fx/site/leak.html"
if IDENTITY_CHECK_REPO="$fx" bash "$0" >/dev/null 2>&1; then echo "self-test failed: a home path in site/leak.html passed"; exit 1; fi
echo "self-test passed: the excluded research path may quote the patterns; an exported document and a served page may not"
rm -f "$fx/site/leak.html"
# a registry source (a batch note) carrying a served-page pattern: must fail (the registry is served at /acceptance)
mkdir -p "$fx/tools/ci/batches"; printf '{"note": "ran on PC 2 overnight"}\n' > "$fx/tools/ci/batches/leak.json"; printf '\\bPC [12]\\b\n' > "$fx/site/forbidden-strings.txt"
if IDENTITY_CHECK_REPO="$fx" bash "$0" >/dev/null 2>&1; then echo "self-test failed: a rig name in a batch note (a served registry source) passed"; exit 1; fi
rm -f "$fx/tools/ci/batches/leak.json"
echo "self-test passed: the excluded research path may quote the patterns; an exported document, a served page and a registry source (a batch, a note, the map) may not"
exit 0
fi
@ -100,6 +105,11 @@ fi
# build scripts are not served and are not in this pass.
SITE_FILES="$(find "$REPO/site" -type f \( -name '*.html' -o -name '*.json' -o -name '*.txt' -o -name '*.xml' -o -name '*.webmanifest' -o -name '*.css' -o -name '*.js' \) \
-not -path '*/node_modules/*' -not -path '*/.vercel/*' -not -path '*/api/*' -not -name 'forbidden-strings.txt' -print)"
# the acceptance registry's sources are served too (8 October 2026, 22:2x UK: /acceptance renders docs/plans/igneum-2.0-test-registry.json,
# which the recorder writes from tools/ci/test-map.json, tools/ci/batches/ and tools/ci/notes/; a rig name in a batch note reached the
# served registry), so those sources take the served-site pattern list as well
REG_FILES="$(find "$REPO/tools/ci/batches" "$REPO/tools/ci/notes" -type f -name '*.json' 2>/dev/null; [ -f "$REPO/tools/ci/test-map.json" ] && echo "$REPO/tools/ci/test-map.json"; [ -f "$REPO/docs/plans/igneum-2.0-test-registry.json" ] && echo "$REPO/docs/plans/igneum-2.0-test-registry.json"; true)"
SITE_FILES="$(printf '%s\n%s\n' "$SITE_FILES" "$REG_FILES" | grep -v '^$' || true)"
SITE_PAT="$(printf '%s\n%s\n' "$PAT" "$(grep -vE '^\s*(#|$)' "$REPO/site/forbidden-strings.txt")")"
SITE_HITS="$(printf '%s\n' "$SITE_FILES" | xargs grep -En -f <(printf '%s\n' "$SITE_PAT") 2>/dev/null || true)"
if [ -n "$SITE_HITS" ]; then

View file

@ -349,7 +349,7 @@ else
fi
# rule 24 (8 October 2026, 17:2x UK): a diff that touches a .rs, Cargo.toml, Cargo.lock, build.rs or .cargo/config runs cargo check
# and the crate suite on the box at gate priority for every crate it touches before the merge; docs/ and site/ alone skip it
if [ "$SELF_TEST" != 1 ]; then lock_acquire "$BRANCH" || exit 1; trap 'lock_release; rm -f "$MERGE_PID_FILE" 2>/dev/null' EXIT; fi
if [ "$SELF_TEST" != 1 ]; then lock_acquire "$BRANCH" || exit 1; trap 'lock_release; rm -f "$MERGE_PID_FILE" 2>/dev/null' EXIT; trap 'lock_release; rm -f "$MERGE_PID_FILE" 2>/dev/null; exit 143' INT TERM; fi # a landing stopped by its pid file releases the lock too (22:3x UK: a killed landing left its holder on build-1 until the hand removed it)
# inside the lock master cannot move under this landing; when master is ahead of the branch, the branch takes master first (the
# registry rebuilt from master's copy with the branch's batches replayed, the map merged structurally, the page regenerated), and that
# merge commit carries the branch's green stamp forward as the union of two gated parents (the branch fully, master's tip on its own

View file

@ -12,6 +12,8 @@ the worker never answered.
(a worker argument that itself starts with "--" must be given as --worker-arg=--serve; argparse reads "--worker-arg --serve" as two options)
[--start 0] [--job-nonces 1048576] [--prehash <64 hex>] [--manifest <sha>] --out <evidence.json>
tools/ci/p01-vectors.py --worker <bin> [--worker-arg X ...] --job-context <job-context.json> --phase 1|2|3 --out <evidence.json>
tools/ci/p01-vectors.py --worker <bin> --worker-arg=--serve --job-context <file> --phase N --prepare-first --out <evidence.json>
(a worker with no --pack flag, the Metal worker: its first pack goes by a prepare line before any job)
tools/ci/p01-vectors.py --self-test
The job context (the same-work test, docs/plans/igneum-2.0-same-work-test.md) names two packs and two references (day D and
day D+1), the prehash, the range width (range_log2, 20) and the boundary nonce; phase N runs nonces [(N-1)*2^w, N*2^w): phase 1
@ -77,26 +79,32 @@ def run(a):
if line.startswith('ready'): ready = line.strip(); break
if time.time() - t0 > 120: break
if not ready: p.kill(); return {'error': 'the worker never said ready'}, 2
prepared = None; prepare_sent = None
if len(seg_fields) > 1:
# the second segment's pair (day D+1) is asked for before any job; the worker builds it in a background thread and
# loads and reports it only between stdin lines (proto-cuda/host.cu: "a finished nvcc step is loaded here, between
# lines"), as the miner's steady stream of jobs gives it; so the driver keeps feeding day D jobs after the prepare,
# never crosses the boundary before the prepared line, and when it has nothing left to send on day D it polls the
# worker with a line every second (the worker answers "info ignored", or the prepared line first). A worker without
# prepare support cannot be driven across the boundary.
if ' prepare 0' in ready: p.kill(); return {'error': f'the worker has no prepare support (ready line: {ready}); phase 2 needs it for the day switch'}, 2
ss2, se2, (sb2, db2, _c2, _er2, _pid2, _gen2) = seg_fields[1]
p.stdin.write(f"prepare {sb2} {db2} {segs[1][2]}\n"); p.stdin.flush(); prepare_sent = time.time()
# which segments the worker holds: a worker started on its --pack holds segment 1; a worker with no --pack flag (the Metal
# worker) takes its first pack by a prepare line (--prepare-first); the day D+1 segment always comes by prepare. The worker
# builds a pair in a background thread and loads and reports it only between stdin lines (proto-cuda/host.cu: "a finished
# nvcc step is loaded here, between lines"), as the miner's steady stream of jobs gives it; so the driver keeps feeding the
# jobs it can, never sends a job on a segment before that segment's prepared line, and when it has nothing to send it polls
# the worker with a line a second (the worker answers "info ignored", or the prepared line first). One prepare is in flight at
# a time (the worker refuses a second while one runs). A worker without prepare support cannot be driven across a boundary.
held = {i: (i == 0 and not a.prepare_first) for i in range(len(seg_fields))}
to_prepare = [i for i in range(len(seg_fields)) if not held[i]]; in_flight = None; prepare_sent = None; prepare_lines = []
if to_prepare and ' prepare 0' in ready: p.kill(); return {'error': f'the worker has no prepare support (ready line: {ready}); a pack by prepare or a day switch needs it'}, 2
def send_prepare():
nonlocal in_flight, prepare_sent
if in_flight is None and to_prepare:
i = to_prepare.pop(0); sb, db, c, er, _pid, _gen = seg_fields[i][2]
p.stdin.write(f"prepare {sb} {db} {segs[i][2]} class={c} era={er}\n"); p.stdin.flush(); in_flight = i; prepare_sent = time.time()
send_prepare()
got = {}; agree = 0; disagree = []; seq = 0; start = a.start; end = a.start + a.count; pending = set()
def feed():
nonlocal seq, start
while start < end and len(pending) < 4:
ss, se, (sb, db, c, er, _pid, _gen) = fields_at(start)
if len(seg_fields) > 1 and start >= seg_fields[1][0] and prepared is None:
# the boundary: no job on day D+1 before the worker says prepared; with nothing pending, poll it
idx = next(i for i, (s1, e1, _f) in enumerate(seg_fields) if s1 <= start < e1)
if not held[idx]:
# no job on a segment before the worker says prepared for it; with nothing pending, poll the worker
if not pending:
if time.time() - prepare_sent > 900: p.kill(); raise SystemExit(f'p01-vectors: the worker never said prepared for the day D+1 pair (900 s)')
if time.time() - prepare_sent > 900: p.kill(); raise SystemExit(f'p01-vectors: the worker never said prepared for segment {idx + 1} (900 s)')
time.sleep(1); p.stdin.write("ping\n"); p.stdin.flush()
return
n = min(a.job_nonces, end - start, se - start); seq += 1 # a job never crosses a segment edge (the day boundary)
@ -114,10 +122,13 @@ def run(a):
if len(disagree) < 10: disagree.append({'nonce': n, 'gpu': h, 'cpu': r})
disagree_count[0] += 1
elif it[0] == 'prepared' and len(it) >= 3:
prepared = line.strip(); feed()
prepare_lines.append(line.strip())
for i, (_s1, _e1, f) in enumerate(seg_fields):
if f[1] == it[2] and f[0] == it[1]: held[i] = True
in_flight = None; send_prepare(); feed()
elif it[0] == 'prepare-failed':
p.kill(); return {'error': f'the worker refused the day D+1 pair: {line.strip()[:300]}'}, 2
elif it[0] == 'info' and 'ignored' in line and prepared is None and len(seg_fields) > 1 and start >= seg_fields[1][0] and not pending:
p.kill(); return {'error': f'the worker refused a pair: {line.strip()[:300]}'}, 2
elif it[0] == 'info' and 'ignored' in line and not pending and start < end and not held[next(i for i, (s1, e1, _f) in enumerate(seg_fields) if s1 <= start < e1)]:
feed() # the poll's answer: ask again after a second
elif it[0] in ('done', 'error') and len(it) >= 2:
try: pending.discard(int(it[1]))
@ -137,7 +148,7 @@ def run(a):
if jc is not None:
ev['job_context'] = os.path.abspath(a.job_context); ev['phase'] = int(a.phase); ev['object'] = jc.get('object')
ev['segments'] = [{'start': ss, 'end': se, 'program_id': f[4], 'day_bytes': f[1], 'class': f[2], 'pack': os.path.basename(os.path.abspath(sg[2]))} for (ss, se, f), sg in zip(seg_fields, segs)]
if prepared: ev['prepare_line'] = prepared
if prepare_lines: ev['prepare_lines'] = prepare_lines; ev['prepare_line'] = prepare_lines[-1]
if len(seg_fields) == 2:
b = seg_fields[1][0]; fb, fa = seg_fields[0][2], seg_fields[1][2]
ev['boundary'] = {'nonce': b, 'program_id_before': fb[4], 'program_id_after': fa[4], 'day_bytes_before': fb[1], 'day_bytes_after': fa[1],
@ -196,11 +207,11 @@ for line in sys.stdin:
refD1 = os.path.join(d, 'refD1.txt'); open(refD1, 'w').write(''.join(f"{k} {((k * 0x9e3779b97f4a7c15) % (1 << 64)) ^ 0xdd00dd00dd00dd00:016x}\n" for k in range(0, 48)))
jc = os.path.join(d, 'job-context.json')
json.dump({'object': 'fake', 'prehash': '00' * 31 + '01', 'range_log2': 4, 'boundary_nonce': 24, 'manifest': 'deadbeef', 'packs': {'D': pack, 'D1': pack2}, 'references': {'D': refD, 'D1': refD1}}, open(jc, 'w'))
def gojc(phase, tag, boundary=None, env=None):
def gojc(phase, tag, boundary=None, env=None, extra=()):
if boundary is not None:
j = json.load(open(jc)); j['boundary_nonce'] = boundary; json.dump(j, open(jc, 'w'))
out = os.path.join(d, f'{tag}.json'); e = dict(os.environ); e.update(env or {})
r = subprocess.run([sys.executable, __file__, '--worker', sys.executable, '--worker-arg', w, '--job-context', jc, '--phase', str(phase), '--job-nonces', '8', '--out', out], capture_output=True, text=True, env=e, timeout=120)
r = subprocess.run([sys.executable, __file__, '--worker', sys.executable, '--worker-arg', w, '--job-context', jc, '--phase', str(phase), '--job-nonces', '8', '--out', out] + list(extra), capture_output=True, text=True, env=e, timeout=120)
return r.returncode, (json.load(open(out)) if os.path.exists(out) else {}), r.stdout + r.stderr
for ph, s0, pid in ((1, 0, '0x1'), (3, 32, '0x2')):
rc, ev, o = gojc(ph, f'jc{ph}', env={'RESIDENT': 'dd' * 19} if ph == 3 else None) # phase 3's worker starts on the day D+1 pack
@ -212,10 +223,13 @@ for line in sys.stdin:
rc, ev, o = gojc(2, 'jc2slow', env={'PREPSLOW': '3'})
b = ev.get('boundary', {})
if not (rc == 0 and ev.get('verdict') == 'PASS' and b.get('switched') is True and str(ev.get('prepare_line', '')).startswith('prepared ')): print(f"self-test failed: a worker whose prepare finishes three lines later (the driver must poll it) was not driven across the boundary: rc={rc} {b} {o[-200:]}"); fails = 1
rc, ev, o = gojc(2, 'jc2first', env={'RESIDENT': 'none', 'PREPSLOW': '2'}, extra=['--prepare-first'])
b = ev.get('boundary', {})
if not (rc == 0 and ev.get('verdict') == 'PASS' and b.get('switched') is True and len(ev.get('prepare_lines', [])) == 2 and ev['prepare_lines'][0].split()[2] == 'cc' * 19): print(f"self-test failed: --prepare-first (a worker with no pack at start) did not prepare day D before the first job and day D+1 before the boundary: rc={rc} {ev.get('prepare_lines')} {o[-200:]}"); fails = 1
rc, ev, o = gojc(2, 'jc2noprep', env={'NOPREPARE': '1'})
if rc != 2 or 'no prepare support' not in o: print(f"self-test failed: a worker without prepare support was not refused for phase 2: rc={rc} {o[-200:]}"); fails = 1
rc, ev, o = gojc(2, 'jc2prepfail', env={'PREPFAIL': '1'})
if rc != 2 or 'refused the day D+1 pair' not in o: print(f"self-test failed: a prepare-failed line was not an error: rc={rc} {o[-200:]}"); fails = 1
if rc != 2 or 'refused a pair' not in o: print(f"self-test failed: a prepare-failed line was not an error: rc={rc} {o[-200:]}"); fails = 1
rc, ev, o = gojc(2, 'jc2bad', boundary=40)
if rc == 0 or 'not inside phase 2' not in o: print(f"self-test failed: a boundary outside phase 2 was not refused: rc={rc} {o[-200:]}"); fails = 1
if not fails: print('self-test passed: a clean million-shape run is PASS with the counts; one wrong hash is FAIL naming the nonce, the gpu and cpu hashes; an unanswered nonce is FAIL naming it; the job-context form runs each phase on its range and pack, splits phase 2 at the boundary nonce with the boundary block, and refuses a boundary outside phase 2; the job lines carry the pack fields and the all-pass target')
@ -227,6 +241,7 @@ if __name__ == '__main__':
ap.add_argument('--reference', default=''); ap.add_argument('--count', type=int, default=1_000_000); ap.add_argument('--start', type=int, default=0); ap.add_argument('--job-nonces', type=int, default=1 << 20)
ap.add_argument('--prehash', default='00' * 31 + '01'); ap.add_argument('--manifest', default=''); ap.add_argument('--out', required=True)
ap.add_argument('--job-context', default=''); ap.add_argument('--phase', type=int, default=0)
ap.add_argument('--prepare-first', action='store_true', help='the worker holds no pack at start (no --pack flag, the Metal worker): the first pack goes by a prepare line before any job')
a = ap.parse_args()
if a.job_context and not a.phase: ap.error('--job-context needs --phase 1|2|3')
if not a.job_context and not (a.pack and a.reference): ap.error('--pack and --reference, or --job-context with --phase')

View file

@ -576,8 +576,8 @@
}
},
"bench:amd-intel-energy": {
"command": "the AMD-and-Intel energy lane jobs on the signed-jobs channel: run-ae-pc2-b580-energy-20261008 (PC 2, Arc B580, the class v6 kit worker --memprobe and --bench-pack on hl-v6-foldrw and hl-v6-all, Level Zero energy counter) and run-ae-pc1-7600-energy-20261008 (the project's own rig, RX 7600, the same with ADLX watts at stock, plimit -30, gmax -500 + plimit -30); scripts in docs/analysis/class-v6/amd-intel-energy/",
"box_class": "the project's own rig and PC 2 bench (OpenCL)",
"command": "the AMD-and-Intel energy lane jobs on the signed-jobs channel: run-ae-pc2-b580-energy-20261008 (the project's second rig, Arc B580, the class v6 kit worker --memprobe and --bench-pack on hl-v6-foldrw and hl-v6-all, Level Zero energy counter) and run-ae-pc1-7600-energy-20261008 (the project's own rig, RX 7600, the same with ADLX watts at stock, plimit -30, gmax -500 + plimit -30); scripts in docs/analysis/class-v6/amd-intel-energy/",
"box_class": "the project's two rigs' bench (OpenCL)",
"fixtures": [
"F0",
"F1"
@ -631,7 +631,7 @@
}
},
"pc:install-update": {
"command": "signed jobs and relay runs on the project's own rig (ae432dc7) and PC 2 (1ccfe586): the installer over the running app (rule 14: installed versions, the process set, the first upload), the OTA path (update-now, the update-return read-back line), and the no-click resume after the install (relay run mining-on-after-200.ps1)",
"command": "signed jobs and relay runs on the project's two rigs (ae432dc7 and 1ccfe586): the installer over the running app (rule 14: installed versions, the process set, the first upload), the OTA path (update-now, the update-return read-back line), and the no-click resume after the install (relay run mining-on-after-200.ps1)",
"box_class": "PC (the two Windows PCs; nothing on the Mac)",
"fixtures": [
"F2"
@ -700,8 +700,8 @@
}
},
"kit:class-v6-fingerprints": {
"command": "KITS_BOX_SCRIPT=kits-v6-on-box.sh tools/class-v5/kits-remote.sh --box 1 (the kit zip with its emulation check), then the kit's workers on every platform: the box's CPU emulation (--check, 96 of 96 vector lanes), the fleet's CUDA 4090 (--check and --bench at 2^24, base nonce 0), the Mac's Metal (proto-metal/packbench.swift --pack) and Apple OpenCL (proto-opencl/host.c --pack --bench-pack), PC 1's RTX 5090 and RX 7600 (tools/class-v5/pc1-v6-bench.ps1), PC 2's Arc B580 (tools/class-v5/arc-v6-bench.ps1); the fingerprint of the 2^24 outputs at base nonce 0 equal on every platform for the all pack and for its known-failed partner, the two distinct",
"box_class": "build box + pods + Mac + PC 1 + PC 2",
"command": "KITS_BOX_SCRIPT=kits-v6-on-box.sh tools/class-v5/kits-remote.sh --box 1 (the kit zip with its emulation check), then the kit's workers on every platform: the box's CPU emulation (--check, 96 of 96 vector lanes), the fleet's CUDA 4090 (--check and --bench at 2^24, base nonce 0), the Mac's Metal (proto-metal/packbench.swift --pack) and Apple OpenCL (proto-opencl/host.c --pack --bench-pack), the project's first rig's RTX 5090 and RX 7600 (tools/class-v5/pc1-v6-bench.ps1), the project's second rig's Arc B580 (tools/class-v5/arc-v6-bench.ps1); the fingerprint of the 2^24 outputs at base nonce 0 equal on every platform for the all pack and for its known-failed partner, the two distinct",
"box_class": "build box + pods + Mac + the project's two rigs",
"fixtures": [
"F0",
"F2"

View file

@ -21,6 +21,24 @@ const MAP = process.env.TEST_MAP || path.join(ROOT, 'tools/ci/test-map.json');
const ACCEPT_KEYS = ['accept', 'acceptance', 'accept_text', 'criteria', 'expected']; // whichever the registry uses; all are frozen
const DECISIONS = new Set(['NOT RUN', 'BLOCKED', 'FAIL', 'PASS']);
const METHODS = new Set(['native', 'GPU', 'SP1', 'model', 'static', 'team-reported']);
export const ISLAND_LABEL = 'on an island, not a network';
export const ISLAND_SINCE = '2026-10-08T19:00:00Z'; // 20:00 UK on 8 October 2026: devnet-4 has been seventeen islands since the epoch-3 cut (main's word through the coordinator, 22:2x UK)
const ISLAND_RE = /devnet-4|devnet 4|2\.0 devnet|chain id 4465|igneum-devnet-4/i;
export function labelIslands(reg, since = ISLAND_SINCE, label = ISLAND_LABEL) { // every record measured on the 2.0 devnet after `since` carries the label until the fleet is one chain
let n = 0;
for (const c of casesOf(reg)) {
for (const r of Object.values(c.evidence_records || {})) {
if (!r || typeof r !== 'object') continue;
const at = String(r.at || ''); if (!at || at < since) continue;
if (!(r.decision === 'PASS' || r.decision === 'FAIL') || r.method === 'static') { if (r.network_label === label) { delete r.network_label; r.note = String(r.note || '').replace(/ ?\(on an island, not a network: devnet-4 has been islands[^)]*\)/, ''); } continue; } // a measurement is a verdict from a run; a build fact, a reason or a BLOCKED placeholder is not on any network
if (r.network_label === label) continue;
const txt = JSON.stringify([r.release_identity?.network_object, r.evidence, r.note, r.cell, c.evidence_path]);
if (!ISLAND_RE.test(txt)) continue;
r.network_label = label; r.note = (r.note ? r.note + ' ' : '') + `(${label}: devnet-4 has been islands since the epoch-3 cut; labelled ${new Date().toISOString()}.)`; c.updated = new Date().toISOString(); n++;
}
}
return n;
}
export function normalize(reg) { // the one-time pass over rows written before the vocabulary: RUNNING -> NOT RUN in progress; DEFERRED -> NOT RUN with the note
let n = 0; const now = new Date().toISOString();
for (const c of casesOf(reg)) {
@ -105,6 +123,8 @@ function record(reg, map, batch) {
release_identity: { commit: ri.commit || batch.manifest_sha || '', lockfile: ri.lockfile || '', binary: ri.binary || '', network_object: ri.network_object || '', activation: ri.activation || '', profile_hashes: ri.profile_hashes || '' },
claim_impact: cell.claim_impact || batch.claim_impact || '', reviewer: cell.reviewer || batch.reviewer || '', at: now,
...(missing.length ? { blocked_on: missing, reason: `INT-17: missing ${missing.join(', ')}; never PASS without them` } : {}) };
if (cell.network_label) c.evidence_record.network_label = cell.network_label;
if (!c.evidence_record.network_label && (status === 'PASS' || status === 'FAIL') && method !== 'static' && ISLAND_RE.test(JSON.stringify([c.evidence_record.release_identity?.network_object, c.evidence_record.evidence, c.evidence_record.note]))) c.evidence_record.network_label = ISLAND_LABEL;
c.evidence_records[cell.cell] = c.evidence_record;
// a lifted legacy 'record' entry that carries only a no-harness reason (no run) is not a run: it never counts in the combined
// decision and is dropped once a real cell lands (8 October 2026, 21:5x UK: R2-F03-R01 read NOT RUN on master beside its PASS cell)
@ -154,6 +174,19 @@ if (args.includes('--self-test')) {
if (!badMethod) { console.log('self-test failed: a batch with no method was accepted (methods are never conflated)'); fails = 1; }
const regO = { cases: [{ id: 'O1', method: 'Automated', accept: 'a', run_status: 'RUNNING', updated: 't', evidence_record: { cell: 'suite:x' } }, { id: 'O2', method: 'Automated', accept: 'b', run_status: 'DEFERRED' }] }; normalize(regO);
if (!(regO.cases[0].run_status === 'NOT RUN' && regO.cases[0].in_progress_since === 't' && regO.cases[0].evidence_record.method === 'native' && regO.cases[1].run_status === 'NOT RUN' && /deferred/.test(regO.cases[1].deferral_note))) { console.log(`self-test failed: normalize: ${JSON.stringify(regO)}`); fails = 1; }
// the island label: a record on the 2.0 devnet after the cut takes the label; one before it, or off the devnet, does not; a cell may carry it
const regI = { cases: [
{ id: 'I1', method: 'Automated', accept: 'a', run_status: 'PASS', evidence_records: { x: { decision: 'PASS', at: '2026-10-08T21:00:00Z', release_identity: { network_object: 'igneum-devnet-4, chain id 4465' }, evidence: '/e' } } },
{ id: 'I2', method: 'Automated', accept: 'b', run_status: 'PASS', evidence_records: { x: { decision: 'PASS', at: '2026-10-08T18:00:00Z', release_identity: { network_object: 'igneum-devnet-4' }, evidence: '/e' } } },
{ id: 'I3', method: 'Automated', accept: 'c', run_status: 'PASS', evidence_records: { x: { decision: 'PASS', at: '2026-10-08T21:00:00Z', release_identity: { network_object: 'a research object' }, evidence: '/e' } } },
{ id: 'I4', method: 'Automated', accept: 'd', run_status: 'PASS', evidence_records: { x: { decision: 'PASS', method: 'static', at: '2026-10-08T21:00:00Z', release_identity: { network_object: 'igneum-devnet-4, chain id 4465' }, evidence: '/e' } } },
{ id: 'I5', method: 'Automated', accept: 'e', run_status: 'BLOCKED', evidence_records: { x: { decision: 'BLOCKED', method: 'team-reported', at: '2026-10-08T21:00:00Z', release_identity: { network_object: 'igneum-devnet-4' }, evidence: '/e', network_label: 'on an island, not a network' } } } ] };
const ni = labelIslands(regI);
if (!(ni === 1 && regI.cases[0].evidence_records.x.network_label === ISLAND_LABEL && !regI.cases[1].evidence_records.x.network_label && !regI.cases[2].evidence_records.x.network_label && !regI.cases[3].evidence_records.x.network_label && !regI.cases[4].evidence_records.x.network_label)) { console.log(`self-test failed: the island label did not land on the devnet-4 record after the cut alone: ${ni}`); fails = 1; }
if (labelIslands(regI) !== 0) { console.log('self-test failed: the island label was applied twice'); fails = 1; }
const regC = { cases: [{ id: 'C9', method: 'Automated', accept: 'a' }] };
record(regC, { cells: { dn: { command: 'x', box_class: 'b', fixtures: [], cases: ['C9'] } }, not_run: {} }, { run_id: 'rdn', manifest_sha: 'abc', method: 'native', release_identity: { network_object: 'igneum-devnet-4, chain id 4465' }, cells: [{ cell: 'dn', status: 'PASS', evidence: '/e/dn.log' }] });
if (regC.cases[0].evidence_record.network_label !== ISLAND_LABEL) { console.log('self-test failed: a record naming the 2.0 devnet at record time did not take the island label'); fails = 1; }
// a lifted reason-only record beside a real cell: the row reads the cell's decision and the placeholder is gone
const regL = { cases: [{ id: 'L1', method: 'Automated', accept: 'a', run_status: 'NOT RUN', evidence_records: { record: { decision: 'NOT RUN', reason: 'no harness yet', at: 't' } } }] };
record(regL, { cells: { lc: { command: 'x', box_class: 'b', fixtures: [], cases: ['L1'] } }, not_run: {} }, { run_id: 'rl', manifest_sha: 'abc', method: 'native', cells: [{ cell: 'lc', status: 'PASS', evidence: '/e/l.log' }] });
@ -201,6 +234,7 @@ if (args.includes('--self-test')) {
}
const reg = load(REG); const map = load(MAP);
if (args.includes('--check')) { const r = check(reg, map); for (const l of r.lines) console.error(`test-record: ${l}`); console.log(`test-record: ${r.automated} Automated cases, ${r.mapped} mapped to cells, ${r.notRun} NOT RUN with a reason${r.bad ? `, ${r.bad} problems` : ''}`); process.exit(r.bad ? 1 : 0); }
if (args.includes('--label-islands')) { const n = labelIslands(reg); fs.writeFileSync(REG, JSON.stringify(reg, null, 2) + '\n'); console.log(`test-record: ${n} record(s) measured on the 2.0 devnet since ${ISLAND_SINCE} labelled "${ISLAND_LABEL}"`); process.exit(0); }
if (args.includes('--normalize')) { const n = normalize(reg); fs.writeFileSync(REG, JSON.stringify(reg, null, 2) + '\n'); console.log(`test-record: normalized ${n} rows to the decision vocabulary and the record schema`); process.exit(0); }
if (arg('--cases')) { console.log(((map.cells || {})[arg('--cases')]?.cases || []).join(',')); process.exit(0); }
if (arg('--note-file')) { const n = load(arg('--note-file')); args.push('--note', n.suite, n.text); }