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}