adv-accept-3: report v1 (id derivation finding, margins bound, static steering table, exhaustion cited, plant), logs

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
igneum-labs 2026-10-07 19:21:22 +00:00
parent 1ef80e9a8e
commit fbdf493b8d
7 changed files with 1000318 additions and 0 deletions

View file

@ -0,0 +1,70 @@
# adv3 exhaust-mirror 2026-10-07T19:06:43Z seed 0 (internal adversarial pass, not an independent review)
cap 256; attempts tried 256; mirror reached the cap: true; mirror program == library last_resort_v4(candidate(seed, 256)): true
last-resort attempt 256 id 1bd0d46f206ca5ec fingerprint 0554dc552bd6b6d7 op mix xor=18 load=16 add=10 shfl=6 rotl=4 rotr=4 mad=3 sub=3; shadow op mix xor=106 shfl=35 add=34 mad=29 rotl=20 rotr=16 sub=16
the REAL rule on the last resort: accept (distinct mean 128.000, saturated 0, bias max 55)
props 88 18979 2 34516 37 0 0 88
0: mad dst=2 src=7 src2=2 rot=24 bit=24 mask=2 win=0 off=0
1: xor dst=0 src=3 src2=1 rot=23 bit=15 mask=4 win=0 off=0
2: xor dst=6 src=5 src2=7 rot=1 bit=20 mask=8 win=0 off=0
3: load dst=0 src=2 src2=2 rot=8 bit=12 mask=1 win=2 off=3
4: load dst=6 src=0 src2=1 rot=18 bit=17 mask=16 win=2 off=1
5: add dst=5 src=4 src2=0 rot=14 bit=6 mask=1 win=0 off=0
6: shfl dst=4 src=3 src2=3 rot=1 bit=3 mask=4 win=0 off=0
7: xor dst=4 src=3 src2=1 rot=17 bit=9 mask=16 win=0 off=0
8: rotl dst=4 src=5 src2=2 rot=25 bit=23 mask=16 win=0 off=0
9: xor dst=4 src=5 src2=3 rot=15 bit=28 mask=4 win=0 off=0
10: xor dst=3 src=2 src2=6 rot=12 bit=7 mask=8 win=0 off=0
11: xor dst=7 src=3 src2=0 rot=13 bit=19 mask=4 win=0 off=0
12: load dst=3 src=5 src2=3 rot=2 bit=27 mask=2 win=0 off=0
13: add dst=4 src=1 src2=3 rot=11 bit=20 mask=2 win=0 off=0
14: xor dst=6 src=3 src2=3 rot=29 bit=20 mask=4 win=0 off=0
15: add dst=4 src=1 src2=2 rot=6 bit=3 mask=2 win=0 off=0
16: rotr dst=1 src=6 src2=6 rot=21 bit=19 mask=8 win=0 off=0
17: rotl dst=5 src=3 src2=2 rot=18 bit=1 mask=16 win=0 off=0
18: xor dst=4 src=0 src2=4 rot=21 bit=2 mask=2 win=0 off=0
19: rotr dst=6 src=3 src2=3 rot=6 bit=20 mask=2 win=0 off=0
20: xor dst=5 src=4 src2=3 rot=15 bit=3 mask=8 win=0 off=0
21: shfl dst=7 src=0 src2=2 rot=7 bit=15 mask=16 win=0 off=0
22: xor dst=2 src=1 src2=2 rot=6 bit=28 mask=2 win=0 off=0
23: rotl dst=5 src=4 src2=7 rot=14 bit=23 mask=1 win=0 off=0
24: add dst=0 src=5 src2=5 rot=3 bit=18 mask=1 win=0 off=0
25: sub dst=3 src=0 src2=2 rot=17 bit=30 mask=1 win=0 off=0
26: add dst=3 src=6 src2=1 rot=13 bit=25 mask=2 win=0 off=0
27: load dst=0 src=2 src2=3 rot=15 bit=30 mask=16 win=2 off=2
28: add dst=2 src=1 src2=2 rot=22 bit=23 mask=8 win=0 off=0
29: shfl dst=4 src=5 src2=2 rot=29 bit=0 mask=1 win=0 off=0
30: xor dst=5 src=7 src2=0 rot=7 bit=5 mask=16 win=0 off=0
31: load dst=2 src=0 src2=5 rot=9 bit=7 mask=8 win=2 off=2
32: add dst=2 src=3 src2=1 rot=10 bit=23 mask=1 win=0 off=0
33: load dst=3 src=7 src2=5 rot=5 bit=28 mask=8 win=2 off=2
34: load dst=1 src=3 src2=0 rot=6 bit=13 mask=2 win=0 off=0
35: xor dst=2 src=4 src2=4 rot=8 bit=4 mask=16 win=0 off=0
36: shfl dst=6 src=3 src2=2 rot=17 bit=25 mask=2 win=0 off=0
37: mad dst=1 src=2 src2=6 rot=16 bit=15 mask=4 win=0 off=0
38: xor dst=2 src=0 src2=2 rot=28 bit=19 mask=4 win=0 off=0
39: xor dst=4 src=6 src2=0 rot=14 bit=23 mask=2 win=0 off=0
40: sub dst=6 src=5 src2=6 rot=27 bit=25 mask=1 win=0 off=0
41: load dst=6 src=1 src2=2 rot=29 bit=4 mask=4 win=0 off=0
42: add dst=0 src=5 src2=4 rot=17 bit=16 mask=1 win=0 off=0
43: add dst=6 src=0 src2=3 rot=5 bit=1 mask=2 win=0 off=0
44: load dst=6 src=0 src2=6 rot=3 bit=1 mask=1 win=2 off=2
45: rotr dst=0 src=5 src2=6 rot=11 bit=4 mask=2 win=0 off=0
46: xor dst=4 src=6 src2=4 rot=9 bit=30 mask=2 win=0 off=0
47: load dst=4 src=6 src2=0 rot=24 bit=13 mask=4 win=0 off=0
48: xor dst=7 src=5 src2=4 rot=31 bit=31 mask=1 win=0 off=0
49: shfl dst=4 src=3 src2=7 rot=1 bit=18 mask=16 win=0 off=0
50: mad dst=1 src=4 src2=5 rot=17 bit=8 mask=1 win=0 off=0
51: load dst=7 src=4 src2=1 rot=19 bit=22 mask=16 win=1 off=0
52: shfl dst=6 src=2 src2=4 rot=6 bit=27 mask=4 win=0 off=0
53: rotl dst=6 src=4 src2=2 rot=15 bit=22 mask=2 win=0 off=0
54: load dst=0 src=7 src2=0 rot=27 bit=21 mask=4 win=2 off=1
55: sub dst=6 src=7 src2=6 rot=15 bit=10 mask=4 win=0 off=0
56: load dst=7 src=5 src2=6 rot=1 bit=6 mask=16 win=1 off=1
57: add dst=2 src=4 src2=7 rot=10 bit=20 mask=8 win=0 off=0
58: load dst=5 src=2 src2=0 rot=11 bit=17 mask=1 win=1 off=1
59: xor dst=5 src=1 src2=4 rot=20 bit=24 mask=1 win=0 off=0
60: load dst=7 src=1 src2=3 rot=6 bit=0 mask=1 win=1 off=0
61: rotr dst=5 src=1 src2=1 rot=20 bit=28 mask=2 win=0 off=0
62: xor dst=4 src=5 src2=7 rot=22 bit=3 mask=16 win=0 off=0
63: load dst=0 src=7 src2=2 rot=7 bit=2 mask=4 win=1 off=1
the chain's own program of this seed: attempt 3 id 6eb252f3a3102cdb

