code wiki / (root) / nx_loadceil_gate.nx

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}