nx_maint_ledger_test.nx source
↩ module page · 71 lines · 3793 B
1// nx_maint_ledger_test.nx -- gate for R4 (the additive maintenance ledger).
2//
3// Proves: append-only history with per-asset isolation; HISTORY SACRED (#13)
4// -- a past SAFETY/DEGRADED is never forgotten after the asset recovers to OK;
5// predictive WORSENING / IMPROVING trend; full ledger never overwrites.
6//
7// expect_exit: 0
8//
9// license_tier: ORIGINAL
10
11import "nx_syscalls_x86_64.nx"
12import "nx_maint_ledger.nx"
13
14func main() -> i64 {
15 if nx_trend_is_valid(NX_TREND_WORSENING) != 1 { return 1 }
16 if nx_trend_is_valid(NX_TREND_N) != 0 { return 2 }
17
18 let entries: *LedgerEntry = sys_mmap(1024) as *LedgerEntry
19 let led: *Ledger = sys_mmap(64) as *Ledger
20 let out: *LedgerEntry = sys_mmap(64) as *LedgerEntry
21 nx_ledger_init(led, 16)
22
23 // ---- append: 3 assets, interleaved over time ----
24 if nx_ledger_append(led, entries, 10, 100, NX_HEALTH_OK, NX_MK_THERMAL, NX_HVAC_EFFICIENT, 350) != 0 { return 10 }
25 nx_ledger_append(led, entries, 20, 110, NX_HEALTH_DEGRADED, NX_MK_FLUID, NX_FLUID_LEAK, 300)
26 nx_ledger_append(led, entries, 10, 120, NX_HEALTH_DEGRADED, NX_MK_THERMAL, NX_HVAC_DEGRADED_CAPACITY, 20)
27 nx_ledger_append(led, entries, 10, 130, NX_HEALTH_SAFETY, NX_MK_ELECTRICAL, NX_ELEC_OVERLOAD, 1100)
28 nx_ledger_append(led, entries, 20, 140, NX_HEALTH_OK, NX_MK_FLUID, NX_FLUID_SEALED, 2)
29 nx_ledger_append(led, entries, 30, 150, NX_HEALTH_WATCH, NX_MK_ROTATING, NX_ROT_ROUGH_WARNING, 2828)
30
31 if led.count != 6 { return 11 }
32 if nx_ledger_count_for(led, entries, 10) != 3 { return 12 }
33 if nx_ledger_count_for(led, entries, 20) != 2 { return 13 }
34
35 // ---- latest_for: most recent per asset ----
36 if nx_ledger_latest_for(led, entries, 10, out) != 1 { return 20 }
37 if out.ts != 130 { return 21 }
38 if out.severity != NX_HEALTH_SAFETY { return 22 }
39 if nx_ledger_latest_for(led, entries, 99, out) != 0 { return 23 } // unknown asset
40
41 // ---- worst_for: HISTORY SACRED (#13) ----
42 // asset 20's LATEST is OK, but its past LEAK (DEGRADED) is NEVER forgotten.
43 if nx_ledger_worst_for(led, entries, 10) != NX_HEALTH_SAFETY { return 30 }
44 if nx_ledger_worst_for(led, entries, 20) != NX_HEALTH_DEGRADED { return 31 }
45 if nx_ledger_worst_for(led, entries, 30) != NX_HEALTH_WATCH { return 32 }
46 if nx_ledger_worst_for(led, entries, 99) != (0 - 1) { return 33 }
47
48 // ---- trend_for: predictive direction ----
49 // asset 10: DEGRADED(t120) -> SAFETY(t130) = WORSENING (act before failure)
50 if nx_ledger_trend_for(led, entries, 10) != NX_TREND_WORSENING { return 40 }
51 // asset 20: DEGRADED(t110) -> OK(t140) = IMPROVING (it was fixed)
52 if nx_ledger_trend_for(led, entries, 20) != NX_TREND_IMPROVING { return 41 }
53 // asset 30: single entry = NODATA
54 if nx_ledger_trend_for(led, entries, 30) != NX_TREND_NODATA { return 42 }
55
56 // ---- ADDITIVE INVARIANT (#13): recovery does NOT erase the bad reading ----
57 let before: i64 = nx_ledger_count_for(led, entries, 20)
58 nx_ledger_append(led, entries, 20, 160, NX_HEALTH_OK, NX_MK_FLUID, NX_FLUID_SEALED, 1)
59 if nx_ledger_count_for(led, entries, 20) != (before + 1) { return 50 } // appended, not overwritten
60 if nx_ledger_worst_for(led, entries, 20) != NX_HEALTH_DEGRADED { return 51 } // past hazard STILL on record
61
62 // ---- full ledger never overwrites ----
63 let entries2: *LedgerEntry = sys_mmap(64) as *LedgerEntry
64 let led2: *Ledger = sys_mmap(64) as *Ledger
65 nx_ledger_init(led2, 1)
66 if nx_ledger_append(led2, entries2, 5, 10, NX_HEALTH_OK, NX_MK_THERMAL, NX_HVAC_EFFICIENT, 0) != 0 { return 60 }
67 if nx_ledger_append(led2, entries2, 5, 20, NX_HEALTH_SAFETY, NX_MK_THERMAL, NX_HVAC_EFFICIENT, 0) != (0 - 1) { return 61 }
68 if led2.count != 1 { return 62 } // the prior entry is intact
69
70 return 0
71}