nx_ferment_invent.nx source
↩ module page · 72 lines · 3083 B
1// nx_ferment_invent.nx -- R5 of the FERMENTATION ladder: GENERATIVE design.
2// "Actually create new fermentations." Given a substrate (-> ferment
3// kind), an oxygen regime, a hold-temperature range, a time target, and a
4// salt level, the inventor SEARCHES the design space, PREDICTS each
5// candidate's set-time with R3 (nx_ferment_kinetics), and HARD-GATES every
6// candidate through R0 (nx_ferment_validate, the never-poison law). It
7// returns the fastest-setting candidate that is SAFE -- or none.
8//
9// The defining property: a returned recipe is SAFE BY CONSTRUCTION. No
10// cookbook does this -- it cannot generate a NOVEL process and prove it
11// won't poison anyone. An unsafe candidate (too-cold anaerobic that never
12// reaches pH 4.6 in time; an under-salted vegetable ferment) is REJECTED
13// by the same R0 gate the live process uses. Composition, not a new stack.
14//
15// genealogy_id: nishi_ferment_safety_r0 + nishi_ferment_kinetics_r3
16// + generate_and_test_synthesis
17
18import "nx_syscalls.nx"
19import "nx_ferment_safety.nx"
20import "nx_ferment_kinetics.nx"
21const K_MAGIC_999999: i64 = 999999
22
23struct NxFermentRecipe {
24 ferment_kind: i64,
25 oxygen: i64,
26 hold_temp_c: i64,
27 predicted_set_hours: i64,
28 salt_pct_milli: i64,
29 safe: i64, // 1 = R0-validated safe-by-construction
30}
31
32// Search hold temperatures in [temp_lo_c, temp_hi_c] for the fastest-
33// setting recipe that (a) sets within target_max_hours and (b) passes the
34// R0 never-poison law at the acidification window. safe = 0 if none.
35func nx_ferment_invent(env: *NxFermentSafetyEnvelope,
36 ferment_kind: i64, oxygen: i64,
37 temp_lo_c: i64, temp_hi_c: i64,
38 target_max_hours: i64, salt_pct_milli: i64) -> *NxFermentRecipe {
39 let rec: *NxFermentRecipe = (sys_mmap(48)) as *NxFermentRecipe
40 rec.ferment_kind = ferment_kind
41 rec.oxygen = oxygen
42 rec.salt_pct_milli = salt_pct_milli
43 rec.hold_temp_c = 0
44 rec.predicted_set_hours = 0 - 1
45 rec.safe = 0
46
47 let win: nx_size = env.max_hours_to_acidify
48 let nolog: *NxFermentReadingLog = (0) as *NxFermentReadingLog
49 var best_set: i64 = K_MAGIC_999999
50 var t: i64 = temp_lo_c
51 while t <= temp_hi_c {
52 let set_h: i64 = nx_ferment_kinetics_set_time(t)
53 if set_h > 0 {
54 if set_h <= target_max_hours {
55 let ph_at_win: i64 = nx_ferment_kinetics_ph_at(t, win as i64)
56 let verdict: nx_int = nx_ferment_validate(env, ferment_kind, oxygen,
57 (t * 1000) as nx_size, ph_at_win as nx_size, salt_pct_milli as nx_size,
58 win, 0, nolog, win)
59 if verdict == NX_FS_OK {
60 if set_h < best_set {
61 best_set = set_h
62 rec.hold_temp_c = t
63 rec.predicted_set_hours = set_h
64 rec.safe = 1
65 }
66 }
67 }
68 }
69 t = t + 1
70 }
71 return rec
72}