nx_autofix_intake_gate.nx source
↩ module page · 204 lines · 13045 B
1// nx_autofix_intake_gate.nx -- THE FOREIGN-BUG INTAKE GATE (2026-07-16; envelope + untrusted-input
2// admission added autodev AD3/AD6, 2026-08-27). Any lane appends `name|path[|origin=external|prov=h..|
3// merged=yes]` rows to knowledge/forge/fix/mut_proposed.txt; this gate ADMITS each (deny by default),
4// BUILDS+RUNS every LOCAL row in a SANDBOX and keeps only instances whose bug REPRODUCES (>=1 failing
5// FNRES row) -- the equivalent-mutant discipline. EXTERNAL rows are DATA-ONLY (provenance-pinned AND
6// maintainer-merged) and are NEVER built or run; anything else is refused BY NAME. Output:
7// knowledge/forge/fix/mut_manifest.txt (nx_autofix_auto's episode list of LOCAL, reproducing instances).
8//
9// WHY THE REWRITE: the old gate exited 1 RED with no proposal plane (there was no mut_proposed.txt), and
10// it built each candidate in place with no untrusted-input admission -- the two sev-8 poisoning rows
11// (1784661149, 1784661346) demand deny-by-default before any ingestion. It now composes nx_autofix_lib:
12// one admission ruler, one sandbox, one FNRES reader -- shared with the loop and the auto gate so they
13// cannot disagree. SKIP (gv_need) when the proposal plane is absent: a host with no plane is not a failure.
14//
15// TEETH
16// T0 precondition: the proposal plane resolves (else SKIP, never a false RED)
17// T1 parsed >=1 proposed row
18// T2 kept >=1 reproducing LOCAL instance
19// T3 DISCARD TOOTH: the deliberate equivalent mutant (nx_autofix_mut_eqv, all-pass) is ABSENT from output
20// T4 ADMISSION: a planted unmerged EXTERNAL row is refused BY NAME and never built (neg-control)
21// T5 the verified manifest is written and every kept row was BUILT+RUN inside a sandbox (tree untouched)
22// expect_exit: 0 license_tier: ORIGINAL
23import "nx_syscalls.nx"
24import "nx_gate_verdict.nx"
25import "nx_estate_path.nx"
26import "nx_autofix_lib.nx"
27
28const AIG_CAP: i64 = 1048576
29const AIG_OUT: i64 = 65536
30// the board's contract symbol: does this capture carry a FAILING per-function row? THE reproduction
31// test, composing the one shared reader (a bug that cannot fail is not an instance).
32func has_failing(cap: *u8, n: i64, namebuf: *u8) -> i64 { return afl_fn_failing(cap, n, namebuf) }
33
34const AIG_TAIL: i64 = 240 // bytes of grader output carried on a NO-FNRES discard (the cause, not the whole log)
35const AIG_PROPOSED: *u8 = "knowledge/forge/fix/mut_proposed.txt"
36const AIG_MANIFEST: *u8 = "knowledge/forge/fix/mut_manifest.txt"
37// nx_sov_build_run exits SBR_ADMIT_REFUSED=6 for EVERY admission denial (it PRINTS rc=3/4/5 for the conjunct;
38// the process exit is 6 -- measured 2026-09-02 on nx_sclass_dispatch_gate, the same class). A sandbox whose compile
39// was refused produced no FNRES rows because it was never BUILT, not because the bug does not reproduce: it is
40// UNEXAMINED, never DISCARDED, and T2/T3/T5 abstain (gv_need) when no LOCAL row was examined at all.
41const AIG_BUILDER_ADMIT_REFUSED: i64 = 6
42
43func main(argc: i64, argv: *i64) -> i64 {
44 let ctr: *i64 = gv_ctr()
45 gv_head("nx_autofix_intake_gate -- deny-by-default admission, sandbox reproduction, equivalent-mutant discard: only LOCAL instances whose bug reproduces enter the resolve rate; external rows are data-only" as *u8)
46
47 var inp: *u8 = 0 as *u8
48 var outp: *u8 = AIG_MANIFEST
49 if argc >= 2 { inp = argv[1] as *u8 }
50 if argc >= 3 { outp = argv[2] as *u8 }
51 let inbuf: *u8 = sys_mmap(AFL_PATH)
52 if (inp as i64) == 0 {
53 if ep_artifact_path(inbuf, AIG_PROPOSED) == 1 { inp = inbuf } else { inp = 0 as *u8 }
54 }
55 var present: i64 = 0
56 if (inp as i64) != 0 { if afl_exists(inp) == 1 { present = 1 } }
57 gv_need("the proposal plane knowledge/forge/fix/mut_proposed.txt" as *u8, present, ctr)
58 if present == 0 {
59 let rc0: i64 = gv_verdict("AUTOFIX-INTAKE-GATE" as *u8, ctr, "" as *u8)
60 sys_exit(rc0)
61 return rc0
62 }
63 gv_puts(" proposal plane: " as *u8); gv_puts(inp); gv_puts("\n" as *u8)
64
65 let lb: *i64 = sys_mmap(8) as *i64
66 let src: *u8 = sys_read_file(inp, lb)
67 let n: i64 = lb[0]
68 let cap: *u8 = sys_mmap(AIG_CAP)
69 let outbuf: *u8 = sys_mmap(AIG_OUT)
70 var oo: i64 = 0
71 let name: *u8 = sys_mmap(AFL_NAME)
72 let path: *u8 = sys_mmap(AFL_PATH)
73 let prov: *u8 = sys_mmap(AFL_HARNESS)
74 let sb: *u8 = sys_mmap(AFL_PATH)
75 let snap: *u8 = sys_mmap(AFL_PATH)
76 let res: *u8 = sys_mmap(AFL_PATH)
77 let wit: *u8 = sys_mmap(AFL_PATH)
78 let nm: *u8 = sys_mmap(AFL_NAME)
79 let st: *i64 = sys_mmap(16) as *i64
80 let wall: i64 = afl_conf_int(AFL_KEY_WALL, AFL_WALL_MS_DEFAULT)
81 let asb: i64 = afl_conf_int(AFL_KEY_AS, AFL_AS_BYTES_DEFAULT)
82 var proposed: i64 = 0
83 var kept: i64 = 0
84 var discarded: i64 = 0
85 var eqv_kept: i64 = 0
86 var external_refused_named: i64 = 0
87 var unexamined: i64 = 0
88 var data_only: i64 = 0
89 var sandbox_all: i64 = 1
90 let ts: i64 = sys_now_realtime_sec()
91 var p: i64 = 0
92 while p < n {
93 let e: i64 = afl_eol(src, n, p)
94 var isrow: i64 = 0
95 if e > p { if src[p] != (35 as u8) { isrow = 1 } }
96 if isrow == 1 {
97 let v: i64 = afl_admit_row(((src as i64) + p) as *u8, e - p, name, path, prov)
98 proposed = proposed + 1
99 gv_puts(" " as *u8); gv_puts(name); gv_puts(" " as *u8); gv_puts(afl_admit_name(v))
100 if v == AFL_ADMIT_LOCAL {
101 // a row path is tree-relative; when it does not open from this CWD, resolve the NAME
102 // through the build lane's own source resolver (buildroot-anchored by construction)
103 var srcp: *u8 = path
104 if afl_exists(srcp) == 0 { if ep_src_path(res, name) == 1 { srcp = res } }
105 let copied: i64 = afl_sandbox_make(ts + proposed, name, srcp, sb)
106 if copied >= 1 {
107 // AD7 witness: snapshot the TREE copy before the run, byte-compare after -- a
108 // self-compare is vacuous and proves nothing (caught on the NAS, 2026-08-27)
109 var wo: i64 = afl_cat(wit, 0, sb)
110 afl_cat(wit, wo, "tree.snapshot" as *u8)
111 afl_copyfile(srcp, wit)
112 let cn: i64 = afl_sandbox_run(sb, name, cap, AIG_CAP, wall, asb, st)
113 let hf: i64 = has_failing(cap, cn, nm)
114 if afl_bytes_eq(srcp, wit) == 0 { sandbox_all = 0 }
115 if st[1] == AIG_BUILDER_ADMIT_REFUSED {
116 unexamined = unexamined + 1
117 gv_puts(" BUILDER-ADMISSION-REFUSED (nx_sov_build_run exit 6, the box is saturated) -> UNEXAMINED, not discarded\n" as *u8)
118 } else {
119 if hf == 1 {
120 kept = kept + 1
121 var z: i64 = p
122 while z < e { outbuf[oo] = src[z]; oo = oo + 1; z = z + 1 }
123 outbuf[oo] = 10 as u8; oo = oo + 1
124 gv_puts(" REPRODUCES(sandbox) -> kept\n" as *u8)
125 var el: i64 = afl_slen(name)
126 if afl_find(name, el, "eqv" as *u8, 0) >= 0 { eqv_kept = 1 }
127 } else {
128 discarded = discarded + 1
129 if hf == 0 { gv_puts(" ALL-PASS (equivalent mutant) -> DISCARDED\n" as *u8) } else {
130 // A DISCARD THAT NAMES NO CAUSE IS AN UNACTIONABLE COUNT (measured 2026-09-02: fifteen
131 // rows read NO FNRES ROWS for two hours, under admission GRANT and REFUSE alike, and
132 // nothing said whether the sandbox build crashed, timed out or ran a program that
133 // printed nothing). The sandbox's rc, its timeout flag and the tail of its grader
134 // output travel with the verdict, so the next reader starts at the cause.
135 gv_puts(" NO FNRES ROWS -> DISCARDED sandbox_rc=" as *u8); gv_num(st[1])
136 gv_puts(" timeout=" as *u8); gv_num(st[0]); gv_puts(" grader_bytes=" as *u8); gv_num(cn)
137 gv_puts(" tail=" as *u8)
138 var tl: i64 = cn - AIG_TAIL
139 if tl < 0 { tl = 0 }
140 while tl < cn { if cap[tl] == (10 as u8) { gv_puts(" | " as *u8) } else { sys_write(1, ((cap as i64) + tl) as *u8, 1) } tl = tl + 1 }
141 gv_puts("\n" as *u8)
142 }
143 }
144 }
145 // MEASURED 2026-09-02 (debt 1788405975): this block used to close the REFUSED-else one line too
146 // late, so `} else { SANDBOX-BUILD-FAILED }` below hung as a SECOND else on the same if and the
147 // compiler accepted it -- every admission-refused row was counted UNEXAMINED *and* DISCARDED
148 // (proposed=15, unexamined=15, discarded=15). The partition tooth below makes that shape
149 // impossible to ship again; the compiler-side refusal of a dangling else is LN30.
150 afl_sandbox_reap(sb, name)
151 } else { discarded = discarded + 1; gv_puts(" SANDBOX-BUILD-FAILED -> DISCARDED\n" as *u8) }
152 } else {
153 if v == AFL_ADMIT_DATA_ONLY { data_only = data_only + 1; gv_puts(" (data only, never executed)\n" as *u8) }
154 else { external_refused_named = external_refused_named + 1; gv_puts(" (refused by name, never built)\n" as *u8) }
155 }
156 }
157 p = e + 1
158 }
159 let fd: i64 = sys_openat_wr(outp, AFL_MODE_0644)
160 var wrote: i64 = 0
161 if fd >= 0 { wrote = sys_write(fd, outbuf, oo); sys_close(fd) }
162
163 gv_puts("\n" as *u8)
164 var t1: i64 = 0
165 if proposed >= 1 { t1 = 1 }
166 gv_check("T1 parsed >=1 proposed row" as *u8, t1, ctr)
167 // ABSTAIN, NEVER CONVICT, ON A REFUSED BUILDER: T2/T3/T5 are properties of EXAMINED rows. When admission
168 // refused every LOCAL compile the subject was never run, so those teeth are not asserted and the gate reads
169 // SKIP (gv_need). T1 and T4 need no build and still run. Measured 2026-09-02: 15 proposed, 15 unexamined
170 // under an I/O storm read RED 3/5 and blocked the deploy lane fleet-wide on autodev.
171 var examined: i64 = kept + discarded
172 var reached: i64 = 0
173 if examined >= 1 { reached = 1 }
174 gv_need("sandbox builder admission GRANTED for at least one LOCAL row (examined = kept + discarded; unexamined rows are admission refusals, exit 6)" as *u8, reached, ctr)
175 var t2: i64 = 0
176 if kept >= 1 { t2 = 1 }
177 if reached == 1 { gv_check("T2 kept >=1 reproducing LOCAL instance" as *u8, t2, ctr) }
178 var t3: i64 = 0
179 if discarded >= 1 { if eqv_kept == 0 { t3 = 1 } }
180 if reached == 1 { gv_check("T3 DISCARD TOOTH: at least one discarded AND the deliberate equivalent mutant is NOT in the output" as *u8, t3, ctr) }
181 // T4 ADMISSION neg-control: a planted unmerged external row is refused BY NAME (data-only path never builds it)
182 let planted: *u8 = "poison_ext|https://x.invalid/p.diff|origin=external|prov=h0123456789abcdef|merged=no" as *u8
183 let pn: *u8 = sys_mmap(AFL_NAME)
184 let pp: *u8 = sys_mmap(AFL_PATH)
185 let ppr: *u8 = sys_mmap(AFL_HARNESS)
186 var t4: i64 = 0
187 if afl_admit_row(planted, afl_slen(planted), pn, pp, ppr) == AFL_REFUSED_UNMERGED { t4 = 1 }
188 gv_check("T4 neg-control-unmerged-external-refused-by-name: a planted unmerged external row is refused, never built" as *u8, t4, ctr)
189 var t5: i64 = 0
190 if wrote > 0 { if sandbox_all == 1 { t5 = 1 } }
191 if reached == 1 { gv_check("T5 verified manifest written and every kept row was BUILT+RUN inside a sandbox with the tree untouched" as *u8, t5, ctr) }
192 // PARTITION TOOTH (2026-09-02): the summary line below used to PRINT the partition identity as prose
193 // while the counters violated it (15 proposed, 30 classified). A partition is a claim; the parts
194 // must sum, and the sum is asserted here so a double-count can never again ship as a green gate.
195 let parts: i64 = kept + discarded + unexamined + data_only + external_refused_named
196 var t6: i64 = 0
197 if parts == proposed { if proposed >= 1 { t6 = 1 } }
198 gv_check("T6 partition sums: kept+discarded+unexamined+data_only+refused == proposed (every row classified exactly once)" as *u8, t6, ctr)
199 gv_puts(" proposed=" as *u8); gv_num(proposed); gv_puts(" kept=" as *u8); gv_num(kept); gv_puts(" discarded=" as *u8); gv_num(discarded); gv_puts(" unexamined=" as *u8); gv_num(unexamined); gv_puts(" data_only=" as *u8); gv_num(data_only); gv_puts(" external_refused=" as *u8); gv_num(external_refused_named); gv_puts(" (partition: local_kept+local_discarded+unexamined+data_only+refused = proposed)\n" as *u8)
200
201 let rc: i64 = gv_verdict("AUTOFIX-INTAKE-GATE" as *u8, ctr, "deny-by-default admission, sandbox reproduction, equivalent-mutant discard; only reproducing local instances reach the resolve rate" as *u8)
202 sys_exit(rc)
203 return rc
204}