nx_comparestale.nx source
↩ module page · 191 lines · 8517 B
1// nx_comparestale.nx -- IS EVERY PUBLISHED COMPARE PAGE STILL TRUE TO ITS SOURCE?
2//
3// WHY THIS EXISTS. /compare/doctor sat a MONTH stale, publishing "THE root blocker: emitted ELFs
4// carry no line mapping" long after that stopped being true -- with a perfectly valid
5// generated_unix. Nothing could see it, because nothing compared the page to the thing it was
6// generated from. A TIMESTAMP TELLS YOU WHEN A PAGE WAS MADE, NEVER WHETHER IT IS CURRENT.
7//
8// HOW. Both generators now stamp "source_hash" = djb2-48 over the .matrix/.sota they read. This
9// organ recomputes that hash from the source on disk and compares it to the published page.
10// Deliberately CLOCK-FREE: mtimes lie across copies (this tree has TWO knowledge/compare
11// directories and I lost an edit to exactly that) and clocks lie across machines. Content does not.
12//
13// VERDICTS, and the distinction is the point:
14// FRESH page hash == source hash
15// STALE page exists and disagrees with its source -> the source of truth moved, publish did not
16// UNPUBLISHED source exists, no page -> never generated, or gate-refused
17// NOSTAMP page predates the provenance stamp -> republish once and it becomes decidable
18// Exit 1 if any STALE. UNPUBLISHED does NOT fail the gate: a domain whose matrix gate legitimately
19// refuses (legal, present>=5) must not be reported as drift -- CONFLATING "REFUSED" WITH "DRIFTED"
20// IS THE SAME DEFECT THIS ESTATE KEEPS PAYING FOR.
21//
22// license_tier: ORIGINAL expect_exit: 0
23import "nx_syscalls.nx"
24const CS_MAGIC_5381: i64 = 5381
25const CS_MAGIC_8192: i64 = 8192
26const CS_MAGIC_1024: i64 = 1024
27const CS_MAGIC_8000: i64 = 8000
28
29const CS_CAP: i64 = 262144
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 }
32func wn(v: i64) -> i64 {
33 var m: i64 = v
34 if m < 0 { w("-" as *u8); m = 0 - m }
35 let t: *u8 = sys_mmap(24)
36 var k: i64 = 0
37 if m == 0 { t[0] = 48 as u8; k = 1 }
38 while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 }
39 let o: *u8 = sys_mmap(24)
40 var i: i64 = 0
41 while i < k { o[i] = t[k-1-i]; i = i + 1 }
42 sys_write(1, o, k)
43 return 0
44}
45func cs_read(path: *u8, buf: *u8, cap: i64) -> i64 {
46 let fd: i64 = sys_openat_rd(path)
47 if fd < 0 { return 0 - 1 }
48 var tot: i64 = 0
49 while tot < cap {
50 let r: i64 = sys_read(fd, (buf as i64 + tot) as *u8, cap - tot)
51 if r <= 0 { break }
52 tot = tot + r
53 }
54 sys_close(fd)
55 return tot
56}
57func cs_cat(dst: *u8, off: i64, s: *u8) -> i64 {
58 var i: i64 = 0
59 while s[i] != (0 as u8) { dst[off+i] = s[i]; i = i + 1 }
60 return off + i
61}
62// MUST match the generators byte for byte. If this ever diverges the organ reports drift that is
63// not there -- a comparator and a writer that disagree on canonical form never converge.
64func cs_hash(b: *u8, n: i64) -> i64 {
65 var h: i64 = CS_MAGIC_5381
66 var i: i64 = 0
67 while i < n { h = h * 33 + (b[i] as i64); i = i + 1 }
68 if h < 0 { h = 0 - h }
69 return h & 0xFFFFFFFFFFFF
70}
71func cs_find(b: *u8, n: i64, pat: *u8) -> i64 {
72 var pl: i64 = 0
73 while pat[pl] != (0 as u8) { pl = pl + 1 }
74 var i: i64 = 0
75 while i + pl <= n {
76 var j: i64 = 0
77 var ok: i64 = 1
78 while j < pl { if b[i+j] != pat[j] { ok = 0; j = pl } else { j = j + 1 } }
79 if ok == 1 { return i }
80 i = i + 1
81 }
82 return 0 - 1
83}
84func cs_int_at(b: *u8, n: i64, off: i64) -> i64 {
85 var i: i64 = off
86 var v: i64 = 0
87 while i < n {
88 let c: i64 = b[i] as i64
89 if c < 48 { break }
90 if c > 57 { break }
91 v = v * 10 + (c - 48)
92 i = i + 1
93 }
94 return v
95}
96
97func main(argc: i64, argv: *i64) -> i64 {
98 if argc>=2{if cd_equal(argv[1] as *u8,"dependency-check")==1{return cd_command(argc,argv)}}
99 var srcd: *u8 = "buildroot/knowledge/compare/" as *u8
100 var docd: *u8 = "sites/nishifamily/compare/" as *u8
101 if argc >= 2 { srcd = argv[1] as *u8 }
102 if argc >= 3 { docd = argv[2] as *u8 }
103
104 let lst: *u8 = sys_mmap(CS_MAGIC_8192)
105 let lp: *u8 = sys_mmap(CS_MAGIC_1024)
106 var lo: i64 = cs_cat(lp, 0, srcd)
107 lo = cs_cat(lp, lo, "regen.list" as *u8)
108 lp[lo] = 0 as u8
109 let ln: i64 = cs_read(lp, lst, CS_MAGIC_8000)
110 if ln <= 0 { w("FAIL: cannot read " as *u8); w(lp); w("\n" as *u8); sys_exit(2); return 2 }
111
112 let sbuf: *u8 = sys_mmap(CS_CAP)
113 let pbuf: *u8 = sys_mmap(CS_CAP)
114 let path: *u8 = sys_mmap(CS_MAGIC_1024)
115 var fresh: i64 = 0
116 var stale: i64 = 0
117 var unpub: i64 = 0
118 var nostamp: i64 = 0
119
120 w("=== NX-COMPARESTALE -- does each published page still match the source it came from? ===\n" as *u8)
121 var p: i64 = 0
122 while p < ln {
123 var e: i64 = p
124 while e < ln { if lst[e] == (10 as u8) { break } e = e + 1 }
125 lst[e] = 0 as u8
126 let dom: *u8 = (lst as i64 + p) as *u8
127 p = e + 1
128 if dom[0] != (0 as u8) {
129 if dom[0] != (35 as u8) {
130 // WHICH SOURCE DID THIS PAGE COME FROM? THE PAGE SAYS. WE DO NOT INFER.
131 // This organ first guessed ".matrix, else .sota". llm and lang each have BOTH, and both
132 // are published from their .sota -- so the guess hashed the wrong file and reported two
133 // perfectly current pages as STALE. AN ARTEFACT MUST DECLARE ITS OWN PROVENANCE; A
134 // CONSUMER THAT INFERS IT IS GUESSING, AND A GUESS THAT IS RIGHT 44 TIMES IN 46 STILL
135 // LIES TWICE -- and lies in the direction of a false alarm, which is the expensive one.
136 var o: i64 = cs_cat(path, 0, docd); o = cs_cat(path, o, dom); o = cs_cat(path, o, "/api.json" as *u8); path[o] = 0 as u8
137 let pn: i64 = cs_read(path, pbuf, CS_CAP)
138 if pn <= 0 {
139 unpub = unpub + 1
140 w(" UNPUBLISHED " as *u8); w(dom); w("\n" as *u8)
141 } else {
142 let sf: i64 = cs_find(pbuf, pn, "\"source_file\":\"" as *u8)
143 let ha: i64 = cs_find(pbuf, pn, "\"source_hash\":" as *u8)
144 if sf < 0 {
145 nostamp = nostamp + 1
146 w(" NOSTAMP " as *u8); w(dom); w(" (no source_file stamp -- republish once and it becomes decidable)\n" as *u8)
147 } else { if ha < 0 {
148 nostamp = nostamp + 1
149 w(" NOSTAMP " as *u8); w(dom); w(" (no source_hash stamp -- republish once)\n" as *u8)
150 } else {
151 // lift the declared basename straight out of the page
152 var bo: i64 = cs_cat(path, 0, srcd)
153 var i: i64 = sf + 15
154 while i < pn { if pbuf[i] == (34 as u8) { break } path[bo] = pbuf[i]; bo = bo + 1; i = i + 1 }
155 path[bo] = 0 as u8
156 let sn: i64 = cs_read(path, sbuf, CS_CAP)
157 if sn <= 0 {
158 // The page names a source that is not there. That is a REAL defect -- either the
159 // source was deleted out from under a live page or the stamp is wrong -- so it
160 // must fail, and it must not be silently folded into "stale".
161 stale = stale + 1
162 w(" MISSINGSRC " as *u8); w(dom); w(" page names a source that does not exist: " as *u8); w(path); w("\n" as *u8)
163 } else {
164 let want: i64 = cs_hash(sbuf, sn)
165 let got: i64 = cs_int_at(pbuf, pn, ha + 14)
166 if got == want { fresh = fresh + 1 } else {
167 stale = stale + 1
168 w(" STALE " as *u8); w(dom)
169 w(" page=" as *u8); wn(got)
170 w(" source=" as *u8); wn(want)
171 w(" src=" as *u8); w(path)
172 w("\n" as *u8)
173 }
174 }
175 } }
176 }
177 } }
178 }
179 w("COMPARESTALE fresh=" as *u8); wn(fresh)
180 w(" stale=" as *u8); wn(stale)
181 w(" unpublished=" as *u8); wn(unpub)
182 w(" nostamp=" as *u8); wn(nostamp)
183 if stale > 0 {
184 w(" verdict=STALE (a published page no longer matches its source -- rerun nishi_compare_regen)\n" as *u8)
185 sys_exit(1)
186 return 1
187 }
188 w(" verdict=GREEN (every published page matches the source it was generated from)\n" as *u8)
189 return 0
190}
191import "nx_comparestale_lib.nx"