nx_mycorrhiza.nx source
↩ module page · 264 lines · 10793 B
1// nx_mycorrhiza.nx -- cross-substrate symbiotic resource exchange.
2//
3// Biology: mycorrhizal fungi form symbiotic networks with ~90% of land
4// plants -- fungus delivers water + minerals (esp. phosphorus) from soil,
5// plant delivers sugars from photosynthesis. Bidirectional, REGULATED,
6// and the partnership only persists when both parties net-benefit. When
7// one partner extracts without giving, the partnership is severed.
8//
9// In Nishi: bridges Nishi-native cells <-> foreign symbiotes (Steam,
10// Linux processes, etc.) for resource exchange under treaty. Composes
11// with [[nx_symbiote]] (existing foreign-process virtual cell) +
12// [[nx_treaty]] (bilateral cooperative agreement) + CONDUCTOR cardinal
13// (heterogeneous-compute orchestration) + [[feedback-reclamation-doctrine
14// -captain-moroni]] (reclaim commodity hardware unused resources).
15//
16// V1 ships exchange-class enum + flow-rate accounting + reciprocity audit.
17
18import "nx_syscalls.nx"
19import "nx_tier.nx"
20const NX_MAGIC_1024: i64 = 1024
21
22// ===== Sealed enum: NxExchangeKind ================================
23
24const NX_MY_KIND_RAM_BYTES: nx_int = 0
25const NX_MY_KIND_VRAM_BYTES: nx_int = 1
26const NX_MY_KIND_DISK_BYTES: nx_int = 2
27const NX_MY_KIND_CPU_MICROSECONDS: nx_int = 3
28const NX_MY_KIND_GPU_MICROSECONDS: nx_int = 4
29const NX_MY_KIND_NETWORK_BYTES: nx_int = 5
30const NX_MY_KIND_COMPUTED_VALUE: nx_int = 6 // domain-specific Q10 utility
31const NX_MY_KIND_N: nx_int = 7
32
33// ===== Sealed enum: NxExchangeDirection ===========================
34
35const NX_MY_DIR_NATIVE_TO_FOREIGN: nx_int = 0 // Nishi gives, foreign receives
36const NX_MY_DIR_FOREIGN_TO_NATIVE: nx_int = 1 // foreign gives, Nishi receives
37const NX_MY_DIR_N: nx_int = 2
38
39// ===== Sealed enum: NxMycorrhizaVerdict ===========================
40
41const NX_MY_V_OK_BALANCED: nx_int = 0 // reciprocity within tolerance
42const NX_MY_V_OK_NATIVE_NET_GIVER: nx_int = 1 // we give more, acceptable
43const NX_MY_V_OK_NATIVE_NET_TAKER: nx_int = 2 // we receive more, acceptable
44const NX_MY_V_EXTRACTION_BY_FOREIGN: nx_int = 3 // foreign takes >> gives
45const NX_MY_V_EXTRACTION_BY_NATIVE: nx_int = 4 // we take >> give (REFUSED)
46const NX_MY_V_SEVERED: nx_int = 5
47const NX_MY_V_INVALID: nx_int = 6
48const NX_MY_V_NULL: nx_int = 7
49const NX_MY_V_N: nx_int = 8
50
51// ===== Struct: NxExchangeFlow =====================================
52
53struct NxExchangeFlow {
54 kind: nx_int,
55 direction: nx_int,
56 units: nx_size,
57 observed_at_us: nx_size,
58 treaty_id: nx_int,
59 consent_token: nx_size,
60}
61
62const NX_MY_F_BYTES: nx_int = 40
63
64struct NxMycorrhiza {
65 partnership_id: nx_int,
66 native_cell_id: nx_int,
67 foreign_symbiote_id: nx_int,
68 flows: *u8,
69 n_flows: nx_int,
70 capacity: nx_int,
71 severed: nx_int, // 1 if partnership terminated
72 formed_at_us: nx_size,
73 tolerance_q10: nx_int, // reciprocity tolerance Q10 (NX_MAGIC_1024 = 1x)
74}
75
76const NX_MY_BYTES: nx_int = 56
77
78// ===== Validators =================================================
79
80func nx_my_kind_is_valid(k: nx_int) -> nx_int {
81 if k < 0 { return 0 }
82 if k >= NX_MY_KIND_N { return 0 }
83 return 1
84}
85
86func nx_my_dir_is_valid(d: nx_int) -> nx_int {
87 if d < 0 { return 0 }
88 if d >= NX_MY_DIR_N { return 0 }
89 return 1
90}
91
92func nx_my_v_is_valid(v: nx_int) -> nx_int {
93 if v < 0 { return 0 }
94 if v >= NX_MY_V_N { return 0 }
95 return 1
96}
97
98// ===== Constructor ================================================
99
100func nx_my_new(partnership_id: nx_int,
101 native_cell_id: nx_int,
102 foreign_symbiote_id: nx_int,
103 capacity: nx_int,
104 tolerance_q10: nx_int,
105 now_us: nx_size) -> *NxMycorrhiza {
106 if capacity <= 0 { return 0 as *NxMycorrhiza }
107 if tolerance_q10 <= 0 { return 0 as *NxMycorrhiza }
108 if native_cell_id == 0 { return 0 as *NxMycorrhiza }
109 if foreign_symbiote_id == 0 { return 0 as *NxMycorrhiza }
110 let raw: *u8 = sys_mmap(NX_MY_BYTES)
111 let m: *NxMycorrhiza = raw as *NxMycorrhiza
112 m.partnership_id = partnership_id
113 m.native_cell_id = native_cell_id
114 m.foreign_symbiote_id = foreign_symbiote_id
115 m.flows = sys_mmap(capacity * NX_MY_F_BYTES)
116 m.n_flows = 0
117 m.capacity = capacity
118 m.severed = 0
119 m.formed_at_us = now_us
120 m.tolerance_q10 = tolerance_q10
121 return m
122}
123
124func _my_flow_at(m: *NxMycorrhiza, idx: nx_int) -> *NxExchangeFlow {
125 if idx < 0 { return 0 as *NxExchangeFlow }
126 if idx >= m.n_flows { return 0 as *NxExchangeFlow }
127 let off: nx_int = idx * NX_MY_F_BYTES
128 return (m.flows + off) as *NxExchangeFlow
129}
130
131// ===== Record exchange flow =======================================
132
133func nx_my_record_flow(m: *NxMycorrhiza,
134 kind: nx_int,
135 direction: nx_int,
136 units: nx_size,
137 treaty_id: nx_int,
138 consent_token: nx_size,
139 now_us: nx_size) -> nx_int {
140 if (m as i64) == 0 { return NX_MY_V_NULL }
141 if m.severed == 1 { return NX_MY_V_SEVERED }
142 if nx_my_kind_is_valid(kind) == 0 { return NX_MY_V_INVALID }
143 if nx_my_dir_is_valid(direction) == 0 { return NX_MY_V_INVALID }
144 if m.n_flows >= m.capacity { return NX_MY_V_INVALID }
145 let off: nx_int = m.n_flows * NX_MY_F_BYTES
146 let f: *NxExchangeFlow = (m.flows + off) as *NxExchangeFlow
147 f.kind = kind
148 f.direction = direction
149 f.units = units
150 f.observed_at_us = now_us
151 f.treaty_id = treaty_id
152 f.consent_token = consent_token
153 m.n_flows = m.n_flows + 1
154 return NX_MY_V_OK_BALANCED
155}
156
157// ===== Sever partnership ==========================================
158
159func nx_my_sever(m: *NxMycorrhiza) -> nx_int {
160 if (m as i64) == 0 { return NX_MY_V_NULL }
161 m.severed = 1
162 return NX_MY_V_SEVERED
163}
164
165// ===== Aggregations ===============================================
166
167func nx_my_total_by_kind_dir(m: *NxMycorrhiza,
168 kind: nx_int,
169 direction: nx_int) -> nx_size {
170 if (m as i64) == 0 { return 0 }
171 var sum: nx_size = 0
172 var i: nx_int = 0
173 while i < m.n_flows {
174 let f: *NxExchangeFlow = _my_flow_at(m, i)
175 if f.kind == kind {
176 if f.direction == direction { sum = sum + f.units }
177 }
178 i = i + 1
179 }
180 return sum
181}
182
183// ===== Overflow-safe Q10 ratio ====================================
184//
185// DEFECT FIXED 2026-08-06 (proven by nx_commons_defect_gate, which was RED 2/5 before this and is
186// GREEN 5/5 after). The audit below used to compute (num * NX_MAGIC_1024) / den directly. That
187// product overflows i64 above ~9.0e15 units -- 9 PB of DISK_BYTES, or 285 CPU-years of
188// CPU_MICROSECONDS. On overflow it goes NEGATIVE, so every `> tolerance` test is false, both
189// net-giver/net-taker tests are false, and the function falls through to OK_BALANCED:
190//
191// IT FAILED TOWARD "NO EXTRACTION DETECTED", AND ON THE LARGEST FLOWS FIRST.
192//
193// Measured before the fix: audit(native=1e16, foreign=1) returned OK_BALANCED where the same shape
194// at 1e4 correctly returned EXTRACTION_BY_FOREIGN. Both directions were affected, so the ethical
195// refusal (EXTRACTION_BY_NATIVE) was silently disabled at scale too -- the guard against OUR OWN
196// extraction was the one that failed hardest, because we are the party most able to move volume.
197//
198// Fix: split num into quotient+remainder against den so neither term can overflow, and SATURATE
199// instead of wrapping when the ratio is genuinely astronomical. A saturated ratio is still an
200// extraction; a wrapped one is a false all-clear. REFUSE, NEVER SILENTLY SHRINK.
201const NX_MY_I64_MAX: nx_int = 9223372036854775807
202
203func _my_ratio_q10(num: nx_int, den: nx_int) -> nx_int {
204 if den <= 0 { return NX_MY_I64_MAX }
205 if num <= 0 { return 0 }
206 let q: nx_int = num / den
207 let r: nx_int = num % den
208 if q > (NX_MY_I64_MAX / NX_MAGIC_1024) { return NX_MY_I64_MAX }
209 var v: nx_int = q * NX_MAGIC_1024
210 if r > 0 {
211 if r <= (NX_MY_I64_MAX / NX_MAGIC_1024) { v = v + (r * NX_MAGIC_1024) / den }
212 }
213 return v
214}
215
216// ===== Reciprocity audit ==========================================
217//
218// Compare gives vs takes for a given exchange kind. Returns verdict
219// per the extraction-or-balance classification.
220
221func nx_my_audit_kind(m: *NxMycorrhiza, kind: nx_int) -> nx_int {
222 if (m as i64) == 0 { return NX_MY_V_NULL }
223 if nx_my_kind_is_valid(kind) == 0 { return NX_MY_V_INVALID }
224 if m.severed == 1 { return NX_MY_V_SEVERED }
225 let native_gives: nx_size = nx_my_total_by_kind_dir(m, kind, NX_MY_DIR_NATIVE_TO_FOREIGN)
226 let foreign_gives: nx_size = nx_my_total_by_kind_dir(m, kind, NX_MY_DIR_FOREIGN_TO_NATIVE)
227 if native_gives == 0 {
228 if foreign_gives == 0 { return NX_MY_V_OK_BALANCED } // no exchange yet
229 return NX_MY_V_OK_NATIVE_NET_TAKER
230 }
231 if foreign_gives == 0 { return NX_MY_V_OK_NATIVE_NET_GIVER }
232 // Ratio comparison: gives/receives in Q10 space against tolerance.
233 // tolerance_q10 = 1024 -> 1.0x perfect parity required (allow ratio in
234 // [1024/tol, tol/1024]). Higher tolerance = more slack.
235 // Compute receives/gives ratio in Q10:
236 var native_gives_q: nx_int = native_gives as nx_int
237 var foreign_gives_q: nx_int = foreign_gives as nx_int
238 if native_gives_q <= 0 { native_gives_q = 1 }
239 if foreign_gives_q <= 0 { foreign_gives_q = 1 }
240 let ratio_native_over_foreign_q10: nx_int = _my_ratio_q10(native_gives_q, foreign_gives_q)
241 // If we (native) give WAY more than receive (foreign extracts):
242 if ratio_native_over_foreign_q10 > m.tolerance_q10 {
243 // ratio > tolerance means native:foreign > tolerance/1024 -> foreign extracts
244 return NX_MY_V_EXTRACTION_BY_FOREIGN
245 }
246 let ratio_foreign_over_native_q10: nx_int = _my_ratio_q10(foreign_gives_q, native_gives_q)
247 if ratio_foreign_over_native_q10 > m.tolerance_q10 {
248 return NX_MY_V_EXTRACTION_BY_NATIVE // we take >> give = REFUSED ethical
249 }
250 // Within tolerance window
251 if ratio_native_over_foreign_q10 > NX_MAGIC_1024 { return NX_MY_V_OK_NATIVE_NET_GIVER }
252 if ratio_foreign_over_native_q10 > NX_MAGIC_1024 { return NX_MY_V_OK_NATIVE_NET_TAKER }
253 return NX_MY_V_OK_BALANCED
254}
255
256func nx_my_flow_count(m: *NxMycorrhiza) -> nx_int {
257 if (m as i64) == 0 { return 0 }
258 return m.n_flows
259}
260
261func nx_my_is_severed(m: *NxMycorrhiza) -> nx_int {
262 if (m as i64) == 0 { return 0 }
263 return m.severed
264}