View file

@ -0,0 +1,11 @@
# adv3 idcheck 2026-10-07T19:06:37Z (internal adversarial pass, not an independent review)
devnet3-epoch0: chain draw attempt 0 id fce15bf61030be57 (want fce15bf61030be57 at attempt 0) class mx8-eraaf3a9139+sh256x27 in 2.6 s: MATCH
library program_id(4, seed, attempt) = fce15bf61030be57; re-done with sub/3 suffix = fce15bf61030be57 (matches the pack); as program.json and spec 1.4.6 STATE it (no suffix) = 30956569d8f3d8d7 (does NOT match the pack); the stated form with generator 3 = 47b921f76ea993fc
attempt bit flipped: e78239ec71736122 (changed, as it must)
seed words of attempt 0: be8c5a0c 7646e626 508e29d0 fb8a5b4a 53c50955 685d62fc 6065c013 881096eb
op mix load=16 add=11 shfl=7 mad=6 xor=6 mul=4 mulhi=4 rotr=4 rotl=3 sub=2 or=1; props 80 18112 4 4881 22 3 9 83
kit v4-devnet-epoch0: chain draw attempt 1 id a785001687d8688a (want a785001687d8688a at attempt 1) class mx8-erad810f22d+sh256x27 in 2.4 s: MATCH
library program_id(4, seed, attempt) = a785001687d8688a; re-done with sub/3 suffix = a785001687d8688a (matches the pack); as program.json and spec 1.4.6 STATE it (no suffix) = 8aa9f185d63f269e (does NOT match the pack); the stated form with generator 3 = 6b02c7c49eb126bd
attempt bit flipped: fc724221fd9545df (changed, as it must)
seed words of attempt 1: 29e76ddb db25cf2a 596c281e b8284534 50556ce6 336eb6d5 01933285 39690d9f
op mix load=16 mad=8 mul=6 xor=6 rotr=5 shfl=5 sub=5 add=4 mulhi=4 rotl=4 or=1; props 96 18113 4 5271 16 1 11 84

View file

@ -0,0 +1,8 @@
# adv3 ids 2026-10-07T19:09:35Z seeds 1000000 attempts 10 (internal adversarial pass, not an independent review)
pairs 10000000: id collisions 0 (expected 2.71e-6 at random); program-stream state collisions 0 (two seeds with one state draw one base program; expected 2.71e-6); seed-word octet collisions 0
control (known-failed shape): low-32 id collisions 11759 and low-32 state collisions 11781 against 11641.5 expected at random: the counter fires when collisions exist
done in 3.0 s
real 0m3.103s
user 0m5.154s
sys 0m0.756s

View file

