code wiki / _hdl_build / nx_deploy_ready.nx

nx_deploy_ready.nx source

↩ module page · 145 lines · 8583 B

1// nx_deploy_ready.nx -- PRE-DEPLOY SAFETY GATE (operator: "prevent things like this... deploy... managed"). 2// The capstone of the deploy-reliability trilogy: an agent/session calls this BEFORE deploying an organ to 3// learn if it is SAFE. Aggregates the supervised signals into ONE actionable verdict instead of 3 separate 4// checks -- proactive prevention (won't deploy into a drifted buildroot or after a contract regression). 5// Data-driven (rule 11): knowledge/registry/deploy_checks.tsv rows = name<TAB>file<TAB>marker<TAB>severity<TAB>remediation. 6// A check PASSES if <file> contains <marker>. severity BLOCK -> a fail makes deploy UNSAFE; WARN -> advisory. 7// nx_deploy_ready check [manifest] (JSON: deploy_safe + per-check pass/severity + blockers + remediations) 8// license_tier: ORIGINAL No hw writes (Rule 26). expect_exit: 0 9import "nx_syscalls.nx" 10 11const DR_CAP: i64 = 262144 12const DR_TAB: i64 = 9 13const DR_NL: i64 = 10 14const DR_HASH: i64 = 35 15const DR_STDERR: i64 = 2 16const DR_SPAN: i64 = 16 17const DR_EXIT_USAGE: i64 = 2 18 19func dr_werr(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(DR_STDERR, s, n); return 0 } 20func dr_vlen(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n } 21func dr_cat(d: *u8, o: i64, s: *u8) -> i64 { var i: i64 = 0; while s[i] != (0 as u8) { d[o] = s[i]; o = o + 1; i = i + 1 } return o } 22func dr_catn(d: *u8, o: i64, v: i64) -> i64 { let t: *u8 = sys_mmap(28); var m: i64 = v; if m < 0 { m = 0 } var k: i64 = 0; if m == 0 { t[0] = 48 as u8; k = 1 } while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 } var i: i64 = 0; while i < k { d[o] = t[k-1-i]; o = o + 1; i = i + 1 } return o } 23func dr_cat_esc(d: *u8, o: i64, q: *u8, s: i64, e: i64) -> i64 { var i: i64 = s; while i < e { var c: i64 = q[i] as i64; if c == 34 { c = 39 } if c == 92 { c = 47 } if c < 32 { c = 32 } d[o] = c as u8; o = o + 1; i = i + 1 } return o } 24func dr_read(path: *u8, buf: *u8, cap: i64) -> i64 { 25 let fd: i64 = sys_openat_rd(path) 26 if fd < 0 { return 0 - 1 } 27 var n: i64 = 0 28 var go: i64 = 1 29 while go == 1 { let r: i64 = sys_read(fd, ((buf as i64) + n) as *u8, cap - n); if r <= 0 { go = 0 } else { n = n + r } if n >= cap { go = 0 } } 30 sys_close(fd) 31 return n 32} 33func dr_contains(buf: *u8, n: i64, lit: *u8) -> i64 { 34 var ll: i64 = 0 35 while lit[ll] != (0 as u8) { ll = ll + 1 } 36 if ll == 0 { return 1 } 37 var i: i64 = 0 38 while i + ll <= n { 39 var j: i64 = 0 40 var ok: i64 = 1 41 while j < ll { if buf[i+j] != lit[j] { ok = 0; j = ll } else { j = j + 1 } } 42 if ok == 1 { return 1 } 43 i = i + 1 44 } 45 return 0 46} 47func dr_le(q: *u8, i: i64, n: i64) -> i64 { var e: i64 = i; var s: i64 = 1; while s == 1 { if e >= n { s = 0 } else { if q[e] == (DR_NL as u8) { s = 0 } else { e = e + 1 } } } return e } 48func dr_col(q: *u8, ls: i64, le: i64, c: i64, out: *i64) -> i64 { 49 var col: i64 = 0 50 var p: i64 = ls 51 while col < c { 52 var s: i64 = 1 53 while s == 1 { if p >= le { return 0 } if q[p] == (DR_TAB as u8) { s = 0 } else { p = p + 1 } } 54 p = p + 1 55 col = col + 1 56 } 57 var e: i64 = p 58 var s2: i64 = 1 59 while s2 == 1 { if e >= le { s2 = 0 } else { if q[e] == (DR_TAB as u8) { s2 = 0 } else { e = e + 1 } } } 60 out[0] = p 61 out[1] = e 62 return 1 63} 64func dr_cstr(q: *u8, s: i64, e: i64, dst: *u8) -> i64 { var i: i64 = 0; while s + i < e { dst[i] = q[s+i]; i = i + 1 } dst[i] = 0 as u8; return i } 65func dr_span_is(q: *u8, s: i64, e: i64, lit: *u8) -> i64 { var i: i64 = 0; while s + i < e { if lit[i] == (0 as u8) { return 0 } if q[s+i] != lit[i] { return 0 } i = i + 1 } if lit[i] != (0 as u8) { return 0 } return 1 } 66func main(argc: i64, argv: *i64) -> i64 { 67 var verb: *u8 = "check" as *u8 68 if argc > 1 { verb = argv[1] as *u8 } 69 if dr_contains(verb, dr_vlen(verb), "check" as *u8) == 0 { dr_werr("usage: nx_deploy_ready check [manifest]\n" as *u8); sys_exit(DR_EXIT_USAGE); return DR_EXIT_USAGE } 70 var mpath: *u8 = "knowledge/registry/deploy_checks.tsv" as *u8 71 if argc > 2 { mpath = argv[2] as *u8 } 72 let man: *u8 = sys_mmap(DR_CAP) 73 let mn: i64 = dr_read(mpath, man, DR_CAP) 74 if mn <= 0 { dr_werr("DR-FAIL manifest empty or unreadable\n" as *u8); sys_exit(1); return 1 } 75 let fbuf: *u8 = sys_mmap(DR_CAP) 76 let fpath: *u8 = sys_mmap(512) 77 let mark: *u8 = sys_mmap(512) 78 let c0: *i64 = sys_mmap(DR_SPAN) as *i64 79 let c1: *i64 = sys_mmap(DR_SPAN) as *i64 80 let c2: *i64 = sys_mmap(DR_SPAN) as *i64 81 let c3: *i64 = sys_mmap(DR_SPAN) as *i64 82 let c4: *i64 = sys_mmap(DR_SPAN) as *i64 83 let out: *u8 = sys_mmap(DR_CAP) 84 var o: i64 = 0 85 o = dr_cat(out, o, "{\"verb\":\"check\",\"checks\":[" as *u8) 86 var total: i64 = 0 87 var blockers: i64 = 0 88 var warns: i64 = 0 89 var emitted: i64 = 0 90 var i: i64 = 0 91 while i < mn { 92 let le: i64 = dr_le(man, i, mn) 93 if le > i { if (man[i] as i64) != DR_HASH { 94 if dr_col(man, i, le, 0, c0) == 1 { if dr_col(man, i, le, 1, c1) == 1 { if dr_col(man, i, le, 2, c2) == 1 { if dr_col(man, i, le, 3, c3) == 1 { 95 dr_cstr(man, c1[0], c1[1], fpath) 96 dr_cstr(man, c2[0], c2[1], mark) 97 total = total + 1 98 let fn: i64 = dr_read(fpath, fbuf, DR_CAP) 99 var pass: i64 = 0 100 if fn > 0 { if dr_contains(fbuf, fn, mark) == 1 { pass = 1 } } 101 var is_block: i64 = 0 102 if dr_span_is(man, c3[0], c3[1], "BLOCK" as *u8) == 1 { is_block = 1 } 103 if pass == 0 { if is_block == 1 { blockers = blockers + 1 } else { warns = warns + 1 } } 104 if emitted > 0 { o = dr_cat(out, o, "," as *u8) } 105 o = dr_cat(out, o, "{\"name\":\"" as *u8) 106 o = dr_cat_esc(out, o, man, c0[0], c0[1]) 107 o = dr_cat(out, o, "\",\"pass\":" as *u8) 108 o = dr_catn(out, o, pass) 109 o = dr_cat(out, o, ",\"severity\":\"" as *u8) 110 o = dr_cat_esc(out, o, man, c3[0], c3[1]) 111 o = dr_cat(out, o, "\"" as *u8) 112 if pass == 0 { if dr_col(man, i, le, 4, c4) == 1 { o = dr_cat(out, o, ",\"remediation\":\"" as *u8); o = dr_cat_esc(out, o, man, c4[0], c4[1]); o = dr_cat(out, o, "\"" as *u8) } } 113 o = dr_cat(out, o, "}" as *u8) 114 emitted = emitted + 1 115 } } } } 116 } } 117 i = le + 1 118 } 119 o = dr_cat(out, o, "],\"total\":" as *u8) 120 o = dr_catn(out, o, total) 121 o = dr_cat(out, o, ",\"blockers\":" as *u8) 122 o = dr_catn(out, o, blockers) 123 o = dr_cat(out, o, ",\"warnings\":" as *u8) 124 o = dr_catn(out, o, warns) 125 o = dr_cat(out, o, ",\"deploy_safe\":" as *u8) 126 if blockers == 0 { o = dr_cat(out, o, "true" as *u8) } else { o = dr_cat(out, o, "false" as *u8) } 127 o = dr_cat(out, o, ",\"verdict\":\"" as *u8) 128 if blockers > 0 { o = dr_cat(out, o, "DEPLOY-BLOCKED" as *u8) } else { if warns > 0 { o = dr_cat(out, o, "DEPLOY-SAFE-WITH-WARNINGS" as *u8) } else { o = dr_cat(out, o, "DEPLOY-SAFE" as *u8) } } 129 o = dr_cat(out, o, "\",\"envelope\":\"manifest knowledge/registry/deploy_checks.tsv + each evidence file read bounded per DR_CAP; a check whose evidence file exceeds the cap reads TRUNCATED and its marker may be missed -- declared per the scale-law (F846), never silent\"}\n" as *u8) 130 sys_write(1, out, o) 131 // ---- EXIT CODE NOW CARRIES THE VERDICT (2026-07-30) ------------------------------------------------ 132 // This was sys_exit(0) UNCONDITIONALLY -- even when the verdict is DEPLOY-BLOCKED. So `nx_deploy_ready 133 // check && deploy` sailed straight through a blocking verdict, and NO caller checking $? could ever act 134 // on this gate. A gate whose exit code is constant cannot gate anything; it can only be read by something 135 // that already knows to parse its JSON. 0 = safe, 3 = DEPLOY-BLOCKED. 136 // WARNINGS DELIBERATELY STILL EXIT 0: warnings here are evidence DEBT, not a stop. A gate that exits 137 // nonzero on every warning gets wrapped in `|| true` and then protects nothing -- this file's own 138 // manifest makes that argument, and it is right. 139 // BLAST RADIUS MEASURED, NOT ASSUMED: grep across 19951 files found exactly ONE in-tree caller of 140 // nx_deploy_ready.elf (md_exec_deploy_ready), and it ignores the exit code and parses the JSON. So no 141 // existing in-tree behaviour changes; this only stops the gate from lying to future callers. 142 if blockers > 0 { sys_exit(3); return 3 } 143 sys_exit(0) 144 return 0 145}