Commit graph

22 commits

Author SHA1 Message Date
igneum-labs
af1b7c46dd Counter ASIC 3.0 gates (hash): class v4 sub-version 3, first commit (AP-F8-3; main's word: 0.3.21 ships byte 5, sub-version 3 is 0.3.22's). The acceptance executes the latency-shadow block as the hash does: run_unit runs the block after instruction 63 of every iteration, reps times with the iteration's sel (verify.rs); until now it ran the 64 base instructions only, so every dynamic acceptance test on a class v4 program judged a program the chain never hashes, which is the whole residual class behind sub-version 2's 8 of 64 gate failures. The test acceptance_executes_the_shadow_block_as_the_verifier_does pins the acceptance's execution to verify.rs on the devnet epoch-0 program and the six test eras (equal output bit counts over the 64 units; different with the shadow stripped). PROGRAM_SUBVERSION_V4 = 3 (a new verdict is a new stream). The seven gate packs re-exported: the devnet epoch-0 seed still accepts at attempt 1, so its program and fingerprint are sub-version 2's (e370fb2080b7dbb1) under the new id a785001687d8688a (must-differ: c120d7963abdcd96, 1a4230699a6b9c60, a788661687db4bb3); the seven 256-block ladder packs re-exported. The ledger entry carries AP-F8-2's exhaustion half as FIXED-AND-PASSED at fbb00320 (0 of 10^6, max attempt 35, r = 0.67), AP-F8-3, and p23's localisation (site 7 reads r6 = (mulhi | r4) ^ r4 = r6 & ~r4; 0.84 of uniform distinct indices at 2^20, 0.55 at 2^24, reproduced in the acceptance's own execution); the second commit, a per-site distinct-index ratio, is held
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-07 14:20:02 +00:00
igneum-labs
fdac338dbc Counter ASIC 3.0 gates (hash): class v4 sub-version 2 (AP-F8-1, main's ruling B2: 0.3.20 ships sub-version 1 untouched; this stream is object byte 7). F1, the draw: a load's source is drawn only from registers fresh by dataflow (fresh at the start; a load keeps freshness only from a fresh source; add, sub, xor, mad, shfl from either operand; rotl, rotr from their operand; or, mul, mulhi never), keyed on the class v4 shape on EVERY draw path (era or not, the pass count set aside), so a census through candidate_class reads the chain's stream. (a'), accept.rs: the same freshness run to its fixpoint over the loop (base then shadow block) and every load's source fresh in the steady state, else the candidate is rejected and the next attempt drawn (closes the iteration boundary the draw cannot see: F8's p11, an or at 63 feeding a load at 1, and the load-after-load and rotate-of-saturated chains of p6, p23, p26, p31, p34). (c'), accept.rs: per load site, the count of source values equal to 0 or all-ones over the 64 units' 16,384 evaluations, rejected at 164 or more (the (c) limit), the backstop for any delivery of saturation (zero and all-ones alike: p45's mulhi zero). Both keyed on the class v4 shape, so v2 and v3 verdicts and ids do not move. PROGRAM_SUBVERSION_V4 = 2 in the id suffix and the pack lines. The seven gate packs re-exported: the devnet epoch-0 seed's attempt 0 is now rejected and attempt 1 accepted, id a788661687db4bb3 (must-differ: c120d7963abdcd96 the 6 October stream, 1a4230699a6b9c60 sub-version 1); the seven 256-block ladder packs of packs-ca3-shadow re-exported under the rule (the no-era path moves too; their measured rates stand as the old stream's). Tests: the generator test checks the fixpoint rule on the amended program and the known-failed case (the v3 stream re-labelled v4); the mixer contract checks the dataflow rule on every V4-shaped class, era or not
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-07 13:01:40 +00:00
igneum-labs
0a62293a95 Counter ASIC 3.0 gates (hash): the class v4 amendment for AP-F8-1 (the project lead: option A, limited testing). The chain draw of class v4 takes a load's source only from registers whose last writer injects (add, sub, xor, mad, shfl, load) or is a rotate (rotl, rotr), never one last written by or, mul or mulhi (candidate_from_words_class, keyed on the era-composed V4_CLASS; no attempts lost, rule (a) unchanged, v2 and v3 and the generator-2 ladder packs byte-identical). Split protection agreed with the node lane: generator stays 4 and the program id of a generator-4 program appends "sub/" || PROGRAM_SUBVERSION_V4 (= 1) as little-endian u16 bytes inside program_id(), so a pre-amendment binary and this one never share an id for one seed; packs carry IGNEUM_PROGRAM_SUBVERSION 1 and program.json sub_version 1, and packcheck refuses a generator-4 pack whose sub-version is absent or other. The seven gate packs re-exported (devnet epoch 0 and eras 0 to 5): id 1a4230699a6b9c60 (was c120d7963abdcd96, now the must-differ vector in tests/recheck.rs), fingerprints Metal = Apple OpenCL 867dbc45cfb36b4d, 2146ecacc8c75a8e, fe52602393f6d3d4, 3b206471a13912b4, c3f03c4a5d7333aa, f1dfd7209f15bb97, 8c194da64fadf31d; the v3 control 73bcbfe8ccf988f1 / 90f794dd556f7a3b untouched. The mixer harness checks the source rule on every load site of an amended program instead of equality with the v3 base
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-07 09:38:51 +00:00
igneum-labs
6836115d65 Capacity layer: idle-core background workload on igneum-build-1 that yields to builds
infra/build-server/capacity: igneum-capacity.service (user build, Nice 19, SCHED_IDLE,
CPUQuota leaving 8 threads free) runs run.sh, a controller over a priority queue of jobs
that pauses (SIGSTOP) the instant a build slot or the measure hold is taken (5 s poll of
/srv/builds/_locks) and resumes after. Jobs, each with a dry-run and a 10-min smoke:
pow fuzz (continuous, seed base advances), sync-request fuzz against a throwaway pruned
node on loopback (the Horizon 28-unwrap gate, igneum-p2p-probe sync-fuzz), GHOSTDAG and
finality sweeps seeds 1 to 1,000, model.py sweeps cached, clippy+audit per recent branch.
Summaries to /srv/workers/capacity.json; the worker dashboard gains a Background lane
(collect.mjs doc.background, page renderBackground). Night battery stops and restarts the
layer. docs/plans/build-server.md section 8. igneum-pow fuzz tests and ghostdag_sim.py /
attacks.py gain a seed-base knob for the continuous sweeps.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-06 20:58:42 +00:00
igneum-labs
4de1b3ba52 Pool v0 rebased onto master and the 0.3.14 fork: the program class and era seed ride with every seeds and job line; the re-check test for class v3 and class v4
The fleet's 10-member load run (6 October 2026, 18:14Z to 18:24Z) accepted 0 shares: the pool fork's miner re-checked GPU
shares with a fixed class v2 program while the 0.3.14 workers hashed class v3 (docs/plans/pool.md section 9).

pool: node.rs builds the share verifier's seeds from the template's pow_epoch with the class and the era, installs the
node's genesis day, dataset size and class v3 activation beside the schedule, and sends program_class, next_program_class,
era_seed, era_index, genesis_day_index, genesis_dataset_log2 and program_class_v3_activation_daa in `seeds` and
program_class and era_seed in `job` (protocol.rs, additive fields); verify.rs tests through EpochSeeds::v2. Protocol,
vardiff, PPLNS, stats API and page otherwise unchanged. Suite 22 of 22 on igneum-build-1.

igneum-pow tests/recheck.rs: for class v3 (packs-ca2-mixer/mx8-devnet-epoch0) and class v4 (packs-ca3-v4/v4-devnet-epoch0)
the pack's program reproduces the pack's 96 vectors (the worker's reference), the chain seam the node engine calls
(Epoch::chain_program, chain_dataset_day) builds the same program, one known nonce hashes equal through both paths, and
the fixed-v2 program of the same seed disagrees; the pinned v3 and v4 program ids differ. 2 of 2 on igneum-build-1.

packaging/hive: the pool:// mode merged with master's per-card IDENTITIES=auto and OVERRIDE handling (selftest passes).
pool/README.md and pool.md: building on igneum-build-1 (the vendor/igneum-node symlink on the box).

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-06 18:49:13 +00:00
igneum-labs
43664184ed Counter ASIC 3.0 gates (hash): follow-up 1 on the program-id fix (e05eb0c merged): crate suite 97 of 97, the seven v4 packs re-exported byte-identical (generator 4, id c120d7963abdcd96), fingerprints unchanged on Metal and Apple OpenCL, Mac G2 16 x 1,024 of 1,024 through the v4 class token, the harness 4 of 4 on the class and on the era with the id assert_ne holding; the job scripts take the class token from the pack
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-06 16:38:48 +00:00
igneum-labs
4d660ceb0a Counter ASIC 3.0 gates (hash): the class v4 packs (mx8+sh256x27 with the era at devnet epoch 0 and eras 0 to 5, the v3 control), the PC 2 G1+G2 playbook, hash-bound --count ported from ca2-era, the mixer harness on a class and an era (IGNEUM_MIXER_CLASS, IGNEUM_MIXER_ERA, the shadow contract)
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-06 15:57:40 +00:00
igneum-labs
3959d66e55 Merge ca3-shadow (item 8's Mac rows) into ca3-coord: LoadClass carries derive_len and shadow; igneum-pow suite 96 passed 2026-10-06 08:11:03 +00:00
igneum-labs
51dba1ce76 Counter ASIC 3.0 item 8: the latency-shadow knob (LoadClass +sh<S>x<R>), its packs and the PC 2 playbook
A shadow block of S ALU instructions run R times at the end of every iteration, drawn from the program stream after
the 64 base instructions, behind LoadClass::shadow: v2 and v3 draw nothing and emit nothing (the pinned packs are
byte-identical, cargo test 54 + 4 + 19 + 7 green). The interpreter, the three kernel dialects (both kernels each),
program.h and program.json carry it; the acceptance rule interprets the base program only. Packs for seed
igneum-genesis over class mx8 at 4,096 to 180,224 shadow instructions per hash (proto-cuda/packs-ca3-shadow), and
the PC 2 bench playbook tools/ca3-shadow/pc2-shadow-bench.ps1 (passes the publisher's three checks).

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-06 07:58:35 +00:00
igneum-labs
50ebdd64d9 Counter ASIC 3.0 item 2: the per-day item-derivation program (class dr736), its interpreter, emitter and packs
A prototype behind a new LoadClass field (derive_len) and Shape field, Shape::for_class_day: every mixer slot of
the item derivation runs a straight-line program of 736 instructions drawn from the day key stream (the same
SplitMix64 stream, after the 40 mixer draws), twelve two-register forms, the chain rule of SuperscalarHash made
strict (every instruction reads the register the previous one wrote), an acceptance test with the x8 mixer's
operation and multiply counts from the code as floors (72 x 144 as written, 72 x 128 hoisted, 1,152 multiplies).
The verifier runs the program with a word-major (SoA) interpreter over the 32 items of a load, dispatching on
instruction pairs; no JIT. The emitter writes mh_round_0..8 into memhard.h, memhard.metal and kernel.cl. Packs
dr736-genesis and dr736-devnet-epoch0 under proto-cuda/packs-ca3-derive. The v2 and v3 paths are untouched: every
pinned pack re-exports byte for byte (tests/packs.rs), cargo test -p igneum-pow 58 + 7 + 4 + 19 + 7 green.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-06 07:41:23 +00:00
igneum-labs
9597374c4d verifier regression of e08909f fixed (derive_items out of line, one instance per cache size with the line mask a constant: v2 0.609 ms per unit against readwidth's 0.607, was 1.33); x8 into class v3 under the delegated rule (V3_CLASS = MX8; mx8-genesis and mx8-devnet-epoch0 re-exported through the seam, the devnet one with the era inside; the mx4 packs kept as the x4 record, generator 2); tests/packs.rs and tests/mixer.rs on the x8 class; mixer-x4.md 6.2a, 6.4a, 6.5 decision, 6.6 the regression; chip-model-v3.md headline x8 (0.92x with the factor); bench-log addendum with the PC 1 build rows
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-05 22:10:55 +00:00
igneum-labs
2fe2626d94 tests/scratch.rs: the Instr literals carry the era fields win and off (0), left out by the merge of ca2-mixer onto the era tree
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-05 22:05:57 +00:00
igneum-labs
147db8db44 mixer x8 candidate beside x4 (coordinator's rule, 5 October 2026 21:30 UTC): LoadClass::MX8 ("mx8", same stream, keys (r m + j + 1) x 0x9E3779B9), the two candidate packs mx8-genesis and mx8-devnet-epoch0 (generator 2 with the class in the id; the vectors are re-cut through the seam after the x4/x8 choice), tests/mixer.rs fuzz takes IGNEUM_MIXER_CLASS, the PC playbooks carry the x8 packs and the gfx1036 fallback; mixer-x4.md: the Metal fuzz row
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-05 22:02:23 +00:00
igneum-labs
36ef07fda2 mixer x4: tests/mixer.rs (200-program v3 fuzz with the Metal pack writer, stats beside v2, dataset edges at every multiplier, determinism against the pinned pack); scratch.rs edge literal gains era_bytes; mixer-x4.md: the v3 vector tables, the v2 diff, the Metal and Apple OpenCL bit-exactness rows, the soundness table so far
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-05 22:02:23 +00:00
igneum-labs
a99fa6375f scratch soundness (layer 3 of Counter ASIC 2.0): verify.rs scratch trace hook; tests/scratch.rs: rewrite and fill bijections, written-word bias and re-hit rates per class, hand-built slot edge programs against a hand model, static scratch-mask check over every emitted kernel of every scr pack with six deliberate breaks, 200-program CPU fuzz and pack writer for the Metal runs; packbench --batch-base for the launch-level nonce wrap
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-05 22:02:23 +00:00
igneum-labs
39ecd7c52b hot table (Counter ASIC 2.0 layer 5), measured and not adopted, on the ca2-v3 composed class (squash of tag ca2-cache-history-2026-10-05)
LoadClass::hot (Option<HotClass { mb, k, added }>) beside mix, slots, scratch, mixer_mult, growth and era; V3_CLASS = { era: None, hot: None, ..LoadClass::MX4 } (hot stays None: the hot code is behind the flag, measured and not adopted). Op::Hot, the hot slots drawn after the scratch slots, no width roll (v2_loads allows the added form's extra slots), the id suffix hot/<S><k>[added], the hot parsing inside parse_loads, the era branch first in name(). HotTable under seed_words("igneum-hot/" || epoch seed) with the cache chain and tag umHT, read at H[mulhi(src, HOT_WORDS)]; DatasetSource::hot attached by new_class_day and from_seed_bytes_class; the acceptance stand-in dataset_elem(idx, S[2], S[3]); the three emitters (hot argument after the init words, ht_segment and igneum_hot_fill beside the layout-aware cores); packfile.h hot fields beside class, era, attempt and mixerMult; OpenCL host, Metal packbench and NVRTC worker fill H on the device and self-test it. Eight packs under proto-cuda/packs-ca2-hot (replaced hot32k4 hot64k4 hot96k4 hot64k2 hot64k8, added hot32k4a hot64k4a hot96k4a) re-exported on the merged crate: vectors unchanged, program.h and program.json carry the mixer fields. docs/plans/hot-table.md (design, spec text, per-tier budget, chip model, Mac and PC measurements, the decision: layer 5 out of v3, the 3.0 note); bench-log entry and addenda with job ids and worker sha256s; the two PC playbooks.

Checks on this commit: cargo test --release 53 + 19 pass (the pinned v2, mx4, era, readwidth and hot packs); the pinned packs under proto-cuda/packs, packs-ca2-mixer, packs-ca2-era and packs-readwidth untouched; Metal packbench and Apple OpenCL --bench-pack on all eight hot packs (run lock, 2^20 at base 0): 96/96 lanes, hot table head, last line and FNV PASS, one fingerprint per pack on both harnesses, equal to the fingerprints before the rebase (hot32k4 679e5e83378d3790, hot64k4 d4c9e456b039fdef, hot96k4 7c98eceffee9fd73, hot64k2 f43b10a95879b8e5, hot64k8 c11309d743be9392, hot32k4a afb700b2d997c847, hot64k4a ba214baa9c1a9e85, hot96k4a 29e1916aed6deff5). No era or mixer behaviour changed: every resolution kept the ca2-v3 side and appended the hot branch.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-05 21:57:39 +00:00
igneum-labs
1558971521 era layout (Counter ASIC 2.0 layers 4 and 8) behind the class flag, on the ca2-v3 seam: the 7-draw era stream from E_n (stride, interleave, width pinned at 4 B), per-site window draws (dataset, half, quarter at a 256 MiB floor), the strided windowed load address in the interpreter, the acceptance mirror and the three emitters, the interleaved dataset layout riding with the program (memhard::Layout, mh_t/mh_j/mh_addr, Epoch::dataset_word), V3_CLASS with the era drawn inside by generate_from_seed_bytes_program_class, --era / --era-widths on the CLI, six class v3 era packs (packs-ca2-era), tests, the design doc, host.cu/host.c deriving host words through the pack's mh_word, emu/test-layout.sh, the PC 1 playbook
Squashed from six commits (tag ca2-era-pre-squash) for one merge.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-05 21:41:33 +00:00
igneum-labs
f74a087443 mixer x4: the two pinned class v3 packs (proto-cuda/packs-ca2-mixer/mx4-genesis and mx4-devnet-epoch0, generator 3 on V3_CLASS = mx4, the devnet pack with era 0's stand-in), tests/packs.rs runs every pinned check over them plus v3_packs_are_the_v2_seeds_under_mixer_x4; igneum-pow --program-class v2|v3 and --era-hex through one epoch_of helper (export, bench, hash, hash-bound); fresh exports of igneum-genesis-mh and igneum-devnet-v4-epoch0 diff clean against the checked-in packs
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-05 21:03:27 +00:00
igneum-labs
fdcab858e3 Lottery hash: generator version 2 (16 load slots, fresh sources, acceptance rule), every vector re-cut, packs regenerated, three workers re-checked, 20,000-program census
igneum-pow 0.2.0: generator v2 draws exactly 16 load slots from instructions 1..63, a
load's source from the registers written earlier and not read by a load since, the other
48 ops from the ten non-load weights; accept.rs is spec 01 section 1.4.6 (static: no
stale load source, every register injected; dynamic: 64 units on the seed-keyed
closed-form dataset, no constant bit, no lane-constant site, under 164 saturated, bias
within 136 of 1024, distinct addresses above 245,760); a rejected candidate is replaced
by the next attempt of the seed (seed || k_le32), 32 a consensus fault. Packs carry the
generator version, attempt and program id. Version 1 kept as generate_v1 for the census.

Packs: igneum-genesis, igneum-hourly, igneum-genesis-mh regenerated by igneum-pow export;
new igneum-devnet-v4-epoch0 (devnet genesis hash, day bytes 20730). Checks: Rust 39 of
39 tests; Metal natively via the Swift port (export cross-check 3 of 3 warps, identical
programs and vectors on five seeds incl. three with attempt 1, fuzz 2,000 of 2,000);
CUDA emu 4 of 4 packs; OpenCL emu 2 packs x 2 configurations; Apple OpenCL 4 of 4 packs
at 27.9 Mhash/s. Census 20,000: 5.225 percent rejected, accepted distinct mean 127.887.

Spec 01 0.2 (1.4.2, 1.4.3, 1.4.6, 1.11, 1.15, 1.16, 1.17), igneum-pow README, the CUDA,
OpenCL and Metal test notes, bench-log entry, ledger M5 and M6 Fixed.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-04 07:52:40 +00:00
igneum-labs
b02b87dfd0 igneum-pow: OpenCL bound kernel in the pack, byte-seed options on the CLI
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-03 19:01:13 +00:00
igneum-labs
07c07d7963 igneum-pow: header binding (init words from the pre-PoW hash and nonce), bound kernels, 8 bound vectors
Implements spec 01 section 1.6 (O-1.9): I = seed_words_from_bytes("igneum-block/" || H || nonce_hi_le32),
lane nonce = low 32 bits. Fixed here: H keeps the timestamp (nonce zeroed only), pow256 = lane in the top 64 bits
with zero low bits, interim day seed "igneum-day/" || day_le64, epoch seed = the 32 bytes of the epoch block hash.
Every existing function and the 288 pack vectors are unchanged; program_bound.metal and kernel_bound.cu are new
pack files.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-03 18:39:34 +00:00
igneum-labs
a09e81d51e igneum-pow: Rust crate bit-exact with proto-metal (seed, generator, memhard, verifier, emitters)
Standard-library Rust port of the Swift prototype for the rusty-kaspa fork. 23 tests
tie it to proto-cuda/packs: program.json instruction by instruction for three packs,
cache FNV 48c4f5bf24166b2e, dataset head/last/64 samples, 96/96 hash vectors per pack,
and kernel.cu, program.metal, kernel.cl, program.h, memhard.h, memhard.metal byte-identical.
CPU verify 0.41 to 0.58 ms per warp (Swift 0.63 to 1.21), cache fill 175 to 181 ms one core.
CLI: bench, export, hash. program.json is written as valid JSON (the Swift quotes the
cache line mask inside the "item" string; fix pending in main.swift).

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-03 16:53:18 +00:00