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