nx_organ_ship.nx source
↩ module page · 955 lines · 69333 B
1// nx_organ_ship.nx -- THE SHIP LOOP AS ONE ORGAN (operator 2026-08-18: "i want all of our workflows mined
2// and built and developed and tested and deployed etc i dont want all this grep and shell and ps1 and
3// other bullshit you have been doing except as fallbacks"). This session hand-pecked the ws-cycle phases
4// WORK->PROVE->EXPOSE->PUBLISH->VERIFY-LIVE ~40 times: build, run gate, contentdiff, behaveprobe,
5// promote with expect_sha256, read the artifact back, register, verify. Every step exists as an organ;
6// nothing ran them as ONE loop with the refusals in the right order. This does, in the nx_dr_chain shape:
7// one call, whole loop, every stage's evidence printed, REFUSE at the first RED with the unblock named.
8//
9// STAGES (each composes the incumbent, never re-implements; each announces its evidence line):
10// 1 BUILD /api/build target=X via nx_mgmt_call (the never-brick lane; the response's src_path MUST
11// name X -- the banked wrong-target compile is caught here -- and its sha256 is captured).
12// REFUSE if src_path is not X (exit 11) or the API refused (exit 12; the API's own reason is
13// printed: magic-ratchet, admit-gate, etc).
14// 2 PROVE RESOLVE the gate that proves X (nx_organ_ship_lib), then RUN it; its EXIT CODE is the
15// verdict (gv_verdict law). Resolution order: gate=<name> the caller declared -> a row in
16// knowledge/organ_gate.conf -> the <X>_gate convention -> X ITSELF when X ends in _gate ->
17// X minus its last underscore segment plus _gate. Each candidate is probed at the serving
18// root (<n>.elf) and at buildroot/_build/ (<n>.sov.elf), and EVERY path probed is printed.
19// FRESHNESS (2026-08-25): for the ONE candidate that is the target this run just built,
20// buildroot/_build/ is probed FIRST -- it holds code from THIS build while the serving
21// root holds the PREVIOUS promote, and an in-process gate compiles its subject IN, so
22// promoted-first reported a tooth count from code the loop did not build. Measured in
23// this loop's own journal: ONE build sha 2d9c5011..., PROVE RED from
24// ./nx_uvunwrap_gate.elf and PROVE GREEN from the artifact just built, consecutive rows.
25// It fails in the FLATTERING direction too -- nx_editstack_gate and nx_domain_map_gate
26// each went GREEN against the promoted copy moments after a build. Every PROVE line, its
27// journal row and the last line now carry artifact=<which one produced this verdict>.
28// REFUSE on a nonzero gate exit (21) with the gate's tail. REFUSE (22) when the caller
29// DECLARED a gate that does not exist -- a caller error, never the ordinary no-gate case.
30// Nothing resolved is announced NO-GATE-FOUND with its full search transcript, journalled,
31// and carried into the final line as prove=NO-GATE-FOUND UNPROVEN: a NAMED loud absence.
32// (Before 2026-08-20 this searched ONE name and silently continued on a miss, so shipping
33// nx_gate_roster_run -- gate nx_gate_roster_gate -- proved nothing and still said SHIPPED.)
34// EVERY DECLARED ROW RUNS (2026-08-23): when organ_gate.conf carries several rows for X
35// (the compiler: one gate per language rung) each further row is resolved at the same two
36// roots and RUN after the first; a declared row with no artifact REFUSES (22) and a RED
37// refuses (21). The last line prints gates_proven=N of_declared=M so a partial proof can
38// never read as a whole one. (Until today only the first row ran and the conf delegated
39// the rest to "the lane's checklist" -- a law that has to be remembered gets skipped.)
40// 2a VINTAGE WHOSE TREE DID THAT VERDICT DESCRIBE? (2026-08-25, part 2). The freshness swap above fixed
41// the target-is-its-own-gate case; this closes the residual that lane NAMED. Shipping
42// nx_foo resolves nx_foo_gate, WHICH THIS LOOP NEVER REBUILT -- and an in-process gate
43// STATICALLY LINKS its subject, so the verdict was a claim about the tree as of the GATE's
44// own build, not about the edit being shipped. It fails in the flattering direction: a
45// regression introduced by this very build is invisible because the older gate binary,
46// which never saw it, still passes. Fleet scale: 715 gates built, 176 current with source.
47// BOUNDED BY MEASUREMENT, never blanket: the gate's own SOURCE is read (both roots, in the
48// builder's order) and a rebuild is spent ONLY when it imports <target>.nx or
49// <target>_lib.nx. Most gates never embed their target -- an end-to-end gate fork/execs the
50// deployed elf -- and rebuilding those would double every ship's compile cost on a box
51// whose governor already refuses builds under load.
52// SCOPE DECLARED: DIRECT import edges only. A target reached through an intermediate lib is
53// a FLOOR miss, NAMED here rather than hidden (nx_rebuild_plan walks the full closure and
54// is far too heavy to fork per ship).
55// A FAILED REBUILD DOES NOT REFUSE THE SHIP. The commonest refusal is the load governor, a
56// fact about the box and not about this target, and refusing would break every lane whose
57// gate cannot build at that moment; silently proving against the stale artifact is the
58// defect being fixed. So it proceeds LABELLED: every PROVE line, its journal row and the
59// LAST line carry vintage=, plus gates_not_current= so a positional reader cannot miss it.
60// The gate rebuild also STAGES <gate>.sov.elf.new and is DELIBERATELY NOT PROMOTED -- said
61// out loud on the line, because an unpromoted build nobody named is a silent drift row.
62// 3+4 ADOPT nx_adoptgate X [args] -- the estate's enforced build->promote gate (contentdiff necessary
63// half + behaveprobe sufficiency half, ONE token). REFUSE (exit 31) on its REFUSED unless the
64// caller passed allow_loss=<n> naming the expected reword losses; missing-live = first promote.
65// 5 PROMOTE /api/promote target=X&expect_sha256=<stage sha> -- then READ THE ARTIFACT (sha256 of the
66// live file) and REFUSE (exit 51) if it does not equal the staged sha: the receipt is never
67// trusted, the artifact is (banked: empty responses, cache fossils, both real).
68// 6 REGISTER /api/tools/register name=X&elf=X.elf (idempotent by the API's own contract) -- announced.
69// 7 VERIFY if the caller passed verify_url=<https-url>, nx_page_verify it; VERDICT=RED refuses (exit 71).
70//
71// usage: nx_organ_ship <target> [gate_args...] [gate=<gatename>] [allow_loss=<n>] [allow_loss_v1=<evidence-sha256>] [verify_url=<url>] [noregister]
72// runs from nishihost cwd; drives the mgmt API through ./nx_mgmt_call.elf (self-minting on-box
73// driver, the same one the MCP nx_mgmt tool wraps); every fork's exit is announced.
74// exit: 0 SHIPPED | 2 usage | 1x build | 21 gate RED | 22 declared gate absent | 3x adoptgate | 5x promote | 7x verify
75// license_tier: ORIGINAL No hw writes (Rule 26).
76import "nx_syscalls.nx"
77import "nx_tool_run.nx"
78import "nx_organ_ship_lib.nx"
79import "nx_build_firsttry_lib.nx"
80
81const OS_CAP: i64 = 262144
82const OS_TIMEOUT_MS: i64 = 900000 // a build under admit backoff can legitimately wait minutes
83// mgmt lane = ./nx_mgmt_call.elf <METHOD> <path> [body] -- the on-box driver the MCP nx_mgmt tool wraps:
84// it mints a fresh admin session per call and drives the never-brick API. Composed, never re-minted here.
85const OS_MGMT_CALL: *u8 = "./nx_mgmt_call.elf"
86const OS_LINE_CAP: i64 = 2048 // one journal line: epoch+target+stage+verdict+detail(a sha or a path)
87const OS_SMALL_CAP: i64 = 4096 // captured stdout of a one-line receipt fork (filehash/offc_install)
88// GATE RESOLUTION ROOTS -- the two places a built gate artifact lives, as (dir, suffix) PAIRS so the
89// resolver in nx_organ_ship_lib can be driven against /tmp fixtures by its own gate instead of against
90// the estate root. Order is the resolver's: promoted serving root first, build scratch second -- EXCEPT
91// for the one candidate that IS the target this invocation just built, where the order flips (see
92// osl_try_fresh). Promoted-first is right for a gate that is a DIFFERENT organ, because this run did
93// not build that one; it is wrong for the target itself, because ./<t>.elf is then the PREVIOUS build.
94const OS_GATE_DIR_A: *u8 = "./"
95const OS_GATE_SUF_A: *u8 = ".elf"
96const OS_GATE_DIR_B: *u8 = "./buildroot/_build/"
97const OS_GATE_SUF_B: *u8 = ".sov.elf"
98// a gate the CALLER declared with gate=<name> and that does not exist is a caller error, not a missing
99// gate -- its own exit so it can never be read as the ordinary no-gate case.
100const OS_EXIT_NO_GATE_NAMED: i64 = 22
101// THE CLOSURE BANK'S COMPARATOR (2026-08-26). COMPOSED, NEVER RE-IMPLEMENTED: nx_provcheck reads
102// <gate>.provenance's closure_sha256 -- which /api/build records at the moment of production -- and
103// recomputes the tree closure through nx_closurehash, so this loop owns no closure walk and no second
104// opinion about what a gate was built from. It forks from the same nishihost cwd as every other fork
105// here, which is exactly the root nx_provcheck already defaults to.
106const OS_PROVCHECK: *u8 = "./nx_provcheck.elf"
107// nx_provcheck's OWN inner deadline for its nx_closurehash fork, read from its source (PC_TMO) rather
108// than guessed. The outer bound MUST exceed it: an outer deadline that fired first would kill the
109// comparator mid-answer and convert a real CURRENT-or-DRIFTED verdict into an UNPROVEN -- this loop
110// would then manufacture the exact blindness it exists to remove, and in the flattering direction.
111const OS_PROV_INNER_TMO_MS: i64 = 90000
112// DERIVED from that inner bound, with a third of it as margin, in the same shape as osl_tried_cap:
113// a second timeout hand-picked beside a known one is a copy of it that drifts.
114func os_prov_timeout_ms() -> i64 { return OS_PROV_INNER_TMO_MS + OS_PROV_INNER_TMO_MS / 3 }
115
116func os_slen(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n }
117func os_puts(s: *u8) -> i64 { sys_write(1, s, os_slen(s)); return 0 }
118func os_pn(v: i64) -> i64 {
119 let t: *u8 = sys_mmap(32) as *u8
120 var m: i64 = v; var w: i64 = 0
121 if m < 0 { t[w] = 45 as u8; w = w + 1; m = 0 - m }
122 if m == 0 { t[w] = 48 as u8; sys_write(1, t, w + 1); return 0 }
123 let d: *u8 = sys_mmap(32) as *u8
124 var k: i64 = 0
125 while m > 0 { d[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 }
126 var j: i64 = 0
127 while j < k { t[w] = d[k-1-j]; w = w + 1; j = j + 1 }
128 sys_write(1, t, w); return 0
129}
130func os_cat(d: *u8, o: i64, s: *u8) -> i64 { var i: i64 = 0; var oo: i64 = o; while s[i] != (0 as u8) { d[oo] = s[i]; oo = oo + 1; i = i + 1 } d[oo] = 0 as u8; return oo }
131// os_pn's buffer twin: the same digit walk, written into d at o instead of to fd 1 (one digit ruler).
132func os_catn(d: *u8, o: i64, v: i64) -> i64 {
133 var m: i64 = v; var w: i64 = o
134 if m < 0 { d[w] = 45 as u8; w = w + 1; m = 0 - m }
135 if m == 0 { d[w] = 48 as u8; d[w + 1] = 0 as u8; return w + 1 }
136 let dg: *u8 = sys_mmap(32) as *u8
137 var k: i64 = 0
138 while m > 0 { dg[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 }
139 var j: i64 = 0
140 while j < k { d[w] = dg[k-1-j]; w = w + 1; j = j + 1 }
141 d[w] = 0 as u8
142 return w
143}
144func os_streq(a: *u8, b: *u8) -> i64 { var i: i64 = 0; while a[i] == b[i] { if a[i] == (0 as u8) { return 1 } i = i + 1 } return 0 }
145func os_starts(s: *u8, p: *u8) -> i64 { var i: i64 = 0; while p[i] != (0 as u8) { if s[i] != p[i] { return 0 } i = i + 1 } return 1 }
146func os_exists(path: *u8) -> i64 { let fd: i64 = sys_openat_rd(path); if fd < 0 { return 0 } sys_close(fd); return 1 }
147// PROVENANCE OF THE VERDICT, as one token on the PROVE line. The gate PATH was always printed and
148// NOTHING SAID WHAT IT MEANT: ./<t>.elf is the PREVIOUS promote and ./buildroot/_build/<t>.sov.elf is
149// what this run just built, and for an in-process gate those are two different tooth sets. A number
150// whose provenance is invisible is exactly how a verdict about the wrong binary survived -- measured
151// 2026-08-25 in this loop's own journal, where ONE build sha carries a RED from ./nx_uvunwrap_gate.elf
152// and a GREEN from ./buildroot/_build/nx_uvunwrap_gate.sov.elf on consecutive rows.
153// The PREVIOUS-BUILD token is spelled loudly on purpose: it is the defect's signature, so if the
154// freshness preference is ever defeated the next reader sees it on the line instead of inferring it.
155func os_prov(gate: *u8, target: *u8) -> *u8 {
156 let pa: *u8 = sys_mmap(OSL_PATHCAP)
157 var o: i64 = os_cat(pa, 0, OS_GATE_DIR_A); o = os_cat(pa, o, target); o = os_cat(pa, o, OS_GATE_SUF_A)
158 if os_streq(gate, pa) == 1 { return "promoted-serving-root-PREVIOUS-BUILD-OF-THIS-TARGET" as *u8 }
159 let pb: *u8 = sys_mmap(OSL_PATHCAP)
160 var p: i64 = os_cat(pb, 0, OS_GATE_DIR_B); p = os_cat(pb, p, target); p = os_cat(pb, p, OS_GATE_SUF_B)
161 if os_streq(gate, pb) == 1 { return "fresh-build-of-this-target-THIS-RUN" as *u8 }
162 let r: i64 = osl_root_of(gate, OS_GATE_DIR_A, OS_GATE_DIR_B)
163 if r == OSL_ROOT_B { return "fresh-build-root-a-DIFFERENT-organ" as *u8 }
164 if r == OSL_ROOT_A { return "promoted-serving-root-a-DIFFERENT-organ" as *u8 }
165 return "unknown-root" as *u8
166}
167func os_find(hay: *u8, hlen: i64, needle: *u8) -> i64 {
168 let nl: i64 = os_slen(needle)
169 var i: i64 = 0
170 while i + nl <= hlen { var k: i64 = 0; var same: i64 = 1; while k < nl { if hay[i+k] != needle[k] { same = 0; k = nl } k = k + 1 } if same == 1 { return i } i = i + 1 }
171 return 0 - 1
172}
173// copy the JSON string value after "key": into dst (stops at the closing quote)
174func os_json_str(hay: *u8, hlen: i64, key: *u8, dst: *u8, dcap: i64) -> i64 {
175 dst[0] = 0 as u8
176 let p: i64 = os_find(hay, hlen, key)
177 if p < 0 { return 0 }
178 var j: i64 = p + os_slen(key)
179 // skip to the opening quote
180 while j < hlen { if hay[j] == (34 as u8) { j = j + 1; break } j = j + 1 }
181 var o: i64 = 0
182 while j < hlen { if hay[j] == (34 as u8) { break } if o < dcap - 1 { dst[o] = hay[j]; o = o + 1 } j = j + 1 }
183 dst[o] = 0 as u8
184 return o
185}
186func os_int_after(hay: *u8, hlen: i64, needle: *u8) -> i64 {
187 let p: i64 = os_find(hay, hlen, needle)
188 if p < 0 { return 0 - 1 }
189 var j: i64 = p + os_slen(needle)
190 var v: i64 = 0; var any: i64 = 0; var go: i64 = 1
191 while go == 1 { if j < hlen { let c: i64 = hay[j] as i64; if c >= 48 { if c <= 57 { v = v * 10 + (c - 48); any = 1; j = j + 1 } else { go = 0 } } else { go = 0 } } else { go = 0 } }
192 if any == 0 { return 0 - 1 }
193 return v
194}
195func os_tail(buf: *u8, n: i64, lines: i64) -> i64 {
196 var i: i64 = n - 1
197 var seen: i64 = 0
198 while i > 0 { if buf[i] == (10 as u8) { seen = seen + 1; if seen > lines { i = i + 1; break } } i = i - 1 }
199 if i < 0 { i = 0 }
200 sys_write(1, (buf as i64 + i) as *u8, n - i)
201 return 0
202}
203// DURABLE STAGE JOURNAL (2026-08-18: two client deaths mid-loop left progress reconstructable only from
204// process lists and artifact hashes -- a workflow whose only evidence is a pipe to a client that can
205// die is hunt-and-peck with extra steps). One appended line per stage: epoch<TAB>target<TAB>stage<TAB>
206// verdict<TAB>detail. Append-only, O_APPEND semantics via seek-to-end; the receipt any seat can read.
207const OS_JRNL: *u8 = "knowledge/status/organ_ship.jrnl"
208const OS_MODE_JRNL: i64 = 420
209// ---- CE2 (codeeffectiveness ce_build_firsttry): the build pillar's rates are read from THIS journal, so the journal
210// must carry the negative rows it never wrote -- a refused or wrong-source build now journals its CLASS (the refusing
211// organ's own tokens: BUILD-ADMIT / VERDICT=QUEUE are the governor's, the magic ratchet names itself) with the reason
212// head so a reader can reclassify, and the SHIPPED row carries bytes= so a byte decrease after an addition is readable
213// as a revert. The rates themselves live in ONE ruler, nx_build_firsttry_lib; this file only journals and dispatches.
214const OS_REFUSAL_HEAD: i64 = 160
215const OS_CTRL_MAX: i64 = 31
216const OS_SPACE: i64 = 32
217func os_bytes_of(path: *u8) -> i64 { let fd: i64 = sys_openat_rd(path); if fd < 0 { return 0 - 1 } let s: i64 = sys_lseek(fd, 0, 2); sys_close(fd); return s }
218func os_build_refusal_class(body: *u8, n: i64) -> *u8 {
219 if os_find(body, n, "BUILD-ADMIT" as *u8) >= 0 { return "REFUSED-ADMIT" as *u8 }
220 if os_find(body, n, "VERDICT=QUEUE" as *u8) >= 0 { return "REFUSED-ADMIT" as *u8 }
221 if os_find(body, n, "magic" as *u8) >= 0 { return "REFUSED-MAGIC" as *u8 }
222 if os_find(body, n, "COMPILE" as *u8) >= 0 { return "COMPILE-FAIL" as *u8 }
223 if os_find(body, n, "error" as *u8) >= 0 { return "COMPILE-FAIL" as *u8 }
224 return "REFUSED-OTHER" as *u8
225}
226// the reason's head on ONE line (control bytes become spaces) so the journal row stays a row
227func os_refusal_head(body: *u8, n: i64, out: *u8) -> i64 {
228 var i: i64 = 0
229 var lim: i64 = n
230 if lim > OS_REFUSAL_HEAD { lim = OS_REFUSAL_HEAD }
231 while i < lim { let c: i64 = body[i] as i64; if c <= OS_CTRL_MAX { out[i] = OS_SPACE as u8 } else { out[i] = body[i] } i = i + 1 }
232 out[i] = 0 as u8
233 return i
234}
235// ce_build_firsttry -- CE2 verb: nx_organ_ship firsttry [journal] [window_days] (exit = the ruler's verdict code)
236func ce_build_firsttry(argc: i64, argv: *i64) -> i64 {
237 var jp: *u8 = BFT_PROD_JRNL
238 var wd: i64 = BFT_DEFAULT_WINDOW_DAYS
239 if argc >= 3 { jp = argv[2] as *u8 }
240 if argc >= 4 { let w: i64 = bft_atoi(argv[3] as *u8); if w > 0 { wd = w } }
241 return bft_report(jp, wd, sys_now_realtime_sec())
242}
243
244func os_jrnl(target: *u8, stage: *u8, verdict: *u8, detail: *u8) -> i64 {
245 let fd: i64 = sys_openat_append(OS_JRNL, OS_MODE_JRNL)
246 if fd < 0 { return 0 - 1 }
247 let ln: *u8 = sys_mmap(OS_LINE_CAP)
248 var o: i64 = 0
249 // epoch: seconds from CLOCK_REALTIME (ts[0]=sec, ts[1]=nsec)
250 let ts: *i64 = sys_mmap(16) as *i64
251 sys_clock_gettime_real(ts)
252 let now: i64 = ts[0]
253 let t: *u8 = sys_mmap(32) as *u8
254 var m: i64 = now; var k: i64 = 0
255 if m == 0 { t[0] = 48 as u8; k = 1 }
256 while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 }
257 while k > 0 { k = k - 1; ln[o] = t[k]; o = o + 1 }
258 ln[o] = 9 as u8; o = o + 1
259 o = os_cat(ln, o, target); ln[o] = 9 as u8; o = o + 1
260 o = os_cat(ln, o, stage); ln[o] = 9 as u8; o = o + 1
261 o = os_cat(ln, o, verdict); ln[o] = 9 as u8; o = o + 1
262 o = os_cat(ln, o, detail); ln[o] = 10 as u8; o = o + 1
263 sys_write(fd, ln, o)
264 sys_close(fd)
265 return 0
266}
267// number -> decimal, appended into a buffer (os_pn prints; a JOURNAL LINE has to be BUILT)
268func os_ncat(d: *u8, o: i64, v: i64) -> i64 {
269 var oo: i64 = o
270 var m: i64 = v
271 if m < 0 { d[oo] = 45 as u8; oo = oo + 1; m = 0 - m }
272 let t: *u8 = sys_mmap(32) as *u8
273 var k: i64 = 0
274 if m == 0 { t[0] = 48 as u8; k = 1 }
275 while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 }
276 while k > 0 { k = k - 1; d[oo] = t[k]; oo = oo + 1 }
277 d[oo] = 0 as u8
278 return oo
279}
280// ONE JOURNAL ROW PER NAMED LOSS (2026-08-20, debt 1787235038). The ADOPT row used to carry an EMPTY
281// detail, so the only evidence that survives a client death could not answer the one question an
282// allowance is granted against: WHICH run was dropped. One subject per row, the writer owns the file.
283// Bytes outside printable ASCII become '.' -- the journal is TAB-separated and a run that smuggled a
284// tab in would silently invent a column.
285func os_jrnl_losses(target: *u8, buf: *u8, n: i64) -> i64 {
286 var cnt: i64 = 0
287 var i: i64 = 0
288 var go: i64 = 1
289 let run: *u8 = sys_mmap(OS_LINE_CAP)
290 while go == 1 {
291 if i >= n { go = 0 } else {
292 let p: i64 = os_find((buf as i64 + i) as *u8, n - i, "LOST: " as *u8)
293 if p < 0 { go = 0 } else {
294 var s: i64 = i + p + 6
295 var o: i64 = 0
296 var scan: i64 = 1
297 while scan == 1 {
298 if s >= n { scan = 0 } else {
299 let c: i64 = buf[s] as i64
300 if c == 10 { scan = 0 } else {
301 if o < OS_LINE_CAP - 512 { if c < 32 { run[o] = 46 as u8 } else { if c > 126 { run[o] = 46 as u8 } else { run[o] = c as u8 } } o = o + 1 }
302 s = s + 1
303 }
304 }
305 }
306 run[o] = 0 as u8
307 os_jrnl(target, "ADOPT-LOST" as *u8, "NAMED" as *u8, run)
308 cnt = cnt + 1
309 i = s + 1
310 }
311 }
312 }
313 return cnt
314}
315// mgmt call through the on-box driver; returns captured length
316func os_mgmt(method: *u8, path: *u8, body: *u8, out: *u8, olen: *i64) -> i64 {
317 let av: *i64 = sys_mmap(8 * 6) as *i64
318 av[0] = OS_MGMT_CALL as i64
319 av[1] = method as i64
320 av[2] = path as i64
321 if (body as i64) != 0 { av[3] = body as i64; av[4] = 0 } else { av[3] = 0 }
322 olen[0] = 0
323 tr_run_capture_to(OS_MGMT_CALL, av, out, OS_CAP - 1, olen, OS_TIMEOUT_MS)
324 return olen[0]
325}
326func os_sha_of(path: *u8, dst: *u8) -> i64 {
327 // nx_filehash <path> prints the sha256 hex first on the line
328 dst[0] = 0 as u8
329 let av: *i64 = sys_mmap(8 * 4) as *i64
330 av[0] = "./nx_filehash.elf" as *u8 as i64
331 av[1] = path as i64
332 av[2] = 0
333 let out: *u8 = sys_mmap(OS_SMALL_CAP)
334 let olen: *i64 = sys_mmap(16) as *i64
335 tr_run_capture_to("./nx_filehash.elf" as *u8, av, out, OS_SMALL_CAP - 1, olen, OS_TIMEOUT_MS)
336 // BY KEY, NEVER "FIRST HEX RUN": nx_filehash prints JSON {"organ":"nx_filehash","sha256":"..."} and a
337 // first-hex-run scanner read the `a` of "organ" as the digest (measured 2026-08-18: live_sha=a refused
338 // a promote that had LANDED -- a false RED in the very stage that exists to distrust receipts).
339 return os_json_str(out, olen[0], "\"sha256\":" as *u8, dst, 80)
340}
341
342// ---- DM8 (devmgmt rung): the documentation-adoption stage ----
343// A capability that exists and cannot be retrieved is an adoption gap, and nothing in this loop was
344// measuring it: a ship could complete perfectly while the symbol it delivered appeared on no compare
345// matrix, plan or watch row, so the next seat rebuilds it rather than finding it.
346//
347// REPORT-ONLY BY CONSTRUCTION. It prints, it journals, and it returns; it cannot change this loop's
348// exit path and it is deliberately placed AFTER the promote so it can never gate a ship. A pre-flight
349// that can refuse gets disabled; one that only informs survives -- and this measures a HABIT, not a
350// boundary, so refusing would be the wrong shape even if it were safe.
351//
352// It FORKS nx_docstage rather than re-implementing the check, which is this loop's own idiom
353// (nx_offc_install, nx_page_verify, nx_filehash are all forks). That keeps the exact-token rule and
354// its three-state verdict in ONE organ behind ONE gate: DOCUMENTED needs a single exact-token witness,
355// UNDOCUMENTED needs complete coverage, and UNMEASURED is what "I could not look" reports instead of
356// quietly becoming one of the other two.
357const OS_DOCSTAGE_ELF: *u8 = "./nx_docstage.elf"
358const OS_DOC_RC_DOC: i64 = 0
359const OS_DOC_RC_UNDOC: i64 = 1
360func os_doc_stage(target: *u8) -> i64 {
361 let av: *i64 = sys_mmap(8 * 4) as *i64
362 av[0] = OS_DOCSTAGE_ELF as i64
363 av[1] = target as i64
364 av[2] = 0
365 let dout: *u8 = sys_mmap(OS_CAP)
366 let dlen: *i64 = sys_mmap(16) as *i64
367 let rc: i64 = tr_run_capture_to(OS_DOCSTAGE_ELF, av, dout, OS_CAP - 1, dlen, OS_TIMEOUT_MS)
368 os_puts(" [6b/7] DOC " as *u8)
369 var v: *u8 = "UNMEASURED" as *u8
370 if rc == OS_DOC_RC_DOC { v = "DOCUMENTED" as *u8 }
371 if rc == OS_DOC_RC_UNDOC { v = "UNDOCUMENTED" as *u8 }
372 if dlen[0] <= 0 {
373 // AN ABSENT ARTIFACT IS INDISTINGUISHABLE FROM A DEAD CHECK, so say which one this is.
374 v = "UNMEASURED" as *u8
375 os_puts("UNMEASURED nx_docstage produced no output (missing artifact reads exactly like a dead check) -- report-only, the ship is unaffected\n" as *u8)
376 } else { os_tail(dout, dlen[0], 1) }
377 os_jrnl(target, "DOC" as *u8, v, "" as *u8)
378 return rc
379}
380
381// THE BUILD RESPONSE MUST NAME THE SOURCE WE ASKED FOR. Banked class: /api/build compiled a DIFFERENT
382// target under concurrent load, and expect_sha256 CANNOT catch it -- that only proves the staged bytes
383// are the ones just built, so if the wrong source was compiled it is the wrong binary's sha and promote
384// installs it reporting success. Extracted 2026-08-25 so stage 1 and the gate rebuild share ONE ruler:
385// a check re-typed at a second site is a check that drifts at one of them.
386func os_src_names(hay: *u8, hlen: i64, name: *u8) -> i64 {
387 let srcp: *u8 = sys_mmap(512)
388 os_json_str(hay, hlen, "\"src_path\":" as *u8, srcp, 512)
389 let want: *u8 = sys_mmap(256)
390 var wo: i64 = os_cat(want, 0, "/" as *u8); wo = os_cat(want, wo, name); wo = os_cat(want, wo, ".nx" as *u8)
391 let sl: i64 = os_slen(srcp)
392 let wl: i64 = os_slen(want)
393 if sl < wl { return 0 }
394 return os_streq((srcp as i64 + sl - wl) as *u8, want)
395}
396
397// ---- 2a IS THE RESOLVED GATE'S BINARY EVIDENCE ABOUT *THIS* RUN? -------------------------------
398// The 2026-08-25 freshness swap fixed the case where the target IS its own gate. This closes the one it
399// named and left open: shipping nx_foo resolves nx_foo_gate, WHICH THIS LOOP NEVER REBUILT. An
400// in-process gate STATICALLY LINKS its subject, so the verdict was a claim about the tree as of the
401// GATE's own build -- and the estate has the scale of that (715 gates built, 176 current with their
402// own source). It fails in the flattering direction: a regression introduced by the very edit being
403// shipped is invisible because the previous gate binary, which never saw it, still passes.
404//
405// BOUNDED BY MEASUREMENT, NOT BLANKET. A rebuild is spent only when this gate's OWN SOURCE imports
406// <target>.nx or <target>_lib.nx (osl_gate_closure / osl_should_rebuild). Most gates never embed their
407// target at all -- an end-to-end gate fork/execs the deployed elf -- and rebuilding those would double
408// the compile cost of every ship on a box whose governor already refuses builds under load.
409//
410// WHEN THE REBUILD FAILS, THE SHIP CONTINUES AND THE VERDICT IS LABELLED. Refusing would break every
411// lane whose gate cannot build at that moment, and the commonest refusal by far is the LOAD GOVERNOR --
412// a fact about the box, not about the target, and the estate's standing answer to it is to pace, never
413// to route around. Silently proving against the stale artifact is the defect being fixed. So the third
414// option is taken: proceed, NAME the state, journal it, and carry the vintage onto the PROVE line and
415// the last line, where a positional reader takes its verdict from.
416//
417// Returns an OSL_VINT_* code and, on a successful rebuild, REWRITES gpath to the fresh artifact.
418func os_gate_freshen(gname: *u8, target: *u8, gpath: *u8) -> i64 {
419 if os_streq(gname, target) == 1 {
420 os_puts(" [2a/7] GATE-VINTAGE gate=" as *u8); os_puts(gname)
421 os_puts(" target-is-its-own-gate: stage 1 built this artifact and the resolver already preferred it -- no second build\n" as *u8)
422 return OSL_VINT_STAGE1
423 }
424 let ctried: *u8 = sys_mmap(osl_closure_tried_cap())
425 let gsrc: *u8 = sys_mmap(OSL_PATHCAP)
426 let seen: *i64 = sys_mmap(16) as *i64
427 let clo: i64 = osl_gate_closure(gname, target, OSL_SRC_DIR_HDL, OSL_SRC_DIR_RT, OSL_SRC_SUF, ctried, osl_closure_tried_cap(), gsrc, seen)
428 os_puts(" [2a/7] GATE-VINTAGE gate=" as *u8); os_puts(gname); os_puts(" closure=" as *u8); os_puts(osl_closure_name(clo))
429 os_puts(" sources_read=" as *u8); os_pn(seen[0]); os_puts(" deciding_src=" as *u8); os_puts(gsrc)
430 os_puts(" probed:" as *u8); os_puts(ctried); os_puts("\n" as *u8)
431 if seen[0] > 1 { os_puts(" SHADOWED: this gate name exists in BOTH source roots. The builder compiles the _hdl_build copy and the runtime copy NEVER compiles, so the two can disagree; the closure answers CONTAINS if EITHER names the target, which is wrong only in the direction of one extra compile. FIX: reconcile to ONE dir.\n" as *u8) }
432 // ---- ASK THE BANK, BEFORE DECIDING. One fork of the incumbent comparator; the hash decides and
433 // the import scan above may only ever ADD a rebuild on top of it. ABSTAINS BY CONSTRUCTION: an
434 // absent nx_provcheck.elf execs to 127 and a fired deadline returns -5, and osl_prov_of_exit maps
435 // both to UNPROVEN -- so when this instrument cannot answer, the loop degrades to EXACTLY its
436 // pre-2026-08-26 behaviour rather than to a refusal or to a green it did not earn.
437 let pcout: *u8 = sys_mmap(OS_CAP)
438 let pclen: *i64 = sys_mmap(16) as *i64
439 let pcav: *i64 = sys_mmap(64) as *i64
440 pcav[0] = OS_PROVCHECK as i64
441 pcav[1] = gname as i64
442 pcav[2] = 0
443 pclen[0] = 0
444 let pcrc: i64 = tr_run_capture_to(OS_PROVCHECK, pcav, pcout, OS_CAP - 4, pclen, os_prov_timeout_ms())
445 let prov: i64 = osl_prov_of_exit(pcrc)
446 os_puts(" BANK " as *u8); os_puts(osl_prov_name(prov))
447 os_puts(" rc=" as *u8); os_pn(pcrc); os_puts(" via=" as *u8); os_puts(OS_PROVCHECK); os_puts("\n" as *u8)
448 // THE REASON TRAVELS WITH THE VERDICT: nx_provcheck prints recorded= and now= on its single line,
449 // so a DRIFTED answer arrives carrying the two hashes that disagree instead of an assertion that
450 // they do, and a reader can act on it without re-running anything.
451 os_tail(pcout, pclen[0], 1)
452 // WHICH ARTIFACT DOES THE BANK DESCRIBE? Computed BEFORE the rebuild decision (2026-09-05). The bank describes the
453 // LAST BUILD (root B) while the resolver prefers the PROMOTED binary (root A). A CURRENT bank vetoes the import
454 // scan's rebuild ONLY when the banked artifact is on disk and is the one PROVE will run; a CURRENT bank whose
455 // artifact is gone (a refused build eats the fossil and leaves the sidecar) vetoes nothing and the incumbent rule
456 // decides. Measured on nx_janitor_caps_gate (bank CURRENT, PROVE ran a 20,695 B promoted fossil while the banked
457 // artifact was 30,649 B) and on this loop's own gate (the import scan demanded a rebuild past a CURRENT bank,
458 // admission refused it, and PROVE fell back to the stale promoted gate while the banked current build sat in root B).
459 let gb: *u8 = sys_mmap(OSL_PATHCAP)
460 var gbo: i64 = os_cat(gb, 0, OS_GATE_DIR_B); gbo = os_cat(gb, gbo, gname); gbo = os_cat(gb, gbo, OS_GATE_SUF_B)
461 let bex: i64 = os_exists(gb)
462 let sha_a: *u8 = sys_mmap(80)
463 let sha_b: *u8 = sys_mmap(80)
464 sha_a[0] = 0 as u8
465 sha_b[0] = 0 as u8
466 let rr: i64 = osl_root_of(gpath, OS_GATE_DIR_A, OS_GATE_DIR_B)
467 var pick: i64 = OSL_PICK_KEEP
468 if prov == OSL_PROV_CURRENT {
469 if rr == OSL_ROOT_A { os_sha_of(gpath, sha_a); if bex == 1 { os_sha_of(gb, sha_b) } }
470 pick = osl_pick_banked(rr, sha_a, sha_b, bex)
471 }
472 if osl_should_rebuild_pick(gname, target, clo, prov, pick) == 0 {
473 let nv: i64 = osl_vint_norebuild(prov, clo)
474 os_jrnl(target, "GATE-VINTAGE" as *u8, osl_vint_name(nv), gname)
475 if nv == OSL_VINT_PROV_CURRENT {
476 if pick == OSL_PICK_SWITCH_B {
477 os_puts(" BANKED-BUILD-USED: the bank describes the LAST BUILD at " as *u8); os_puts(gb)
478 os_puts(" (sha " as *u8); os_puts(sha_b); os_puts("), and the resolver had picked the PROMOTED binary " as *u8); os_puts(gpath)
479 os_puts(" (sha " as *u8); os_puts(sha_a); os_puts(") whose bytes DIFFER. PROVE runs the banked artifact; the promoted gate is BEHIND its own source and its own lane should ship it.\n" as *u8)
480 os_cat(gpath, 0, gb)
481 os_jrnl(target, "GATE-VINTAGE" as *u8, osl_pick_name(pick), gb)
482 return nv
483 }
484 if pick == OSL_PICK_UNPROVEN {
485 os_puts(" BANK-UNMATCHED: the sidecar says CURRENT but the artifact it describes could not be matched to the one resolved (root B " as *u8)
486 if bex == 1 { os_puts("present, a digest unreadable" as *u8) } else { os_puts("ABSENT -- a refused build eats the fossil and leaves the sidecar" as *u8) }
487 os_puts("), so the bank vouches for nothing this run can execute and the resolved binary's vintage is UNPROVEN, not CURRENT.\n" as *u8)
488 os_jrnl(target, "GATE-VINTAGE" as *u8, osl_pick_name(pick), gpath)
489 return OSL_VINT_UNKNOWN
490 }
491 os_puts(" NO REBUILD, and this is the STRONG no: the bank says this gate's artifact was built from exactly the sources the tree holds now, and the binary PROVE runs IS that artifact (root B, or root A byte-identical to it). No compile is spent to re-establish something already proven by content.\n" as *u8)
492 return nv
493 }
494 if nv == OSL_VINT_STALE_PROV {
495 os_puts(" THE BANK SAYS THE ARTIFACT IS OLD AND NO REBUILD WAS ATTEMPTED. This pairing is reachable only if the decision and the vintage disagree, which would be a defect in THIS loop rather than in the gate -- it is reported as STALE so that it can never read as a pass.\n" as *u8)
496 return nv
497 }
498 if nv == OSL_VINT_UNKNOWN_NOSRC {
499 os_puts(" NO SOURCE at either root and no banked closure to ask instead, so whether this gate's build closure contains the target is UNDECIDABLE. That is NOT the same as INDEPENDENT: the verdict below is about an artifact this loop cannot relate to the tree at all, and it is reported as UNKNOWN rather than allowed to acquit.\n" as *u8)
500 return nv
501 }
502 os_puts(" NO REBUILD: this gate's source imports neither the target nor its lib, and the bank held no recorded closure that could contradict that. This is the incumbent's direct-edge approximation and it is a FLOOR, not a proof -- to turn it into one, build this gate once through /api/build so its closure gets banked.\n" as *u8)
503 return nv
504 }
505 if prov == OSL_PROV_DRIFTED {
506 os_puts(" REBUILD, AND THE BANK IS WHAT DECIDED IT: this gate's recorded closure no longer matches the tree, so its artifact proves the tree as of ITS OWN build. This fires whether or not the gate imports the target directly, which is precisely the shared-third-lib case the import scan cannot see.\n" as *u8)
507 }
508 if prov != OSL_PROV_DRIFTED {
509 os_puts(" REBUILD: this gate's source imports the target or its lib, so the artifact on disk proves the tree as of ITS OWN build, not as of the edit being shipped.\n" as *u8)
510 }
511 let rb: *u8 = sys_mmap(512)
512 var rbo: i64 = os_cat(rb, 0, "target=" as *u8); rbo = os_cat(rb, rbo, gname)
513 // the same replay bust as the target build above (a fix in one verb and not its sibling is half a fix)
514 rbo = os_cat(rb, rbo, "&bust=r" as *u8); rbo = os_catn(rb, rbo, sys_now_realtime_sec())
515 let rout: *u8 = sys_mmap(OS_CAP)
516 let rlen: *i64 = sys_mmap(16) as *i64
517 os_mgmt("POST" as *u8, "/api/build" as *u8, rb, rout, rlen)
518 if os_find(rout, rlen[0], "\"BUILT\"" as *u8) < 0 {
519 os_jrnl(target, "GATE-REBUILD" as *u8, "REFUSED" as *u8, gname)
520 os_puts(" GATE-REBUILD REFUSED by /api/build -- PROCEEDING against the artifact already on disk, whose vintage is BEFORE this run's edit. The API's own reason, passed through and not paraphrased:\n" as *u8)
521 os_tail(rout, rlen[0], 6)
522 os_puts(" THIS IS NOT A PASS: the PROVE verdict below is a claim about the tree as of that older artifact, and the last line says so. UNBLOCK: re-run when the build lane admits, or build the gate by hand and re-ship.\n" as *u8)
523 return OSL_VINT_STALE_REFUSED
524 }
525 if os_src_names(rout, rlen[0], gname) == 0 {
526 os_jrnl(target, "GATE-REBUILD" as *u8, "WRONG-SRC" as *u8, gname)
527 os_puts(" GATE-REBUILD compiled a DIFFERENT source (the banked concurrent-load class), so the artifact it produced is not this gate and the proof below would run the OLD one. Response tail:\n" as *u8)
528 os_tail(rout, rlen[0], 4)
529 return OSL_VINT_STALE_WRONGSRC
530 }
531 let t3: *u8 = sys_mmap(osl_tried_cap())
532 t3[0] = 0 as u8
533 let p3: *i64 = sys_mmap(16) as *i64
534 p3[0] = 0
535 let g3: *u8 = sys_mmap(OSL_PATHCAP)
536 if osl_try_fresh(gname, gname, OS_GATE_DIR_A, OS_GATE_SUF_A, OS_GATE_DIR_B, OS_GATE_SUF_B, t3, osl_tried_cap(), p3, g3) == 0 {
537 os_jrnl(target, "GATE-REBUILD" as *u8, "NO-ARTIFACT" as *u8, gname)
538 os_puts(" GATE-REBUILD said BUILT and NO artifact resolves at either root. Probed:" as *u8); os_puts(t3); os_puts("\n" as *u8)
539 return OSL_VINT_STALE_NOARTIFACT
540 }
541 if osl_root_of(g3, OS_GATE_DIR_A, OS_GATE_DIR_B) != OSL_ROOT_B {
542 os_jrnl(target, "GATE-REBUILD" as *u8, "NO-FRESH-ARTIFACT" as *u8, g3)
543 os_puts(" GATE-REBUILD said BUILT and the fresh-build artifact is still absent -- the resolver fell back to " as *u8); os_puts(g3)
544 os_puts(", the PREVIOUS build. A rebuild that leaves you running the old binary must never read as fresh.\n" as *u8)
545 return OSL_VINT_STALE_NOARTIFACT
546 }
547 os_cat(gpath, 0, g3)
548 os_jrnl(target, "GATE-REBUILD" as *u8, "BUILT" as *u8, g3)
549 os_puts(" GATE-REBUILT -> " as *u8); os_puts(g3)
550 os_puts(" (DECLARED: this build also stages " as *u8); os_puts(gname); os_puts(".sov.elf.new and is DELIBERATELY NOT PROMOTED -- this loop promotes the target it was asked to ship and nothing else, and promoting another lane's organ is the banked capability-loss action. Expect " as *u8); os_puts(gname); os_puts(" to read BEHIND on the drift census until its own lane ships it.)\n" as *u8)
551 // WHICH INSTRUMENT DEMANDED THIS REBUILD TRAVELS WITH IT: REBUILT_PROV when the bank decided,
552 // REBUILT when the import scan did. They are kept apart because that split IS the measurement of
553 // what the bank buys over the edge scan, and one merged bucket would hide exactly that number.
554 return osl_vint_rebuilt(prov)
555}
556
557// AD2 contract symbol: the harness disclosure manifest, composed from the lib's ONE ruler -- never a
558// second copy. Wired at stage 4b of every ship; the SHIPPED line carries the token.
559func os_harness_manifest(outpath: *u8, src_sha: *u8, gatepath: *u8, timeout_ms: i64, allow_loss: i64, extra: *u8, tok: *u8) -> i64 { return osl_harness_manifest(outpath, src_sha, gatepath, timeout_ms, allow_loss, extra, tok) }
560
561
562
563func os_loss_refused(reason:*u8)->i64{os_puts("{\"schema\":\"nishi-ship-loss-approval/1\",\"state\":\"needs-intervention\",\"reason\":\"");os_puts(reason);os_puts("\"}\n");return 31}
564func os_loss_exact_inner(target:*u8,live:*u8,stage_sha:*u8,approval:*u8,scratch:*u8)->i64{
565 let stage:*u8=scratch
566 os_cat(stage,os_cat(stage,0,target),".sov.elf.new")
567 let lhs:*u8=stage+os_slen(target)+os_slen(".sov.elf.new")+1;let rhs:*u8=lhs+80
568 os_sha_of(live,lhs);os_sha_of(stage,rhs)
569 if osls_hex(lhs)==0||osls_hex(rhs)==0{return os_loss_refused("artifact-hash-unavailable")}
570 if os_streq(rhs,stage_sha)!=1{return os_loss_refused("staged-artifact-changed")}
571 var av0:i64="./nx_contentdiff.elf" as *u8 as i64
572 let av:*i64=(rhs+80) as *i64
573 av[0]=av0;av[1]=live as i64;av[2]=stage as i64;av[3]="all" as *u8 as i64;av[4]=0
574 var out:NxBufOwned;out.buf=0 as *u8;out.len=0;out.cap=0;var observed:NxRunEvidence
575 let rc:i64=tr_run_capture_owned_result("./nx_contentdiff.elf",av,&out,OS_TIMEOUT_MS,0,0 as *u8,&observed)
576
577 if rc!=1||observed.reaped!=1||observed.exited!=1||observed.exit_code!=1{nx_bo_release(&out);return os_loss_refused("complete-ruler-execution-unqualified")}
578 var set:OslLossSet
579 let built:i64=osls_build(lhs,rhs,out.buf,out.len,&set);nx_bo_release(&out)
580 if built!=0{return os_loss_refused("complete-loss-enumeration-required")}
581 let dir:*u8="knowledge/status/harness";sys_mkdir(dir,493)
582 let pathlen:i64=os_slen(dir)+os_slen("/loss-.record")+64+1
583 let path:*u8=(av as *u8)+5*__size_of(i64)
584 var po:i64=os_cat(path,0,dir);po=os_cat(path,po,"/loss-");po=os_cat(path,po,set.digest);os_cat(path,po,".record")
585 let kept:i64=osls_retain(path,dir,&set)
586 if kept!=0{osls_close(&set);return os_loss_refused("complete-evidence-write-failed")}
587 os_puts("{\"schema\":\"nishi-ship-loss-approval/1\",\"loss_count\":");os_pn(set.count);os_puts(",\"evidence_bytes\":");os_pn(set.record.len)
588 os_puts(",\"evidence_path\":\"");os_puts(path);os_puts("\",\"required_allow_loss_v1\":\"");os_puts(set.digest);os_puts("\"}\n")
589 os_sha_of(live,lhs);os_sha_of(stage,rhs)
590 let approved:i64=osls_approve(&set,approval,lhs,rhs)
591 var detail:NxBufOwned;detail.buf=0 as *u8;detail.len=0;detail.cap=0
592 var drc:i64=osls_text(&detail,path);if drc==0{drc=osls_text(&detail," sha256=")};if drc==0{drc=osls_add(&detail,set.digest,64)}
593 if drc==0{drc=osls_add(&detail,"",1)}
594 var jr:i64=-1;if drc==0{jr=os_loss_journal(target,detail.buf)}
595 nx_bo_release(&detail);osls_close(&set);
596 if jr!=0{return os_loss_refused("evidence-journal-failed")}
597 if approved!=1{return os_loss_refused("exact-artifact-bound-allow_loss_v1-required")}
598 return 0
599}
600
601func os_loss_exact(target:*u8,live:*u8,stage_sha:*u8,approval:*u8)->i64{
602 let tn:i64=os_slen(target)
603 let overhead:i64=os_slen(".sov.elf.new")+1+160+5*__size_of(i64)+os_slen("knowledge/status/harness/loss-.record")+64+1
604 if tn>NX_BO_I64_MAX-overhead{return os_loss_refused("allocation-range")}
605 let extent:i64=tn+overhead;let scratch:*u8=sys_mmap_try(extent)
606 if (scratch as i64)<=0{return os_loss_refused("allocation-failed")}
607 let rc:i64=os_loss_exact_inner(target,live,stage_sha,approval,scratch)
608 let freed:i64=sys_munmap_direct(scratch,extent);if freed<0{return os_loss_refused("allocation-release-failed")};return rc
609}
610func os_loss_journal(target:*u8,detail:*u8)->i64{
611 var line:NxBufOwned;line.buf=0 as *u8;line.len=0;line.cap=0
612 let number:*u8=sys_mmap_try(32);if (number as i64)<=0{return -1}
613 let nn:i64=os_ncat(number,0,sys_now_realtime_sec())
614 var rc:i64=osls_add(&line,number,nn);sys_munmap_direct(number,32)
615 if rc==0{rc=osls_text(&line,"\t")};if rc==0{rc=osls_text(&line,target)}
616 if rc==0{rc=osls_text(&line,"\tADOPT-LOSS-SET\tCOMPLETE\t")};if rc==0{rc=osls_text(&line,detail)};if rc==0{rc=osls_text(&line,"\n")}
617 if rc==0{
618 let fd:i64=sys_openat_append(OS_JRNL,OS_MODE_JRNL)
619 if fd<0{rc=-1}else{var off:i64=0;while off<line.len{let w:i64=sys_write(fd,line.buf+off,line.len-off);if w==TR_EINTR{continue};if w<=0{rc=-1;break};off=off+w};if sys_fsync(fd)<0{rc=-1};if sys_close(fd)<0{rc=-1}}
620 }
621 let freed:i64=nx_bo_release(&line);if freed<0{rc=freed};return rc
622}
623
624func main(argc: i64, argv: *i64) -> i64 {
625 if argc < 2 { os_puts("usage: nx_organ_ship <target> [gate_args...] [gate=<gatename>] [allow_loss=<n>] [allow_loss_v1=<evidence-sha256>] [verify_url=<url>] [noregister]\n" as *u8); return 2 }
626 // CE2: the build pillar's rates, read from this loop's own journal -- one ruler (nx_build_firsttry_lib)
627 if os_streq(argv[1] as *u8, "firsttry" as *u8) == 1 { return ce_build_firsttry(argc, argv) }
628 let target: *u8 = argv[1] as *u8
629 var allow_loss: i64 = 0
630 var loss_approval:*u8=0 as *u8
631 var loss_approved:i64=0
632 var loss_live_sha:*u8=0 as *u8
633 var verify_url: *u8 = 0 as *u8
634 var noregister: i64 = 0
635 // gate=<name> DECLARES which gate proves this target, for a gate whose name no rule can derive.
636 // It is an ASSERTION, not a hint: an absent declared gate REFUSES (exit 22) instead of falling
637 // through to derivation, because proving a DIFFERENT gate than the one named is a false proof.
638 var gate_arg: *u8 = 0 as *u8
639 // gate args = every argv[2..] that is not a key=value option
640 let gargs: *i64 = sys_mmap(8 * 32) as *i64
641 var ng: i64 = 0
642 var ai: i64 = 2
643 while ai < argc {
644 let a: *u8 = argv[ai] as *u8
645 if os_starts(a,"allow_loss_v1=")==1{loss_approval=a+14;ai=ai+1;continue}
646 if os_starts(a, "allow_loss=" as *u8) == 1 { allow_loss = os_int_after(a, os_slen(a), "allow_loss=" as *u8) }
647 else { if os_starts(a, "verify_url=" as *u8) == 1 { verify_url = (a as i64 + 11) as *u8 }
648 else { if os_starts(a, "gate=" as *u8) == 1 { gate_arg = (a as i64 + 5) as *u8 }
649 else { if os_streq(a, "noregister" as *u8) == 1 { noregister = 1 }
650 else { if ng < 30 { gargs[ng] = a as i64; ng = ng + 1 } } } } }
651 ai = ai + 1
652 }
653 os_puts("=== NX-ORGAN-SHIP target=" as *u8); os_puts(target); os_puts(" (one loop: build > prove > adoptgate > promote > offc-twin > register > verify; refuses at the first RED, and exact approved loss evidence is retained with both artifact hashes)\n" as *u8)
654
655 // 0 (mint is inside nx_mgmt_call: one fresh admin session per call, no token file on disk)
656 // 1 BUILD
657 let body: *u8 = sys_mmap(512)
658 var bo: i64 = os_cat(body, 0, "target=" as *u8); bo = os_cat(body, bo, target)
659 // PER-RUN NONCE ON THE BUILD BODY (2026-09-05). CORRECTED THE SAME DAY: this was first written as "bust the
660 // ~1 h idempotency replay" -- and that mechanism was REFUTED by reading the source: no client sends an
661 // Idempotency-Key and the mgmt dedup keys on that header, so a bare target= body was never being replayed. The
662 // stale promote it was written against (nx_actlog: live_sha == the prior promote, selftest still 15/15 against a
663 // 65,611 B source, prove GREEN) was nx_hostctl cmd_buildrun staging the PREVIOUS build's artifact after the
664 // builder REFUSED under its own admission check; that is fixed at the root in cmd_buildrun (exit 0 + the
665 // builder's own success token gate the stage). The nonce stays: it costs nothing, keeps every ship a distinct
666 // request for any future body-keyed dedup, and a retry of the SAME ship run still shares a body.
667 bo = os_cat(body, bo, "&bust=r" as *u8); bo = os_catn(body, bo, sys_now_realtime_sec())
668 let out: *u8 = sys_mmap(OS_CAP)
669 let olen: *i64 = sys_mmap(16) as *i64
670 os_mgmt("POST" as *u8, "/api/build" as *u8, body, out, olen)
671 let sha: *u8 = sys_mmap(80)
672 os_json_str(out, olen[0], "\"sha256\":" as *u8, sha, 80)
673 let srcp: *u8 = sys_mmap(512)
674 os_json_str(out, olen[0], "\"src_path\":" as *u8, srcp, 512)
675 os_puts(" [1/7] BUILD " as *u8)
676 if os_find(out, olen[0], "\"BUILT\"" as *u8) < 0 { let rh: *u8 = sys_mmap(OS_REFUSAL_HEAD + 1); os_refusal_head(out, olen[0], rh); os_jrnl(target, "BUILD" as *u8, os_build_refusal_class(out, olen[0]), rh); os_puts("REFUSED by /api/build (exit 12) -- the API's own reason:\n" as *u8); os_tail(out, olen[0], 6); os_puts(" UNBLOCK: read the reason above (magic-ratchet -> nx_magic apply; admit-gate -> re-issue after load clears; refusal text names the gate)\n" as *u8); return 12 }
677 // src_path must name the target: "/<target>.nx" at the end. ONE ruler (os_src_names), shared with
678 // the gate rebuild below -- the same test typed twice is the test that drifts at one of the sites.
679 if os_src_names(out, olen[0], target) == 0 { os_puts("REFUSED: src_path does not name the target (exit 11): " as *u8); os_puts(srcp); os_puts("\n UNBLOCK: the build lane compiled a DIFFERENT source under concurrent load (banked class) -- discard and rebuild\n" as *u8); os_jrnl(target, "BUILD" as *u8, "WRONG-SRC" as *u8, srcp); return 11 }
680 os_puts("BUILT sha=" as *u8); os_puts(sha); os_puts(" src_path=" as *u8); os_puts(srcp); os_puts("\n" as *u8)
681 os_jrnl(target, "BUILD" as *u8, "BUILT" as *u8, sha)
682
683 // 2 PROVE -- the gate that proves this target, RESOLVED (nx_organ_ship_lib), never guessed from one
684 // name. Until 2026-08-20 this looked for exactly "<target>_gate" and, on a miss, printed GATE=NONE
685 // and carried on -- so shipping nx_gate_roster_run SKIPPED THE PROVE STAGE ENTIRELY, because its
686 // gate is nx_gate_roster_gate. A SHIP LOOP THAT SILENTLY SKIPS ITS PROOF STAGE WHEN A NAME DOES NOT
687 // MATCH REPORTS SUCCESS HAVING PROVEN NOTHING, in the one organ every other ship depends on.
688 // The resolver tries: caller declaration -> organ_gate.conf row -> convention -> self (the target IS
689 // a gate) -> one-segment strip; and it PUBLISHES EVERY PATH IT PROBED plus the rule that matched, so
690 // a miss is a NAMED loud state carrying its own search transcript and never a silent skip.
691 let tried: *u8 = sys_mmap(osl_tried_cap())
692 let gpath: *u8 = sys_mmap(OSL_PATHCAP)
693 let why: *i64 = sys_mmap(16) as *i64
694 var proved: i64 = 0
695 var nproved: i64 = 0 // gates actually RUN green in this PROVE stage (the first + every further declared row)
696 // THE VINTAGE OF THE ARTIFACT EACH VERDICT CAME FROM (2026-08-25, part 2). vint is the FIRST gate's;
697 // nstale counts every proven gate whose verdict is NOT current with this run, so a partial staleness
698 // can never hide behind a green first gate on the last line.
699 var vint: i64 = OSL_VINT_UNKNOWN
700 var nstale: i64 = 0
701 // THE TARGET IS DECLARED FRESH: stage 1 above built exactly this name, so the build scratch holds
702 // code from THIS run while the serving root holds the previous promote. Passing `target` as the
703 // fresh name flips the probe order for that ONE candidate and leaves every other rule untouched.
704 let found: i64 = osl_gate_resolve_fresh(target, gate_arg, target, OSL_CONF_DEFAULT, OS_GATE_DIR_A, OS_GATE_SUF_A, OS_GATE_DIR_B, OS_GATE_SUF_B, tried, osl_tried_cap(), gpath, why)
705 var gate: *u8 = 0 as *u8
706 if found == 1 { gate = gpath }
707 if found == 0 { if (gate_arg as i64) != 0 {
708 os_jrnl(target, "PROVE" as *u8, "NO-GATE-NAMED" as *u8, tried)
709 os_puts(" [2/7] PROVE REFUSED (exit 22) -- the caller DECLARED gate=" as *u8); os_puts(gate_arg)
710 os_puts(" and no such artifact exists. Probed:" as *u8); os_puts(tried)
711 os_puts("\n UNBLOCK: build that gate first, or drop gate= and let the loop resolve it (conf row, convention, self, one-segment strip)\n" as *u8)
712 return OS_EXIT_NO_GATE_NAMED
713 } }
714 if (gate as i64) == 0 {
715 os_jrnl(target, "PROVE" as *u8, "NO-GATE-FOUND" as *u8, tried)
716 os_puts(" [2/7] PROVE NO-GATE-FOUND -- a NAMED absence, NOT a pass: NOTHING about this target has been proven. Probed:" as *u8); os_puts(tried)
717 os_puts("\n UNBLOCK: if this target has a gate under another name pass gate=<name>, or declare it with a row <target> TAB <gatename> in knowledge/organ_gate.conf; if it genuinely has no gate this ship is UNPROVEN and its last line says so\n" as *u8)
718 return OS_EXIT_NO_GATE_NAMED
719 }
720 else {
721 // 2a IS THIS GATE'S BINARY EVIDENCE ABOUT THIS RUN? The resolver hands back a PATH; the source
722 // lookup needs a NAME, and osl_name_of derives it from the same root pair the resolver probed
723 // (refusing rather than guessing when the path is under neither root, so a gate we cannot name
724 // reports UNKNOWN instead of quietly reading as up to date). gpath is rewritten in place on a
725 // successful rebuild, and `gate` points at that buffer, so the run below picks up the fresh one.
726 let gname: *u8 = sys_mmap(OSL_NAMECAP)
727 if osl_name_of(gate, OS_GATE_DIR_A, OS_GATE_SUF_A, OS_GATE_DIR_B, OS_GATE_SUF_B, gname) == 1 { vint = os_gate_freshen(gname, target, gpath) }
728 else {
729 vint = OSL_VINT_UNKNOWN_NONAME
730 os_puts(" [2a/7] GATE-VINTAGE UNKNOWN -- the resolved artifact is under neither known root, so its NAME cannot be derived and its source cannot be found: " as *u8); os_puts(gate); os_puts("\n" as *u8)
731 }
732 if osl_vint_current(vint) == 0 { nstale = nstale + 1 }
733 let gav: *i64 = sys_mmap(8 * 40) as *i64
734 gav[0] = gate as i64
735 var gi: i64 = 0
736 while gi < ng { gav[1 + gi] = gargs[gi]; gi = gi + 1 }
737 gav[1 + ng] = 0
738 let gout: *u8 = sys_mmap(OS_CAP)
739 let glen: *i64 = sys_mmap(16) as *i64
740 let grc: i64 = tr_run_capture_to(gate, gav, gout, OS_CAP - 1, glen, OS_TIMEOUT_MS)
741 os_puts(" [2/7] PROVE gate=" as *u8); os_puts(gate); os_puts(" resolved_by=" as *u8); os_puts(osl_why_name(why[0])); os_puts(" artifact=" as *u8); os_puts(os_prov(gate, target)); os_puts(" vintage=" as *u8); os_puts(osl_vint_name(vint)); os_puts(" exit=" as *u8); os_pn(grc); os_puts(" last: " as *u8); os_tail(gout, glen[0], 1)
742 if grc != 0 {
743 // A GATE THAT PRODUCED NO OUTPUT AT ALL IS NOT A RED VERDICT, and the tail below would be
744 // empty -- silence reading as a failing gate. The build-scratch artifact is the one that
745 // can be present-but-unrunnable (installed without +x is the banked class), so say which
746 // state this is instead of letting the reader infer a verdict that was never emitted.
747 if glen[0] == 0 { os_puts(" NOTE: the gate emitted ZERO BYTES -- an unrunnable artifact (e.g. no execute bit) is indistinguishable from a gate that failed silently. Check the mode of the artifact named above before reading this as a tooth failing.\n" as *u8) }
748 os_jrnl(target, "PROVE" as *u8, "RED" as *u8, gate); os_puts(" REFUSED: gate exit nonzero (exit 21). Gate tail:\n" as *u8); os_tail(gout, glen[0], 12); os_puts(" UNBLOCK: every RED tooth above names its condition; fix the source, not the tooth\n" as *u8); return 21 }
749 // THE PROOF GETS A JOURNAL ROW OF ITS OWN, naming the gate AND the rule that resolved it. After
750 // the client that saw stdout is gone, that row is the only thing that can tell a ship whose gate
751 // went GREEN from a ship whose gate was never resolved.
752 proved = 1
753 nproved = 1
754 let pdet: *u8 = sys_mmap(OS_LINE_CAP)
755 var pdo: i64 = os_cat(pdet, 0, gate)
756 pdo = os_cat(pdet, pdo, " resolved_by=" as *u8)
757 pdo = os_cat(pdet, pdo, osl_why_name(why[0]))
758 // the provenance goes in the JOURNAL too, not only on stdout: after the client that saw the
759 // terminal is gone this row is the only thing that can say WHICH artifact the verdict was about.
760 pdo = os_cat(pdet, pdo, " artifact=" as *u8)
761 pdo = os_cat(pdet, pdo, os_prov(gate, target))
762 // AND ITS VINTAGE. A GREEN row that cannot say whether the binary behind it was built from this
763 // run's tree is exactly the row that let a stale proof read as a fresh one for weeks.
764 pdo = os_cat(pdet, pdo, " vintage=" as *u8)
765 pdo = os_cat(pdet, pdo, osl_vint_name(vint))
766 os_jrnl(target, "PROVE" as *u8, "GREEN" as *u8, pdet)
767 // EVERY DECLARED GATE IS PROVEN (2026-08-23). One target may carry several organ_gate.conf rows
768 // -- the compiler is proven by one gate PER LANGUAGE RUNG -- and until today the loop ran only
769 // the first row and the conf's own comment delegated the rest to "the lane's checklist". A proof
770 // stage that proves one of four declared gates and prints SHIPPED is the vacuous-proof defect
771 // wearing a partial receipt. Rows after the one the resolver already ran are resolved through
772 // the same two artifact roots and RUN; a declared row whose artifact is absent REFUSES (exit 22,
773 // the same rule the explicit gate= path applies: a declared gate that is not there is a
774 // declaration error, never a pass), and any RED refuses exactly as the first gate would.
775 let ndecl: i64 = osl_conf_gate_count(OSL_CONF_DEFAULT, target)
776 var kdecl: i64 = 0
777 if why[0] == OSL_WHY_CONF { kdecl = 1 }
778 while kdecl < ndecl {
779 let cand2: *u8 = sys_mmap(OSL_NAMECAP)
780 if osl_conf_gate_nth(OSL_CONF_DEFAULT, target, kdecl, cand2) == 1 {
781 let tried2: *u8 = sys_mmap(osl_tried_cap())
782 tried2[0] = 0 as u8
783 let tp2: *i64 = sys_mmap(16) as *i64
784 tp2[0] = 0
785 let gpath2: *u8 = sys_mmap(OSL_PATHCAP)
786 // same freshness rule as the first gate: a declared row is almost always a DIFFERENT
787 // organ (promoted-first, unchanged), but a row may legitimately declare the target
788 // itself, and that row must run the artifact this invocation just built.
789 if osl_try_fresh(cand2, target, OS_GATE_DIR_A, OS_GATE_SUF_A, OS_GATE_DIR_B, OS_GATE_SUF_B, tried2, osl_tried_cap(), tp2, gpath2) == 0 {
790 os_jrnl(target, "PROVE" as *u8, "DECLARED-GATE-ABSENT" as *u8, cand2)
791 os_puts(" [2/7] PROVE REFUSED (exit 22) -- organ_gate.conf declares gate=" as *u8); os_puts(cand2)
792 os_puts(" for this target and no such artifact exists. Probed:" as *u8); os_puts(tried2)
793 os_puts("\n UNBLOCK: build and promote that gate first, or remove the row -- a declared gate that is not there is a declaration error, not a pass\n" as *u8)
794 return OS_EXIT_NO_GATE_NAMED
795 }
796 // EVERY DECLARED ROW GETS THE SAME VINTAGE TREATMENT. A fix applied to the first gate and
797 // not to its siblings is half a fix, and the half left undone is the one that ships: the
798 // compiler declares FIVE gates, and a stale one of those proves the previous tree exactly
799 // as silently as a stale first one would. cand2 is already the NAME, so no derivation here.
800 let vint2: i64 = os_gate_freshen(cand2, target, gpath2)
801 if osl_vint_current(vint2) == 0 { nstale = nstale + 1 }
802 gav[0] = gpath2 as i64
803 let grc2: i64 = tr_run_capture_to(gpath2, gav, gout, OS_CAP - 1, glen, OS_TIMEOUT_MS)
804 os_puts(" [2/7] PROVE gate=" as *u8); os_puts(gpath2); os_puts(" resolved_by=organ_gate.conf-declaration#" as *u8); os_pn(kdecl); os_puts(" vintage=" as *u8); os_puts(osl_vint_name(vint2)); os_puts(" exit=" as *u8); os_pn(grc2); os_puts(" last: " as *u8); os_tail(gout, glen[0], 1)
805 if grc2 != 0 { os_jrnl(target, "PROVE" as *u8, "RED" as *u8, gpath2); os_puts(" REFUSED: gate exit nonzero (exit 21). Gate tail:\n" as *u8); os_tail(gout, glen[0], 12); os_puts(" UNBLOCK: every RED tooth above names its condition; fix the source, not the tooth\n" as *u8); return 21 }
806 let pdet2: *u8 = sys_mmap(OS_LINE_CAP)
807 var pdo2: i64 = os_cat(pdet2, 0, gpath2)
808 pdo2 = os_cat(pdet2, pdo2, " resolved_by=organ_gate.conf-declaration#" as *u8)
809 pdo2 = os_catn(pdet2, pdo2, kdecl)
810 pdo2 = os_cat(pdet2, pdo2, " vintage=" as *u8)
811 pdo2 = os_cat(pdet2, pdo2, osl_vint_name(vint2))
812 os_jrnl(target, "PROVE" as *u8, "GREEN" as *u8, pdet2)
813 nproved = nproved + 1
814 }
815 kdecl = kdecl + 1
816 }
817 }
818
819 // 3+4 ADOPT-GATE: the estate's ENFORCED gate between /api/build and /api/promote (2026-08-07) --
820 // nx_contentdiff (necessary half) + nx_behaveprobe (sufficiency half) in ONE call emitting ONE
821 // machine-checkable token, deliberately neither building nor promoting so it can be re-run to audit
822 // its own decision. Composed here, never re-implemented (a duplicate ruler was already retracted once).
823 let live: *u8 = sys_mmap(256); var lo: i64 = os_cat(live, 0, target); lo = os_cat(live, lo, ".elf" as *u8)
824 let aav: *i64 = sys_mmap(8 * 40) as *i64
825 aav[0] = "./nx_adoptgate.elf" as *u8 as i64
826 aav[1] = target as i64
827 var ai2: i64 = 0
828 while ai2 < ng { aav[2 + ai2] = gargs[ai2]; ai2 = ai2 + 1 }
829 aav[2 + ng] = 0
830 let aout: *u8 = sys_mmap(OS_CAP)
831 let alen: *i64 = sys_mmap(16) as *i64
832 let arc: i64 = tr_run_capture_to("./nx_adoptgate.elf" as *u8, aav, aout, OS_CAP - 1, alen, OS_TIMEOUT_MS)
833 // COUNT THE EVIDENCE BEFORE JOURNALLING IT (2026-08-20). nx_adoptgate now passes the ruler's own
834 // "LOST: <run>" rows through, plus the count it published -- so this loop finally has something to
835 // count, and the stage row can say WHAT was dropped instead of only THAT something was.
836 var ag_named: i64 = 0
837 var li: i64 = 0
838 while li < alen[0] { let p: i64 = os_find((aout as i64 + li) as *u8, alen[0] - li, "LOST:" as *u8); if p < 0 { li = alen[0] } else { ag_named = ag_named + 1; li = li + p + 5 } }
839 let ag_lost_auth: i64 = os_int_after(aout, alen[0], "lost_from_live=" as *u8)
840 var ag_lost_bar: i64 = ag_named
841 if ag_lost_auth > ag_lost_bar { ag_lost_bar = ag_lost_auth }
842 let adet: *u8 = sys_mmap(OS_LINE_CAP)
843 var ado: i64 = os_cat(adet, 0, "named=" as *u8); ado = os_ncat(adet, ado, ag_named)
844 ado = os_cat(adet, ado, " ruler_count=" as *u8); ado = os_ncat(adet, ado, ag_lost_auth)
845 ado = os_cat(adet, ado, " bar=" as *u8); ado = os_ncat(adet, ado, ag_lost_bar)
846 ado = os_cat(adet, ado, " allow_loss=" as *u8); ado = os_ncat(adet, ado, allow_loss)
847 if arc == 0 { os_jrnl(target, "ADOPT" as *u8, "APPROVED" as *u8, adet) } else { os_jrnl(target, "ADOPT" as *u8, "REFUSED-OR-MISSING" as *u8, adet) }
848 // Complete loss evidence is retained by os_loss_exact; the adoptgate prefix is summary only.
849 os_puts(" [3+4/7] ADOPT-GATE exit=" as *u8); os_pn(arc); os_puts(" " as *u8); os_tail(aout, alen[0], 1)
850 if arc == 2 { os_puts(" (adoptgate: missing artifact -- live absent = FIRST promote of this target; proceeding, announced)\n" as *u8) }
851 else { if arc != 0 {
852 loss_live_sha=sys_mmap_try(80)
853 if (loss_live_sha as i64)<=0{return os_loss_refused("allocation-failed")}
854 os_sha_of(live,loss_live_sha)
855 let exact:i64=os_loss_exact(target,live,sha,loss_approval)
856 if exact!=0{return exact}
857 // A content allowance cannot authorize a behavior refusal. Execute the same workload now.
858 aav[0]="./nx_behaveprobe.elf" as *u8 as i64
859 let brc:i64=tr_run_capture_to("./nx_behaveprobe.elf",aav,aout,OS_CAP-1,alen,OS_TIMEOUT_MS)
860 os_puts(" [4/7] APPROVED-LOSS-BEHAVIOR ");sys_write(1,aout,alen[0])
861 if brc!=0{return os_loss_refused("behavior-comparison-refused")}
862 loss_approved=1
863 } }
864
865 // 4b HARNESS DISCLOSURE (AD2): every verdict above was produced under a configuration; write it
866 // as rows and carry its token. Two ships compare directly only when their tokens match
867 // (gv_envelope_comparable is the consumer half, in the gate base class).
868 sys_mkdir("knowledge/status/harness" as *u8, 493)
869 let hmp: *u8 = sys_mmap(512)
870 var hmo: i64 = os_cat(hmp, 0, "knowledge/status/harness/" as *u8)
871 hmo = os_cat(hmp, hmo, target)
872 os_cat(hmp, hmo, ".manifest" as *u8)
873 let hm_tok: *u8 = sys_mmap(24)
874 var hm_gate: *u8 = "-" as *u8
875 if (gate as i64) != 0 { hm_gate = gate }
876 let hm_rows: i64 = os_harness_manifest(hmp, sha, hm_gate, OS_TIMEOUT_MS, allow_loss, "" as *u8, hm_tok)
877 os_puts(" [4b/7] HARNESS manifest=" as *u8); os_puts(hmp); os_puts(" token=" as *u8); os_puts(hm_tok); os_puts(" rows=" as *u8); os_pn(hm_rows); os_puts(" scope=ship-loop(builder+rulers+gate+confs+budgets; the fix loop model/prompt half carries its own token)\n" as *u8)
878 os_jrnl(target, "HARNESS" as *u8, "MANIFEST" as *u8, hm_tok)
879
880 // Recheck the reviewed live artifact after behavior execution; staged CAS remains the API guard.
881 if loss_approved==1{
882 let current:*u8=sys_mmap_try(80);if (current as i64)<=0{return os_loss_refused("allocation-failed")}
883 os_sha_of(live,current);let unchanged:i64=os_streq(current,loss_live_sha);sys_munmap_direct(current,80);sys_munmap_direct(loss_live_sha,80)
884 if unchanged!=1{return os_loss_refused("live-artifact-changed-after-review")}
885 }
886
887 // 5 PROMOTE with expect_sha256, then READ THE ARTIFACT
888 let pb: *u8 = sys_mmap(512)
889 var pbo: i64 = os_cat(pb, 0, "target=" as *u8); pbo = os_cat(pb, pbo, target); pbo = os_cat(pb, pbo, "&confirm=yes&expect_sha256=" as *u8); pbo = os_cat(pb, pbo, sha)
890 if loss_approved == 1 { pbo = os_cat(pb, pbo, "&allow_capability_loss=yes" as *u8) }
891 os_mgmt("POST" as *u8, "/api/promote" as *u8, pb, out, olen)
892 let livesha: *u8 = sys_mmap(80)
893 os_sha_of(live, livesha)
894 os_puts(" [5/7] PROMOTE response_bytes=" as *u8); os_pn(olen[0]); os_puts(" live_sha=" as *u8); os_puts(livesha); os_puts(" staged_sha=" as *u8); os_puts(sha); os_puts("\n" as *u8)
895 if os_streq(livesha, sha) == 0 {
896 // one settle re-read: the banked cache-fossil class
897 os_sha_of(live, livesha)
898 if os_streq(livesha, sha) == 0 { os_puts(" REFUSED: live artifact != staged sha after promote (exit 51) -- the receipt is not the artifact. Response tail:\n" as *u8); os_tail(out, olen[0], 4); os_puts(" UNBLOCK: read the response (artefact-mismatch = a sibling restaged; NOTHING-STAGED with live==sha = it DID land, re-run to confirm)\n" as *u8); return 51 }
899 os_puts(" (settle re-read matched -- the first sha read was a fossil, banked class)\n" as *u8)
900 }
901
902 // 5b OFFC TWIN (LM-026, banked): /api/promote writes the SERVING ROOT; runners (nx_job_run, a beat's
903 // own fork) exec _offc/<target>.elf. A promote that does not refresh the twin leaves every runner on
904 // the OLD binary -- measured 2026-08-18: the ranker and fleet promoted, ran fine as MCP tools, and
905 // their _offc twins were ABSENT (a runner would exec staleness). nx_offc_install is the atomic organ
906 // for exactly this; announced, not silently skipped when there is no twin to refresh.
907 let oav: *i64 = sys_mmap(8 * 4) as *i64
908 oav[0] = "./nx_offc_install.elf" as *u8 as i64
909 oav[1] = target as i64
910 oav[2] = 0
911 let oout: *u8 = sys_mmap(OS_SMALL_CAP)
912 let oolen: *i64 = sys_mmap(16) as *i64
913 tr_run_capture_to("./nx_offc_install.elf" as *u8, oav, oout, OS_SMALL_CAP - 1, oolen, OS_TIMEOUT_MS)
914 os_puts(" [5b/7] OFFC-TWIN " as *u8); os_tail(oout, oolen[0], 1)
915
916 // 6 REGISTER
917 if noregister == 0 {
918 let rb: *u8 = sys_mmap(512)
919 var rbo: i64 = os_cat(rb, 0, "name=" as *u8); rbo = os_cat(rb, rbo, target); rbo = os_cat(rb, rbo, "&elf=" as *u8); rbo = os_cat(rb, rbo, target); rbo = os_cat(rb, rbo, ".elf&confirm=yes" as *u8)
920 os_mgmt("POST" as *u8, "/api/tools/register" as *u8, rb, out, olen)
921 os_puts(" [6/7] REGISTER " as *u8); os_tail(out, olen[0], 1)
922 } else { os_puts(" [6/7] REGISTER skipped (noregister)\n" as *u8) }
923
924 // 6b DOC-ADOPTION (report-only; its return value is deliberately discarded)
925 os_doc_stage(target)
926
927 // 7 VERIFY-LIVE
928 if (verify_url as i64) != 0 {
929 let vav: *i64 = sys_mmap(8 * 4) as *i64
930 vav[0] = "./nx_page_verify.elf" as *u8 as i64
931 vav[1] = verify_url as i64
932 vav[2] = 0
933 let vout: *u8 = sys_mmap(OS_CAP)
934 let vlen: *i64 = sys_mmap(16) as *i64
935 tr_run_capture_to("./nx_page_verify.elf" as *u8, vav, vout, OS_CAP - 1, vlen, OS_TIMEOUT_MS)
936 os_puts(" [7/7] VERIFY " as *u8); os_tail(vout, vlen[0], 1)
937 if os_find(vout, vlen[0], "VERDICT=GREEN" as *u8) < 0 { os_puts(" REFUSED: live verify not GREEN (exit 71). UNBLOCK: read the asset lines above; a status=0 bytes=82 is the client bad-url class, a 404 is a missing publish\n" as *u8); return 71 }
938 } else { os_puts(" [7/7] VERIFY skipped (no verify_url)\n" as *u8) }
939
940 let sdet: *u8 = sys_mmap(OS_LINE_CAP); var sdo: i64 = os_cat(sdet, 0, sha); sdo = os_cat(sdet, sdo, " bytes=" as *u8); sdo = os_ncat(sdet, sdo, os_bytes_of(live)); os_jrnl(target, "SHIPPED" as *u8, "GREEN" as *u8, sdet)
941 os_puts("SHIPPED " as *u8); os_puts(target); os_puts(" sha=" as *u8); os_puts(sha); os_puts(" harness=" as *u8); os_puts(hm_tok)
942 // THE LAST LINE CARRIES WHETHER THE PROOF STAGE ACTUALLY RAN. A positional reader takes the final
943 // line as the verdict, and a ship whose gate was never resolved is NOT the same event as one whose
944 // gate went GREEN -- printing SHIPPED without saying which is exactly how a skipped proof stays
945 // invisible to every reader of this loop.
946 if proved == 1 { os_puts(" prove=GREEN gate=" as *u8); os_puts(gate); os_puts(" resolved_by=" as *u8); os_puts(osl_why_name(why[0])); os_puts(" artifact=" as *u8); os_puts(os_prov(gate, target)); os_puts(" gate_vintage=" as *u8); os_puts(osl_vint_name(vint)); os_puts(" gates_proven=" as *u8); os_pn(nproved); os_puts(" of_declared=" as *u8); os_pn(osl_conf_gate_count(OSL_CONF_DEFAULT, target)); os_puts(" gates_not_current=" as *u8); os_pn(nstale)
947 // A POSITIONAL READER TAKES THE LAST LINE AS THE VERDICT, so a GREEN produced by a binary older
948 // than the edit being shipped must say so HERE, not only in the stage lines above. This is the
949 // whole reason the loud fallback is safe: the ship proceeds, and it proceeds ANNOUNCED.
950 if nstale > 0 { os_puts(" -- WARNING: that many gate verdict(s) came from an artifact this run could NOT make current (read the GATE-VINTAGE / GATE-REBUILD lines above): the proof is about an OLDER tree than the one just promoted" as *u8) } }
951 else { os_puts(" prove=NO-GATE-FOUND UNPROVEN -- no gate resolved for this target; the PROVE stage above names every path it probed" as *u8) }
952 os_puts(" -- every stage above carries its evidence line\n" as *u8)
953 return 0
954}
955