code wiki / _hdl_build / nx_staledir_gate.nx
nx_staledir_gate.nx source
↩ module page · 76 lines · 4444 B
1// nx_staledir_gate.nx -- proves the DIRECTION GUARD in nx_stale_check (F1145 / debt seq1008).
2//
3// WHY THIS GATE EXISTS: nx_stale_check's byte-compare tells you source and deployment DISAGREE but is
4// structurally blind to WHICH IS AHEAD. The old code called every disagreement STALE, whose remedy text
5// is "rebuild+restage" -- and for a binary that is AHEAD of its source that remedy DELETES the shipped
6// feature. That is exactly how the nx_page_verify auto-connect-override would have been destroyed.
7// So the guard is not cosmetic: it decides whether a human is told to run a DESTRUCTIVE command.
8//
9// The classifier under test is pure size-direction arithmetic, so it is testable without building
10// anything: sd_verdict(fresh_bytes, deployed_bytes, identical) -> the verdict id.
11// T1 identical -> CURRENT
12// T2 fresh << deployed and tiny -> AMBIGUOUS (the pre-existing stub trap must SURVIVE this change)
13// T3 fresh < deployed -> DEPLOYED-AHEAD <== THE NEW TOOTH: the seq1008 shape, remedy WITHHELD
14// T4 fresh > deployed -> STALE (source genuinely ahead; rebuild IS the right remedy)
15// T5 same size, differing bytes -> STALE (direction unknowable by size; must not claim AHEAD)
16// T6 REGRESSION: the exact seq1008 magnitudes (572834 vs 574963) must classify DEPLOYED-AHEAD,
17// NOT the stub AMBIGUOUS and NOT STALE -- a 2KB delta on a 575KB binary is the real case that
18// slipped through the old stub-only guard.
19// T7 ANTI-VACUITY: the guard must NOT swallow everything -- a genuinely stale target still reaches
20// STALE, so the useful remedy is not lost. A guard that flags every case is as useless as none.
21// expect_exit: 0 license_tier: ORIGINAL No hw writes (Rule 26).
22import "nx_gate_verdict.nx"
23
24const SD_CURRENT: i64 = 0
25const SD_AMBIGUOUS: i64 = 1
26const SD_AHEAD: i64 = 2
27const SD_STALE: i64 = 3
28const SD_STUB_CAP: i64 = 4096
29
30// MIRRORS the shipped decision order in nx_stale_check.main() exactly: identical -> stub-trap ->
31// direction -> stale. Kept in the same order because the ORDER is the contract: the stub guard must
32// win over the direction guard, and the direction guard must win over the STALE remedy.
33func sd_verdict(fresh: i64, deployed: i64, identical: i64) -> i64 {
34 if identical == 1 { return SD_CURRENT }
35 if fresh * 2 < deployed { if fresh < SD_STUB_CAP { return SD_AMBIGUOUS } }
36 if fresh < deployed { return SD_AHEAD }
37 return SD_STALE
38}
39
40func main() -> i64 {
41 let ctr: *i64 = gv_ctr()
42 gv_head("nx_staledir_gate -- a disagreement must never prescribe a destructive rebuild" as *u8)
43 var ok: i64 = 0
44
45 if sd_verdict(1000, 1000, 1) == SD_CURRENT { ok=1 } else { ok=0 }
46 gv_check("T1 identical bytes -> CURRENT" as *u8, ok, ctr)
47
48 if sd_verdict(200, 500000, 0) == SD_AMBIGUOUS { ok=1 } else { ok=0 }
49 gv_check("T2 tiny fresh vs huge deployed -> AMBIGUOUS (stub trap SURVIVES)" as *u8, ok, ctr)
50
51 if sd_verdict(572834, 574963, 0) == SD_AHEAD { ok=1 } else { ok=0 }
52 gv_check("T3 fresh < deployed -> DEPLOYED-AHEAD (remedy withheld)" as *u8, ok, ctr)
53
54 if sd_verdict(580000, 574963, 0) == SD_STALE { ok=1 } else { ok=0 }
55 gv_check("T4 fresh > deployed -> STALE (rebuild IS correct here)" as *u8, ok, ctr)
56
57 if sd_verdict(574963, 574963, 0) == SD_STALE { ok=1 } else { ok=0 }
58 gv_check("T5 same size, bytes differ -> STALE (never claim AHEAD without evidence)" as *u8, ok, ctr)
59
60 // T6 is the regression tooth: these are the REAL magnitudes from the incident.
61 var v6: i64 = sd_verdict(572834, 574963, 0)
62 if v6 == SD_AHEAD { if v6 != SD_AMBIGUOUS { if v6 != SD_STALE { ok=1 } else { ok=0 } } else { ok=0 } } else { ok=0 }
63 gv_check("T6 REGRESSION seq1008 magnitudes classify AHEAD, not stub-AMBIGUOUS, not STALE" as *u8, ok, ctr)
64
65 // T7 anti-vacuity: the new guard must not eat the STALE path entirely.
66 var stales: i64 = 0
67 if sd_verdict(600000, 574963, 0) == SD_STALE { stales = stales + 1 }
68 if sd_verdict(10000, 9999, 0) == SD_STALE { stales = stales + 1 }
69 if sd_verdict(50, 50, 0) == SD_STALE { stales = stales + 1 }
70 if stales == 3 { ok=1 } else { ok=0 }
71 gv_check("T7 ANTI-VACUITY: genuinely-stale targets still reach STALE (guard is not a catch-all)" as *u8, ok, ctr)
72
73 let rc: i64 = gv_verdict("STALEDIR" as *u8, ctr, "a byte-disagreement can no longer prescribe a rebuild that deletes shipped code" as *u8)
74 sys_exit(rc)
75 return rc
76}