From 0365e1add1833d79995d545fa6b9594fcbee8660 Mon Sep 17 00:00:00 2001 From: igneum-labs <337424239+igneum-labs@users.noreply.github.com> Date: Wed, 7 Oct 2026 12:10:11 +0000 Subject: [PATCH] class v5 on the amended v4 (ca3-v4-amend cc01cfa6 merged): the source rule's class key sets the state flag aside so V5_CLASS and its rungs draw under it; the test class_v5_chain_draw_is_the_amended_v4_draw (the v5 chain draw equals the amended v4's instruction for instruction at rung 0 and 1 with no lossy-sourced load; the unamended v3 stream of the same seeds carries them: the known-failed case); the pinned v4 control pack re-exported with its sub-version line and id a21e93f6988dce82 (the string-seed packs carry no era, so the rule touches neither draw; the v5 pack is unchanged); generator 5 keeps program_id(5, seed, attempt) with no sub-version, the hash lane's reading Co-Authored-By: Claude Fable 5.1 --- igneum-pow/src/generator.rs | 45 +++++++++++++++++++ proto-cuda/packs-ca3-v5/v4-genesis/program.h | 3 +- .../packs-ca3-v5/v4-genesis/program.json | 3 +- 3 files changed, 49 insertions(+), 2 deletions(-) diff --git a/igneum-pow/src/generator.rs b/igneum-pow/src/generator.rs index 85bd50e83..19d169ee0 100644 --- a/igneum-pow/src/generator.rs +++ b/igneum-pow/src/generator.rs @@ -539,6 +539,11 @@ impl LoadClass { LoadClass { shadow: Some(ShadowClass { instrs, reps }), ..self } } + /// This class with another class's era draw (tests: a rung's class composed with the chain's era). + pub fn with_era_of(self, other: &LoadClass) -> LoadClass { + LoadClass { era: other.era, ..self } + } + /// The class with the state leaves of class v5 folded into every item ("mx8+sh256x27+state"). pub fn with_state(self) -> LoadClass { LoadClass { state: true, ..self } @@ -1885,6 +1890,46 @@ mod tests { assert!(!ProgramClass::V4.has_state() && ProgramClass::V5.has_state()); } + /// Class v5 (docs/design/class-v5-stored-state.md) takes the amended class v4 draw (AP-F8-1) as the chain draws it: + /// with an era present every load's source was last written by an injecting op or a rotate, the base program and + /// the shadow block equal the amended v4's of the same seed, and the same holds at a ladder rung; the state flag + /// changes the id and the dataset, never the draw. The known-failed case first: a v5 draw with a lossy-sourced + /// load would fail the same scan the amended v4 passes. + #[test] + fn class_v5_chain_draw_is_the_amended_v4_draw() { + let era = [7u8; 32]; + let scan = |p: &Program| { + let mut kept = [false; 8]; + let mut lossy = 0; + for i in &p.instrs { + if i.op.is_load() && !kept[i.src as usize] { + lossy += 1; + } + kept[i.dst as usize] = i.op.injects() || matches!(i.op, Op::Rotl | Op::Rotr); + } + lossy + }; + for seed in ["igneum-genesis", "igneum-epoch-7", "igneum-epoch-99"] { + let v4 = generate_from_seed_bytes_program_class(seed, seed.as_bytes(), ProgramClass::V4, Some(&era)); + let v5 = generate_from_seed_bytes_program_class(seed, seed.as_bytes(), ProgramClass::V5, Some(&era)); + assert_eq!(v5.instrs, v4.instrs, "{seed}: the base program is the amended v4's"); + assert_eq!(v5.shadow, v4.shadow, "{seed}: and the shadow block"); + assert_eq!((v5.seed, v5.attempt), (v4.seed, v4.attempt)); + assert_eq!(scan(&v5), 0, "{seed}: no lossy-sourced load under the rule"); + assert_eq!(v5.generator, GENERATOR_VERSION_V5); + assert!(v5.class.state && !v4.class.state); + assert_ne!(v5.program_id(), v4.program_id()); + let r1 = generate_from_seed_bytes_program_class_shadow(seed, seed.as_bytes(), ProgramClass::V5, Some(&era), 35); + let r1v4 = generate_from_seed_bytes_program_class_shadow(seed, seed.as_bytes(), ProgramClass::V4, Some(&era), 35); + assert_eq!(r1.instrs, r1v4.instrs, "{seed}: rung 1 too"); + assert_eq!(scan(&r1), 0); + assert_eq!(r1.class, v5_class_at(35).with_era_of(&r1v4.class)); + } + // the stream of 6 October (no rule) differs: a v3 program of the same seed is lossy-sourced somewhere in three seeds + let lossy_v3: usize = ["igneum-genesis", "igneum-epoch-7", "igneum-epoch-99"].iter().map(|seed| scan(&generate_from_seed_bytes_program_class(seed, seed.as_bytes(), ProgramClass::V3, Some(&era)))).sum(); + assert!(lossy_v3 > 0, "the known-failed case: the unamended stream carries lossy-sourced loads"); + } + /// Counter ASIC 3.0 (6 October 2026): class v4 is class v3 with the latency-shadow block `sh256x27`, drawn after /// the base program; since the AP-F8-1 amendment (7 October 2026) its base program draws a load's source only /// from registers whose last writer keeps entropy, so it is its own stream over class v3's load slots and era diff --git a/proto-cuda/packs-ca3-v5/v4-genesis/program.h b/proto-cuda/packs-ca3-v5/v4-genesis/program.h index 55bfd8226..6da268aee 100644 --- a/proto-cuda/packs-ca3-v5/v4-genesis/program.h +++ b/proto-cuda/packs-ca3-v5/v4-genesis/program.h @@ -15,7 +15,7 @@ #define IGNEUM_SEED_BYTES_HEX "69676e65756d2d67656e65736973" #define IGNEUM_GENERATOR 4 #define IGNEUM_PROGRAM_ATTEMPT 0 -#define IGNEUM_PROGRAM_ID 0x853a971d7813fd5cull +#define IGNEUM_PROGRAM_ID 0xa21e93f6988dce82ull #define IGNEUM_DAY_STRING "2026-10-03" #define IGNEUM_DAY_BYTES_HEX "6461792f323032362d31302d3033" #define IGNEUM_DAY0 0x3067619fu @@ -32,6 +32,7 @@ // latency-shadow block (IGNEUM_SHADOW_INSTRS x IGNEUM_SHADOW_REPS per iteration); a worker that runs another class // refuses this pack, and a job line names the class it wants (class=v4 era=). #define IGNEUM_PROGRAM_CLASS "v4" +#define IGNEUM_PROGRAM_SUBVERSION 1 // Class v3 construction (Counter ASIC 2.0, 5 October 2026, docs/plans/mixer-x4.md): version 2 loads; the dataset item // derivation applies the mixer IGNEUM_MIXER_MULT times per round (memhard.h), and the cache follows the growth rule. #define IGNEUM_LOAD_CLASS "mx8+sh256x27" diff --git a/proto-cuda/packs-ca3-v5/v4-genesis/program.json b/proto-cuda/packs-ca3-v5/v4-genesis/program.json index 76a4e4c27..1c3480c80 100644 --- a/proto-cuda/packs-ca3-v5/v4-genesis/program.json +++ b/proto-cuda/packs-ca3-v5/v4-genesis/program.json @@ -2,7 +2,7 @@ "format": "igneum-program-pack-3", "generator": 4, "attempt": 0, - "program_id": "0x853a971d7813fd5c", + "program_id": "0xa21e93f6988dce82", "program_id_derivation": "FNV-1a 64 over 'igneum-program/' || generator_le32 || seed_words as little-endian bytes || attempt_le32", "dataset_mode": "memory-hard", "seed": "igneum-genesis", @@ -16,6 +16,7 @@ "instruction_count": 64, "loads_per_hash": 128, "program_class": "v4", + "sub_version": 1, "load_class": "mx8+sh256x27", "mixer_mult": 8, "cache_growth": true,