nx_ferment_safety.nx
buildroot/runtime/nx_ferment_safety.nx
about
nx_ferment_safety.nx -- NEVER-POISON substrate (Global Rule 26 recast).
Global Rule 26 ("Never Brick The Electronics") for fermentation:
a fermentation capability may NEVER recommend or execute a process
that risks producing unsafe food. No botulism, no time-temperature
pathogen abuse, no under-salted anaerobic vegetable ferment, no
raw-milk cheese under the legal aging floor. STRUCTURAL refusal --
not a policy, not a warning string -- mirrored exactly on the proven
nx_battery_safety architecture (envelope + sealed verdicts +
validate predicate + abuse-PATTERN detector).
The never-poison law (no higher rung may bypass this layer):
- botulism_ph_milli: an anaerobic low-acid food MUST reach
pH <= 4.6 (FDA 21 CFR 114 acidified-foods
boundary -- C. botulinum cannot grow below
pH 4.6). Past its acidification window and
still above 4.6 (or pH unknown) = REFUSE.
- danger zone 4..60 C: USDA-FSIS "danger zone" (40-140 F).
- min_salt_pct_milli: >= 2.0% w/w selects Lactobacillus over
pathogens in vegetable ferments (NCHFP).
- min_raw_milk_age_days: raw-milk cheese aged >= 60 days (FDA).
- culture_kill_temp: above this the culture dies -> no
acidification -> the food never becomes
safe. REFUSE.
The STALLED-FERMENT detector is the never-poison analog of
nx_battery_safety's thermal-runaway detector. A warm ferment is
NORMAL early on (danger-zone temp + still-high pH while the culture
sours it). It is ABUSE only when pH FAILS TO DECLINE across the
window -- stuck high = trending septic, not souring. This is proven
MECHANICALLY by the gate (the stall must fire; a souring batch must
NOT be refused) -- never asserted as a promise (Rule 26 discipline).
genealogy_id: fda_21cfr114_acidified_ph4.6
+ usda_fsis_danger_zone_40_140F
+ fda_raw_milk_cheese_60day_aging
+ nchfp_vegetable_ferment_2pct_salt
+ nishi_battery_safety_envelope_architecture_2026
NOTE: the public-health constants below are NAMED + CITED (Rule 11,
dependencies 1 imports · 18 importers
diagram shows first 10 each side; +0 more imports, +8 more importers in the complete lists below.
imports: nx_syscalls.nx
imported by: nx_ferment_invent.nxnx_ferment_invent_test.nxnx_ferment_kinetics_test.nxnx_ferment_process.nxnx_ferment_process_test.nxnx_ferment_recipes.nxnx_ferment_recipes_test.nxnx_ferment_safety_test.nxnx_ferment_thermal.nxnx_ferment_thermal_test.nxnx_vessel_design.nxnx_vessel_design_test.nxnx_vessel_faults.nxnx_vessel_faults_test.nxnx_vessel_geometry_test.nxnx_vessel_io_test.nxnx_vessel_twin.nxnx_vessel_twin_test.nx
structs
| 89 | struct NxFermentSafetyEnvelope |
| 108 | struct NxFermentReading |
| 116 | struct NxFermentReadingLog |
consts
| 50 | const NX_FK_VEG_ANAEROBIC: nx_int = 0 // kraut, kimchi, brined pickles |
| 51 | const NX_FK_DAIRY_CULTURED: nx_int = 1 // yogurt, kefir, buttermilk |
| 52 | const NX_FK_CHEESE_RAWMILK: nx_int = 2 // raw-milk cheese (60-day rule) |
| 53 | const NX_FK_CHEESE_PASTEUR: nx_int = 3 // pasteurized-milk cheese |
| 54 | const NX_FK_MOLD_RIPENED: nx_int = 4 // tempeh, koji, blue (intended mold) |
| 55 | const NX_FK_ALCOHOL_ACID: nx_int = 5 // kombucha, vinegar, wine |
| 56 | const NX_FK_N_KINDS: nx_int = 6 |
| 60 | const NX_OX_ANAEROBIC: nx_int = 0 |
| 61 | const NX_OX_AEROBIC: nx_int = 1 |
| 65 | const NX_FS_OK: nx_int = 0 |
| 66 | const NX_FS_REFUSED_BOTULISM_PH: nx_int = 1 |
| 67 | const NX_FS_REFUSED_TIME_TEMP_ABUSE: nx_int = 2 |
| 68 | const NX_FS_REFUSED_INSUFFICIENT_SALT: nx_int = 3 |
| 69 | const NX_FS_REFUSED_CULTURE_KILLED: nx_int = 4 |
| 70 | const NX_FS_REFUSED_RAW_MILK_AGE: nx_int = 5 |
| 71 | const NX_FS_REFUSED_PATHOGEN_PATTERN: nx_int = 6 |
| 72 | const NX_FS_REFUSED_BAD_KIND: nx_int = 7 |
| 76 | const NX_FS_BOTULISM_PH_MILLI: nx_size = 4600 // pH 4.600 x1000 |
| 77 | const NX_FS_DZ_LO_MILLI_C: nx_size = 4000 // 4.0 C (40 F) |
| 78 | const NX_FS_DZ_HI_MILLI_C: nx_size = 60000 // 60.0 C (140 F) |
| 79 | const NX_FS_CULTURE_KILL_MILLI_C: nx_size = 55000 // 55 C thermophile death |
| 80 | const NX_FS_MIN_SALT_PCT_MILLI: nx_size = 2000 // 2.000% w/w |
| 81 | const NX_FS_RAW_MILK_AGE_DAYS: nx_size = 60 // FDA |
| 82 | const NX_FS_ABUSE_WINDOW_HOURS: nx_size = 48 |
| 83 | const NX_FS_ABUSE_THRESHOLD: nx_int = 3 |
| 84 | const NX_FS_DEFAULT_ACID_HOURS: nx_size = 48 // must cross pH 4.6 within 48 h |
| 85 | const NX_FS_STALL_MIN_PROGRESS_MILLI: nx_size = 200 // pH must drop >= 0.2 / window or stalled |
| 114 | const NX_FS_READING_BYTES: nx_size = 24 |
functions
| 123 | func nx_fk_is_valid(k: nx_int) -> nx_int |
| 129 | func nx_ferment_safety_envelope_new(ferment_id: nx_int, |
| 156 | func nx_ferment_safety_envelope_default(ferment_id: nx_int) -> *NxFermentSafetyEnvelope |
| 165 | func nx_ferment_reading_log_new(capacity: nx_size) -> *NxFermentReadingLog |
| 175 | func _fs_reading_at(l: *NxFermentReadingLog, idx: nx_size) -> *NxFermentReading called by 1: nx_ferment_validate |
| 185 | func nx_ferment_validate(env: *NxFermentSafetyEnvelope, |
| 294 | func nx_ferment_envelope_ph_ceiling(env: *NxFermentSafetyEnvelope) -> nx_size |