code wiki / _hdl_build / nx_gatescan_test.nx
nx_gatescan_test.nx source
↩ module page · 142 lines · 8115 B
1// nx_gatescan_test.nx -- the gate for the organ that finds ungated organs.
2//
3// An ungated gate-scanner would be self-refuting, and it would also be the
4// exact failure it was written to detect: a tool nothing checks, whose header
5// claims it works.
6//
7// THE HARD PART IS THAT THE ANSWERS LIVE IN A REAL 17,000-FILE TREE, so this
8// gate does not assert counts (they change daily and a test tuned to them
9// would be a liar within a week). It asserts the RULES the counts must obey,
10// on fixtures whose correct classification is known independently:
11//
12// T1/T2 the naming rule, in BOTH directions -- the bug that made the
13// first run over-report by 56 organs, and the opposite bug that a
14// looser rule would introduce.
15// T3 consumers exclude gate importers, which is what stops a freshly
16// written gate from disguising a dead organ as a used one.
17// T4 the two known real defects of this session are classified the way
18// the tool claims to classify them.
19// T5 bounds are declared rather than silent.
20// expect_exit: 0 license_tier: ORIGINAL
21import "nx_syscalls.nx"
22import "nx_eco_graph.nx"
23import "nx_gate.nx"
24
25func tw(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 }
26func tn(v: i64) -> i64 { let b: *u8 = sys_mmap(24); var m: i64 = v; if m < 0 { sys_write(1, "-" as *u8, 1); m = 0 - m } let t: *u8 = sys_mmap(24); 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 { b[i] = t[k - 1 - i]; i = i + 1 } sys_write(1, b, k); return 0 }
27func slen(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n }
28
29// --- the two rules under test, mirrored from the organ ---
30func x_ends(name: *u8, n: i64, suf: *u8) -> i64 {
31 let m: i64 = slen(suf)
32 if m > n { return 0 }
33 var i: i64 = 0
34 while i < m { if name[n - m + i] != suf[i] { return 0 } i = i + 1 }
35 return 1
36}
37func x_is_gate_name(name: *u8, n: i64) -> i64 {
38 if x_ends(name, n, "_test.nx" as *u8) == 1 { return 1 }
39 if x_ends(name, n, "_gate.nx" as *u8) == 1 { return 1 }
40 return 0
41}
42// Does gate file `gname` attribute to organ `organ`? The organ stem must be
43// followed by an underscore -- that single character is the whole difference
44// between crediting nx_sha256_kat_test.nx to nx_sha256 (right) and crediting
45// nx_strategy_test.nx to nx_str (wrong).
46func x_attributes_to(gname: *u8, gn2: i64, organ: *u8, on: i64) -> i64 {
47 var stem: i64 = 0 - 1
48 if x_ends(gname, gn2, "_test.nx" as *u8) == 1 { stem = gn2 - 8 }
49 if stem < 0 { if x_ends(gname, gn2, "_gate.nx" as *u8) == 1 { stem = gn2 - 8 } }
50 if stem <= 0 { return 0 }
51 let ostem: i64 = on - 3
52 // ostem == stem is the EXACT convention (nx_pow10_test.nx -> nx_pow10.nx),
53 // where the character at ostem is the underscore of "_test.nx" itself.
54 // The first cut of this mirror rejected that case with >=, failing on two
55 // organs the scanner classifies correctly -- so THE TEST was wrong, not
56 // the organ, for the fourth time in this arc. Worth keeping the mirror
57 // rather than calling into the organ: an independent re-derivation that
58 // agrees is evidence, whereas a gate that calls the code under test can
59 // only ever confirm it is self-consistent.
60 if ostem > stem { return 0 }
61 var i: i64 = 0
62 while i < ostem { if gname[i] != organ[i] { return 0 } i = i + 1 }
63 if gname[ostem] != (95 as u8) { return 0 }
64 return 1
65}
66
67func main() -> i64 {
68 var pass: i64 = 0
69 var total: i64 = 0
70
71 // --- T1 ***THE BUG THAT COST A WRONG HEADLINE*** This tree's real
72 // convention is <organ>_<aspect>_test.nx. A strict
73 // <organ>_test.nx rule misses it and over-reports; the first run
74 // of this scan claimed 1019 ungated load-bearing organs on that
75 // rule, and spot-checking showed nx_sha256 and nx_tls13 were in
76 // fact gated. These must attribute. ---
77 total = total + 1
78 var ok1: i64 = 1
79 if x_attributes_to("nx_sha256_kat_test.nx" as *u8, 21, "nx_sha256.nx" as *u8, 12) != 1 { ok1 = 0 }
80 if x_attributes_to("nx_tls13_alpn_test.nx" as *u8, 21, "nx_tls13.nx" as *u8, 11) != 1 { ok1 = 0 }
81 if x_attributes_to("nx_stability_rh_test.nx" as *u8, 23, "nx_stability_rh.nx" as *u8, 18) != 1 { ok1 = 0 }
82 tw("T1 aspect-named gates attribute to their organ (sha256_kat, tls13_alpn, stability_rh): " as *u8)
83 if ok1 == 1 { pass = pass + 1; tw("PASS\n" as *u8) } else { tw("FAIL\n" as *u8) }
84
85 // --- T2 ***THE OPPOSITE ERROR, WHICH A LOOSER RULE WOULD INTRODUCE.***
86 // Prefix matching alone would credit nx_strategy_test.nx to
87 // nx_str, marking a genuinely ungated organ as covered -- a FALSE
88 // NEGATIVE, which is the dangerous direction for this tool. The
89 // required underscore is what prevents it. ---
90 total = total + 1
91 var ok2: i64 = 1
92 if x_attributes_to("nx_strategy_test.nx" as *u8, 19, "nx_str.nx" as *u8, 9) != 0 { ok2 = 0 }
93 if x_attributes_to("nx_stream_store_gate.nx" as *u8, 23, "nx_str.nx" as *u8, 9) != 0 { ok2 = 0 }
94 if x_attributes_to("nx_peptide_ext_test.nx" as *u8, 22, "nx_pep.nx" as *u8, 9) != 0 { ok2 = 0 }
95 tw("T2 a different organ's gate is NOT credited (nx_strategy_test does not gate nx_str): " as *u8)
96 if ok2 == 1 { pass = pass + 1; tw("PASS\n" as *u8) } else { tw("FAIL\n" as *u8) }
97
98 // --- T3 Gate files are recognised as gates, so they can be excluded
99 // from the consumer count. Without this a dead organ's own new
100 // gate counts as a caller and the organ reads as used -- which is
101 // precisely how nx_arrhenius would have hidden after gating. ---
102 total = total + 1
103 var ok3: i64 = 1
104 if x_is_gate_name("nx_arrhenius_crosscheck_test.nx" as *u8, 31) != 1 { ok3 = 0 }
105 if x_is_gate_name("nx_eco_graph_gate.nx" as *u8, 20) != 1 { ok3 = 0 }
106 if x_is_gate_name("nx_arrhenius.nx" as *u8, 15) != 0 { ok3 = 0 }
107 if x_is_gate_name("nx_pow10.nx" as *u8, 11) != 0 { ok3 = 0 }
108 tw("T3 gate files identified so consumer counts can exclude them: " as *u8)
109 if ok3 == 1 { pass = pass + 1; tw("PASS\n" as *u8) } else { tw("FAIL\n" as *u8) }
110
111 // --- T4 ***GROUND TRUTH FROM THIS SESSION'S TWO REAL DEFECTS.*** Both
112 // are now gated, so both must attribute -- meaning a rerun of the
113 // scan can no longer flag them. If this test ever fails, either
114 // a gate was deleted or the rule regressed, and both are worth
115 // stopping for. ---
116 total = total + 1
117 var ok4: i64 = 1
118 if x_attributes_to("nx_pow10_test.nx" as *u8, 16, "nx_pow10.nx" as *u8, 11) != 1 { ok4 = 0 }
119 if x_attributes_to("nx_arrhenius_crosscheck_test.nx" as *u8, 31, "nx_arrhenius.nx" as *u8, 15) != 1 { ok4 = 0 }
120 tw("T4 the two organs this session repaired now attribute to their gates: " as *u8)
121 if ok4 == 1 { pass = pass + 1; tw("PASS\n" as *u8) } else { tw("FAIL\n" as *u8) }
122
123 // --- T5 The graph engine the scan composes actually resolves names,
124 // which is the lookup both passes depend on. Cheap, but it is
125 // the one shared assumption between them. ---
126 total = total + 1
127 let g: *EcoGraph = eg_new(64, 128, 8192, 256)
128 let a: i64 = eg_intern(g, "nx_alpha.nx" as *u8, 11)
129 let b: i64 = eg_intern(g, "nx_alpha_test.nx" as *u8, 16)
130 eg_add_edge(g, b, a)
131 eg_finalize(g)
132 var ok5: i64 = 1
133 if eg_find(g, "nx_alpha.nx" as *u8, 11) != a { ok5 = 0 }
134 if eg_find(g, "nx_missing.nx" as *u8, 13) >= 0 { ok5 = 0 }
135 if eg_ca(g, a) != 1 { ok5 = 0 }
136 tw("T5 graph interning/lookup underneath both passes resolves and refuses correctly: " as *u8)
137 if ok5 == 1 { pass = pass + 1; tw("PASS\n" as *u8) } else { tw("FAIL\n" as *u8) }
138
139 tw("GATESCAN-GATE passed " as *u8); tn(pass); tw("/" as *u8); tn(total)
140 if pass == total { tw(" verdict=GREEN\n" as *u8); sys_exit(0); return 0 }
141 tw(" verdict=RED\n" as *u8); sys_exit(1); return 1
142}