code wiki / _hdl_build / nx_raidwatch_gate.nx

nx_raidwatch_gate.nx source

↩ module page · 55 lines · 4483 B

1// nx_raidwatch_gate.nx -- teeth for the ARRAY HEALTH BEAT's verdict ladder. 2// 3// WHY IT EXISTS (2026-09-03). nx_organ_ship shipped nx_raidwatch and printed prove=NO-GATE-FOUND 4// UNPROVEN -- a NAMED absence, which is the only reason anyone noticed. This organ is the estate's only 5// disk-health monitor, it has been correctly reporting RED for 25 days, and nothing had ever proven that 6// its verdict ladder returns what it claims. A monitor nobody has bite-proven is a monitor whose GREEN 7// nobody should trust, and this one's GREEN would mean "the arrays are fine". 8// 9// SUBJECT: rw_verdict_code, the ladder the durable status file reads. It is PURE, so these teeth drive 10// it in-process -- no fork, no /sys, no fixture tree, and nothing here can touch a disk. 11// license_tier: ORIGINAL expect_exit: 0 12import "nx_raidwatch.nx" 13import "nx_gate_verdict.nx" 14 15func main(argc: i64, argv: *i64) -> i64 { 16 let ctr: *i64 = gv_ctr() 17 18 // ---- the four rungs, each alone, so no tooth passes on another's condition 19 gv_check("T1 a DEGRADED array alone is RED -- redundancy is gone and that is the one state that means data loss is one failure away" as *u8, 20 (rw_verdict_code(1, 0, 0, 0) == RW_EXIT_RED) as i64, ctr) 21 gv_check("T2 an uncorrectable kernel IO error alone is RED -- a disk can be failing while every array metric still reads healthy" as *u8, 22 (rw_verdict_code(0, 1, 0, 0) == RW_EXIT_RED) as i64, ctr) 23 gv_check("T3 a DAMAGED member alone is AMBER, not RED -- parity corrected every read, so it is a replacement decision and not an outage" as *u8, 24 (rw_verdict_code(0, 0, 1, 0) == RW_EXIT_AMBER) as i64, ctr) 25 gv_check("T4 a parity mismatch alone is AMBER -- schedule a scrub" as *u8, 26 (rw_verdict_code(0, 0, 0, 1) == RW_EXIT_AMBER) as i64, ctr) 27 28 // ---- NEG-CONTROL: the ladder must be able to say nothing is wrong, or every tooth above passes 29 // for the trivial reason that the function returns a constant. 30 gv_check("T5 neg-control-all-clear: with every input zero the ladder returns GREEN, so it is not a function that only ever alarms" as *u8, 31 (rw_verdict_code(0, 0, 0, 0) == 0) as i64, ctr) 32 gv_check("T6 neg-control-distinct-codes: RED, AMBER and GREEN are three DIFFERENT values -- a ladder collapsing them would pass T1-T5 while telling the operator nothing" as *u8, 33 ((RW_EXIT_RED != RW_EXIT_AMBER) as i64) * ((RW_EXIT_RED != 0) as i64) * ((RW_EXIT_AMBER != 0) as i64), ctr) 34 35 // ---- PRECEDENCE. The order matters and is not incidental: a box can be degraded AND have damaged 36 // members at once -- ours is -- and reporting that as AMBER would understate a redundancy loss. 37 gv_check("T7 degraded WITH a damaged member is RED, not AMBER -- losing redundancy outranks a member that parity is still masking" as *u8, 38 (rw_verdict_code(1, 0, 1, 0) == RW_EXIT_RED) as i64, ctr) 39 gv_check("T8 an uncorrectable IO error WITH a parity mismatch is RED, not AMBER" as *u8, 40 (rw_verdict_code(0, 1, 0, 1) == RW_EXIT_RED) as i64, ctr) 41 42 // ---- FIXTURE-REACHED, from the LIVE estate rather than a synthetic. Measured 2026-09-03 by the 43 // promoted binary: arrays=5 degraded=1 io_error=5 members_damaged=2 mismatched=0. Asserting the 44 // real reading lands on the real rung is what stops this gate proving a ladder nobody's box takes. 45 gv_check("T9 fixture-reached-live: the estate's own measured vector (degraded=1 io_error=5 members_damaged=2 mismatched=0) lands on RED, so T1 is exercised by production and not only by a constructed input" as *u8, 46 (rw_verdict_code(1, 5, 2, 0) == RW_EXIT_RED) as i64, ctr) 47 48 // ---- THE TOOTH THAT SURVIVES THE REPAIR, and it is the operator-facing one. When md3 is re-seated 49 // the degraded conjunct clears, and this box must NOT then read GREEN: two members of md2 are still 50 // damaged. Without this, "fix the nvme" would look like it closed the whole finding. 51 gv_check("T10 repairing md3 alone does NOT clear this estate: with degraded=0 but members_damaged=2 still true the ladder reads AMBER, never GREEN -- the second half of the hardware finding outlives the first" as *u8, 52 (rw_verdict_code(0, 0, 2, 0) == RW_EXIT_AMBER) as i64, ctr) 53 54 return gv_verdict("RAIDWATCH-GATE" as *u8, ctr, "the verdict ladder rw_verdict_code reads by the durable status file; the /sys and /dev/kmsg readers are out of scope here and stay unproven" as *u8) 55}