code wiki / (root) / nx_stability.nx

nx_stability.nx

buildroot/runtime/nx_stability.nx

17421 B396 linesdepth 3pulls 3 transitivereach 2 importersview sourcekind library
docsdependenciesstructsconstsfunctions

about

nx_stability.nx -- ICH Q1A(R2)/Q1E STABILITY rung: the temperature physics that turns "how long is it good for" into a computed number instead of a printed guess. Serves the peptide / supplement / frozen-dessert lanes alike, because degradation kinetics does not care what the product is. ===== WHY THIS EXISTS ============================================ nx_shelf_life already models Q10 scaling, but ONLY at decade-aligned temperature steps -- and the actual regulatory question is 25 C vs 40 C, a FIFTEEN degree gap. The organ returned -1 for the one comparison the whole category rests on. This rung supplies the Arrhenius layer beneath it and the ICH machinery above it. ===== THE KEYSTONE: Ea IS RECOVERED, NOT ASSERTED ================ Every stability model needs an activation energy, and asserting one is how a plausible-looking shelf life becomes a lie. We do not assert it. ICH Q1A(R2) declares that 6 months at the accelerated condition (40 C) supports a 24-month re-test period at the long-term condition (25 C). Two conditions the regulation itself calls EQUIVALENT uniquely determine the kinetics between them: acceleration factor = 24/6 = 4 over dT = 15 C Q10 = 4^(10/15) = 2.512 (published pharma/food band: 2 - 3) Ea = R*ln(4)*T1*T2/dT = 71.6 kJ/mol (published band: 60 - 100) BOTH recovered figures land inside independently published bands that were never used as inputs. That is the liar-kill: the regulation's own arithmetic agrees with the thermal-degradation literature. This is the same discipline nx_thermal_process used to recover the pasteurisation z-value from the PMO's two equivalent schedules. ===== ⚠THE RECOVERED Ea IS LUMPED, AND SAYING SO IS THE POINT ===== ICH's two conditions are 25 C / 60% RH and 40 C / 75% RH. They differ in TEMPERATURE **AND IN HUMIDITY**. Two conditions differing in two variables cannot separate two parameters -- the system is underdetermined -- so the figure recovered above is an EFFECTIVE activation energy that carries the moisture contribution inside it, not a pure thermal Ea.

dependencies 2 imports · 2 importers

nx_syscalls.nx nx_pow10.nx nx_stability.nx nx_labsci_svc.nx nx_stability_rh.nx

imports: nx_syscalls.nxnx_pow10.nx

imported by: nx_labsci_svc.nxnx_stability_rh.nx

structs

none

consts

83const STAB_MAGIC_10000: i64 = 10000
84const STAB_MAGIC_1000000: i64 = 1000000
85const STAB_MAGIC_100000: i64 = 100000
87const STAB_INVALID: i64 = 0 - 1
90const STAB_R_MILLI: i64 = 8314
93const STAB_LN10_MILLI: i64 = 2303
95const STAB_KELVIN_OFF_CENTI: i64 = 27315
100const STAB_ICH_LONG_C: i64 = 25
101const STAB_ICH_LONG_MONTHS: i64 = 24
102const STAB_ICH_ACCEL_C: i64 = 40
103const STAB_ICH_ACCEL_MONTHS: i64 = 6
107const STAB_SIGNIFICANT_LOSS_PCT: i64 = 5
110const STAB_PUB_Q10_LO_Q3: i64 = 2000
111const STAB_PUB_Q10_HI_Q3: i64 = 3000
112const STAB_PUB_EA_LO_J: i64 = 60000
113const STAB_PUB_EA_HI_J: i64 = 100000
184const STAB_ICH_LONG_RH_PCT: i64 = 60
185const STAB_ICH_ACCEL_RH_PCT: i64 = 75

functions

118func stab_c_to_centi_kelvin(c: i64) -> i64
129func stab_q10_from_equivalence_q3(t_lo_c: i64, months_lo: i64, t_hi_c: i64, months_hi: i64) -> i64
147func stab_ea_from_equivalence(t_lo_c: i64, months_lo: i64, t_hi_c: i64, months_hi: i64) -> i64
170func stab_ich_q10_q3() -> i64
175func stab_ich_ea_j() -> i64
190func stab_ea_is_lumped_with_humidity() -> i64
called by 1: lab_stability_shelf
198func stab_conditions_needed_to_separate() -> i64
207func stab_projection_on_recovered_path(target_rh_pct: i64) -> i64
214func stab_recovered_q10_in_published_band() -> i64
calls 1: stab_ich_q10_q3
223func stab_recovered_ea_in_published_band() -> i64
calls 1: stab_ich_ea_j
236func stab_accel_factor_q3(q10_q3: i64, dt_c: i64) -> i64
249func stab_e10_milli_kelvin(ea_j: i64) -> i64
257func stab_e10_over_t_milli(e10_mk: i64, t_centi_k: i64) -> i64
267func stab_convexity_ratio_milli(ea_j: i64, t_centi_k: i64) -> i64
280func stab_mkt_centi_kelvin(temps_c: *i64, hours: *i64, n: i64, ea_j: i64) -> i64
321func stab_mean_centi_kelvin(temps_c: *i64, hours: *i64, n: i64) -> i64
346func stab_potency_retained_permil(t_months: i64, shelf_months: i64, loss_pct: i64) -> i64
367func stab_overage_permil(retained_permil: i64) -> i64
called by 1: lab_stability_shelf
374func stab_is_significant_change(retained_permil: i64) -> i64
called by 1: lab_stability_shelf
387func stab_accelerated_alone_sets_shelf_life() -> i64
called by 1: lab_stability_shelf
392func stab_max_extrapolated_months(long_term_months: i64) -> i64