@ -0,0 +1,8 @@
# adv3 margins 2026-10-07T19:06:42Z (internal adversarial pass, not an independent review)
n = 1048576 evaluations per site; floor 0.98
window 2^28 words: E = 1046528 (f64 1046528); 0.98 E = 1025597.440; nearest integer 1025597; margin 0.440 counts; relative margin 4.29e-7
over all d in 0..=1048576: f64 compare disagrees with the integer rule on 0 values; an f32 compare on 0
window 2^27 words: E = 1044480 (f64 1044480); 0.98 E = 1023590.400; nearest integer 1023590; margin 0.400 counts; relative margin 3.91e-7
over all d in 0..=1048576: f64 compare disagrees with the integer rule on 0 values; an f32 compare on 0
window 2^26 words: E = 1040384 (f64 1040384); 0.98 E = 1019576.320; nearest integer 1019576; margin 0.320 counts; relative margin 3.14e-7
over all d in 0..=1048576: f64 compare disagrees with the integer rule on 0 values; an f32 compare on 0

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,50 @@
# adv3 steer 2026-10-07T19:06:50Z seeds 900000..900048 plant true (internal adversarial pass, not an independent review)
seed attempt id min_ratio256_milli min_site distinct_mean_milli saturated bias_max rejects cp_loads cp_alu pred_it0 chi2_milli opmax_pct lossy_last lossy_base shadow_depth chain_eq secs plant_ratio_milli plant_verdict
900010 3 78912a5de3bd33b6 999 10 128000 0 52 a',a',a' 64 18482 4 15753 20 0 12 85 DIFF 14.7 983 reject:a'
900020 0 c2f29c00b30a5e5d 999 0 128000 1 64 - 80 18754 3 5619 16 4 12 86 DIFF 16.7 982 reject:a'
900011 5 9563061c64bdecca 999 7 128000 0 44 a',a',a',a',a' 72 17233 2 4751 22 2 13 79 DIFF 16.6 981 reject:a'
900018 0 143b558805860f10 999 7 128000 0 64 - 80 18353 3 15783 33 0 8 86 DIFF 18.4 632 reject:a'
900032 0 7c84e8bb94667f21 999 1 128000 0 61 - 64 20288 3 7424 14 1 9 94 DIFF 18.8 601 reject:a'
900040 0 009458ab6658a8c7 999 3 127870 0 47 - 64 16793 2 4985 14 3 14 77 DIFF 24.3 986 reject:a'
900016 1 b165f4211bf5ebc4 999 9 127633 0 65 a' 72 18753 3 12632 16 0 16 86 DIFF 29.4 612 reject:a'
900001 7 54c3f9adbefa16a2 999 4 127999 0 71 a',a',a',a',a',a',a' 72 19153 3 5805 14 3 15 88 DIFF 29.1 705 reject:a'
900021 0 51b01aa1124a0d0e 999 14 127935 0 47 - 80 19595 1 5675 14 0 11 91 DIFF 29.5 993 reject:a'
900041 2 c4bd5787e0518b5d 999 3 128000 0 65 a',a' 80 17041 1 8266 22 1 6 79 DIFF 31.0 569 reject:a'
900019 0 9a926a06bde1c5f1 999 11 128000 0 63 - 64 19419 2 8947 16 2 15 89 DIFF 31.0 631 reject:a'
900015 1 386d4b144d9a2cd1 999 3 128000 0 48 a' 96 19688 2 6456 22 2 11 91 DIFF 33.7 642 reject:a'
900000 3 ccd4708fc59eb2e2 999 9 128000 0 52 a',a',a' 96 18306 2 9460 14 0 13 84 DIFF 33.1 986 reject:a'
900037 1 dbea0f699425ad1b 999 3 127943 0 45 a' 56 17464 2 13010 25 1 8 82 DIFF 35.2 987 reject:a'
900006 3 b68620e2c19689c3 999 12 128000 1 56 a',a',a' 80 17874 4 8865 18 1 10 84 DIFF 36.4 984 reject:a'
900034 1 079bf3ed530e6dfa 999 2 128000 0 57 a' 80 18744 3 5061 16 3 13 88 DIFF 37.8 983 reject:a'
900028 3 4c4e94ce351f9064 999 10 127876 21 53 a',a,a' 64 18082 1 7085 22 2 12 83 DIFF 40.5 990 reject:a'
900045 7 112123f425b810e3 999 6 128000 0 68 a',a',b,a',a',a',a' 72 18529 3 5908 22 1 10 86 DIFF 40.3 989 reject:a'
900005 1 2342b95129d1c209 999 14 128000 24 65 a' 48 20033 3 5757 18 2 10 93 DIFF 40.3 976 reject:a'
900026 3 48926937a9293a6b 999 11 128000 0 55 a',a',a' 80 20283 4 4230 20 1 10 93 DIFF 40.8 987 reject:a'
900036 0 cf3f6f0a28965f74 999 0 128000 0 49 - 80 17898 2 8279 18 0 13 84 DIFF 41.5 976 reject:a'
900038 2 acde51d358d949e2 999 3 128000 0 45 a',a' 96 19441 3 17327 25 1 8 92 DIFF 42.5 988 reject:a'
900025 0 c32171a38c52038b 999 1 128000 0 56 - 96 17104 1 6109 18 3 16 78 DIFF 42.2 994 reject:a'
900008 5 52bb6108b5f70311 999 11 127999 0 63 a',a',a',a',a' 72 19625 1 4633 16 1 14 91 DIFF 36.0 999 accept
900031 1 9108f53fcc735fb2 999 11 128000 0 62 a 72 19152 3 6713 16 3 11 88 DIFF 43.2 986 reject:a'
900004 1 6a70b22e9959f6fd 999 5 128000 0 47 a' 80 18746 1 8731 18 2 12 88 DIFF 43.7 982 reject:a'
900047 1 bde1eeebcca1d616 999 10 128000 0 57 a' 80 16600 2 11404 20 3 14 76 DIFF 44.1 988 reject:a'
900035 0 8b4be7db79d92a35 999 1 128000 0 69 - 88 17498 3 5467 20 0 14 82 DIFF 45.2 975 reject:a'
900042 1 95ee4bd7b604c0ea 999 12 128000 0 37 a' 72 17273 2 11382 20 1 8 84 DIFF 45.6 987 reject:a'
900003 6 6ed19c746cd435ac 999 3 127880 0 63 a',a',a',a',a,a' 56 16824 3 10418 27 1 7 82 DIFF 45.6 572 reject:a'
900012 8 da0520c80a9e35c2 999 6 127999 0 50 a',a',a',a',a',a',a',a' 72 20489 5 17671 20 0 13 94 DIFF 46.2 599 reject:a'
900002 1 7de58330c4b1190b 999 10 128000 0 62 a' 88 17641 1 3852 18 0 12 81 DIFF 46.6 982 reject:a'
900009 2 a3135bb853e2488d 999 15 127999 0 51 b,a' 64 16371 4 12212 20 1 13 76 DIFF 47.4 975 reject:a'
900014 2 d55a60c026304437 999 1 128000 0 53 a,a' 56 19577 3 8670 14 2 15 90 DIFF 47.4 618 reject:a'
900030 4 ebee859c79ecf21e 999 5 128000 0 66 a',a',a',a' 72 20026 4 6825 16 1 15 92 DIFF 48.6 987 reject:a'
900043 4 44c284e2a9e2fc7f 999 1 128000 0 58 a',a',a',a' 64 17425 1 7392 18 2 6 80 DIFF 40.6 999 accept
900046 3 44ea2876ecb51b45 999 4 128000 0 48 a',a',b 72 17473 2 6642 16 1 11 81 DIFF 48.5 986 reject:a'
900024 0 cdfe112bab988392 999 3 128000 0 56 - 80 18530 3 5803 25 1 10 85 DIFF 48.8 207 reject:a'
900029 0 512a9477ba25d6b0 999 10 127999 0 79 - 72 19626 3 6843 16 1 12 93 DIFF 50.0 982 reject:a'
900023 0 61663f0b00f10e70 999 9 128000 0 72 - 96 19472 1 6890 22 0 7 91 DIFF 50.1 989 reject:a'
900007 4 56d0ae56599bfe20 999 1 128000 0 49 a',a',a,a 88 16392 1 12489 14 4 15 76 DIFF 50.5 987 reject:a'
900033 0 28786312006269bc 999 2 127935 0 59 - 56 17016 3 4866 16 0 10 81 DIFF 51.2 984 reject:a'
900027 1 48ef56e631e04d5f 999 5 128000 0 59 a 72 19393 5 9410 20 1 9 89 DIFF 51.5 586 reject:a'
900039 0 ad2bc8323791e361 999 0 127997 0 64 - 80 16377 2 5580 14 1 14 76 DIFF 51.6 599 reject:a'
900044 10 4647275112a740e2 999 13 127737 0 85 a,a',a,a,a',a',a',a',a,a' 96 19000 2 5571 18 1 16 87 DIFF 51.8 643 reject:a'
900022 1 719b184fd178e616 999 1 128000 0 62 c'' 64 17657 4 4620 14 1 10 82 DIFF 52.8 579 reject:a'
900013 1 03fa77d0bc468486 999 4 128000 0 53 a 96 16816 1 9803 20 2 15 77 DIFF 44.6 999 accept
900017 7 16bfa9e9e692abeb 999 3 128000 0 86 a',a',a',a',a',c'',a' 88 19009 1 9559 16 0 12 89 DIFF 56.9 986 reject:a'

