code wiki / _hdl_build / nx_presubmit_lib.nx

nx_presubmit_lib.nx source

↩ module page · 89 lines · 5021 B

1// nx_presubmit_lib.nx -- PRE-SUBMIT correctness guard (stage 1 of the 3-stage lifecycle: catch BEFORE a 2// build cycle is spent, to save token waste). The at-submit dup_shadow warning (seq207) fires AFTER a build; 3// this fires BEFORE, so a session/agent never spends a build+revert on a name collision (the nx_emit landmine 4// 2026-07-21 was caught at-submit and cost a full cycle -- this makes it a one-call pre-check). 5// Composes: nx_build_admit = the RESOURCE pre-submit gate (headroom); this = the CORRECTNESS pre-submit gate 6// (name/collision). Dogfoods the nx_estr shared base (2nd adopter). ZERO deps beyond nx_syscalls+nx_estr so a 7// preflight can never itself be the heavy thing that fails. license_tier: ORIGINAL No hw writes (Rule 26). 8import "nx_syscalls.nx" 9import "nx_estr.nx" 10 11const PS_DIRBUF: i64 = 65536 // getdents read buffer (rule 11: named, not an inline magic number) 12 13// does exactly "<name>.nx" exist as a directory entry of dir? 14func ps_has(dir: *u8, name: *u8) -> i64 { 15 let fd: i64 = sys_openat_rd(dir) 16 if fd < 0 { return 0 } 17 let dbuf: *u8 = sys_mmap(PS_DIRBUF) 18 let tgt: *u8 = sys_mmap(256) 19 var t: i64 = es_cat(tgt, 0, name) 20 t = es_cat(tgt, t, ".nx" as *u8) 21 tgt[t] = 0 as u8 22 var found: i64 = 0 23 var go: i64 = 1 24 while go == 1 { 25 let nr: i64 = sys_getdents64(fd, dbuf, PS_DIRBUF) 26 if nr <= 0 { go = 0 } else { 27 var off: i64 = 0 28 while off < nr { 29 let rec: *u8 = (dbuf as i64 + off) as *u8 30 let nm: *u8 = dirent_name(rec) 31 var i: i64 = 0 32 var scan: i64 = 1 33 while scan == 1 { 34 if tgt[i] == (0 as u8) { if nm[i] == (0 as u8) { found = 1 } scan = 0 } 35 else { if nm[i] != tgt[i] { scan = 0 } else { i = i + 1 } } 36 } 37 off = off + dirent_reclen(rec) 38 } 39 } 40 } 41 sys_close(fd) 42 return found 43} 44 45// write the JSON verdict for creating an organ named `name`, given the two source dirs. returns rc: 46// 0 FREE -- name in neither dir: safe to create 47// 4 EXISTS-in-hdl_build -- already in the primary dir: you are EDITING, or the name is taken 48// 3 SHADOW-RISK / DUAL -- present in the OTHER (or both) dir: creating here makes a dual-copy landmine 49func ps_check(name: *u8, hdl: *u8, rt: *u8, out: *u8) -> i64 { 50 let in_hdl: i64 = ps_has(hdl, name) 51 let in_rt: i64 = ps_has(rt, name) 52 var o: i64 = es_cat(out, 0, "{\"tool\":\"nx_presubmit\",\"name\":\"" as *u8) 53 o = es_cat(out, o, name) 54 o = es_cat(out, o, "\",\"in_hdl_build\":" as *u8) 55 o = es_catn(out, o, in_hdl) 56 o = es_cat(out, o, ",\"in_runtime\":" as *u8) 57 o = es_catn(out, o, in_rt) 58 // every verdict carries a why + a fix RECOMMENDATION (operator 2026-07-21: a refusal must tell the AI+ 59 // human what/why/how, never a bare verdict). 60 o = es_cat(out, o, ",\"verdict\":\"" as *u8) 61 var rc: i64 = 0 62 var done: i64 = 0 63 if in_hdl == 1 { if in_rt == 1 { 64 o = es_cat(out, o, "DUAL-COPY-ALREADY\",\"why\":\"" as *u8) 65 o = es_cat(out, o, name) 66 o = es_cat(out, o, ".nx exists in BOTH source dirs. Imports resolve DIRECTORY-LOCAL (proven 2026-07-21): _hdl_build organs bind the _hdl_build copy and runtime organs bind the runtime copy, so BOTH are load-bearing (neither auto-stale); the real hazard is DIVERGENCE -- the twins drift apart and same-named consumers in different trees silently get different behavior (seq207)\",\"fix\":\"do NOT blind-delete either twin -- it may serve dozens of importers; count importers per tree first, then reconcile via STAGED MERGE to one canonical tree (unify the sources, migrate the other-tree consumers, retire the emptied copy per rule 13). Direct retire is safe ONLY when a copy has 0 importers AND no standalone deploy" as *u8) 67 rc = 3; done = 1 68 } } 69 if done == 0 { if in_hdl == 1 { 70 o = es_cat(out, o, "EXISTS-in-hdl_build\",\"why\":\"an organ named " as *u8) 71 o = es_cat(out, o, name) 72 o = es_cat(out, o, " already exists in the primary source dir\",\"fix\":\"to CHANGE it, EDIT that file; for a NEW organ, pick a different name" as *u8) 73 rc = 4; done = 1 74 } } 75 if done == 0 { if in_rt == 1 { 76 o = es_cat(out, o, "SHADOW-RISK-runtime-twin\",\"why\":\"" as *u8) 77 o = es_cat(out, o, name) 78 o = es_cat(out, o, ".nx exists in buildroot/runtime; creating a copy in _hdl_build makes a dual-copy that diverges and silently regresses (the nx_emit landmine)\",\"fix\":\"either EDIT the existing buildroot/runtime/" as *u8) 79 o = es_cat(out, o, name) 80 o = es_cat(out, o, ".nx, or pick a DIFFERENT name for the new organ" as *u8) 81 rc = 3; done = 1 82 } } 83 if done == 0 { 84 o = es_cat(out, o, "FREE\",\"why\":\"the name is free in both source dirs\",\"fix\":\"safe to create -- no action needed" as *u8) 85 } 86 o = es_cat(out, o, "\"}" as *u8) 87 out[o] = 0 as u8 88 return rc 89}