code wiki / (root) / nx_disturbance.nx

nx_disturbance.nx source

↩ module page · 264 lines · 10866 B

1// nx_disturbance.nx -- constructive disturbance regime per Regenerative- 2// Stewardship Doctrine. 3// 4// Per META-CARDINAL feedback-regenerative-stewardship-doctrine-captain-moroni: 5// most ecosystems Earth produces REQUIRE disturbance to renew -- 6// prairies need fire every 2-5 years; oak savannas every 1-3 years; 7// longleaf pine ground fire every 1-3 years; salt marshes need tidal 8// scouring; Pacific NW old-growth shaped by windfall + Indigenous 9// burning + salmon-marine-nitrogen pulses. Substrate REFUSES both 10// extraction-as-disturbance (clear-cut, drain, monocrop) AND 11// preservation-as-freeze (no-fire, no-grazing, no-coppice). 12// 13// V1 ships sealed enum of disturbance types + per-ecosystem regime 14// frequency + Indigenous-consultation-required predicate. Operator 15// uses to plan stewardship actions; substrate informs, never executes 16// disturbance. 17// 18// Composes: 19// nx_niche -- ecosystem niche gates which regimes apply 20// nx_covenant -- Indigenous fire-stewardship + ancestral-land FPIC 21// nx_phenology -- disturbance timing aligned with seasonal cycle 22// nx_pollinator -- some disturbance regimes preserve pollinator habitat 23// 24// Gap list (V1 honest perf verdict): 25// - safety + regulatory constraints (urban/wildland-interface fire 26// risk, permits) are operator + jurisdiction-supplied; V2 composes 27// with nx_jurisdiction_egress + permitting layer 28// - Indigenous TEK integration requires partnership; V1 flags the 29// requirement, V2 (gated on nx_covenant maturity) handles workflow 30// - regime-frequency targets are research-derived; per-site 31// calibration is multi-year fieldwork 32// 33// genealogy_id: nishi_metacardinal_2026-05-19_regenerative_stewardship 34// lineage_id: substrate_disturbance_v1 35// 36// nx_safety_envelope: 37// intended_use: "Constructive-disturbance regime classification 38// + frequency-per-ecosystem + Indigenous- 39// consultation-required predicate; refuses both 40// extraction and preservation framings" 41// sil_target: SIL2 42// evidence: [enum_sealed, refuses_extraction_AND_preservation, 43// Indigenous_consultation_flagged] 44// verdict: NOT_YET_EVALUATED 45 46import "nx_syscalls.nx" 47import "nx_tier.nx" 48 49// ===== Sealed enum: NxDisturbanceType ============================= 50// 51// Constructive disturbance regimes used in restoration / stewardship. 52// V1 covers fire / flood / herbivory / coppicing. V2 extends with 53// region-specific (e.g., Aboriginal fire-stick mosaic) which require 54// FPIC + community partnership. 55 56const NX_DI_FIRE_PRESCRIBED: nx_int = 0 // controlled burn 57const NX_DI_FIRE_INDIGENOUS: nx_int = 1 // TEK-managed fire (FPIC required) 58const NX_DI_FLOOD_PULSE: nx_int = 2 // managed flood release 59const NX_DI_HERBIVORY_ROTATIONAL: nx_int = 3 // Allan Savory-class grazing 60const NX_DI_COPPICE: nx_int = 4 // cut-to-stump then regrow 61const NX_DI_POLLARD: nx_int = 5 // cut top + branches above browse line 62const NX_DI_WINDFALL_NATURAL: nx_int = 6 // accept storm-disturbance 63const NX_DI_SELECTIVE_HARVEST: nx_int = 7 // single-tree selection 64const NX_DI_BEAVER_REINTRO: nx_int = 8 // beaver-driven hydrology 65const NX_DI_NONE_FROZEN: nx_int = 9 // explicit no-disturbance (rare; refused as default) 66const NX_DI_N_TYPES: nx_int = 10 67 68// ===== Sealed enum: NxEcosystemType =============================== 69 70const NX_ECO_TALLGRASS_PRAIRIE: nx_int = 0 71const NX_ECO_OAK_SAVANNA: nx_int = 1 72const NX_ECO_LONGLEAF_PINE: nx_int = 2 73const NX_ECO_PACIFIC_NW_OLDGROWTH: nx_int = 3 74const NX_ECO_SALT_MARSH: nx_int = 4 75const NX_ECO_RIPARIAN_BOTTOMLAND: nx_int = 5 76const NX_ECO_MIXED_HARDWOOD: nx_int = 6 77const NX_ECO_CONIFER_BOREAL: nx_int = 7 78const NX_ECO_DESERT_ARID: nx_int = 8 79const NX_ECO_ABORIGINAL_AUSTRALIAN: nx_int = 9 80const NX_ECO_N_TYPES: nx_int = 10 81 82// ===== Sealed enum: NxDisturbanceVerdict ========================== 83 84const NX_DI_V_REGIME_OK: nx_int = 0 85const NX_DI_V_REQUIRES_FPIC: nx_int = 1 // Indigenous consultation 86const NX_DI_V_REQUIRES_PERMIT: nx_int = 2 // legal/regulatory 87const NX_DI_V_REFUSED_FROZEN: nx_int = 3 // preservation-as-freeze refused 88const NX_DI_V_REFUSED_EXTRACTION: nx_int = 4 // extraction disguised as disturbance 89const NX_DI_V_INCOMPATIBLE: nx_int = 5 // disturbance not appropriate for ecosystem 90const NX_DI_V_INVALID: nx_int = 99 91const NX_DI_V_N_VERDICTS: nx_int = 6 92 93// ===== nx_di_type_is_valid ======================================== 94 95func nx_di_type_is_valid(t: nx_int) -> nx_int { 96 if t < 0 { return 0 } 97 if t >= NX_DI_N_TYPES { return 0 } 98 return 1 99} 100 101// ===== nx_eco_type_is_valid ======================================= 102 103func nx_eco_type_is_valid(e: nx_int) -> nx_int { 104 if e < 0 { return 0 } 105 if e >= NX_ECO_N_TYPES { return 0 } 106 return 1 107} 108 109// ===== nx_di_v_is_valid =========================================== 110 111func nx_di_v_is_valid(v: nx_int) -> nx_int { 112 if v < 0 { return 0 } 113 if v >= NX_DI_V_N_VERDICTS { return 0 } 114 return 1 115} 116 117// ===== nx_di_requires_fpic ======================================== 118// 119// Predicate: returns 1 if this disturbance type requires Indigenous 120// Free Prior and Informed Consent before substrate proceeds. 121 122func nx_di_requires_fpic(t: nx_int) -> nx_int { 123 if t == NX_DI_FIRE_INDIGENOUS { return 1 } 124 return 0 125} 126 127// ===== nx_di_requires_permit ====================================== 128// 129// Predicate: returns 1 if this disturbance type typically requires 130// legal/regulatory permit (substrate flags; operator + counsel 131// handle actual permit acquisition). 132 133func nx_di_requires_permit(t: nx_int) -> nx_int { 134 if t == NX_DI_FIRE_PRESCRIBED { return 1 } 135 if t == NX_DI_FIRE_INDIGENOUS { return 1 } 136 if t == NX_DI_FLOOD_PULSE { return 1 } 137 if t == NX_DI_BEAVER_REINTRO { return 1 } 138 if t == NX_DI_SELECTIVE_HARVEST { return 1 } 139 return 0 140} 141 142// ===== nx_di_is_extraction_class ================================== 143// 144// Predicate: returns 1 if this is extraction-disguised-as-disturbance 145// (substrate refuses). V1: NONE_FROZEN is the inverse-refusal; we 146// don't yet enumerate extraction-class disturbances explicitly 147// because they aren't on the legitimate-disturbance enum. V2 may 148// add explicit extraction-class refusal markers. 149 150func nx_di_is_extraction_class(t: nx_int) -> nx_int { 151 return 0 152} 153 154// ===== nx_di_ecosystem_regime_frequency_years ===================== 155// 156// Per-ecosystem expected disturbance-frequency target (years). 157// Research-derived; substrate documents the threshold, doesn't 158// claim universal correctness. 159// 160// 0 = invalid pairing; ecosystem doesn't depend on this disturbance. 161 162func nx_di_ecosystem_regime_frequency_years(eco: nx_int, dis: nx_int) -> nx_int { 163 if nx_eco_type_is_valid(eco) == 0 { return 0 } 164 if nx_di_type_is_valid(dis) == 0 { return 0 } 165 166 // TALLGRASS_PRAIRIE: fire every 2-5 years (use midpoint 3) 167 if eco == NX_ECO_TALLGRASS_PRAIRIE { 168 if dis == NX_DI_FIRE_PRESCRIBED { return 3 } 169 if dis == NX_DI_FIRE_INDIGENOUS { return 3 } 170 if dis == NX_DI_HERBIVORY_ROTATIONAL { return 1 } 171 return 0 172 } 173 // OAK_SAVANNA: fire every 1-3 years (midpoint 2) 174 if eco == NX_ECO_OAK_SAVANNA { 175 if dis == NX_DI_FIRE_PRESCRIBED { return 2 } 176 if dis == NX_DI_FIRE_INDIGENOUS { return 2 } 177 return 0 178 } 179 // LONGLEAF_PINE: ground fire 1-3 years (midpoint 2) 180 if eco == NX_ECO_LONGLEAF_PINE { 181 if dis == NX_DI_FIRE_PRESCRIBED { return 2 } 182 return 0 183 } 184 // PACIFIC_NW_OLDGROWTH: mixed-severity 100-300 years (midpoint 200) 185 if eco == NX_ECO_PACIFIC_NW_OLDGROWTH { 186 if dis == NX_DI_WINDFALL_NATURAL { return 50 } 187 if dis == NX_DI_FIRE_INDIGENOUS { return 30 } 188 if dis == NX_DI_BEAVER_REINTRO { return 100 } 189 return 0 190 } 191 // SALT_MARSH: tidal scouring; not in our type set 192 if eco == NX_ECO_SALT_MARSH { 193 if dis == NX_DI_FLOOD_PULSE { return 1 } 194 return 0 195 } 196 // RIPARIAN_BOTTOMLAND: flood pulse 197 if eco == NX_ECO_RIPARIAN_BOTTOMLAND { 198 if dis == NX_DI_FLOOD_PULSE { return 5 } 199 if dis == NX_DI_BEAVER_REINTRO { return 25 } 200 return 0 201 } 202 // MIXED_HARDWOOD: selective harvest + coppice 203 if eco == NX_ECO_MIXED_HARDWOOD { 204 if dis == NX_DI_SELECTIVE_HARVEST { return 15 } 205 if dis == NX_DI_COPPICE { return 7 } 206 if dis == NX_DI_POLLARD { return 10 } 207 return 0 208 } 209 // CONIFER_BOREAL: stand-replacing fire 100-300 years 210 if eco == NX_ECO_CONIFER_BOREAL { 211 if dis == NX_DI_FIRE_PRESCRIBED { return 150 } 212 if dis == NX_DI_WINDFALL_NATURAL { return 100 } 213 return 0 214 } 215 // DESERT_ARID: minimal natural disturbance; herbivory rotational 216 if eco == NX_ECO_DESERT_ARID { 217 if dis == NX_DI_HERBIVORY_ROTATIONAL { return 2 } 218 return 0 219 } 220 // ABORIGINAL_AUSTRALIAN: fire-stick mosaic 1-5 years (midpoint 3) 221 if eco == NX_ECO_ABORIGINAL_AUSTRALIAN { 222 if dis == NX_DI_FIRE_INDIGENOUS { return 3 } 223 return 0 224 } 225 return 0 226} 227 228// ===== nx_di_classify_proposal ==================================== 229// 230// Given an operator-proposed (ecosystem, disturbance_type), emit 231// verdict accounting for FPIC + permit requirements + compatibility 232// + the no-disturbance refusal. 233 234func nx_di_classify_proposal(eco: nx_int, dis: nx_int) -> nx_int { 235 if nx_eco_type_is_valid(eco) == 0 { return NX_DI_V_INVALID } 236 if nx_di_type_is_valid(dis) == 0 { return NX_DI_V_INVALID } 237 238 // Refuse explicit "no disturbance" default (preservation-as-freeze pole) 239 if dis == NX_DI_NONE_FROZEN { return NX_DI_V_REFUSED_FROZEN } 240 241 // Extraction-class refusal 242 if nx_di_is_extraction_class(dis) == 1 { return NX_DI_V_REFUSED_EXTRACTION } 243 244 // Compatibility check FIRST: if the ecosystem doesn't depend on this 245 // disturbance, there's no need to ask about permits/FPIC. 246 let freq: nx_int = nx_di_ecosystem_regime_frequency_years(eco, dis) 247 if freq == 0 { return NX_DI_V_INCOMPATIBLE } 248 249 // FPIC priority -- highest gate of remaining 250 if nx_di_requires_fpic(dis) == 1 { return NX_DI_V_REQUIRES_FPIC } 251 252 // Permit priority -- next gate 253 if nx_di_requires_permit(dis) == 1 { return NX_DI_V_REQUIRES_PERMIT } 254 255 return NX_DI_V_REGIME_OK 256} 257 258// ===== nx_di_v_is_concerning ====================================== 259 260func nx_di_v_is_concerning(v: nx_int) -> nx_int { 261 if v == NX_DI_V_REGIME_OK { return 0 } 262 if nx_di_v_is_valid(v) == 0 { return 0 } 263 return 1 264}