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}