code wiki / _hdl_build / nx_gated_edit.nx
nx_gated_edit.nx source
↩ module page · 96 lines · 4288 B
1// nx_gated_edit.nx -- GATED SOURCE-EDIT APPLIER (2026-07-21, closes the D001 mechanization gap:
2// nx_consol_apply retires dead FILE shadows byte-identical; THIS applies a function-body -> shared-lib
3// DELEGATION (or any exact-string source edit) and keeps it ONLY IF a verify command's output is
4// byte-identical BEFORE vs AFTER. Behaviour-preserving BY CONSTRUCTION: run verify (BEFORE) -> apply the
5// unique old->new edit -> run verify (AFTER). If AFTER == BEFORE the edit changed no observable behaviour
6// -> CONSOLIDATED. Else the edit IS live -> RESTORE source + re-run verify (rebuild good) + REFUSE.
7// Uniqueness contract (exactly one match, else untouched) = nx_fs_write-edit's; before/after diff =
8// nx_consol_apply's proof, generalised from file-rename to string-edit. A seat/PM points verify at a
9// build+gate driver so "output preserved" == "the organ still builds and its gate stays GREEN".
10// argv: <srcfile> <oldfile> <newfile> <verifyelf> <verifyarg> (old/new from FILES: no argv escaping)
11// exit: 0 CONSOLIDATED | 1 REFUSED (source restored) | 2 usage/NOMATCH/AMBIGUOUS (untouched)
12// | 3 verify-before-empty (untouched)
13// license_tier: ORIGINAL No hw writes (Rule 26).
14import "nx_seat_drive_lib.nx"
15import "nx_deploy_lib.nx"
16import "nx_syscalls.nx"
17import "nx_ge_str_lib.nx"
18
19const GE_CAP: i64 = 1048576
20const GE_ECAP: i64 = 2097152
21
22// ge_find/ge_count/ge_eq now shared via nx_ge_str_lib.nx (rule-15 extraction, 2nd consumer)
23
24func main(argc: i64, argv: *i64) -> i64 {
25 if argc < 6 { sd_w("usage: nx_gated_edit <srcfile> <oldfile> <newfile> <verifyelf> <verifyarg>\n" as *u8); sys_exit(2); return 2 }
26 let srcp: *u8 = argv[1] as *u8
27 let oldp: *u8 = argv[2] as *u8
28 let newp: *u8 = argv[3] as *u8
29 let velf: *u8 = argv[4] as *u8
30 let varg: *u8 = argv[5] as *u8
31
32 let src: *u8 = sys_mmap(GE_CAP)
33 let sn: i64 = dp_read(srcp, src, GE_CAP)
34 if sn <= 0 { sd_w("NX-GATED-EDIT verdict=SRC-ABSENT " as *u8); sd_w(srcp); sd_w("\n" as *u8); sys_exit(2); return 2 }
35 let oldb: *u8 = sys_mmap(GE_CAP)
36 let on: i64 = dp_read(oldp, oldb, GE_CAP)
37 if on <= 0 { sd_w("NX-GATED-EDIT verdict=OLD-EMPTY (source untouched)\n" as *u8); sys_exit(2); return 2 }
38 let newb: *u8 = sys_mmap(GE_CAP)
39 let nn: i64 = dp_read(newp, newb, GE_CAP)
40
41 let cnt: i64 = ge_count(src, sn, oldb, on)
42 if cnt == 0 { sd_w("NX-GATED-EDIT verdict=NOMATCH (source untouched)\n" as *u8); sys_exit(2); return 2 }
43 if cnt > 1 {
44 sd_w("NX-GATED-EDIT verdict=AMBIGUOUS matches=" as *u8)
45 let mb: *u8 = sys_mmap(24)
46 sd_num(mb, 0, cnt)
47 sd_w(mb)
48 sd_w(" (source untouched)\n" as *u8)
49 sys_exit(2); return 2
50 }
51 let pos: i64 = ge_find(src, sn, oldb, on, 0)
52
53 let av: *i64 = sys_mmap(32) as *i64
54 av[0] = varg as i64
55 dep_run_capture(velf, av, 1, "/tmp/ge_before.out" as *u8)
56 let before: *u8 = sys_mmap(GE_CAP)
57 let bn: i64 = dp_read("/tmp/ge_before.out" as *u8, before, GE_CAP)
58 if bn <= 0 { sd_w("NX-GATED-EDIT verdict=VERIFY-BEFORE-EMPTY (source untouched)\n" as *u8); sys_exit(3); return 3 }
59
60 let edited: *u8 = sys_mmap(GE_ECAP)
61 var eo: i64 = 0
62 var i: i64 = 0
63 while i < pos { edited[eo] = src[i]; eo = eo + 1; i = i + 1 }
64 var j: i64 = 0
65 while j < nn { edited[eo] = newb[j]; eo = eo + 1; j = j + 1 }
66 var k: i64 = pos + on
67 while k < sn { edited[eo] = src[k]; eo = eo + 1; k = k + 1 }
68 dp_writefile(srcp, edited, eo)
69
70 dep_run_capture(velf, av, 1, "/tmp/ge_after.out" as *u8)
71 let after: *u8 = sys_mmap(GE_CAP)
72 let an: i64 = dp_read("/tmp/ge_after.out" as *u8, after, GE_CAP)
73
74 if an > 0 { if ge_eq(before, bn, after, an) == 1 {
75 sd_w("NX-GATED-EDIT verdict=CONSOLIDATED (verify byte-identical) src=" as *u8)
76 sd_w(srcp)
77 sd_w("\n" as *u8)
78 sys_exit(0)
79 return 0
80 } }
81
82 dp_writefile(srcp, src, sn)
83 dep_run_capture(velf, av, 1, "/tmp/ge_restore.out" as *u8)
84 sd_w("NX-GATED-EDIT verdict=REFUSED (verify changed -> edit is live) restored src=" as *u8)
85 sd_w(srcp)
86 sd_w(" bytesBefore=" as *u8)
87 let nb: *u8 = sys_mmap(24)
88 sd_num(nb, 0, bn)
89 sd_w(nb)
90 sd_w(" bytesAfter=" as *u8)
91 sd_num(nb, 0, an)
92 sd_w(nb)
93 sd_w("\n" as *u8)
94 sys_exit(1)
95 return 1
96}