code wiki / _hdl_build / nx_evindep_gate.nx
nx_evindep_gate.nx source
↩ module page · 240 lines · 12353 B
1// nx_evindep_gate.nx -- THE INDEPENDENCE AXIS, LIVE ON THE BOARD THAT JUDGES CLAIMS.
2//
3// The independence law (nx_evoracle) was live on the NAS but nothing CONSUMED it, so no claim's standing
4// changed. A capability that beats the baseline in a gate but is not wired at the live chokepoint IS the
5// baseline -- this ecosystem has paid for that law four times. This organ is the consumer.
6//
7// WHAT IT ANSWERS, per compare domain that declares executable evidence:
8// does ANY of its declared gates rest on an authority OUTSIDE this ecosystem?
9// It reads <domain>.gates, takes the 4th field (the declared SUBJECT SOURCE), and classifies that subject's
10// party-ness with evo_classify. THIRD => the domain has at least one externally-anchored gate. FIRST or
11// UNRESOLVED => every gate it declares is graded against answers we wrote ourselves.
12//
13// ★DELIBERATELY A SEPARATE ORGAN FROM nx_sota_status (rule 9). nx_sota_status feeds deploy check #12, and a
14// sibling is landing a change that makes POST /api/deploy REFUSE on RED. Adding an axis there could flip a
15// domain and stop every deploy in the ecosystem the hour it shipped. This reports; it never convicts.
16// ★AND IT IS GENUINELY A READ-ONLY VERIFIER, which is why running it through /api/gate_run is honest --
17// that route executes verifiers only, and that bound is what makes it never-brick. My row-DERIVING organ
18// (nx_evoracle_sweep) writes a file and is correctly refused by that same route; I did not rename it to
19// slip past the bound.
20//
21// ★SELF-CHECK TEETH FIRST (T1/T2). A census that silently finds nothing reads exactly like a corpus that
22// contains nothing -- the single most repeated failure in this ecosystem. So before reporting anything the
23// organ proves its classifier still separates a known third-party header from a known first-party one, and
24// FAILS RED if it cannot. An instrument must prove itself before it grades a corpus.
25// ⚠A domain whose .gates file is absent is reported NO-GATES, never skipped: a domain we could not measure
26// and a domain with no external anchor must never look the same.
27// license_tier: ORIGINAL expect_exit: 0
28import "nx_syscalls.nx"
29import "nx_evoracle.nx"
30
31func w(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 }
32
33func nn(v: i64) -> i64 {
34 var m: i64 = v
35 if m < 0 { w("-" as *u8); m = 0 - m }
36 let t: *u8 = sys_mmap(32)
37 var k: i64 = 0
38 if m == 0 { t[0] = 48 as u8; k = 1 }
39 while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 }
40 let b: *u8 = sys_mmap(32)
41 var j: i64 = 0
42 while j < k { b[j] = t[k - 1 - j]; j = j + 1 }
43 sys_write(1, b, k)
44 return 0
45}
46
47func slen(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n }
48
49func bcat(buf: *u8, at: i64, s: *u8) -> i64 {
50 var i: i64 = 0
51 while s[i] != (0 as u8) { buf[at + i] = s[i]; i = i + 1 }
52 return at + i
53}
54
55// Resolve a declared subject path against the roots this host actually uses. Tried as written first, then
56// under buildroot/. Returns the length loaded, 0 if unresolvable. An eager resolver is a WORSE bug than a
57// blind one -- it would ground a claim against whatever file it happened to land on -- so this only ever
58// tries two EXACT candidates and never guesses a basename.
59func load_subject(rel: *u8, rl: i64, lp: *i64) -> *u8 {
60 let p1: *u8 = sys_mmap(512)
61 var i: i64 = 0
62 while i < rl { p1[i] = rel[i]; i = i + 1 }
63 p1[rl] = 0 as u8
64 lp[0] = 0
65 let b1: *u8 = sys_read_file(p1, lp)
66 if lp[0] > 0 { return b1 }
67 let p2: *u8 = sys_mmap(512)
68 var o: i64 = bcat(p2, 0, "buildroot/" as *u8)
69 i = 0
70 while i < rl { p2[o + i] = rel[i]; i = i + 1 }
71 p2[o + rl] = 0 as u8
72 lp[0] = 0
73 let b2: *u8 = sys_read_file(p2, lp)
74 if lp[0] > 0 { return b2 }
75 lp[0] = 0
76 return p1
77}
78
79// c[0]=domains with a THIRD anchor c[1]=domains with gates but NO third anchor c[2]=NO-GATES
80// c[3]=gates rows seen c[4]=rows with a THIRD subject c[5]=rows whose subject would not resolve
81func domain(c: *i64, dom: *u8) -> i64 {
82 let path: *u8 = sys_mmap(512)
83 var o: i64 = bcat(path, 0, "knowledge/compare/" as *u8)
84 o = bcat(path, o, dom)
85 o = bcat(path, o, ".gates" as *u8)
86 path[o] = 0 as u8
87
88 let lp: *i64 = sys_mmap(16) as *i64
89 lp[0] = 0
90 let b: *u8 = sys_read_file(path, lp)
91 if lp[0] <= 0 {
92 c[2] = c[2] + 1
93 w(" NO-GATES " as *u8); w(dom); w(" (no executable evidence declared -- not measurable here)\n" as *u8)
94 return 0
95 }
96
97 var rows: i64 = 0
98 var third: i64 = 0
99 var unres: i64 = 0
100 // NO-SUBJECT-DECLARED is a DIFFERENT finding from SUBJECT-WONT-RESOLVE and must never share a counter.
101 // Measured 2026-07-31: finance.gates declares `<elf>|<argv|->|<label>` -- THREE fields. The 4th field
102 // (subject source) is an additive extension those domains were never migrated to. My first cut called
103 // all 26 of them `unresolved`, which named the artifact-root class and sent the reader hunting a roots
104 // table that would have fixed nothing. The two demand OPPOSITE work: no-subject needs a DECLARATION
105 // (nx_subject_infer derives it; never guess -- a wrong subject slanders a working gate), wont-resolve
106 // needs a ROOTS fix. A diagnostic that misnames the defect IS the defect.
107 var nosub: i64 = 0
108 var ls: i64 = 0
109 var p: i64 = 0
110 while p <= lp[0] {
111 var eol: i64 = 0
112 if p == lp[0] { eol = 1 } else { if b[p] == (10 as u8) { eol = 1 } }
113 if eol == 1 {
114 if p > ls {
115 if b[ls] != (35 as u8) {
116 rows = rows + 1
117 // 4th pipe-separated field = the declared subject source
118 var bars: i64 = 0
119 var q: i64 = ls
120 var sstart: i64 = 0 - 1
121 while q < p {
122 if b[q] == (124 as u8) {
123 bars = bars + 1
124 if bars == 3 { sstart = q + 1 }
125 }
126 q = q + 1
127 }
128 if sstart < 0 { nosub = nosub + 1 }
129 else {
130 var send: i64 = sstart
131 while send < p { if b[send] == (124 as u8) { send = p } else { send = send + 1 } }
132 let sl: i64 = send - sstart
133 if sl <= 0 { nosub = nosub + 1 }
134 else {
135 let sp: i64 = (b as i64) + sstart
136 let slp: *i64 = sys_mmap(16) as *i64
137 let sb: *u8 = load_subject(sp as *u8, sl, slp)
138 if slp[0] <= 0 { unres = unres + 1 }
139 else {
140 if evo_classify(sb, slp[0]) == EVO_P_THIRD {
141 third = third + 1
142 // NEVER SUMMED: a VALIDATED row is graded against answers published
143 // outside; a SPECIFIED row implements an external rule but is tested
144 // with cases we chose. Reporting one mixed total reads as validation.
145 if evo_validation_tier(sb, slp[0]) == EVO_V_VALIDATED { c[7] = c[7] + 1 }
146 else { c[8] = c[8] + 1 }
147 }
148 }
149 }
150 }
151 }
152 }
153 ls = p + 1
154 }
155 p = p + 1
156 }
157
158 c[3] = c[3] + rows
159 c[4] = c[4] + third
160 c[5] = c[5] + unres
161 c[6] = c[6] + nosub
162 if third > 0 {
163 c[0] = c[0] + 1
164 w(" THIRD-ANCHOR " as *u8); w(dom); w(" gates=" as *u8); nn(rows)
165 w(" externally-anchored=" as *u8); nn(third); w("\n" as *u8)
166 return 0
167 }
168 c[1] = c[1] + 1
169 w(" self-graded " as *u8); w(dom); w(" gates=" as *u8); nn(rows)
170 w(" externally-anchored=0 no-subject-declared=" as *u8); nn(nosub)
171 w(" subject-wont-resolve=" as *u8); nn(unres); w("\n" as *u8)
172 return 0
173}
174
175func main() -> i64 {
176 w("nx_evindep_gate -- THE INDEPENDENCE AXIS over the compare corpus\n" as *u8)
177
178 // ---- SELF-CHECK: prove the instrument before grading the corpus ----
179 let k3: *u8 = "standing KAT for X25519 (RFC 7748), OpenSSL-verified\x00" as *u8
180 let k1: *u8 = "all 256 bytes vs inlined ground truth. func gt_ws(c: i64)\x00" as *u8
181 var self_ok: i64 = 0
182 if evo_classify(k3, slen(k3)) == EVO_P_THIRD {
183 if evo_classify(k1, slen(k1)) == EVO_P_FIRST { self_ok = 1 }
184 }
185 if self_ok == 1 { w(" T1/T2 self-check: classifier separates THIRD from FIRST -- PASS\n\n" as *u8) }
186 else {
187 w(" T1/T2 self-check FAILED -- the instrument is broken; refusing to grade the corpus\n" as *u8)
188 w("nx_evindep_gate: verdict=RED\n" as *u8)
189 return 1
190 }
191
192 let c: *i64 = sys_mmap(128) as *i64
193 var z: i64 = 0
194 while z < 10 { c[z] = 0; z = z + 1 }
195
196 domain(c, "authz\x00" as *u8)
197 domain(c, "warden\x00" as *u8)
198 domain(c, "surveys\x00" as *u8)
199 domain(c, "librarian\x00" as *u8)
200 domain(c, "medbilling\x00" as *u8)
201 domain(c, "projectmgmt\x00" as *u8)
202 domain(c, "ecosysdesign\x00" as *u8)
203 domain(c, "toolchain-syscall-abi\x00" as *u8)
204 domain(c, "finance\x00" as *u8)
205 domain(c, "videocodec\x00" as *u8)
206 // ADDED after ENUMERATING instead of assuming: `glob *.gates knowledge/compare` returns TWELVE files,
207 // not the ten I hardcoded. I had missed legal, deploy and media entirely -- so my first two runs
208 // reported a census over a denominator I had chosen rather than measured. CHECK THE DENOMINATOR BEFORE
209 // SIZING THE WORK is a banked law of this very lane, and I broke it inside the instrument built to
210 // audit exactly this class. toolchain-syscall-abi is KEPT deliberately: it has no .gates and reporting
211 // it as NO-GATES is information, not noise.
212 domain(c, "legal\x00" as *u8)
213 domain(c, "deploy\x00" as *u8)
214 domain(c, "media\x00" as *u8)
215
216 w("\n-- INDEPENDENCE OF THE EVIDENCE (not its quantity) --\n" as *u8)
217 w(" domains with >=1 EXTERNALLY-ANCHORED gate : " as *u8); nn(c[0]); w("\n" as *u8)
218 w(" domains whose gates are ALL self-graded : " as *u8); nn(c[1]); w("\n" as *u8)
219 w(" domains declaring NO executable evidence : " as *u8); nn(c[2]); w("\n" as *u8)
220 w(" declared gate rows seen : " as *u8); nn(c[3]); w("\n" as *u8)
221 w(" rows with a THIRD-party subject : " as *u8); nn(c[4]); w("\n" as *u8)
222 w(" rows with NO SUBJECT DECLARED (3-field) : " as *u8); nn(c[6]); w(" <- needs a DECLARATION\n" as *u8)
223 w(" rows whose declared subject won't resolve : " as *u8); nn(c[5]); w(" <- needs a ROOTS fix\n" as *u8)
224 let gradable: i64 = c[3] - c[5] - c[6]
225 w(" GRADABLE rows (subject present+readable) : " as *u8); nn(gradable); w("\n" as *u8)
226 w(" ** of those gradable, THIRD-party : " as *u8); nn(c[4])
227 w(" -- not third/total\n" as *u8)
228 w(" of which VALIDATED (graded against externally-published answers) : " as *u8); nn(c[7]); w("\n" as *u8)
229 w(" of which SPECIFIED (external RULE, but OUR test cases) : " as *u8); nn(c[8]); w("\n" as *u8)
230 w(" ** VALIDATED IS THE ONLY TRUE THIRD-PARTY NUMBER. Do not sum it with SPECIFIED: a mixed\n" as *u8)
231 w(" total reads as validation and is not. A framework we merely DESIGNED TOWARD (EDRM,\n" as *u8)
232 w(" 'TigerBeetle is the reference design') counts as NEITHER -- that is influence, not evidence.\n" as *u8)
233 w("\nSELF-GRADED IS NOT WORTHLESS -- it is a consistency test. It cannot detect an error we and it\n" as *u8)
234 w("share. Only the externally-anchored column is evidence that something OUTSIDE this ecosystem\n" as *u8)
235 w("agrees with us. An unresolved subject is UNMEASURED and is counted apart from both, so a domain\n" as *u8)
236 w("we could not grade can never be mistaken for one that has no external anchor.\n" as *u8)
237 w("\nnx_evindep_gate: verdict=GREEN (census reports; it never convicts -- unmet independence costs a\n" as *u8)
238 w("domain PROVEN, never RED, so this axis can never brick a deploy)\n" as *u8)
239 return 0
240}