code wiki / (root) / nx_buildrun_verdict_lib.nx

nx_buildrun_verdict_lib.nx source

↩ module page · 50 lines · 3060 B

1// nx_buildrun_verdict_lib.nx -- THE ONE RULE for "did this buildrun produce the artifact on disk?" (2026-09-05). 2// Extracted from nx_hostctl cmd_buildrun so the decision is a PURE FUNCTION a gate can drive without a fixture build 3// tree: the supervisor's paths are absolute by design (the safe choice for a supervisor, the wrong shape for a fixture). 4// WHY IT EXISTS: cmd_buildrun used to probe _build/<name>.sov.elf WHATEVER the child did, so a builder that REFUSED 5// under its own admission check (rc=4 in an I/O storm) left the PREVIOUS artifact to be validated, echoed as 6// "BUILT size=", re-staged with a fresh mtime and promoted by every caller that trusted action=BUILT -- the false-green 7// build class, measured live on nx_actlog 2026-09-05 (debt 1788634371, superseding the July "idempotency" story in 8// 1785363417). Two conjuncts, both required, in this order: 9// 1. the builder's exit status is 0 (a refusal is rc=4, a dead exec is 127) 10// 2. its capture carries the builder's own success token, printed on a real compile AND on a cache hit 11// POLL FOR THE POSITIVE MARKER, NEVER THE ABSENCE OF A NEGATIVE ONE. The token is matched EXACTLY and contiguously: 12// the two words on separate lines are not the token (a neg-control in nx_hostctl_buildrun_gate pins that). 13// license_tier: ORIGINAL No hw writes (Rule 26). 14import "nx_syscalls.nx" 15 16const BV_OK: i64 = 1 // this run produced the artifact on disk 17const BV_EXIT_NONZERO: i64 = 2 // the builder refused or died; the artifact on disk is a PREVIOUS build 18const BV_NO_TOKEN: i64 = 3 // exit 0 but no success token; nothing this run produced is on disk 19 20func bv_token() -> *u8 { return "SOVEREIGN build" as *u8 } 21 22func bv_find(q: *u8, n: i64, lit: *u8) -> i64 { 23 var ll: i64 = 0 24 while lit[ll] != (0 as u8) { ll = ll + 1 } 25 if ll == 0 { return 0 } 26 var i: i64 = 0 27 while i + ll <= n { 28 var j: i64 = 0 29 var ok: i64 = 1 30 while j < ll { if q[i + j] != lit[j] { ok = 0; j = ll } else { j = j + 1 } } 31 if ok == 1 { return 1 } 32 i = i + 1 33 } 34 return 0 35} 36 37// cexit = the child's exit status (already shifted out of the wait4 word), cap/n = the builder's captured output. 38func bv_verdict(cexit: i64, cap: *u8, n: i64) -> i64 { 39 if cexit != 0 { return BV_EXIT_NONZERO } 40 if n <= 0 { return BV_NO_TOKEN } 41 if bv_find(cap, n, bv_token()) == 0 { return BV_NO_TOKEN } 42 return BV_OK 43} 44 45// the receipt text for a verdict, so hostctl and any other caller print the SAME words for the same reason 46func bv_reason(v: i64) -> *u8 { 47 if v == BV_OK { return "BUILDRUN VERIFIED: builder exit 0 and its own SOVEREIGN build token seen" as *u8 } 48 if v == BV_EXIT_NONZERO { return "BUILDRUN FAIL: the builder exited non-zero -- whatever sits in _build/ is a PREVIOUS build and is NOT staged (the builder's own refusal or failure text is above)" as *u8 } 49 return "BUILDRUN FAIL: the builder exited 0 but printed no SOVEREIGN build token, so nothing this run produced is on disk -- NOT staged" as *u8 50}