code wiki / (root) / nx_dyad.nx

nx_dyad.nx source

↩ module page · 201 lines · 8276 B

1// nx_dyad.nx -- paired-cell side-by-side composition. 2// 3// Biology: a chromatid dyad is two sister chromatids paired during 4// cell division -- bound by structure, separate by identity. Paired 5// biological organs (kidneys, lungs, eyes) operate in parallel with 6// independent function. nx_dyad runs cell A and cell B side by side 7// receiving the SAME input, producing separate outputs, with NO 8// cross-leak between them. 9// 10// Per [[feedback-cell-immune-system-ransomware-judo-ddos-by-bit]]: 11// "i want to test game a and test game b in a side by side window 12// for user or ai or system bot review i can without it garbaging 13// up everything but also being exclusive so if website a got hit 14// with ransomware we laugh and delete and shift to website b and 15// load up c as the new backup." 16// 17// Naming refusal: nx_compose was the cardinal's tentative name but 18// it's already taken in the repo for image-composition (rule-of- 19// thirds visual scoring). nx_dyad keeps biology naming + unambiguous. 20// 21// Composes: 22// nx_observatory -- watches dyad outputs from outside (parallel 23// telemetry without crossing the cells) 24// nx_brane -- capability tokens ensure A cannot read B's 25// memory and vice versa 26// nx_promote -- when one of the dyad cells gets compromised, 27// its slot in the dyad can be promoted from 28// a chromatin replica 29// nx_pathway -- a dyad is a 2-cell pathway with a special 30// "no cross-edges" constraint 31// 32// V1 ships: 33// - struct NxDyad bundling cell_a_id, cell_b_id, both their input 34// ptrs + output ptrs, both their attention classes 35// - same_input verbs: feed both A and B from one source buffer 36// - both_outputs reader: read both outputs without merging 37// - cross_leak detector: predicate that asserts no shared buffer 38// 39// Gap list (V1 honest perf verdict): 40// - cross_leak is a STRUCTURAL check (different buffer pointers); 41// V2 adds runtime side-channel detection 42// - no automatic input-divergence detector (caller drives) 43// - N-way generalization (triad / quad / N-yad) queued 44// - no transactional commit (V2 ensures both A and B observe the 45// same input even under preemption) 46// 47// genealogy_id: cardinal_2026-05-17_cell_immune_judo + 48// biology_chromatid_dyad_paired_organs 49// lineage_id: substrate_dyad_v1 50// 51// nx_safety_envelope: 52// intended_use: "Paired-cell side-by-side run with explicit 53// no-cross-leak constraint; foundation for 54// A/B testing and resilience drills" 55// sil_target: SIL2 56// evidence: [structural_buffer_isolation, 57// no_shared_memory_at_substrate_layer] 58// verdict: NOT_YET_EVALUATED 59 60import "nx_syscalls.nx" 61import "nx_tier.nx" 62import "nx_attention_class.nx" 63 64// ===== Sealed enum: NxDyadVerdict ================================= 65 66const NX_DY_OK: nx_int = 0 67const NX_DY_ERR_CROSS_LEAK: nx_int = 1 68const NX_DY_ERR_BAD_CLASS: nx_int = 2 69const NX_DY_ERR_BUF_NULL: nx_int = 3 70const NX_DY_ERR_INPUT_DIVERGED: nx_int = 4 // dyad's invariant broken 71 72// ===== Struct: NxDyad ============================================= 73// 74// Two cells in side-by-side compose. Each cell has its own in/out 75// buffers; the dyad's job is the no-cross-leak structural guarantee. 76 77struct NxDyad { 78 cell_a_id: nx_int, 79 cell_a_class: nx_int, 80 cell_a_in: *u8, 81 cell_a_in_len: nx_size, 82 cell_a_out: *u8, 83 cell_a_out_len: nx_size, 84 cell_b_id: nx_int, 85 cell_b_class: nx_int, 86 cell_b_in: *u8, 87 cell_b_in_len: nx_size, 88 cell_b_out: *u8, 89 cell_b_out_len: nx_size, 90} 91 92// ===== nx_dyad_new ================================================ 93// 94// Construct a dyad. Caller has already allocated the four buffers 95// (A.in, A.out, B.in, B.out) with no overlap. nx_dyad_new validates 96// that input pointers differ and output pointers differ (cross-leak 97// prevention). 98 99func nx_dyad_new(cell_a_id: nx_int, cell_a_class: nx_int, 100 cell_a_in: *u8, cell_a_in_len: nx_size, 101 cell_a_out: *u8, cell_a_out_len: nx_size, 102 cell_b_id: nx_int, cell_b_class: nx_int, 103 cell_b_in: *u8, cell_b_in_len: nx_size, 104 cell_b_out: *u8, cell_b_out_len: nx_size) -> *NxDyad { 105 if nx_ac_is_valid(cell_a_class) == 0 { return (0 as i64) as *NxDyad } 106 if nx_ac_is_valid(cell_b_class) == 0 { return (0 as i64) as *NxDyad } 107 if (cell_a_in as i64) == 0 { return (0 as i64) as *NxDyad } 108 if (cell_a_out as i64) == 0 { return (0 as i64) as *NxDyad } 109 if (cell_b_in as i64) == 0 { return (0 as i64) as *NxDyad } 110 if (cell_b_out as i64) == 0 { return (0 as i64) as *NxDyad } 111 // Cross-leak refuse: A and B must not share buffers 112 if (cell_a_in as i64) == (cell_b_in as i64) { return (0 as i64) as *NxDyad } 113 if (cell_a_out as i64) == (cell_b_out as i64) { return (0 as i64) as *NxDyad } 114 if (cell_a_in as i64) == (cell_b_out as i64) { return (0 as i64) as *NxDyad } 115 if (cell_a_out as i64) == (cell_b_in as i64) { return (0 as i64) as *NxDyad } 116 let d: *NxDyad = (sys_mmap(96)) as *NxDyad 117 d.cell_a_id = cell_a_id 118 d.cell_a_class = cell_a_class 119 d.cell_a_in = cell_a_in 120 d.cell_a_in_len = cell_a_in_len 121 d.cell_a_out = cell_a_out 122 d.cell_a_out_len = cell_a_out_len 123 d.cell_b_id = cell_b_id 124 d.cell_b_class = cell_b_class 125 d.cell_b_in = cell_b_in 126 d.cell_b_in_len = cell_b_in_len 127 d.cell_b_out = cell_b_out 128 d.cell_b_out_len = cell_b_out_len 129 return d 130} 131 132// ===== nx_dyad_feed_same_input =================================== 133// 134// Copy `src[0..n]` into BOTH A's and B's input buffers. Returns 135// OK if both copies succeeded; INPUT_DIVERGED if either buffer was 136// too small (caller's allocation didn't match). 137 138func nx_dyad_feed_same_input(d: *NxDyad, src: *u8, n: nx_size) -> nx_int { 139 if d.cell_a_in_len < n { return NX_DY_ERR_INPUT_DIVERGED } 140 if d.cell_b_in_len < n { return NX_DY_ERR_INPUT_DIVERGED } 141 var i: nx_size = 0 142 while i < n { 143 d.cell_a_in[i] = src[i] 144 d.cell_b_in[i] = src[i] 145 i = i + 1 146 } 147 return NX_DY_OK 148} 149 150// ===== nx_dyad_inputs_match ======================================= 151// 152// Sanity check: both A and B did receive the SAME input bytes. 153// Returns 1 if buffers are byte-identical up to n bytes, 0 if any 154// differ. Used by observatory to assert dyad invariant pre-execute. 155 156func nx_dyad_inputs_match(d: *NxDyad, n: nx_size) -> nx_int { 157 if d.cell_a_in_len < n { return 0 } 158 if d.cell_b_in_len < n { return 0 } 159 var i: nx_size = 0 160 while i < n { 161 if d.cell_a_in[i] != d.cell_b_in[i] { return 0 } 162 i = i + 1 163 } 164 return 1 165} 166 167// ===== nx_dyad_outputs_differ ==================================== 168// 169// Predicate: did A and B produce DIFFERENT outputs from the same 170// input? Returns count of differing bytes (0 = identical outputs; 171// positive = A and B diverged). Used by observatory to score the 172// dyad's discriminative power. 173 174func nx_dyad_outputs_differ(d: *NxDyad, n: nx_size) -> nx_size { 175 var diffs: nx_size = 0 176 var i: nx_size = 0 177 while i < n { 178 if i >= d.cell_a_out_len { return diffs } 179 if i >= d.cell_b_out_len { return diffs } 180 if d.cell_a_out[i] != d.cell_b_out[i] { diffs = diffs + 1 } 181 i = i + 1 182 } 183 return diffs 184} 185 186// ===== nx_dyad_buffers_isolated =================================== 187// 188// Predicate: are all four buffer pointers structurally distinct? 189// Returns 1 if no cross-leak risk via pointer aliasing. The 190// constructor already checks this; this predicate exposes it for 191// runtime re-verification after mutation. 192 193func nx_dyad_buffers_isolated(d: *NxDyad) -> nx_int { 194 if (d.cell_a_in as i64) == (d.cell_b_in as i64) { return 0 } 195 if (d.cell_a_out as i64) == (d.cell_b_out as i64) { return 0 } 196 if (d.cell_a_in as i64) == (d.cell_b_out as i64) { return 0 } 197 if (d.cell_a_out as i64) == (d.cell_b_in as i64) { return 0 } 198 if (d.cell_a_in as i64) == (d.cell_a_out as i64) { return 0 } 199 if (d.cell_b_in as i64) == (d.cell_b_out as i64) { return 0 } 200 return 1 201}