View file

@ -0,0 +1,169 @@
# Report: exhaustion and steering of the program draw (lane adv-accept-3)
internal adversarial pass, not an independent review
- Target commit: 017e70376489251e18564c0abce7e466e606c8b3 (class v4 sub-version 3, object byte 7). Worktree HEAD 45845b09 at the start (build/master, 19:51 BST); `git diff --quiet 017e7037 HEAD -- igneum-pow` prints IDENTICAL.
- Harness: tools/attack/adv-accept-3 (crate adv-accept-3, bin `adv3`), igneum-pow by path, nothing in the library modified. Binaries built on build-2 through tools/build-remote.sh: 35336b84039b76538916c5c2a715aefd06ecc5b215d100bedfa9215b750eaa5b (first build, 20:05 BST: idcheck, margins, exhaust-mirror, ids, the first static sweep, the plant run), 928272e0a4f426a33380612bbcf5cde52017765f5185fc73a4396d5581105785 (20:09 BST, generator 4 stamped on every candidate: every queued sweep), 60613d0c4412401d1bed6dd55a831eb42ffc6b1524c36d79500766b7515ef212 (20:13 BST, the multiply columns: the static sweep v2). Pinned copies under /srv/builds/_adv-accept-3/bin/ on both boxes.
- Boxes: build-1 and build-2, nice 10, cores 8 to 95, one sweep per box under `flock /srv/builds/_adv/locks/sweep.lock` (the coordinator's rule of 19:55 BST). Load 430 to 560 on 96 threads throughout. No GPU: the live-hash-rate confirmation of any gain is BLOCKED and the gain is priced from read counts, as chip-model-v3.md section 5 prices it.
- Logs: /srv/builds/_adv-accept-3/ on each box; copies in docs/analysis/cryptanalysis/logs/adv-accept-3/ on this branch.
- Seed space: `seed_words_from_bytes("igneum-adv-accept-3/steer/<i>")` as 32 little-endian bytes (chain-shaped epoch seeds), era fixed to the Devnet 3 era bytes 4020cb43...b925 (the era is a 180-day constant the epoch attacker does not re-roll). Every program is drawn through the library's own attempt loop and rule.
- Queue: 90 (exhaustion census) was claimed by lane adv-accept before this lane started; its row is cited, not repeated. 91 and 92 claimed at 19:5x BST; 93 to 99 written, claimed and queued (section 9).
- Box-hours spent at 20:20 BST: about 0.15 (three builds under a minute each; idcheck 5 s, margins 1 min, exhaust-mirror 10 s, ids 3 s, two static sweeps of 1 min, the 48-seed plant run at 48 threads 1 min). Queued sweeps had not yet taken a lock at 20:20 BST.
## Draw-path validation (passed before any claim)
`adv3 idcheck` (box 2, 20:06 BST, log logs/adv-accept-3/idcheck.log): the Devnet 3 epoch-0 seed drawn through `Epoch::chain_program(ProgramClass::V4)` gives attempt 0, id fce15bf61030be57, class mx8-eraaf3a9139+sh256x27 (MATCH with the pack, sha256 e025750f... verified on build-1); the kit's shared devnet epoch-0 seed gives attempt 1, id a785001687d8688a (MATCH). So the harness draws what the chain draws.
## Status board
| Q | Question | Method | Known-failed shape (must fire) | Gate | Result | Status |
|---|---|---|---|---|---|---|
| Q1 | Exhaustion: P(a seed exhausts 256 attempts), per-part rejection rates, attempt distribution | Cite row 90 (lane adv-accept, 16,337 seeds); add this lane's static per-part rates over 3,009,928 candidates of 10^6 seeds and the geometric fit | the reject-everything mirror of Q1b | P(exhaust) bounded with its count | per attempt: accept 0.323, reject 0.677 ((a') 0.568, (a) 0.079, (b) 0.022, dynamic parts about 0.009); histogram geometric (bin ratios 0.65 to 0.71); P(exhaust) = 0.677^256 = 4.6 x 10^-44; 0 of 16,337 seeds reached the cap | BOUND |
| Q1b | The last-resort program: weak, constant, predictable | `last_resort_v4(candidate(b, 256))` through the library on 3,000 seeds, the REAL rule run on each | `adv3 exhaust-mirror`: a reject-everything loop must hit the cap and print the last resort | last resort characterised; no predictable or weak accepted program | mirror fired: cap 256 reached, program byte-identical to the library's, the real rule ACCEPTS it (distinct 128.000, saturated 0, bias max 55); seed 0's last resort has 0 lossy ops (or, mul, mulhi all xor), 3 mad kept; 3,000-seed sweep queued | RUNNING (sweep 95) |
| Q2 | Steering with the full rule: tries per quantile of each property | `adv3 steer`, the real draw per seed, min per-site ratio at 256 units plus static properties; 2 x 10^4 seeds queued | `--plant hot`: two `or` writers before a load's source must put the planted set in the lowest quantile | tabulated; no property reaches a 1.1x chip gain under 10^5 tries | plant: 45 of 48 planted rows at ratio 0.207 to 0.993 against a population minimum of 0.999 at 256 units (3 did not fire: the scan found no ALU writer to change); the real rule rejects every effective plant by (a') | RUNNING (sweeps 93, 96) |
| Q2b | Static steering at 10^6 seeds | `adv3 static`: the first candidate passing (a), (b), (a') per seed, static properties, quantiles to 10^-6 | the plant of Q2 (the same property code) | the 10^-5 and 10^-6 quantiles of each property, priced | DONE: table in section 3; the best property at 1 in 10^6 tries is a shadow block with 38 multiplies of 256 (mean 74), worth about 2 to 3 percent of the f = 1 chip's energy per hash (approximate); the load critical path at 40 of 128 (median 72) is worth nothing at the memory activate ceiling | BOUND |
| Q2c | Live hot set of the lowest-ratio steered seeds | f8 `warps` on the lowest-ratio seeds of Q2 | f8's own const-item plant | the worst steered seed's gain priced | not started; lane adv-accept's live rows on its five lowest of 4,600 price the selector at 1.002x | PENDING |
| Q3 | Program id: collisions and derivation agreement | `adv3 ids` over 10^7 (seed, attempt) pairs; `adv3 idcheck` by three derivations | low-32 collision counts must match the birthday expectation; one attempt bit flipped must change the id | 0 collisions; the derivation that matches the packs named | 0 id collisions, 0 program-stream state collisions, 0 seed-word collisions over 10^7 pairs (control: 11,759 low-32 id collisions against 11,641 expected); FINDING: program.json's `program_id_derivation` string and spec 1.4.6 state a derivation WITHOUT the `"sub/" || 3_le16` suffix the code appends for generator 4; an implementation written from the text computes 30956569d8f3d8d7 for Devnet 3 where the pack carries fce15bf61030be57 | FINDING (interoperability, not consensus) |
| Q4 | Determinism traps | `adv3 margins`; a second interpretation of the rule (`adv3 verdicts`, 2,000 seeds, every attempt); a spec-1.4.6-only interpretation (400 seeds); the read list | `--variant floor97` must change at least one verdict | 0 disagreements between code and the faithful second interpretation; the spec-only disagreement rate measured; every divergence listed | margins: the f64 ratio compare of (c'') never disagrees with the integer rule `50 d >= 49 E` on any of the 2^20 + 1 values of d for any window (margins 0.32 to 0.44 counts); read list in section 6 (the spec text is behind the code on six points; the CLI `accept` command caps at 32 with no last resort) | RUNNING (sweeps 94, 97, 98) |
| Q5 | Era steering | `adv3 era-steer` over 400 era seeds: stride, interleave, epoch 0's min ratio | none needed (a listing) | noted | queued | RUNNING (sweep 99) |
## 1. Q1: exhaustion (row 90, owner adv-accept, cited; this lane's static rates added)
Lane adv-accept's census (its report at build/adv-accept d9638927, "The selector's base rate", 16,337 accepted programs of the F8 label space, read 20:12 BST): accepted at attempt 0..11: 5,271, 3,602, 2,434, 1,585, 1,110, 740, 521, 368, 211, 166, 100, 72; max 26; mean 2.097; last-resort programs 0. Its forced-exhaust plant hit the cap and printed the last resort, which the real rule accepted (op mix xor 17 to 19, 0 lossy ops).
This lane's static sweep (`adv3 static --from 0 --count 1000000 --threads 8`, box 1, 20:14 BST, 61 s, log logs/adv-accept-3/static-1e6-v2.tsv): 10^6 seeds, 3,009,928 candidates drawn until the first that passes the static rule.
| Quantity | Value |
|---|---|
| Candidates per seed to the first static pass | 3.010 |
| Static rejection per candidate | 0.6678 |
| (a') dataflow freshness | 1,708,418 of 3,009,928 = 0.5676 |
| (a) cyclic stale load | 236,693 = 0.0786 |
| (b) no injecting write | 64,817 = 0.0215 |
| Dynamic parts (c), (c'), (c'') on a static pass (from the full-rule accept rate 0.323 against the static pass rate 0.332) | about 0.027 of static passes, 0.009 of candidates |
| Seeds reaching 256 static rejections | 0 of 10^6 (max first-static-pass attempt 33) |
| Static attempt histogram 0..11 | 332,037, 222,134, 148,201, 98,797, 66,094, 44,000, 29,246, 19,867, 13,210, 8,916, 5,790, 3,895 |
The histogram is geometric: successive bin ratios 0.669, 0.667, 0.667, 0.669, 0.666, 0.665, 0.679, 0.665, 0.675 (static), and 0.683, 0.676, 0.651, 0.700, 0.667, 0.704, 0.706, 0.573, 0.787 on the sibling's 16,337 full-rule seeds. Attempt k's words are `seed_words_from_bytes(b || k_le32)`, an FNV-1a prefix state shared across attempts and finalised by the murmur mix; the bins show no correlation between attempts at this sample size. With r = 0.677 per attempt, P(exhaust) = r^256 = exp(256 ln 0.677) = 4.6 x 10^-44 per epoch seed. An attacker who re-rolls the epoch seed to reach the last resort needs about 2 x 10^43 tries. No seed class exhausts: the attempts of one seed are 256 independent draws by construction. Bound: 1.016 x 10^6 full-rule seeds (this lane's plant run plus the sibling's) and 10^6 static seeds, 0 at the cap.
## 2. Q1b: the last-resort program
`adv3 exhaust-mirror --seed 0` (box 1, 20:06 BST, log logs/adv-accept-3/exhaust-mirror-0.log). A mirror of `try_generate_class` with the rule replaced by reject-everything tried 256 attempts, reached the cap, and produced `last_resort_v4(candidate(seed, 256))`; the library's own last-resort call on the same seed is byte-identical (`==` on the Program). The real rule, run on that program, ACCEPTS it: distinct mean 128.000, saturated 0, bias max 55. Its base op mix: xor 18, load 16, add 10, shfl 6, rotl 4, rotr 4, mad 3, sub 3 (0 or, 0 mul, 0 mulhi; the 3 `mad` multiplies are kept by the rewrite). Its static properties: 88 loads on the critical path, 18,979 ALU ops on it, 2 predictable sites, chi-square 34.5 against the weights (the rewrite moves every or, mul and mulhi to xor, so its op mix is the one structural tell), 0 lossy ops.
What the last resort is: a deterministic function of the seed (the attempt-256 draw), different for every seed, computable by anyone, reachable only at 4.6 x 10^-44 per seed. Whether it is weak by the rule's own measures over many seeds, and how often the rule would have rejected it, is sweep 95 (3,000 seeds, the real rule on each, queued). What a chip would gain from it: nothing beyond any accepted program's gain; it has no hot set by construction (no lossy op feeds a load) and its only skew is the missing or, mul and mulhi, which a fixed datapath pays for in the shadow block anyway (the shadow's multiplies become xor too, so a last-resort epoch is the cheapest epoch a multiplier-poor chip could see: a 256-instruction shadow with 0 mul and mulhi and only its `mad` multiplies, about 27 of 256). At its probability that epoch never comes.
## 3. Q2b: static steering at 10^6 seeds (DONE)
The property of the first statically accepted candidate of each seed (the dynamic rule then rejects about 2.7 percent of these; the full-rule sweep of section 4 checks that the conditioning does not move the tails). Tries per quantile are 1/q by definition; the table's content is the value a grinder buys at each quantile.
| Property (per hash unless said) | Mean | Min | 10^-1 low / high | 10^-2 | 10^-3 | 10^-4 | 10^-5 | 10^-6 (1 of 10^6) | Max |
|---|---|---|---|---|---|---|---|---|---|
| Loads on the critical path (of 128) | 76.4 | 40 | 64 / 96 | 48 / 104 | 48 / 120 | 40 / 128 | 40 / 128 | 40 / 128 | 128 |
| ALU ops on the critical path (base and shadow, all reps) | 18,326 | 14,008 | 17,001 / 19,808 | 15,937 / 20,952 | 15,273 / 21,992 | 14,664 / 22,835 | 14,251 / 23,506 | 14,033 / 24,410 | 24,593 |
| Load sites of iteration 0 with an init-only address (of 16) | 2.5 | 1 | 1 / 4 | 1 / 6 | 1 / 7 | 1 / 8 | 1 / 9 | 1 / 10 | 10 |
| Chi-square of the 48 non-load ops against the weights | 8.94 | 0.25 | 4.23 / 14.46 | 2.15 / 21.63 | 1.18 / 28.40 | 0.71 / 35.49 | 0.44 / 41.43 | 0.25 / 46.62 | 52.35 |
| Largest single-op share of the 48, percent | 19.0 | 10 | 16 / 25 | 14 / 29 | 12 / 35 | 12 / 37 | 12 / 41 | 10 / 43 | 43 |
| Output registers whose last write is or, mul or mulhi | 1.6 | 0 | 0 / 3 | 0 / 4 | 0 / 5 | 0 / 6 | 0 / 7 | 0 / 7 | 7 |
| or, mul, mulhi in the base program | 11.2 | 0 | 8 / 15 | 5 / 18 | 3 / 21 | 2 / 23 | 1 / 24 | 0 / 25 | 27 |
| Multiplies (mul, mulhi, mad) in the base program (of 48) | 13.9 | 2 | 10 / 18 | 7 / 21 | 5 / 24 | 3 / 26 | 2 / 28 | 2 / 29 | 30 |
| Multiplies in the shadow block (of 256) | 73.9 | 38 | 65 / 83 | 58 / 91 | 52 / 97 | 48 / 101 | 45 / 105 | 40 / 109 | 110 |
| Dependency depth of one shadow pass (of 256) | 84.9 | 64 | 79 / 91 | 74 / 97 | 70 / 102 | 68 / 105 | 67 / 109 | 65 / 112 | 114 |
Priced against chip-model-v3.md section 5:
| Lever a grinder could pull | Best value at 10^-4 (10^4 tries) and 10^-6 | What it buys a chip | Reading |
|---|---|---|---|
| Short load chain (memory-level parallelism) | 40 loads on the critical path against a median of 72: 3.2 independent reads in flight per lane against 1.8 | The f = 1 chip and the card both sit at the memory's activate ceiling (section 5.3: 21.3 G reads/s, the 5090 at 82 percent of it); more reads in flight per lane lowers the lanes needed, not the ceiling; both sides mine the same program | 1.00x |
| Short ALU chain | 14,664 ops at 10^-4, 14,033 at 10^-6, against 18,326: 20 to 23 percent shorter | The ALU chain is 7.6 microseconds per hash at one op per cycle at 2.4 GHz against 128 dependent reads at about 400 ns (51 microseconds): the shadow sits inside the read latency on both sides (section 5.7, the program-length lever); shorter helps the honest card and the chip alike | 1.00x |
| Init-only addresses in iteration 0 | 8 of 16 sites at 10^-4, 10 at 10^-6 (median 2) | Addresses a lane can issue before its first read returns: more parallelism at the start of the hash, the same ceiling; the addresses are nonce-dependent (init words are a hash of header and nonce), not a hot set | 1.00x |
| Fewer multiplies for a multiplier-poor datapath | shadow 48 of 256 at 10^-4, 38 at 10^-6 (mean 74); base 3 at 10^-4 | The shadow is 55,296 ops per hash. At N5 datapath figures (section 5.1: multiply 0.52 pJ, add 0.06, 2x pipeline) the mean shadow pass costs 74 x 0.52 + 182 x 0.06 = 49 pJ, the 10^-6 one 38 x 0.52 + 218 x 0.06 = 33 pJ: 34 percent less shadow ALU energy. The shadow is about 11 to 22 nJ of the f = 1 chip's 470 nJ per hash (approximate), so the saving is 2 to 3 percent of its energy for one epoch in a million tries. The chip still needs multipliers for every other epoch | about 1.02x to 1.03x per joule at 10^-6, approximate; under the 1.1x gate at every quantile |
| Lossy last writes (output bias shape) | 6 of 8 registers at 10^-4, 7 at 10^-6 | A lossy last write narrows an output register's value set; the rule's bias test bounds every output bit to 6 sigma and the final values to under 1 percent saturated; nothing a chip reads faster | 1.00x |
Static steering buys no asymmetric gain: every property a seed grinder can move in the static program helps the honest card by the same amount or not at all, because the rate on both sides is reads per second at the memory ceiling. The one asymmetric lever is a hot set on the live dataset, which is the full-rule sweep's ratio column (section 4) and lane adv-accept's live measurement (its five lowest-ratio seeds of 4,600 all beyond the f8 1.2x gate live, the worst a 1 MB copy serving 0.31 percent of loads, 1.002x; its selector table: ratio under 0.999 at 256 units in 85 of 16,337, one try in 192).
## 4. Q2: steering with the full rule (RUNNING)
Sweeps 93 and 96 (`adv3 steer --from 0 --count 10000 --threads 88 --check-every 50` and `--from 10000`), box 2, queued 20:11 BST behind lane adv-cache-2's census under the sweep lock. Per seed: the real attempt loop and rule, the accepted attempt, the chain id, the minimum per-site distinct-index ratio at 256 units and its site, the (c) report, every rejection reason of the seed's earlier attempts, the static properties of section 3, and every 50th seed re-drawn through `Epoch::chain_program` for equality. Rows land in the log as they finish; the quantile table lands here from the first 10^4 seeds.
Known-failed shape (`adv3 steer --from 900000 --count 48 --threads 48 --plant hot --check-every 1`, box 1, 20:07 to 20:08 BST, binary 35336b84, log logs/adv-accept-3/steer-plant.log): on each accepted program the two ALU instructions that last wrote the source register of one load were rewritten to `or` (the source then saturates toward all ones) and the ratio re-read.
| Rows | Planted ratio at 256 units | Population ratio (the same 48 unplanted) | The real rule on the planted program |
|---|---|---|---|
| 45 of 48 | 0.207 to 0.993 (median about 0.98) | 0.999 on every row | rejected, (a') on every one |
| 3 of 48 | 0.999 (the plant did not fire: the backward scan found loads only before the site and changed nothing) | 0.999 | accepted (unchanged program) |
Every effective plant sits below the population minimum, so the property column separates a forced hot source at once. Rejection reasons over the 48 seeds' 106 rejected attempts: (a') 89, (a) 12, (b) 3, (c'') 2; mean accepted attempt 2.21. Per seed under the box's load: 15 to 57 s at 48 threads (the 2^20 pass of (c'') on every static-passing candidate is the cost), so the two 10^4-seed shards are about 2 box-hours each at 88 threads once they hold the lock. The `chain_eq` column of that run read DIFF on every row because the first binary left generator 2 on the candidates (the id then took the class path); the comparison is meaningful from binary 928272e0 on, which every queued sweep runs.
## 5. Q3: the program id
`adv3 ids --seeds 1000000 --attempts 10 --threads 16` (box 1, 20:09 BST, 3.0 s, log logs/adv-accept-3/ids-1e7.log): 10^7 (seed, attempt) pairs of this lane's seed space.
| Quantity | Count | Expected at random |
|---|---|---|
| Equal program ids (FNV-1a-64 with the generator-4 suffix) | 0 | 2.7 x 10^-6 |
| Equal program-stream states (the 64-bit `lo ^ hi * golden` that fixes the base program and shadow: two seeds with one state draw one program) | 0 | 2.7 x 10^-6 |
| Equal seed-word octets | 0 | about 0 |
| Control: equal low 32 bits of the id / of the state | 11,759 / 11,781 | 11,641 |
The control is the known-failed shape: at 32 bits the counter sees the birthday collisions the model predicts, so a 64-bit collision would have been counted. Bound: 10^7 pairs; the 64-bit birthday bound for the chain's whole life (about 10^5 epochs a decade) is 2.7 x 10^-10 per decade. FNV-1a-64 is not collision-resistant against a chosen input, but the id's preimage is the seed words, themselves the murmur-finalised FNV of the epoch seed, so a chosen-id attack needs a preimage through that step; this lane did not attempt one, and the id is a label, not a commitment.
FINDING (interoperability): `adv3 idcheck` recomputed the two public ids from the seed words three ways. The code's derivation (`"igneum-program/" || 4_le32 || words || attempt_le32 || "sub/" || 3_le16`) reproduces both pack ids. The derivation the pack STATES in its own `program_id_derivation` field ("FNV-1a 64 over 'igneum-program/' || generator_le32 || seed_words as little-endian bytes || attempt_le32") and spec 1.4.6's text at this commit give 30956569d8f3d8d7 for Devnet 3 (pack: fce15bf61030be57) and 8aa9f185d63f269e for the kit's shared devnet pack (pack: a785001687d8688a). A worker or verifier written from the pack's own description computes a different id from the node for every generator-4 program and is refused at the id check (`packcheck.rs`, "a worker MUST refuse a pack whose class or era seed does not match"), or, if it trusts its own id, splits from the node's view of which pack is which. Not a consensus fault (the id does not enter the hash) and not an attack gain; it is a divergence source two conforming-by-the-text implementations hit at once. Fix: the `program_id_derivation` string in program.json and spec 1.4.6 should carry the suffix. Where it lives: `generator.rs` `program_id` (the suffix), `emit.rs` (the string, not read by this lane; the string is quoted from the pack).
## 6. Q4: determinism traps
### 6.1 The f64 in (c'') (`adv3 margins`, box 2, 20:06 BST, log logs/adv-accept-3/margins.log)
`distinct_ratio_pass` computes `ratio = d / (n - n^2 / 2W)` in f64 and compares `ratio < 0.98`, inside the consensus rule, while spec 1.14 item 1 says "no floating point anywhere". At n = 2^20 evaluations and the three windows the expectation E is an integer and 0.98 E is never within 0.32 of an integer:
| Window | E = n - n^2 / 2W | 0.98 E | Nearest integer | Margin (counts) | f64 compare against `50 d >= 49 E`, all 2^20 + 1 values of d | f32 compare |
|---|---|---|---|---|---|---|
| 2^28 words | 1,046,528 | 1,025,597.44 | 1,025,597 | 0.44 | 0 disagreements | 0 |
| 2^27 | 1,044,480 | 1,023,590.40 | 1,023,590 | 0.40 | 0 | 0 |
| 2^26 | 1,040,384 | 1,019,576.32 | 1,019,576 | 0.32 | 0 | 0 |
So no conforming implementation, in f64 or f32 or integers, can flip a (c'') verdict at these constants. The trap is latent: it depends on `ACCEPT_UNITS_DISTINCT_V4` and the floor staying at values where 0.98 E is not near an integer; a floor of 0.9800 at E = 1,046,528 is safe by 0.44 counts, 0.9790 by 0.21, and some floor and unit pairs sit under 0.01. The exact form `50 d >= 49 E` costs nothing and removes the dependence. BOUND.
### 6.2 The spec text against the code (measured by sweep 97)
Spec 01 section 1.4.6 at 017e7037 describes (a), (b), (c), a 5.14 percent rejection rate, a 32-attempt consensus fault and an id without a suffix. The code adds (a') with the shared-operand idiom, (c'), (c'') at 2^20 evaluations, a 256-attempt cap keyed on the class v4 shape, a total draw with the last resort, generator 4, the suffix, and executes the 256-instruction shadow block 27 times per iteration inside the acceptance interpreter (which the spec's section 1.7 does not have). An implementation written from the spec text disagrees with the node on about two thirds of attempt-0 verdicts (the (a') rate of section 1) and so on the epoch program for about two thirds of seeds; sweep 97 (`adv3 verdicts --variant spec`, 400 seeds) measures the attempt-verdict and chosen-program disagreement rates. This is the largest divergence source found and it is documentary: the public spec at the frozen commit does not describe the frozen rule.
### 6.3 Read list
| # | Where | What two implementations could do differently | Verdict |
|---|---|---|---|
| D1 | accept.rs `distinct_ratio_pass`, f64 ratio | section 6.1 | safe at these constants, latent |
| D2 | spec 1.4.6 against accept.rs and generator.rs | section 6.2 | FINDING (documentary), rate from sweep 97 |
| D3 | program.json `program_id_derivation`, spec 1.4.6 id | section 5 | FINDING (interoperability) |
| D4 | generator.rs `attempts_class` (the CLI `igneum-pow accept` command) | loops `0..MAX_ATTEMPTS` (32) and has no last resort, while the chain's `try_generate_class` loops to 256 and falls back; the diagnostic tool and the node disagree on a seed needing more than 32 attempts (0.677^32 = 3.8 x 10^-6 per seed; the code comment names one seen seed) | tool-only, not consensus |
| D5 | accept.rs `run_unit` early return on a lane-constant site; `check_dynamic` order of tests | the verdict is accept iff every test passes, so the order and the early return change only the reported reason | no divergence |
| D6 | `distinct_indices_v4` allocates 16 x 2^20 u32 (64 MiB) and sorts per site | a memory-poor verifier is slower, not different | no divergence |
| D7 | `is_class_v4_shape` keys (a'), (c'), (c''), the cap and the last resort on `shadow.instrs == 256` with the era and the rep count set aside | a rung change (other reps) keeps the rules; a class with a different shadow size silently loses them | by design, noted |
| D8 | `load_index` under an era at the rule's constant D = 28, `window` with k = min(win, 2) | matches spec 1.13.1's formula at D = 28 | no divergence |
| D9 | `below(n)` as `next() % n` | defined by spec 1.3.2 | no divergence |
| D10 | panics: `check_static` on a wrong instruction count; `generate_from_seed_bytes_class` on exhaustion for v2 and v3 | unreachable from the generator; class v4's draw is total | none on the chain path |
### 6.4 The second interpretation (sweeps 94, 98)
`adv3 verdicts --variant faithful` re-implements (a) cyclic, (b), (a') to its fixpoint with the shared-operand idiom, (c), (c') and (c'') as a per-lane scalar interpreter with its own accumulators and an integer ratio compare, from the module table of accept.rs and the spec's instruction semantics (reusing the library's `splitmix32`, `dataset_elem` and `load_index` as primitives), and compares verdict by verdict with `accept::check` on every attempt of 2,000 seeds. `--variant floor97` (300 seeds) is the known-failed shape: the floor at 0.97 must change at least one verdict against the code, or the comparison is not reading the ratio. Numbers land here.
## 7. Q5: era steering (sweep 99)
`adv3 era-steer --from 0 --count 400` lists, per era seed of this lane's label space, the stride multiplier (its popcount and NAF weight), the rotation, the interleave, and epoch 0's accepted attempt and minimum ratio under that era. The era attacker re-rolls one 32-byte value per 180 days; the stride is an odd 32-bit multiplier and the interleave four positions of 16, so the properties a chip wants (a weak stride: popcount 1, NAF weight 1 or 2) are at 2^-27 and about 2^-22 per try. Numbers land here.
## 8. Box-hours and what a longer pass would add
Spent at 20:20 BST: about 0.15 box-hours (section header). Queued: sweeps 93 and 96 (about 2 box-hours each), 94 (about 1), 95 (about 1), 97, 98, 99 (under 0.5 together). A longer pass would run the full-rule steering sweep to 10^5 seeds (10 box-hours at the lock's rate) to read the ratio tail at 10^-5 with the live f8 census on the lowest ten, and a chosen-id preimage attempt through `seed_words_from_bytes` (a 2^32-class meet in the middle on FNV-1a-64 is the published shape; the murmur finaliser is the obstacle).
## 9. Queue files (all on build-2 under /srv/builds/_adv/accept/queue/, claimed under claims/)
| File | Box | Command | State at 20:20 BST |
|---|---|---|---|
| 91-adv-accept-3-seed-steering.sh (definition) | | implemented as 93 and 96 | claimed |
| 92-adv-accept-3-program-id-determinism.sh (definition) | | implemented as `ids`, `idcheck`, `margins`, 94, 97, 98 | claimed; ids, idcheck, margins done |
| 93-adv-accept-3-steer-s00.sh | 2 | steer 0..10000 | queued (lock held by adv-cache-2) |
| 94-adv-accept-3-verdicts-faithful.sh | 1 | verdicts faithful 0..2000 | queued (lock held by adv-mixer-3) |
| 95-adv-accept-3-lastresort.sh | 1 | lastresort 0..3000 | queued |
| 96-adv-accept-3-steer-s01.sh | 2 | steer 10000..20000 | queued |
| 97-adv-accept-3-verdicts-spec.sh | 1 | verdicts spec 0..400 | queued |
| 98-adv-accept-3-verdicts-knownfailed.sh | 1 | verdicts floor97 0..300 | queued |
| 99-adv-accept-3-era-steer.sh | 1 | era-steer 0..400 | queued |