nx_quality_gate.nx source
↩ module page · 160 lines · 6086 B
1// nx_quality_gate.nx -- substrate-native shipped/incomplete classifier.
2//
3// Per user oversight directive 2026-05-14 (gap #6): a substrate
4// primitive is "shipped" only if it has BOTH a curated card AND an
5// audit-journal entry. Anything missing either is "incomplete".
6//
7// Reads three inputs (caller writes them under nxc2/_offc/):
8// - quality_modules.txt : module names, one per line
9// - algorithm_cards.jsonl : the curated cards file
10// - quality_journal.jsonl : concatenated audit journal(s)
11//
12// Outputs to stdout:
13// shipped: <n>
14// with_card: <n>
15// with_journ: <n>
16// incomplete: <n>
17//
18// Plus stderr-style listings of which modules are missing what.
19// Cardinal-aligned: no magic numbers; bounded by NX_QG_MAX_MODULES.
20//
21// genealogy_id: substrate_oversight_quality_gate_2026_05_14
22// lineage_id: shipped_classifier
23
24// nx_safety_envelope:
25// intended_use: AUTO_APPLIED -- primitive-specific tuning queued
26// sil_target: SIL1
27// evidence: [bulk_applied_2026-05-16, see-file-comment-for-detail]
28// verdict: NOT_YET_EVALUATED
29
30import "nx_syscalls.nx"
31import "nx_runtime.nx"
32import "nx_tier.nx"
33import "nx_str.nx"
34
35const NX_QG_MAX_MODULES: nx_int = 4096
36const NX_QG_NAME_LEN: nx_size = 128
37const NX_QG_NEEDLE_LEN: nx_size = 160 // "\"module\":\"<name>\"" or "\"" + name + "\""
38
39// Naive but fine substring search for the volumes here (~MB scale).
40func nx_qg_substr_in(haystack: *u8, hay_n: nx_int, needle: *u8, n_n: nx_int) -> nx_int {
41 if n_n == 0 { return 1 }
42 if hay_n < n_n { return 0 }
43 let last: nx_int = hay_n - n_n
44 var i: nx_int = 0
45 while i <= last {
46 var j: nx_int = 0
47 var miss: nx_int = 0
48 while miss == 0 {
49 if j >= n_n { miss = 2 } // 2 = matched
50 if miss == 0 {
51 if haystack[i + j] != needle[j] { miss = 1 }
52 if miss == 0 { j = j + 1 }
53 }
54 }
55 if miss == 2 { return 1 }
56 i = i + 1
57 }
58 return 0
59}
60
61func main() -> nx_exit {
62 // ----- read inputs -----
63 let mod_len_p: *nx_size = (sys_mmap(NX_SIZEOF_NX_SIZE)) as *nx_size
64 let card_len_p: *nx_size = (sys_mmap(NX_SIZEOF_NX_SIZE)) as *nx_size
65 let jour_len_p: *nx_size = (sys_mmap(NX_SIZEOF_NX_SIZE)) as *nx_size
66 mod_len_p[0] = 0
67 card_len_p[0] = 0
68 jour_len_p[0] = 0
69
70 let mods: *u8 = sys_read_file("nxc2/_offc/quality_modules.txt" as *u8, mod_len_p)
71 let cards: *u8 = sys_read_file("nxc2/specs/algorithm_cards.jsonl" as *u8, card_len_p)
72 let jour: *u8 = sys_read_file("nxc2/_offc/quality_journal.jsonl" as *u8, jour_len_p)
73
74 if (mods as nx_size) == 0 {
75 sys_write(NX_FD_STDOUT, "nx_quality_gate: cannot read module list\n" as *u8, 41)
76 return 1
77 }
78
79 let mods_n: nx_int = mod_len_p[0] as nx_int
80 var cards_n: nx_int = 0
81 if (cards as nx_size) != 0 { cards_n = card_len_p[0] as nx_int }
82 var jour_n: nx_int = 0
83 if (jour as nx_size) != 0 { jour_n = jour_len_p[0] as nx_int }
84
85 var n_total: nx_int = 0
86 var n_with_card: nx_int = 0
87 var n_with_journal: nx_int = 0
88 var n_shipped: nx_int = 0
89
90 let needle_card: *u8 = sys_mmap(NX_QG_NEEDLE_LEN)
91 let needle_jour: *u8 = sys_mmap(NX_QG_NEEDLE_LEN)
92 let name_buf: *u8 = sys_mmap(NX_QG_NAME_LEN)
93
94 var pos: nx_int = 0
95 while pos < mods_n {
96 // Read one name (up to newline or EOF)
97 var eol: nx_int = pos
98 var done: nx_int = 0
99 while done == 0 {
100 if eol >= mods_n { done = 1 }
101 if done == 0 {
102 if mods[eol] == 10 { done = 1 }
103 if done == 0 { eol = eol + 1 }
104 }
105 }
106 let name_len: nx_int = eol - pos
107 if name_len > 0 {
108 // Trim trailing CR if present.
109 var nl: nx_int = name_len
110 if nl > 0 { if mods[pos + nl - 1] == 13 { nl = nl - 1 } }
111
112 if nl > 0 {
113 if nl < (NX_QG_NAME_LEN as nx_int) {
114 var i: nx_int = 0
115 while i < nl { name_buf[i] = mods[pos + i]; i = i + 1 }
116 name_buf[nl] = 0
117
118 n_total = n_total + 1
119
120 // Build needle for card: just the module name in quotes.
121 needle_card[0] = 34 // '"'
122 var k: nx_int = 0
123 while k < nl { needle_card[1 + k] = name_buf[k]; k = k + 1 }
124 needle_card[1 + nl] = 34 // '"'
125 needle_card[2 + nl] = 0
126
127 // Build needle for journal: "module":"<name>"
128 let prefix: *u8 = "\"module\":\"" as *u8
129 var pk: nx_int = 0
130 while prefix[pk] != 0 { needle_jour[pk] = prefix[pk]; pk = pk + 1 }
131 var k2: nx_int = 0
132 while k2 < nl { needle_jour[pk + k2] = name_buf[k2]; k2 = k2 + 1 }
133 needle_jour[pk + nl] = 34 // '"'
134 needle_jour[pk + nl + 1] = 0
135
136 let has_card: nx_int = nx_qg_substr_in(cards, cards_n, needle_card, nl + 2)
137 let has_jour: nx_int = nx_qg_substr_in(jour, jour_n, needle_jour, pk + nl + 1)
138
139 if has_card == 1 { n_with_card = n_with_card + 1 }
140 if has_jour == 1 { n_with_journal = n_with_journal + 1 }
141 if has_card == 1 { if has_jour == 1 { n_shipped = n_shipped + 1 } }
142 }
143 }
144 }
145 pos = eol + 1
146 }
147
148 sys_write(NX_FD_STDOUT, "quality_gate.total=" as *u8, 19)
149 print_i64(n_total as i64)
150 sys_write(NX_FD_STDOUT, "\nquality_gate.with_card=" as *u8, 24)
151 print_i64(n_with_card as i64)
152 sys_write(NX_FD_STDOUT, "\nquality_gate.with_journal=" as *u8, 27)
153 print_i64(n_with_journal as i64)
154 sys_write(NX_FD_STDOUT, "\nquality_gate.shipped=" as *u8, 22)
155 print_i64(n_shipped as i64)
156 sys_write(NX_FD_STDOUT, "\nquality_gate.incomplete=" as *u8, 25)
157 print_i64((n_total - n_shipped) as i64)
158 sys_write(NX_FD_STDOUT, "\n" as *u8, 1)
159 return 0
160}