nx_loadceil_gate.nx source
↩ module page · 163 lines · 9685 B
1// nx_loadceil_gate.nx -- GATE for the load-ceiling calibrator (LV3). Composes nx_loadceil_lib in-process on
2// PLANTED resmon-log buffers, so every value is asserted with no /proc, no fork and no real log.
3//
4// THE LOAD-BEARING TOOTH is the coupling: recommend * LC_HARD_FACTOR == storm_trigger, and storm_trigger is
5// the GREEN load at the declared quantile. If either drifts from ba_verdict's arithmetic the arming value
6// would land the storm trigger in the wrong place -- so the gate asserts the whole chain, not just that a
7// number came out.
8//
9// NEG-CONTROLS: an all-RED log yields zero green samples -> INSUFFICIENT (never a recommendation from no
10// healthy history); a below-minimum sample -> INSUFFICIENT; RED beats with high load must NOT enter the
11// green distribution (the exact failure that would let a wedge's load calibrate the ceiling that exists to
12// catch wedges).
13
14import "nx_syscalls.nx"
15import "nx_gate_verdict.nx"
16import "nx_loadceil_lib.nx"
17
18// A prime, coprime to every fixture size used here, so (i * stride) % n walks each residue exactly once:
19// the fixture values arrive SHUFFLED while remaining the same SET. Named for its purpose, never for its
20// value. An ascending fixture is what let a broken lc_sort pass this gate.
21const VLG_SHUFFLE_STRIDE: i64 = 7919
22// Size of the direct lc_sort tooth array. Built by arithmetic, not by a hand-typed literal table.
23const VLG_SORTN: i64 = 100
24
25// build a synthetic resmon.log into buf: `greens` GREEN beats with load = base + i (so the distribution is
26// known and sorted-recoverable), then `reds` RED beats at a high load `redload`. Returns the byte length.
27func vlg_synth(buf: *u8, base: i64, greens: i64, reds: i64, redload: i64) -> i64 {
28 var o: i64 = 0
29 var i: i64 = 0
30 while i < greens {
31 // SHUFFLED, not ascending: 7919 is prime and coprime to both fixture sizes, so (i*7919)%greens
32 // walks every residue exactly once -- the same value SET, arriving out of order. An ascending
33 // fixture is what let a broken lc_sort pass this gate: every quantile above index 0 was still
34 // right by luck, and only the minimum lied.
35 o = vlg_line(buf, o, base + ((i * VLG_SHUFFLE_STRIDE) % greens), "GREEN" as *u8)
36 i = i + 1
37 }
38 i = 0
39 while i < reds {
40 o = vlg_line(buf, o, redload, "RED" as *u8)
41 i = i + 1
42 }
43 buf[o] = 0 as u8
44 return o
45}
46func vlg_line(buf: *u8, o0: i64, load: i64, state: *u8) -> i64 {
47 var o: i64 = vlg_cat(buf, o0, "RESMON swap_used_permil=500 mem_avail_permil=400 load1_centi=" as *u8)
48 o = vlg_catn(buf, o, load)
49 o = vlg_cat(buf, o, " worst_committed_kb=1000 worst=x state=" as *u8)
50 o = vlg_cat(buf, o, state)
51 o = vlg_cat(buf, o, " sev=0 verdict=" as *u8)
52 o = vlg_cat(buf, o, state)
53 buf[o] = LC_NL as u8; o = o + 1
54 return o
55}
56func vlg_cat(buf: *u8, o0: i64, s: *u8) -> i64 { var o: i64 = o0; var i: i64 = 0; while s[i] != (0 as u8) { buf[o] = s[i]; o = o + 1; i = i + 1 } return o }
57func vlg_catn(buf: *u8, o0: i64, v0: i64) -> i64 {
58 var v: i64 = v0
59 if v == 0 { buf[o0] = 48 as u8; return o0 + 1 }
60 let tmp: *u8 = sys_mmap(32)
61 var k: i64 = 0
62 while v > 0 { tmp[k] = ((v % 10) + 48) as u8; v = v / 10; k = k + 1 }
63 var o: i64 = o0
64 while k > 0 { k = k - 1; buf[o] = tmp[k]; o = o + 1 }
65 sys_munmap(tmp, 32)
66 return o
67}
68
69func main() -> i64 {
70 let c: *i64 = gv_ctr()
71 gv_head("NX-LOADCEIL-GATE -- derive the build-admission load ceiling from GREEN-beat history (LV3)" as *u8)
72
73 let buf: *u8 = sys_mmap(1 << 20)
74 let out: *i64 = sys_mmap(LC_O_N * 8) as *i64
75
76 // 500 GREEN beats, loads 100..599 (so p99 index = 990*499/1000 = 494 -> value 100+494 = 594), plus 50
77 // RED beats at load 5000. minn=200.
78 let n: i64 = vlg_synth(buf, 100, 500, 50, 5000)
79 gv_puts(" synthetic log bytes=" as *u8); gv_num(n); gv_puts(" (500 GREEN 100..599, 50 RED at 5000)\n" as *u8)
80 gv_subjects("synthetic-log-bytes" as *u8, n, c)
81
82 let v: i64 = lc_recommend(buf, n, 990, 200, out)
83 gv_puts(" verdict=" as *u8); gv_num(v); gv_puts(" green=" as *u8); gv_num(out[LC_O_GREEN])
84 gv_puts(" total=" as *u8); gv_num(out[LC_O_TOTAL]); gv_puts(" p50=" as *u8); gv_num(out[LC_O_P50])
85 gv_puts(" p99=" as *u8); gv_num(out[LC_O_P99]); gv_puts(" max=" as *u8); gv_num(out[LC_O_MAX])
86 gv_puts(" trigger=" as *u8); gv_num(out[LC_O_TRIGGER]); gv_puts(" rec=" as *u8); gv_num(out[LC_O_REC]); gv_puts("\n" as *u8)
87
88 gv_check("recommends-when-history-is-sufficient" as *u8, v == LC_RECOMMENDED, c)
89 gv_check("counts-every-beat-green-plus-red" as *u8, out[LC_O_TOTAL] == 550, c)
90 gv_check("only-green-beats-enter-the-distribution" as *u8, out[LC_O_GREEN] == 500, c)
91 // THE MINIMUM WAS THIS GATE BLIND SPOT. It asserted the max and every quantile but never greens[0],
92 // and a cursor-clobbering insertion sort corrupts EXACTLY position 0 -- so green 500/550, max 599,
93 // p50 349 and p99 594 all read correct while the minimum was wrong. Found 2026-08-25 by
94 // nx_replyreserve_gate, whose fixture asserted its own minimum.
95 gv_check("the-minimum-green-load-is-the-smallest-planted-value-not-the-last-one-examined" as *u8, out[LC_O_MIN] == 100, c)
96 // the 50 RED beats sit at load 5000; the green max is 599. If a RED load leaked in, max would be 5000.
97 gv_check("neg-control-red-beat-load-does-not-enter-the-green-distribution" as *u8, out[LC_O_MAX] == 599, c)
98 gv_check("p50-is-the-median-green-load" as *u8, out[LC_O_P50] == 100 + (500 * 499) / 1000, c)
99 gv_check("p99-is-the-99th-percentile-green-load" as *u8, out[LC_O_P99] == 100 + (990 * 499) / 1000, c)
100 gv_check("storm-trigger-is-the-green-load-at-the-requested-quantile" as *u8, out[LC_O_TRIGGER] == out[LC_O_P99], c)
101 // THE COUPLING: recommend * hard_factor == storm_trigger, so the value written to the conf lands the
102 // trigger exactly at the derived quantile. This is the tooth that keeps the arithmetic aligned with ba_verdict.
103 gv_check("recommend-times-hard-factor-equals-the-storm-trigger" as *u8, out[LC_O_REC] * LC_HARD_FACTOR == out[LC_O_TRIGGER], c)
104 gv_check("hard-factor-mirrors-ba_verdict-storm-multiplier-of-two" as *u8, LC_HARD_FACTOR == 2, c)
105
106 // ---- neg-control: too little history ----
107 let buf2: *u8 = sys_mmap(1 << 16)
108 let n2: i64 = vlg_synth(buf2, 100, 50, 0, 0)
109 let out2: *i64 = sys_mmap(LC_O_N * 8) as *i64
110 let v2: i64 = lc_recommend(buf2, n2, 990, 200, out2)
111 gv_puts(" small-sample verdict=" as *u8); gv_num(v2); gv_puts(" green=" as *u8); gv_num(out2[LC_O_GREEN]); gv_puts("\n" as *u8)
112 gv_check("neg-control-below-minimum-green-samples-refuses-to-recommend" as *u8, v2 == LC_INSUFFICIENT && out2[LC_O_REC] == 0, c)
113
114 // ---- neg-control: all-RED log (a wedge history) yields no recommendation ----
115 let buf3: *u8 = sys_mmap(1 << 16)
116 let n3: i64 = vlg_synth(buf3, 0, 0, 400, 9000)
117 let out3: *i64 = sys_mmap(LC_O_N * 8) as *i64
118 let v3: i64 = lc_recommend(buf3, n3, 990, 200, out3)
119 gv_check("neg-control-all-red-history-yields-zero-green-and-refuses" as *u8, v3 == LC_INSUFFICIENT && out3[LC_O_GREEN] == 0, c)
120
121 // ---- neg-control: an empty buffer is UNREADABLE, distinct from insufficient ----
122 let out4: *i64 = sys_mmap(LC_O_N * 8) as *i64
123 let v4: i64 = lc_recommend(buf, 0, 990, 200, out4)
124 gv_check("neg-control-empty-buffer-is-unreadable-not-a-zero-recommendation" as *u8, v4 == LC_UNREADABLE, c)
125
126 // ---- the safe direction: a HIGHER quantile recommends a HIGHER (looser) ceiling ----
127 let outA: *i64 = sys_mmap(LC_O_N * 8) as *i64
128 let outB: *i64 = sys_mmap(LC_O_N * 8) as *i64
129 lc_recommend(buf, n, 500, 200, outA)
130 lc_recommend(buf, n, 990, 200, outB)
131 gv_check("a-higher-quantile-recommends-a-higher-ceiling-so-the-safe-direction-is-up" as *u8, outB[LC_O_REC] > outA[LC_O_REC], c)
132
133 // ---- lc_sort, DIRECTLY, on a SCRAMBLED input ----
134 // NOT ascending and NOT descending: BOTH are vacuous for this defect. A fully descending array sorts
135 // correctly even with the cursor-clobber bug, because every element genuinely belongs at position 0
136 // and the inner loop never takes its early exit. The bug only shows when an element stops PART WAY,
137 // so the input is a stride permutation of 1..n.
138 let sa: *i64 = sys_mmap(VLG_SORTN * 8) as *i64
139 var si: i64 = 0
140 while si < VLG_SORTN { sa[si] = 1 + ((si * VLG_SHUFFLE_STRIDE) % VLG_SORTN); si = si + 1 }
141 lc_sort(sa, VLG_SORTN)
142 var sok: i64 = 1
143 var ssum: i64 = 0
144 si = 0
145 while si < VLG_SORTN {
146 if sa[si] != si + 1 { sok = 0 }
147 ssum = ssum + sa[si]
148 si = si + 1
149 }
150 gv_puts(" lc_sort scrambled 1.." as *u8); gv_num(VLG_SORTN)
151 gv_puts(" -> a[0]=" as *u8); gv_num(sa[0])
152 gv_puts(" a[last]=" as *u8); gv_num(sa[VLG_SORTN - 1])
153 gv_puts(" in_order=" as *u8); gv_num(sok)
154 gv_puts(" sum=" as *u8); gv_num(ssum); gv_puts("\n" as *u8)
155 gv_check("sort-orders-a-scrambled-array-with-every-position-checked" as *u8, sok == 1, c)
156 // The pre-fix signature was exact: position 0 held the LAST key examined, and an element was LOST.
157 gv_check("neg-control-sort-does-not-write-the-last-examined-key-into-position-zero" as *u8, sa[0] == 1, c)
158 gv_check("neg-control-sort-loses-no-element-the-sum-is-the-triangular-number" as *u8,
159 ssum == (VLG_SORTN * (VLG_SORTN + 1)) / 2, c)
160
161 return gv_verdict("nx_loadceil_gate" as *u8, c,
162 "Load-ceiling calibrator: only GREEN beats enter the distribution, the recommendation couples to ba_verdict's 2x storm trigger, and too little or no healthy history refuses rather than arming a permanently-red ceiling." as *u8)
163}