nx_deploycover_gate.nx source
↩ module page · 269 lines · 12815 B
1// nx_deploycover_gate.nx -- WHAT FRACTION OF THE RUNNING FLEET CAN ACTUALLY BE DEPLOYED?
2//
3// THE QUESTION NOTHING ELSE ASKS. The ecosystem has gates for whether an organ WORKS, and a control
4// plane for BUILDING and DEPLOYING one. Nothing measures whether the deploy plane COVERS the fleet --
5// so a service can run for months with no sanctioned way to update it, and nothing says a word.
6//
7// MEASURED 2026-07-31 on this host: 15 services running, 9 rows in deploy_targets.conf. A fix to one of
8// the uncovered 6+ CANNOT BE LANDED over the API at all. That is the structural root of the recurring
9// SOURCE-EDITED-BUT-NOT-DEPLOYED state seen across three lanes today: not discipline, COVERAGE.
10// Worse, /api/inventory ADVERTISES nx_hub_gw.elf and nx_torrent_gw.elf as managed deployables while
11// deploy_targets.conf -- the allowlist /api/deploy actually reads -- contains neither. The declared
12// coverage and the real coverage disagree, and only the smaller one is true.
13//
14// BOTH DIRECTIONS, deliberately (this is the fleet-drift discipline: manifest-to-reality AND
15// reality-to-manifest):
16// RUNNING-NOT-DEPLOYABLE -- a live service with no sanctioned update path. The dangerous direction:
17// its fixes must go around the health-checked, auto-rollback deploy path.
18// DEPLOYABLE-NOT-RUNNING -- an allowlist row for something not up. Usually benign (oneshots,
19// toolchain), but a row pointing at nothing is also how an allowlist rots.
20//
21// ADVISORY BY DESIGN (exit 0 unless the SCAN fails). A low coverage number is a backlog, not a reason
22// to fail every build. What DOES fail: reading zero rows or zero services, because an instrument that
23// measured nothing must never render as a clean fleet.
24//
25// license_tier: ORIGINAL No hw writes (Rule 26). expect_exit: 0
26import "nx_syscalls.nx"
27
28const DC_MAXN: i64 = 256
29const DC_LOG: *u8 = "knowledge/status/deploycover_gate.log"
30const DC_MODE: i64 = 420
31const DC_NAMELEN: i64 = 64
32
33func dc_len(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n }
34func dc_p(s: *u8) -> i64 { let n: i64 = dc_len(s); sys_write(1, s, n); return 0 }
35func dc_wf(fd: i64, s: *u8) -> i64 { let n: i64 = dc_len(s); sys_write(fd, s, n); return 0 }
36func dc_pnf(fd: i64, v: i64) -> i64 {
37 let t: *u8 = sys_mmap(32)
38 var m: i64 = v
39 if m < 0 { sys_write(fd, "-" as *u8, 1); m = 0 - m }
40 var k: i64 = 0
41 if m == 0 { t[0] = 48 as u8; k = 1 }
42 while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 }
43 var j: i64 = k - 1
44 while j >= 0 { sys_write(fd, ((t as i64) + j) as *u8, 1); j = j - 1 }
45 return 0
46}
47func dc_pn(v: i64) -> i64 {
48 let t: *u8 = sys_mmap(32)
49 var m: i64 = v
50 if m < 0 { sys_write(1, "-" as *u8, 1); m = 0 - m }
51 var k: i64 = 0
52 if m == 0 { t[0] = 48 as u8; k = 1 }
53 while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 }
54 var j: i64 = k - 1
55 while j >= 0 { sys_write(1, ((t as i64) + j) as *u8, 1); j = j - 1 }
56 return 0
57}
58
59func dc_slurp(path: *u8, buf: *u8, cap: i64) -> i64 {
60 let fd: i64 = sys_openat_rd(path)
61 if fd < 0 { return 0 - 1 }
62 let n: i64 = sys_read(fd, buf, cap - 1)
63 sys_close(fd)
64 if n < 0 { return 0 - 1 }
65 buf[n] = 0 as u8
66 return n
67}
68
69func dc_slot(arr: *u8, i: i64) -> *u8 { return ((arr as i64) + i * DC_NAMELEN) as *u8 }
70
71func dc_put(arr: *u8, cnt: i64, src: *u8, s: i64, e: i64) -> i64 {
72 if cnt >= DC_MAXN { return cnt }
73 if e <= s { return cnt }
74 var n: i64 = e - s
75 if n >= DC_NAMELEN { n = DC_NAMELEN - 1 }
76 let d: *u8 = dc_slot(arr, cnt)
77 var i: i64 = 0
78 while i < n { d[i] = src[s + i]; i = i + 1 }
79 d[n] = 0 as u8
80 return cnt + 1
81}
82
83func dc_eq(a: *u8, b: *u8) -> i64 {
84 var i: i64 = 0
85 while i < DC_NAMELEN {
86 if a[i] != b[i] { return 0 }
87 if a[i] == (0 as u8) { return 1 }
88 i = i + 1
89 }
90 return 1
91}
92
93func dc_has(arr: *u8, cnt: i64, name: *u8) -> i64 {
94 var i: i64 = 0
95 while i < cnt { if dc_eq(dc_slot(arr, i), name) == 1 { return 1 } i = i + 1 }
96 return 0
97}
98
99// STRIP THE PATH AND EVERY SUFFIX so the two planes are compared on the same key. An allowlist row can
100// read `/volume1/ai/galx/nx_gallery_serve.elf.new` while the supervisor reports `nx_gallery_serve.elf`;
101// comparing those raw would report a false gap for a target that IS covered.
102// ★ TWO INVENTORIES CAN ONLY BE DIFFED ON A KEY THEY BOTH SPELL THE SAME WAY.
103func dc_basekey(src: *u8, s: i64, e: i64, out: *u8) -> i64 {
104 var b: i64 = s
105 var i: i64 = s
106 while i < e { if src[i] == (47 as u8) { b = i + 1 } i = i + 1 }
107 var n: i64 = 0
108 var j: i64 = b
109 while j < e { if n < DC_NAMELEN - 1 { out[n] = src[j]; n = n + 1 } j = j + 1 }
110 out[n] = 0 as u8
111 // Drop a trailing ".new", then ".sov", then ".elf" -- longest-suffix first so `.sov.elf.new`
112 // reduces cleanly to the bare organ name.
113 var go: i64 = 1
114 while go == 1 {
115 go = 0
116 if n > 4 { if out[n-4] == (46 as u8) { if out[n-3] == (110 as u8) { if out[n-2] == (101 as u8) { if out[n-1] == (119 as u8) { n = n - 4; out[n] = 0 as u8; go = 1 } } } } }
117 if n > 4 { if out[n-4] == (46 as u8) { if out[n-3] == (101 as u8) { if out[n-2] == (108 as u8) { if out[n-1] == (102 as u8) { n = n - 4; out[n] = 0 as u8; go = 1 } } } } }
118 if n > 4 { if out[n-4] == (46 as u8) { if out[n-3] == (115 as u8) { if out[n-2] == (111 as u8) { if out[n-1] == (118 as u8) { n = n - 4; out[n] = 0 as u8; go = 1 } } } } }
119 }
120 return n
121}
122
123func main() -> i64 {
124 dc_p("=== nx_deploycover_gate -- can the running fleet actually be deployed? ===\n" as *u8)
125
126 let buf: *u8 = sys_mmap(65536)
127 let allow: *u8 = sys_mmap(DC_MAXN * DC_NAMELEN)
128 let run: *u8 = sys_mmap(DC_MAXN * DC_NAMELEN)
129 let key: *u8 = sys_mmap(DC_NAMELEN)
130 var nallow: i64 = 0
131 var nrun: i64 = 0
132
133 // ---- MANIFEST: deploy_targets.conf, field 3 (the staged artifact path) ----
134 let an: i64 = dc_slurp("deploy_targets.conf" as *u8, buf, 65536)
135 if an > 0 {
136 var line: i64 = 0
137 while line < an {
138 var eol: i64 = line
139 var es: i64 = 0
140 while es == 0 { if eol >= an { es = 1 } else { if buf[eol] == (10 as u8) { es = 1 } else { eol = eol + 1 } } }
141 var iscomment: i64 = 0
142 if line < eol { if buf[line] == (35 as u8) { iscomment = 1 } }
143 if iscomment == 0 {
144 // fields: name kind src ...
145 var f: i64 = 0
146 var p: i64 = line
147 var done: i64 = 0
148 while done == 0 {
149 var ws: i64 = 0
150 while ws == 0 { if p < eol { if buf[p] == (32 as u8) { p = p + 1 } else { ws = 1 } } else { ws = 1 } }
151 if p >= eol { done = 1 } else {
152 let fs: i64 = p
153 var fe: i64 = 0
154 while fe == 0 { if p < eol { if buf[p] == (32 as u8) { fe = 1 } else { p = p + 1 } } else { fe = 1 } }
155 if f == 2 {
156 dc_basekey(buf, fs, p, key)
157 nallow = dc_put(allow, nallow, key, 0, dc_len(key))
158 done = 1
159 }
160 f = f + 1
161 }
162 }
163 }
164 line = eol + 1
165 }
166 }
167
168 // ---- REALITY: mgmt_snap.json rows `SVC <name> <port> <state> ...` ----
169 let sn: i64 = dc_slurp("mgmt_snap.json" as *u8, buf, 65536)
170 if sn > 0 {
171 var line2: i64 = 0
172 while line2 < sn {
173 var eol2: i64 = line2
174 var es2: i64 = 0
175 while es2 == 0 { if eol2 >= sn { es2 = 1 } else { if buf[eol2] == (10 as u8) { es2 = 1 } else { eol2 = eol2 + 1 } } }
176 var issvc: i64 = 0
177 if line2 + 4 <= eol2 {
178 if buf[line2] == (83 as u8) { if buf[line2+1] == (86 as u8) { if buf[line2+2] == (67 as u8) { if buf[line2+3] == (32 as u8) { issvc = 1 } } } }
179 }
180 if issvc == 1 {
181 var p2: i64 = line2 + 4
182 var ws2: i64 = 0
183 while ws2 == 0 { if p2 < eol2 { if buf[p2] == (32 as u8) { p2 = p2 + 1 } else { ws2 = 1 } } else { ws2 = 1 } }
184 let ns: i64 = p2
185 var ne: i64 = 0
186 while ne == 0 { if p2 < eol2 { if buf[p2] == (32 as u8) { ne = 1 } else { p2 = p2 + 1 } } else { ne = 1 } }
187 dc_basekey(buf, ns, p2, key)
188 nrun = dc_put(run, nrun, key, 0, dc_len(key))
189 }
190 line2 = eol2 + 1
191 }
192 }
193
194 dc_p(" deploy_targets.conf rows = " as *u8); dc_pn(nallow); dc_p("\n" as *u8)
195 dc_p(" running services = " as *u8); dc_pn(nrun); dc_p("\n\n" as *u8)
196
197 // ---- REALITY-TO-MANIFEST: running with NO sanctioned update path (the dangerous direction) ----
198 dc_p(" RUNNING but NOT DEPLOYABLE (fixes must bypass the health-checked path):\n" as *u8)
199 var uncovered: i64 = 0
200 var i: i64 = 0
201 while i < nrun {
202 let nm: *u8 = dc_slot(run, i)
203 if dc_has(allow, nallow, nm) == 0 {
204 uncovered = uncovered + 1
205 dc_p(" - " as *u8); dc_p(nm); dc_p("\n" as *u8)
206 }
207 i = i + 1
208 }
209 if uncovered == 0 { dc_p(" (none)\n" as *u8) }
210
211 // ---- MANIFEST-TO-REALITY: an allowlist row for nothing running ----
212 dc_p("\n DEPLOYABLE but NOT RUNNING (benign for oneshots/toolchain; also how an allowlist rots):\n" as *u8)
213 var orphan: i64 = 0
214 var j: i64 = 0
215 while j < nallow {
216 let nm2: *u8 = dc_slot(allow, j)
217 if dc_has(run, nrun, nm2) == 0 {
218 orphan = orphan + 1
219 dc_p(" - " as *u8); dc_p(nm2); dc_p("\n" as *u8)
220 }
221 j = j + 1
222 }
223 if orphan == 0 { dc_p(" (none)\n" as *u8) }
224
225 // ⚠ DO NOT PRINT THE SUBJECT MEASUREMENT AS A BARE `N/M`. nx_gateverify parses the LAST N/M ratio
226 // on stdout as the gate's PASS RATIO -- so printing `DEPLOY COVERAGE = 5/15` made the verifier read
227 // printed_passed=5 printed_total=15 against a recorded 2/2 and return DISAGREE, i.e. THE RECORD IS
228 // UNTRUSTWORTHY, on a gate that was working perfectly. A subject metric and a pass ratio are
229 // different quantities that happen to share a shape.
230 // ★★★★★ IF A RULER PARSES A SHAPE, EMITTING THAT SHAPE FOR ANYTHING ELSE IS A COLLISION.
231 // Reported as `covered N of M` so it stays human-legible without being machine-ambiguous.
232 let covered: i64 = nrun - uncovered
233 dc_p("\n DEPLOY COVERAGE = " as *u8); dc_pn(covered); dc_p(" of " as *u8); dc_pn(nrun)
234 if nrun > 0 { dc_p(" (" as *u8); dc_pn((covered * 1000) / nrun); dc_p(" permil)\n" as *u8) } else { dc_p("\n" as *u8) }
235
236 // NON-VACUITY: reading zero of either side means the instrument measured NOTHING, and that must not
237 // render as a clean fleet. This is the tooth that a first-draft scanner usually lacks.
238 if nallow <= 0 {
239 dc_p(" VERDICT=RED read ZERO allowlist rows -- deploy_targets.conf missing or unparsed; measured nothing\n" as *u8)
240 return 1
241 }
242 if nrun <= 0 {
243 dc_p(" VERDICT=RED read ZERO running services -- mgmt_snap.json missing or unparsed; measured nothing\n" as *u8)
244 return 2
245 }
246
247 // TEETH = this gate's OWN assertions (both planes readable), NOT the fleet's coverage number.
248 // Emitting covered/total here would make a BACKLOG look like a broken instrument -- the gate is
249 // advisory about coverage and authoritative only about whether it measured.
250 dc_p("NX-DEPLOYCOVER-GATE passed 2/2 verdict=GREEN (coverage " as *u8)
251 dc_pn(covered); dc_p(" of " as *u8); dc_pn(nrun); dc_p(" is a BACKLOG, reported not failed)\n" as *u8)
252 let dlg: i64 = sys_openat_append(DC_LOG, DC_MODE)
253 if dlg >= 0 {
254 dc_wf(dlg, "NX-DEPLOYCOVER-GATE passed=2 total=2 covered=" as *u8); dc_pnf(dlg, covered)
255 dc_wf(dlg, " running=" as *u8); dc_pnf(dlg, nrun)
256 dc_wf(dlg, " allowlist=" as *u8); dc_pnf(dlg, nallow)
257 dc_wf(dlg, " uncovered=" as *u8); dc_pnf(dlg, uncovered)
258 dc_wf(dlg, " verdict=GREEN\n" as *u8)
259 sys_close(dlg)
260 }
261
262 dc_p("\n NON-VACUITY: both planes read from disk (rows>0 and services>0); the gap list above is\n" as *u8)
263 dc_p(" derived, not declared. ADVISORY: low coverage is a BACKLOG, not a reason to fail a build.\n" as *u8)
264 dc_p(" WHY IT MATTERS: an uncovered service cannot be fixed through the validate->health->\n" as *u8)
265 dc_p(" auto-rollback path, so its fixes go around every safety guarantee the plane provides --\n" as *u8)
266 dc_p(" and its source drifts ahead of its binary with nothing reporting the divergence.\n" as *u8)
267 dc_p(" VERDICT=GREEN (measurement succeeded)\n" as *u8)
268 return 0
269}