nx_headroom.nx
buildroot/runtime/nx_headroom.nx
about
nx_headroom.nx -- S4 of the SRE program (seq1295, incident 2026-07-29): the SPAWN-TIME HEADROOM
GATE every background producer must consult before forking work. The outage proof: an 8-wide TLS
fork pool spooling to tmpfs on a memory-tight box (which had ALREADY refused a build on the
MemAvailable floor) co-produced a host-wide starvation + hard crash. /api/build has this gate
baked in; this organ EXTRACTS it as the shared, config-driven primitive so no producer derives
width from taste again (bounds-derived law).
nx_headroom width <cap> <child_cost_mb> [meminfo] [loadavg] [cpuinfo]
-> NX-HEADROOM ok width=<n> avail_mb= usable_mb= cores= load1_centi= (exit 0)
-> NX-HEADROOM REFUSED reason=mem_floor|load_ceiling ... (exit 5)
width = min(cap, cores/2, (MemAvailable-floor)/child_cost), floor 1 -- else REFUSED.
nx_headroom gate <need_mb> [meminfo] [loadavg] [cpuinfo]
-> ok (exit 0) iff need_mb fits above the floor AND load is under ceiling; else REFUSED exit 5.
Conf headroom.conf in CWD: floor_mb= loadceil_centi_per_core= (else derived defaults below).
Path override args exist so the GATE can prove exact math on fixture files -- real callers omit them.
Read-only; no hw writes (Rule 26).
license_tier: ORIGINAL expect_exit: 0
dependencies 1 imports · 0 importers
imports: nx_syscalls.nx
imported by: nobody (leaf or entry point)
call flow from main pre-order; caps 40 nodes / depth 6 declared; ↻ = already shown
structs
| none |
consts
| 18 | const H_MAGIC_1024: i64 = 1024 |
| 19 | const H_MAGIC_4096: i64 = 4096 |
| 20 | const H_MAGIC_4095: i64 = 4095 |
| 22 | const H_EXIT_USAGE: i64 = 2 |
| 23 | const H_EXIT_REFUSED: i64 = 5 |
| 24 | const H_READCAP: i64 = 131072 |
| 25 | const H_DEF_FLOOR_MB: i64 = 4096 // derived: control plane + page-cache reserve ~11% of the 36GB hub |
| 26 | const H_DEF_LOADCEIL: i64 = 200 // 2.00 load per core: beyond that the box is already saturated |
functions
| 28 | func h_puts(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 } |
| 29 | func h_putn(v: i64) -> i64 |
| 40 | func h_slen(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n } called by 1: h_num_after |
| 41 | func h_streq(a: *u8, b: *u8) -> i64 { var i: i64 = 0; while a[i] != (0 as u8) { if a[i] != b[i] { return 0 } i = i + 1 } if b[i] != (0 as u8) { return 0 } return 1 } called by 1: main |
| 42 | func h_atoi(s: *u8) -> i64 { var v: i64 = 0; var i: i64 = 0; while s[i] != (0 as u8) { let c: i64 = s[i] as i64; if c >= 48 { if c <= 57 { v = v * 10 + (c - 48) } } i = i + 1 } return v } called by 1: main |
| 43 | func h_read(path: *u8, buf: *u8, cap: i64) -> i64 |
| 53 | func h_num_after(buf: *u8, n: i64, key: *u8) -> i64 |
| 82 | func h_load_centi(buf: *u8, n: i64) -> i64 called by 1: main |
| 108 | func h_cores(buf: *u8, n: i64) -> i64 called by 1: main |
| 128 | func h_refuse(reason: *u8, avail: i64, usable: i64, cores: i64, load: i64) -> i64 |
| 137 | func main(argc: i64, argv: *i64) -> i64 |