class-v6: the acceptance's class v4 shape predicate and the draw's source rule set the window and layer 8 off aside (lane D's finding: a +nowin or +reg64c program was judged by the class v2 parts on the chain's path); test: every v6 flag keeps the shape and the attempt cap

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
igneum-labs 2026-10-08 18:18:54 +00:00
parent ab4c36c5c0
commit a326de8eab
3 changed files with 21 additions and 2 deletions

View file

@ -489,7 +489,9 @@ pub fn is_class_v4_shape(class: &LoadClass) -> bool {
// 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
// not the shape)
&& LoadClass { era: None, shadow: None, state: false, fold: false, rw: 0, ..*class } == LoadClass { shadow: None, ..V4_CLASS }
// the window and layer 8 off are set aside too (lane D's finding of 8 October 2026, 19:1x UK: a +nowin or +reg64c
// program was judged by the class v2 parts alone on the chain's path; the harness's own predicate hid it)
&& LoadClass { era: None, shadow: None, state: false, fold: false, rw: 0, nowin: false, reg64: false, reg64_chain: false, ..*class } == LoadClass { shadow: None, ..V4_CLASS }
}
/// One pass of the dataflow freshness over the base program then the shadow block (the order of one iteration),

View file

@ -1705,7 +1705,7 @@ pub fn candidate_from_words_class(
// 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, ..class } == LoadClass { shadow: None, ..V4_CLASS };
&& LoadClass { era: None, shadow: None, state: false, fold: false, rw: 0, nowin: false, reg64: false, reg64_chain: false, ..class } == LoadClass { shadow: None, ..V4_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

@ -247,6 +247,23 @@ fn v6_draw_connects_all_lanes_and_keeps_mad_bijective_by_construction() {
assert_ne!(a.program_id(), b.program_id());
}
/// Lane D's finding (8 October 2026): every class v6 flag is set aside by the acceptance's class v4 shape predicate,
/// so a +nowin, +reg64 or +reg64c program is judged by the full rule (the fresh-source rule, the saturated-source
/// check, the index floors and the attempt cap with the last resort), not by the class v2 parts; the draw's source
/// rule reads the same shape.
#[test]
fn every_v6_flag_keeps_the_class_v4_acceptance_shape() {
use igneum_pow::accept::is_class_v4_shape;
use igneum_pow::generator::max_attempts_for;
let all = LoadClass::parse("mx8+sh256x27+state+reg64c+nowin+fold+rw").unwrap();
for c in [V5_CLASS, V5_CLASS.with_nowin(), V5_CLASS.with_reg64(), V5_CLASS.with_reg64().with_reg64_chain(), V5_CLASS.with_fold(), all] {
assert!(is_class_v4_shape(&c), "{}", c.name());
assert!(is_class_v4_shape(&LoadClass::era(c, &f8_bytes("era", 4), &V3_ALLOWED)), "{} under an era", c.name());
assert_eq!(max_attempts_for(&c), max_attempts_for(&V5_CLASS), "{}: the same attempt cap and last resort", c.name());
}
assert!(!is_class_v4_shape(&V3_CLASS) && !is_class_v4_shape(&LoadClass::V2));
}
/// 2. The fold's form: `y = x * M; y ^= y >> 16; y = rotl(y, R)`, and nothing else moves. The plain era's stride is
/// `rotl(x * M, R)` byte for byte.
#[test]