nx_toolreg_reconcile_gate.nx source
↩ module page · 153 lines · 9276 B
1// nx_toolreg_reconcile_gate.nx -- gates the discovery reconciler on a THROWAWAY registry prefix +
2// fixture confs (runner: cd a scratch dir with a knowledge/ subdir). Asserts: missing GREEN tools get
3// registered with the AUTHOR'S schema desc; schema-less tools are SKIPPED (fail-closed, counted);
4// already-registered tools are LEFT ALONE; the whole run is IDEMPOTENT (2nd pass registers 0);
5// comment rows ignored. Exit 0 only on all-PASS. license_tier: ORIGINAL expect_exit: 0
6import "nx_toolreg_reconcile_lib.nx"
7import "nx_seg_store.nx" // ss_writefile -- fixture author
8
9const TG_CHECKS: i64 = 10
10const TG_PTR: i64 = 16 // ptr/len out cells
11const TG_FIX_ROWS: i64 = 4 // non-comment fixture allowlist rows (toola/toolb/toolc/toold)
12const TG_ASCII_0: i64 = 48 // '0'
13const TG_SLASH: i64 = 47 // '/'
14const TG_EXP_ALREADY2: i64 = 2 // idempotent 2nd pass: both schema-tools "already"; also = drift on the 2-tool dirty audit
15const TG_TENS: i64 = 10 // 2-digit score render
16
17func tg_check(name: *u8, ok: i64, pass: *i64) -> i64 {
18 let t: *u8 = "T " as *u8
19 sys_write(1, t, rr_len(t)); sys_write(1, name, rr_len(name))
20 // pass[1] = TOTAL, counted here rather than declared as a constant. The old verdict compared
21 // pass[0] against a hardcoded TG_CHECKS, so adding an 11th tooth made the gate print
22 // "idempotent-second-pass -> FAIL" and then "pass=10/10 verdict=GREEN" and EXIT 0 -- a gate
23 // that reports GREEN while a tooth is failing. Self-caught 2026-07-30.
24 // LAW: A GATE MUST COUNT ITS OWN ASSERTIONS -- a hardcoded denominator turns every newly added
25 // tooth into a silent free pass, which is the one failure mode a gate must not have.
26 pass[1] = pass[1] + 1
27 if ok == 1 { let p: *u8 = " -> PASS\n" as *u8; sys_write(1, p, rr_len(p)); pass[0] = pass[0] + 1 }
28 else { let f: *u8 = " -> FAIL\n" as *u8; sys_write(1, f, rr_len(f)) }
29 return 0
30}
31func tg_write(path: *u8, body: *u8) -> i64 { return ss_writefile(path, body, rr_len(body)) }
32
33func tg_cat(o: *u8, at: i64, s: *u8) -> i64 {
34 var a: i64 = at
35 var i: i64 = 0
36 while s[i] != (0 as u8) { o[a] = s[i]; a = a + 1; i = i + 1 }
37 return a
38}
39func tg_num(o: *u8, at: i64, v: i64) -> i64 {
40 if v == 0 { o[at] = 48 as u8; return at + 1 }
41 let t: *u8 = sys_mmap(32)
42 var n: i64 = 0
43 var x: i64 = v
44 while x > 0 { t[n] = ((x % 10) + 48) as u8; x = x / 10; n = n + 1 }
45 var a: i64 = at
46 while n > 0 { n = n - 1; o[a] = t[n]; a = a + 1 }
47 return a
48}
49
50func main() -> i64 {
51 let pass: *i64 = sys_mmap(TG_PTR) as *i64
52 pass[0] = 0
53 pass[1] = 0
54 // ISOLATED FIXTURE PLANE PER RUN. The prefix used to be a fixed "knowledge/tg-", so the plane
55 // SURVIVED between runs: the previous run left toola registered, the next run counted REG=0,
56 // and the suite only ever passed on a virgin plane. Self-caught while changing the already-
57 // registered branch. LAW: A GATE WHOSE VERDICT DEPENDS ON LEFTOVER STATE FROM ITS OWN LAST RUN
58 // IS NOT A GATE -- isolate the fixture, do not tune the assertions around the residue.
59 let pfx: *u8 = sys_mmap(TG_PTR)
60 var pl: i64 = 0
61 pl = tg_cat(pfx, pl, "knowledge/tg" as *u8)
62 pl = tg_num(pfx, pl, sys_now_realtime_sec())
63 pl = tg_cat(pfx, pl, "-" as *u8)
64 pfx[pl] = 0 as u8
65 // fixtures: 3 tools -- toola (schema YES), toolb (schema NO), toolc (schema YES, pre-registered)
66 // toolc is pre-registered with a STALE desc ("pre-existing row") that DISAGREES with its schema
67 // ("does C things") -> the seq1526 drift case, which must now be REWRITTEN, not skipped.
68 // toold is pre-registered with a desc that MATCHES its schema -> must be left ALONE. Keeping both
69 // means the update path cannot be satisfied by blindly re-registering everything every run.
70 tg_write("allow.conf" as *u8, "# comment row\ntoola\t/x/toola.elf\tGREEN\ntoolb\t/x/toolb.elf\tGREEN\ntoolc\t/x/toolc.elf\tGREEN\ntoold\t/x/toold.elf\tGREEN\n" as *u8)
71 tg_write("sch.conf" as *u8, "# schemas\ntoola\tTool A\t1\t0\t1\t0\tdoes A things safely\ntoolc\tTool C\t1\t0\t1\t0\tdoes C things\ntoold\tTool D\t1\t0\t1\t0\tdoes D things\n" as *u8)
72 tool_register_pfx(pfx, "toolc" as *u8, "pre-existing row" as *u8, "inv" as *u8, "GREEN" as *u8)
73 tool_register_pfx(pfx, "toold" as *u8, "does D things" as *u8, "inv" as *u8, "GREEN" as *u8)
74 let counts: *i64 = sys_mmap(RR_COUNTS) as *i64
75 let rows: i64 = rr_reconcile(pfx, "allow.conf" as *u8, "sch.conf" as *u8, counts)
76 // T1 examined exactly the 3 non-comment rows
77 tg_check("rows-parsed" as *u8, (rows == TG_FIX_ROWS) as i64, pass)
78 // T2 toola registered (had a schema row)
79 tg_check("missing-with-schema-registered" as *u8, (counts[RR_C_REG] == 1) as i64, pass)
80 // T3 toolb SKIPPED (no schema -- fail-closed)
81 tg_check("no-schema-skipped" as *u8, (counts[RR_C_NOSCHEMA] == 1) as i64, pass)
82 // T4 toolc's stored desc DRIFTED from its author's schema -> REWRITTEN, not silently skipped
83 // (debt seq1526: before this, a corrected description could never reach consumers).
84 tg_check("drifted-desc-updated" as *u8, (counts[RR_C_UPDATED] == 1) as i64, pass)
85 // T4b NEG-CONTROL: toold already MATCHES its schema -> left alone. Without this, "update on
86 // drift" could be satisfied by re-registering every tool on every run (churn, not reconciliation).
87 tg_check("matching-desc-left-alone" as *u8, (counts[RR_C_ALREADY] == 1) as i64, pass)
88 // T5 the registered record carries the AUTHOR'S desc (not invented text)
89 var ok5: i64 = 0
90 let po: *i64 = sys_mmap(TG_PTR) as *i64
91 let lo: *i64 = sys_mmap(TG_PTR) as *i64
92 if tool_get_pfx(pfx, "toola" as *u8, po, lo) == 1 {
93 let rec: *u8 = po[0] as *u8
94 let n: i64 = lo[0]
95 let want: *u8 = "does A things safely" as *u8
96 let wl: i64 = rr_len(want)
97 var i: i64 = 0
98 while i + wl <= n {
99 var m: i64 = 1
100 var j: i64 = 0
101 while j < wl { if rec[i+j] != want[j] { m = 0; j = wl } else { j = j + 1 } }
102 if m == 1 { ok5 = 1; i = n } else { i = i + 1 }
103 }
104 }
105 tg_check("author-desc-carried" as *u8, ok5, pass)
106 // T6 IDEMPOTENT: second pass registers 0, everything already/skipped
107 rr_reconcile(pfx, "allow.conf" as *u8, "sch.conf" as *u8, counts)
108 var ok6: i64 = 0
109 // IDEMPOTENCE now also requires UPDATED==0: once descriptions match, a second pass must rewrite
110 // NOTHING. Without this the update path could churn every tool on every run and still look clean.
111 // ALREADY is 3 (toola registered in pass 1, toolc updated in pass 1, toold matched) -- derived
112 // from the fixture, not a leftover constant.
113 if counts[RR_C_REG] == 0 { if counts[RR_C_UPDATED] == 0 { if counts[RR_C_ALREADY] == 3 { if counts[RR_C_NOSCHEMA] == 1 { ok6 = 1 } } } }
114 tg_check("idempotent-second-pass" as *u8, ok6, pass)
115 // ---- AUDIT MODE (the regression tooth) ----
116 // clean fixture: allow2 = toola+toolc, both have schemas
117 tg_write("allow2.conf" as *u8, "toola\t/x/toola.elf\tGREEN\ntoolc\t/x/toolc.elf\tGREEN\n" as *u8)
118 // T7 DIRTY prefix (nothing registered): audit reports drift=2 AND mutates NOTHING (register-free)
119 var ok7: i64 = 0
120 let po7: *i64 = sys_mmap(TG_PTR) as *i64
121 let lo7: *i64 = sys_mmap(TG_PTR) as *i64
122 let d_dirty: i64 = rr_drift("knowledge/tgd-" as *u8, "allow2.conf" as *u8, "sch.conf" as *u8, counts)
123 if d_dirty == TG_EXP_ALREADY2 { // both would register = drift 2
124 if tool_get_pfx("knowledge/tgd-" as *u8, "toola" as *u8, po7, lo7) == 0 - 1 { ok7 = 1 } // NOT mutated
125 }
126 tg_check("audit-detects-drift-no-mutation" as *u8, ok7, pass)
127 // T8 CLEAN prefix: reconcile allow2, then audit -> drift 0 (every tool contracted+discoverable)
128 rr_reconcile("knowledge/tgc-" as *u8, "allow2.conf" as *u8, "sch.conf" as *u8, counts)
129 let d_clean: i64 = rr_drift("knowledge/tgc-" as *u8, "allow2.conf" as *u8, "sch.conf" as *u8, counts)
130 tg_check("audit-clean-drift-zero" as *u8, (d_clean == 0) as i64, pass)
131 // T9 SELF-HEAL residue naming: allow.conf has toolb with NO schema -> named exactly, count 1
132 let nmbuf: *u8 = sys_mmap(RR_FILE_CAP)
133 let nsc: i64 = rr_no_schema_names(pfx, "allow.conf" as *u8, "sch.conf" as *u8, nmbuf, RR_FILE_CAP)
134 var ok9: i64 = 0
135 if nsc == 1 { if rr_seq(nmbuf, "toolb" as *u8) == 1 { ok9 = 1 } }
136 tg_check("heal-names-no-schema-residue" as *u8, ok9, pass)
137 // T10 fully-contracted allowlist (allow2 = toola+toolc, both have schema) -> ZERO residue (self-healed green)
138 let nsc2: i64 = rr_no_schema_names("knowledge/tgc-" as *u8, "allow2.conf" as *u8, "sch.conf" as *u8, nmbuf, RR_FILE_CAP)
139 tg_check("heal-zero-residue-when-contracted" as *u8, (nsc2 == 0) as i64, pass)
140
141 let hdr: *u8 = "TOOLREG-RECONCILE-GATE pass=" as *u8
142 sys_write(1, hdr, rr_len(hdr))
143 let b: *u8 = sys_mmap(TG_PTR)
144 var bo: i64 = 0
145 bo = tg_num(b, bo, pass[0])
146 b[bo] = TG_SLASH as u8; bo = bo + 1
147 bo = tg_num(b, bo, pass[1])
148 sys_write(1, b, bo)
149 if pass[0] == pass[1] { let g: *u8 = " verdict=GREEN\n" as *u8; sys_write(1, g, rr_len(g)); sys_exit(0); return 0 }
150 let r: *u8 = " verdict=RED\n" as *u8; sys_write(1, r, rr_len(r))
151 sys_exit(1)
152 return 1
153}