code wiki / (root) / nx_abortive.nx

nx_abortive.nx source

↩ module page · 295 lines · 11970 B

1// nx_abortive.nx -- compromised-cell self-termination state machine 2// (Tier-1 immune). 3// 4// Biology: bacterial abortive-infection (Abi) systems are altruistic 5// suicide mechanisms. When a phage infects a bacterium that has an 6// Abi system, the cell kills itself BEFORE the phage can replicate + 7// spread to neighbors. The colony survives because the infected cell 8// took the phage down with it. In multicellular organisms, the 9// analogous mechanism is apoptosis -- programmed cell death of 10// compromised, mutated, or virally-infected cells, recycled cleanly 11// by macrophages without inflammation. 12// 13// Substrate equivalent: a cell that detects internal compromise (failed 14// self-attestation, ransomware-pattern via nx_immune, sustained PAMP 15// hits, BMS-firmware-out-of-spec, etc.) terminates itself BEFORE it 16// can spread the compromise to peers via nx_hypha EXCHANGE_*. The 17// germline data persists per soma/germline doctrine; the cell can be 18// regenerated cleanly via nx_regenerate from sovereign source. 19// 20// Per META-CARDINAL feedback-unified-immune-architecture-three-tier: 21// nx_abortive is the safe-shutdown primitive in the cell layer; nx_lysis 22// is the substrate's external selective-neutralization toolkit; nx_prune 23// is the operator-confirmed quarantine of contaminated soma. All three 24// compose; nx_abortive is the cell's own self-honest mechanism. 25// 26// State machine (sealed): 27// HEALTHY -- no compromise indicators 28// FLAGGED -- one+ indicator surfaced, awaiting corroboration 29// QUARANTINED -- cell stopped accepting new work; existing work drains 30// TERMINATING -- shutdown sequence active 31// TERMINATED -- cell stopped; germline preserved 32// 33// Transitions: 34// HEALTHY -> FLAGGED (one indicator) 35// HEALTHY -> QUARANTINED (two+ corroborated indicators) 36// FLAGGED -> QUARANTINED (corroboration) 37// FLAGGED -> HEALTHY (false positive cleared) 38// QUARANTINED -> TERMINATING (drain complete OR explicit abort) 39// TERMINATING -> TERMINATED (germline preserved + cell stopped) 40// 41// Per [[feedback-self-surfacing-intelligence-staged-autonomy]]: 42// HEALTHY -> FLAGGED is auto. Beyond FLAGGED, operator review gates 43// the next transition (unless emergency-abort triggered by nx_immune 44// confirmed-ransomware signal). 45// 46// Composes: 47// nx_chromatin -- germline data preserved through state transitions 48// nx_regenerate -- rebuild from sovereign source after TERMINATED 49// nx_immune -- emergency-abort trigger for confirmed ransomware 50// nx_evict_journal -- every state transition logged for forensics 51// 52// V1 ships the state enum + transition predicates + the cell-state 53// struct + transition function with safety gates. 54// 55// Gap list (V1 honest perf verdict): 56// - operator-review gate is a predicate not a UI hook (V2 wires 57// /audit/abortive.html review queue) 58// - emergency-abort is caller-supplied (V2 composes with nx_immune 59// ransomware-judo for automatic emergency path) 60// - drain-deadline timer is data not enforced (V2 adds wall-clock 61// timeout) 62// 63// genealogy_id: nishi_metacardinal_2026-05-19_unified_immune_architecture 64// lineage_id: substrate_abortive_v1 65// 66// nx_safety_envelope: 67// intended_use: "Cell self-termination state machine with 68// germline-preservation guarantee + operator- 69// gated transitions beyond FLAGGED" 70// sil_target: SIL3 71// evidence: [enum_sealed, transition_table_explicit, 72// operator_gate_default_conservative, 73// germline_preserved_invariant] 74// verdict: NOT_YET_EVALUATED 75 76import "nx_syscalls.nx" 77import "nx_tier.nx" 78 79// ===== Sealed enum: NxAbortiveState =============================== 80 81const NX_AB_HEALTHY: nx_int = 0 82const NX_AB_FLAGGED: nx_int = 1 83const NX_AB_QUARANTINED: nx_int = 2 84const NX_AB_TERMINATING: nx_int = 3 85const NX_AB_TERMINATED: nx_int = 4 86const NX_AB_INVALID: nx_int = 99 87const NX_AB_N_STATES: nx_int = 5 88 89// ===== Sealed enum: NxAbortiveTrigger ============================= 90// 91// What caused a state transition. Used for forensic logging. 92 93const NX_AB_TRG_NONE: nx_int = 0 94const NX_AB_TRG_PAMP_HIT: nx_int = 1 95const NX_AB_TRG_CRISPR_HIT: nx_int = 2 96const NX_AB_TRG_METHYL_FAIL: nx_int = 3 97const NX_AB_TRG_RANSOMWARE_CONFIRMED: nx_int = 4 // emergency 98const NX_AB_TRG_OPERATOR_REQUEST: nx_int = 5 99const NX_AB_TRG_BMS_OUT_OF_SPEC: nx_int = 6 100const NX_AB_TRG_FALSE_POSITIVE_CLEAR: nx_int = 7 // revert to HEALTHY 101const NX_AB_TRG_DRAIN_COMPLETE: nx_int = 8 102const NX_AB_TRG_GERMLINE_FLUSHED: nx_int = 9 103const NX_AB_TRG_N_TRIGGERS: nx_int = 10 104 105// ===== Sealed enum: NxAbortiveVerdict ============================= 106 107const NX_AB_OK: nx_int = 0 108const NX_AB_REJECTED_INVALID_TRANSITION: nx_int = 1 109const NX_AB_REJECTED_OPERATOR_REQUIRED: nx_int = 2 110const NX_AB_N_VERDICTS: nx_int = 3 111 112// ===== Struct: NxCellAbortiveState ================================ 113// 114// Per-cell state record. cell_id is the cell's stable identifier; 115// state is the current NxAbortiveState; last_trigger is what caused 116// the most recent transition; indicator_count is how many distinct 117// indicators have fired (corroboration gate threshold = 2). 118 119struct NxCellAbortiveState { 120 cell_id: nx_int, 121 state: nx_int, 122 last_trigger: nx_int, 123 indicator_count: nx_int, 124 last_transition_us: nx_size, 125 germline_preserved: nx_int, // invariant: 1 across all transitions 126} 127 128const NX_AB_CELL_BYTES: nx_int = 40 129 130// ===== nx_ab_state_is_valid ======================================= 131 132func nx_ab_state_is_valid(s: nx_int) -> nx_int { 133 if s < 0 { return 0 } 134 if s >= NX_AB_N_STATES { return 0 } 135 return 1 136} 137 138// ===== nx_ab_trigger_is_valid ===================================== 139 140func nx_ab_trigger_is_valid(t: nx_int) -> nx_int { 141 if t < 0 { return 0 } 142 if t >= NX_AB_TRG_N_TRIGGERS { return 0 } 143 return 1 144} 145 146// ===== nx_ab_state_accepts_work =================================== 147// 148// Predicate: is the cell in a state where it accepts new work? 149// Only HEALTHY does. FLAGGED is still operational but watched; 150// QUARANTINED+ refuses new work. 151 152func nx_ab_state_accepts_work(s: nx_int) -> nx_int { 153 if s == NX_AB_HEALTHY { return 1 } 154 return 0 155} 156 157// ===== nx_ab_state_is_terminal ==================================== 158// 159// Predicate: TERMINATED is the only terminal state. No transition 160// is allowed out of TERMINATED (cell must be regenerated by nx_regenerate 161// to come back to HEALTHY). 162 163func nx_ab_state_is_terminal(s: nx_int) -> nx_int { 164 if s == NX_AB_TERMINATED { return 1 } 165 return 0 166} 167 168// ===== nx_ab_cell_new ============================================= 169 170func nx_ab_cell_new(cell_id: nx_int) -> *NxCellAbortiveState { 171 let raw: *u8 = sys_mmap(NX_AB_CELL_BYTES) 172 let c: *NxCellAbortiveState = raw as *NxCellAbortiveState 173 c.cell_id = cell_id 174 c.state = NX_AB_HEALTHY 175 c.last_trigger = NX_AB_TRG_NONE 176 c.indicator_count = 0 177 c.last_transition_us = 0 178 c.germline_preserved = 1 179 return c 180} 181 182// ===== _ab_transition_allowed ===================================== 183// 184// Transition rules per state machine documented in module header. 185// Returns 1 if the from->to edge is valid; 0 otherwise. 186 187func _ab_transition_allowed(from: nx_int, to: nx_int) -> nx_int { 188 if from == NX_AB_HEALTHY { 189 if to == NX_AB_FLAGGED { return 1 } 190 if to == NX_AB_QUARANTINED { return 1 } 191 return 0 192 } 193 if from == NX_AB_FLAGGED { 194 if to == NX_AB_HEALTHY { return 1 } 195 if to == NX_AB_QUARANTINED { return 1 } 196 return 0 197 } 198 if from == NX_AB_QUARANTINED { 199 if to == NX_AB_TERMINATING { return 1 } 200 return 0 201 } 202 if from == NX_AB_TERMINATING { 203 if to == NX_AB_TERMINATED { return 1 } 204 return 0 205 } 206 // TERMINATED is terminal -- no transitions out 207 return 0 208} 209 210// ===== _ab_trigger_is_emergency =================================== 211// 212// Emergency triggers (RANSOMWARE_CONFIRMED, OPERATOR_REQUEST, 213// BMS_OUT_OF_SPEC) bypass the per-step operator-review gate. 214// Per [[feedback-self-surfacing-intelligence-staged-autonomy]]: most 215// transitions surface for operator decision, but explicit operator 216// requests AND confirmed-ransomware (already operator-acknowledged at 217// the nx_immune layer) AND safety-critical BMS conditions don't wait. 218 219func _ab_trigger_is_emergency(t: nx_int) -> nx_int { 220 if t == NX_AB_TRG_RANSOMWARE_CONFIRMED { return 1 } 221 if t == NX_AB_TRG_OPERATOR_REQUEST { return 1 } 222 if t == NX_AB_TRG_BMS_OUT_OF_SPEC { return 1 } 223 return 0 224} 225 226// ===== _ab_transition_requires_operator =========================== 227// 228// Per [[feedback-self-surfacing-intelligence-staged-autonomy]]: HEALTHY -> 229// FLAGGED is automatic. FLAGGED -> HEALTHY (false positive) is automatic. 230// All other transitions require operator review unless emergency-triggered. 231 232func _ab_transition_requires_operator(from: nx_int, 233 to: nx_int, 234 trigger: nx_int) -> nx_int { 235 if _ab_trigger_is_emergency(trigger) == 1 { return 0 } 236 if from == NX_AB_HEALTHY { 237 if to == NX_AB_FLAGGED { return 0 } // auto 238 } 239 if from == NX_AB_FLAGGED { 240 if to == NX_AB_HEALTHY { return 0 } // auto false-positive clear 241 } 242 return 1 // every other transition needs operator review 243} 244 245// ===== nx_ab_transition =========================================== 246// 247// Apply a state transition with safety gates. Returns OK on success, 248// REJECTED_INVALID_TRANSITION if the from->to edge is illegal, 249// REJECTED_OPERATOR_REQUIRED if operator gate not satisfied. 250// 251// operator_authorized: 1 if operator has explicitly approved this 252// specific transition (e.g., via /audit/abortive.html review UI). 253// 0 means substrate is asking; the gate decides. 254 255func nx_ab_transition(c: *NxCellAbortiveState, 256 to: nx_int, 257 trigger: nx_int, 258 now_us: nx_size, 259 operator_authorized: nx_int) -> nx_int { 260 if nx_ab_state_is_valid(to) == 0 { return NX_AB_REJECTED_INVALID_TRANSITION } 261 if nx_ab_trigger_is_valid(trigger) == 0 { return NX_AB_REJECTED_INVALID_TRANSITION } 262 if _ab_transition_allowed(c.state, to) == 0 { 263 return NX_AB_REJECTED_INVALID_TRANSITION 264 } 265 if _ab_transition_requires_operator(c.state, to, trigger) == 1 { 266 if operator_authorized != 1 { return NX_AB_REJECTED_OPERATOR_REQUIRED } 267 } 268 c.state = to 269 c.last_trigger = trigger 270 c.last_transition_us = now_us 271 // Indicator-count semantics: FLAGGED transitions increment; HEALTHY/clear 272 // resets; QUARANTINED+ doesn't change because we're already past the 273 // corroboration gate. 274 if to == NX_AB_FLAGGED { c.indicator_count = c.indicator_count + 1 } 275 if to == NX_AB_HEALTHY { 276 if trigger == NX_AB_TRG_FALSE_POSITIVE_CLEAR { 277 c.indicator_count = 0 278 } 279 } 280 // Invariant: germline ALWAYS preserved; this primitive cannot 281 // unset that flag. Per soma/germline doctrine. 282 if c.germline_preserved != 1 { return NX_AB_REJECTED_INVALID_TRANSITION } 283 return NX_AB_OK 284} 285 286// ===== nx_ab_germline_invariant_holds ============================= 287// 288// Predicate: returns 1 iff the cell-state has not violated the 289// germline-preservation invariant. Called by audit reports to confirm 290// no abortive transition has touched germline data. 291 292func nx_ab_germline_invariant_holds(c: *NxCellAbortiveState) -> nx_int { 293 if (c as i64) == 0 { return 0 } 294 return c.germline_preserved 295}