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}