code wiki / (root) / nx_immune.nx

nx_immune.nx source

↩ module page · 288 lines · 10944 B

1// nx_immune.nx -- Tier-2 colony-level adaptive immune coordinator. 2// 3// Per [[feedback-unified-immune-architecture-three-tier]] Tier 2: 4// "ADAPTIVE / MULTICELLULAR -- specialized cells + learning + memory; 5// existing nx_thymus (substrate audit) + nx_immune (runtime defense)." 6// nx_antibody is the per-cell defense-generation primitive (Tier 1+); 7// nx_immune is the COLONY-LEVEL orchestrator that: 8// 9// 1. Tracks which cells in the host are currently HEALTHY/ALERTED/ 10// RESPONDING/COMPROMISED 11// 2. Propagates antibody discoveries (clonal-expansion analog): 12// when one cell's antibody matures to MEMORY state, immune 13// distributes a copy to every other cell so the same threat 14// is detected colony-wide on first encounter 15// 3. Coordinates lysis-response: when any cell calls for lysis on 16// a foreign entity touching multiple cells, immune issues a 17// colony-wide enforcement (vs each cell deciding alone) 18// 4. Surfaces a COLONY STATUS to the operator (HEALTHY when all 19// cells healthy; ALERTED when any cell sees a hit; RESPONDING 20// when active lysis ongoing; COMPROMISED when any cell entered 21// the abortive-terminal state) 22// 23// Per [[feedback-captain-moroni-doctrine]]: defensive-only. Colony 24// response is to PROTECT remaining cells, never to attack. 25// 26// Composes: 27// nx_antibody -- per-cell antibodies clone-expand via immune 28// nx_lysis -- colony-wide enforcement decision 29// nx_xenocell -- intrusions observed across cells aggregate here 30// nx_abortive -- cell-state-machine; immune watches transitions 31// nx_evict_journal -- colony events logged 32// nx_pollinate (queued) -- cross-host community distribution 33// 34// V1 ships: 35// - struct NxImmune holding cell registry + antibody clone-store 36// - cell-state tracking 37// - antibody clonal-expansion broadcast 38// - colony status aggregation 39// 40// Gap list (V1 honest perf verdict): 41// - per-cell antibody arrays are caller-allocated; immune holds 42// pointers, doesn't deep-clone (V2 deep-clones when crossing 43// cell isolation boundary) 44// - no automatic alert-decay (caller drives status refresh) 45// - no clonal-suppression of false positives (V2 demotes antibodies 46// that fire on legitimate traffic frequently) 47// - federation across hosts is nx_pollinate's job, not immune 48// 49// genealogy_id: cardinal_2026-05-19_unified_immune_architecture_tier_2 + 50// biology_multicellular_adaptive_immunity 51// lineage_id: substrate_immune_v1 52// 53// nx_safety_envelope: 54// intended_use: "Colony-level coordination of per-cell adaptive 55// immune primitives; defensive only" 56// sil_target: SIL3 57// evidence: [defensive_only, observation_not_retaliation, 58// captain_moroni_aligned] 59// verdict: NOT_YET_EVALUATED 60 61import "nx_syscalls.nx" 62import "nx_tier.nx" 63import "nx_evict_journal.nx" 64import "nx_antibody.nx" 65import "nx_lysis.nx" 66 67// ===== Sealed enum: NxColonyStatus ================================ 68 69const NX_COL_HEALTHY: nx_int = 0 70const NX_COL_ALERTED: nx_int = 1 // at least one cell saw a hit 71const NX_COL_RESPONDING: nx_int = 2 // active lysis ongoing 72const NX_COL_COMPROMISED: nx_int = 3 // at least one cell terminal 73const NX_COL_N_STATUSES: nx_int = 4 74 75// ===== Sealed enum: NxImmuneVerdict =============================== 76 77const NX_IM_OK: nx_int = 0 78const NX_IM_ERR_FULL: nx_int = 1 79const NX_IM_ERR_BAD_CELL: nx_int = 2 80const NX_IM_ERR_BAD_STATUS: nx_int = 3 81 82// ===== Struct: NxImmuneCellRow ==================================== 83// 84// One row per cell registered with the immune system. cell_id is 85// stable. status is the cell's current health classification. 86// antibody_arr is a pointer to the cell's own nx_antibody_array 87// (immune doesn't own them; cells do). 88 89struct NxImmuneCellRow { 90 cell_id: nx_int, 91 status: nx_int, 92 antibody_arr: *NxAntibodyArray, 93 last_alert_us: nx_size, 94 alert_count: nx_int, 95} 96 97// ===== Struct: NxImmune =========================================== 98// 99// The colony coordinator. cells is an array of cell rows; capacity 100// fixed at construction. global_status is the aggregate status the 101// operator sees. journal is the host-level eviction/forensic log. 102 103struct NxImmune { 104 cells: *NxImmuneCellRow, 105 cell_capacity: nx_size, 106 n_cells: nx_size, 107 global_status: nx_int, 108 journal: *NxEvictJournal, 109} 110 111const NX_IM_CELL_BYTES: nx_size = 40 112 113// ===== Validators ================================================ 114 115func nx_col_status_is_valid(s: nx_int) -> nx_int { 116 if s < 0 { return 0 } 117 if s >= NX_COL_N_STATUSES { return 0 } 118 return 1 119} 120 121// ===== nx_immune_new ============================================= 122 123func nx_immune_new(cell_capacity: nx_size, journal: *NxEvictJournal) -> *NxImmune { 124 let i: *NxImmune = (sys_mmap(40)) as *NxImmune 125 let bytes: nx_size = cell_capacity * NX_IM_CELL_BYTES 126 i.cells = (sys_mmap(bytes)) as *NxImmuneCellRow 127 i.cell_capacity = cell_capacity 128 i.n_cells = 0 129 i.global_status = NX_COL_HEALTHY 130 i.journal = journal 131 return i 132} 133 134// ===== _immune_at ================================================ 135 136func _immune_at(i: *NxImmune, idx: nx_size) -> *NxImmuneCellRow { 137 return (i.cells as i64 + (idx as i64) * NX_IM_CELL_BYTES) as *NxImmuneCellRow 138} 139 140// ===== _immune_find_cell ========================================= 141 142func _immune_find_cell(i: *NxImmune, cell_id: nx_int) -> nx_int { 143 var k: nx_size = 0 144 while k < i.n_cells { 145 let r: *NxImmuneCellRow = _immune_at(i, k) 146 if r.cell_id == cell_id { return k as i64 } 147 k = k + 1 148 } 149 return -1 150} 151 152// ===== nx_immune_register_cell =================================== 153// 154// Register a cell + its antibody array with the immune system. The 155// cell starts HEALTHY. Returns the registration index, or -1 if 156// full / duplicate. 157 158func nx_immune_register_cell(i: *NxImmune, 159 cell_id: nx_int, 160 antibody_arr: *NxAntibodyArray) -> nx_int { 161 if i.n_cells >= i.cell_capacity { return -1 } 162 if _immune_find_cell(i, cell_id) >= 0 { return -1 } 163 let r: *NxImmuneCellRow = _immune_at(i, i.n_cells) 164 r.cell_id = cell_id 165 r.status = NX_COL_HEALTHY 166 r.antibody_arr = antibody_arr 167 r.last_alert_us = 0 168 r.alert_count = 0 169 i.n_cells = i.n_cells + 1 170 return (i.n_cells - 1) as i64 171} 172 173// ===== nx_immune_set_cell_status ================================= 174 175func nx_immune_set_cell_status(i: *NxImmune, 176 cell_id: nx_int, 177 status: nx_int, 178 now_us: nx_size) -> nx_int { 179 if nx_col_status_is_valid(status) == 0 { return NX_IM_ERR_BAD_STATUS } 180 let idx: nx_int = _immune_find_cell(i, cell_id) 181 if idx < 0 { return NX_IM_ERR_BAD_CELL } 182 let r: *NxImmuneCellRow = _immune_at(i, idx as nx_size) 183 r.status = status 184 if status > NX_COL_HEALTHY { 185 r.last_alert_us = now_us 186 r.alert_count = r.alert_count + 1 187 } 188 return NX_IM_OK 189} 190 191// ===== nx_immune_global_status =================================== 192// 193// Recompute global status as max(per-cell statuses). Caller invokes 194// after any cell-status change; returns the new global status. 195 196func nx_immune_global_status(i: *NxImmune) -> nx_int { 197 var worst: nx_int = NX_COL_HEALTHY 198 var k: nx_size = 0 199 while k < i.n_cells { 200 let r: *NxImmuneCellRow = _immune_at(i, k) 201 if r.status > worst { worst = r.status } 202 k = k + 1 203 } 204 i.global_status = worst 205 return worst 206} 207 208// ===== nx_immune_clonal_expand =================================== 209// 210// THE clonal-expansion operation. When one cell's antibody matures 211// to MEMORY state, broadcast the signature to all OTHER cells' 212// antibody arrays so they catch the same threat on first encounter. 213// Returns the number of cells that received the clone. 214// 215// Source cell is identified by cell_id; antibody is identified by 216// its array index. Caller has the matured antibody in source's 217// array; immune walks every other cell and calls nx_antibody_generate 218// on each with the same (kind, signature_hash, affinity) parameters. 219 220func nx_immune_clonal_expand(i: *NxImmune, 221 source_cell_id: nx_int, 222 kind: nx_int, 223 signature_hash: nx_size, 224 initial_affinity_q10: nx_int, 225 now_us: nx_size) -> nx_int { 226 let src_idx: nx_int = _immune_find_cell(i, source_cell_id) 227 if src_idx < 0 { return 0 } 228 var distributed: nx_int = 0 229 var k: nx_size = 0 230 while k < i.n_cells { 231 if (k as i64) != src_idx { 232 let r: *NxImmuneCellRow = _immune_at(i, k) 233 if (r.antibody_arr as i64) != 0 { 234 // Skip if recipient already has this signature 235 let existing: nx_int = nx_antibody_match(r.antibody_arr, 236 kind, signature_hash) 237 if existing < 0 { 238 let new_idx: nx_int = nx_antibody_generate(r.antibody_arr, 239 kind, signature_hash, initial_affinity_q10, now_us) 240 if new_idx >= 0 { distributed = distributed + 1 } 241 } 242 } 243 } 244 k = k + 1 245 } 246 return distributed 247} 248 249// ===== nx_immune_alert_count ===================================== 250 251func nx_immune_alert_count(i: *NxImmune, cell_id: nx_int) -> nx_int { 252 let idx: nx_int = _immune_find_cell(i, cell_id) 253 if idx < 0 { return 0 } 254 let r: *NxImmuneCellRow = _immune_at(i, idx as nx_size) 255 return r.alert_count 256} 257 258// ===== nx_immune_count_cells_in_status ============================ 259 260func nx_immune_count_cells_in_status(i: *NxImmune, status: nx_int) -> nx_size { 261 var hits: nx_size = 0 262 var k: nx_size = 0 263 while k < i.n_cells { 264 let r: *NxImmuneCellRow = _immune_at(i, k) 265 if r.status == status { hits = hits + 1 } 266 k = k + 1 267 } 268 return hits 269} 270 271// ===== nx_immune_should_quarantine_host ========================== 272// 273// Coarse colony-level decision: if >=50% of cells are at ALERTED or 274// higher, recommend host-level quarantine (operator should pause new 275// cell instantiation until the threat is understood). Returns 1 if 276// quarantine is recommended. 277 278func nx_immune_should_quarantine_host(i: *NxImmune) -> nx_int { 279 if i.n_cells == 0 { return 0 } 280 let alerted: nx_size = nx_immune_count_cells_in_status(i, NX_COL_ALERTED) + 281 nx_immune_count_cells_in_status(i, NX_COL_RESPONDING) + 282 nx_immune_count_cells_in_status(i, NX_COL_COMPROMISED) 283 let half: nx_size = i.n_cells / 2 284 if alerted >= half { 285 if alerted > 0 { return 1 } 286 } 287 return 0 288}