nx_hazard_lib.nx
buildroot/runtime/nx_hazard_lib.nx
about
nx_hazard_lib.nx -- THE WEAR-AND-TEAR CORE. Weibull survival in pure integer fixed point.
WHY THIS EXISTS (measured, not assumed, 2026-08-08):
nx_flip_score decides per component with `margin = lift - repair`. Verified over all 8 parts of
the live FOCUS13A deal: EVERY margin is exactly lift-minus-repair. The findings plane carries a
`cond` (condition 0-100) column -- and it appears in ZERO decisions. It prints a number, it reads
as evidence, and it drives nothing. There was no mileage, no age, no failure probability and no
expected cost anywhere in the engine. `nx_capsearch` over 960 registered tools returned no
survival/hazard organ. So this is net-new, and it is the half the operator named: "the fail
points and wear and tear".
THE MODEL: two-parameter Weibull, S(t) = exp(-(t/eta)^beta).
beta (SHAPE) is literally the wear regime, and that is why this model and not a flat rate:
beta < 1 infant mortality -- a DEFECT/recall class; risk FALLS with miles
beta ~ 1 memoryless random failure; miles tell you nothing
beta > 1 WEAR-OUT; risk RISES with miles <- "wear and tear", as one number
eta (SCALE) characteristic life; S(eta) = 1/e, i.e. 63.2% have failed by eta.
THE QUANTITY THAT ACTUALLY PRICES A DEAL is not P(fail ever) but the CONDITIONAL probability of
failing during the holding window, given the part already survived to today's odometer:
P(fail in (t0,t1] | survived t0) = 1 - S(t1)/S(t0) = 1 - exp( (t0/eta)^beta - (t1/eta)^beta )
Measured consequence on a real fitted curve (beta=2.5, eta=150000): the SAME part with the SAME
repair cost carries 335 bps of risk over a 12k-mile hold at 40k miles, and 1427 bps at 120k --
4.3x. An engine without this prices both at zero.
ESTIMATOR: median-rank regression (the Weibull probability plot), Benard's approximation
F_i = (i-0.3)/(n+0.4), then least squares of ln(-ln(1-F_i)) on ln(t_i). Slope IS beta.
Chosen over MLE deliberately: it is exact-arithmetic-friendly, it degrades honestly on small
samples, and it is THE reliability-engineering standard, so a third party can check our number.
ASSET-AGNOSTIC BY CONSTRUCTION -- there is no "car" in this file. `t` is any monotone usage/age
measure: miles for a car, months-in-force for a bond, cycles for a battery, days-held for a
position. Same curve, same estimator. That is what makes the omni ask reachable.
PRECISION: Q20 fixed point (HZ_FP = 1048576 = 1.0), i64 throughout. Measured against Python
ground truth: beta recovered to <1 bps, eta to <0.3%. Callers MUST treat eta as +/-1%.
license_tier: ORIGINAL No hw writes (Rule 26).
dependencies 1 imports · 3 importers
imports: nx_syscalls.nx
imported by: nx_appliedmath_gate.nxnx_flip_hazard.nxnx_flip_score.nx
structs
| none |
consts
| 40 | const HZ_FP: i64 = 1048576 // Q20: 1.0 |
| 41 | const HZ_LN2: i64 = 726817 // ln(2) * HZ_FP (exact 726817.498, python-verified) |
| 42 | const HZ_BPS: i64 = 10000 |
| 43 | const HZ_TWO: i64 = 2 |
| 44 | const HZ_LN_ODD_FIRST: i64 = 3 // atanh series divisors 3,5,7..13 |
| 45 | const HZ_LN_ODD_LAST: i64 = 13 |
| 46 | const HZ_EXP_TERMS: i64 = 9 // Taylor order for exp(r), r in [0,ln2) |
| 47 | const HZ_KCAP: i64 = 40 // |k| cap: sum(<=2*FP) << 40 stays inside i64 |
| 48 | const HZ_SAT: i64 = 4000000000000000000 |
| 49 | const HZ_I64: i64 = 8 // bytes per i64 slot |
| 115 | const HZ_MR_NUM: i64 = 3 // 0.3 * 10 |
| 116 | const HZ_MR_DEN: i64 = 4 // 0.4 * 10 |
| 117 | const HZ_TEN: i64 = 10 |
| 216 | const HZ_ERR: i64 = 0 - 1 |
functions
| 57 | func hz_ln(x_fp: i64) -> i64 |
| 79 | func hz_exp(y_fp: i64) -> i64 |
| 108 | func hz_pow(base_fp: i64, e_fp: i64) -> i64 |
| 118 | func hz_median_rank_fp(i: i64, n: i64) -> i64 |
| 134 | func hz_wb_fit(ts: *i64, n: i64, min_obs: i64, min_r2_bps: i64, out: *i64) -> i64 |
| 217 | func hz_cond_pfail_bps(t0: i64, t1: i64, beta_fp: i64, eta: i64) -> i64 |
| 233 | func hz_expected_cost(pfail_bps: i64, repair_cost: i64) -> i64 |