code wiki / _hdl_build / nx_pub_smoke_gate.nx
nx_pub_smoke_gate.nx source
↩ module page · 94 lines · 7106 B
1// nx_pub_smoke_gate.nx -- R9 PROOF + MEASURED HEAD-TO-HEAD: post-deploy HTTP smoke test + health-gated auto-rollback.
2//
3// The publisher's pre-promote sha-verify (pub_deploy) proves the staged BYTES are right; it is BLIND to whether the
4// live URL actually SERVES them. This gate forks the publisher's own static server, then stages a "disk-OK but URL
5// broken" failure (the content lands where the served URL does NOT map -- the literal sites.elf shape: a deploy that
6// "succeeded" on disk while the world gets nothing) and measures, head-to-head, over real loopback HTTP:
7// NAIVE blind deploy : writes bytes, reports SUCCESS, never checks the URL -> ships broken-but-claims-success.
8// pub_deploy_smoke : promotes, GETs the live URL, hashes the SERVED body -> catches it, auto-rolls-back, REJECTS.
9// EXCEEDS iff naive false-successes > 0 (the gap is REAL, not a strawman -- liar-kill) AND publisher false-successes = 0.
10// Sovereign both sides (our sockets), per-wsid liveroot+port. license_tier: ORIGINAL expect_exit: 0
11import "nx_syscalls.nx"
12import "nx_publisher.nx"
13import "nx_pub_serve.nx"
14import "nx_runpath.nx"
15
16func g_w(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 }
17func g_n(v: i64) -> i64 { var m: i64=v; if m<0{g_w("-" as *u8);m=0-m} let t:*u8=sys_mmap(24); var k:i64=0; if m==0{t[0]=48 as u8;k=1} while m>0{t[k]=(48+(m%10)) as u8;m=m/10;k=k+1} var i:i64=0; let o:*u8=sys_mmap(24); while i<k{o[i]=t[k-1-i];i=i+1} sys_write(1,o,k); return 0 }
18func g_row(id: *u8, ok: i64, pass: *i64) -> i64 { g_w(" " as *u8); g_w(id); g_w(": " as *u8); if ok==1 { g_w("OK\n" as *u8); pass[0]=pass[0]+1 } else { g_w("FAIL\n" as *u8) } return 0 }
19func sv_write(path: *u8, content: *u8) -> i64 { let fd: i64 = sys_openat_wr(path, 0x1a4); if fd<0 { return 0 } var n: i64=0; while content[n]!=(0 as u8){n=n+1} sys_write(fd, content, n); sys_close(fd); return 1 }
20
21func main() -> i64 {
22 let pass: *i64 = sys_mmap(8) as *i64; pass[0]=0
23 g_w("=== NX-PUB-SMOKE GATE (post-deploy HTTP smoke + health-gated auto-rollback; measured vs naive) ===\n" as *u8)
24 let wsid: *u8 = sys_mmap(64); rp_wsid(wsid); rp_ensure(wsid)
25 let liveroot: *u8 = sys_mmap(512); rp_path(wsid, "pks_live" as *u8, liveroot); __syscall(83, liveroot as i64, 493, 0, 0, 0, 0)
26 let stageroot: *u8 = sys_mmap(512); rp_path(wsid, "pks_stage" as *u8, stageroot); __syscall(83, stageroot as i64, 493, 0, 0, 0, 0)
27 var psum: i64 = 0; var pj: i64 = 0; while wsid[pj]!=(0 as u8){ psum = psum + (wsid[pj] as i64); pj = pj + 1 }
28 let port: i64 = 18920 + (psum % 300)
29
30 // the approved NEW artifact (C2) + its sha; and the last-good page (C1) already live at the URL.
31 let src2: *u8 = sys_mmap(512); pub_join(stageroot, "src2.html" as *u8, src2)
32 sv_write(src2, "<h1>SHIPPED-V2</h1>\n" as *u8)
33 let sha2: *u8 = sys_mmap(72); pub_sha_file(src2, sha2)
34
35 let livepage: *u8 = sys_mmap(700); pub_join(liveroot, "page.html" as *u8, livepage)
36 let stagepage: *u8 = sys_mmap(700); pub_join(stageroot, "page.html" as *u8, stagepage)
37 let typopath: *u8 = sys_mmap(700); pub_join(liveroot, "page_typo.html" as *u8, typopath) // a path the URL does NOT map to
38 let stagetypo: *u8 = sys_mmap(700); pub_join(stageroot, "page_typo.html" as *u8, stagetypo)
39 sv_write(livepage, "<h1>LASTGOOD-V1</h1>\n" as *u8) // C1 live at the URL
40
41 let pid: i64 = sys_fork()
42 if pid == 0 { psv_listen(liveroot, port); sys_exit(0) } // child: serve liveroot forever
43
44 let resp: *u8 = sys_mmap(262144)
45
46 // ---- scenario GOOD: correct-path deploy -> smoke verifies the live URL serves C2 (happy path works e2e) ----
47 let r_good: i64 = pub_deploy_smoke(sha2, src2, stagepage, livepage, port, "page.html" as *u8)
48 let ng: i64 = pub_http_get(port, "page.html" as *u8, resp, 262144)
49 let good_serves_v2: i64 = pub_substr(resp, ng, "SHIPPED-V2" as *u8)
50
51 // reset the served URL back to the last-good C1 for the broken scenario
52 sv_write(livepage, "<h1>LASTGOOD-V1</h1>\n" as *u8)
53
54 // ---- scenario BROKEN-SERVE: content lands at a path the URL does NOT serve (disk OK, URL broken) ----
55 var naive_false: i64 = 0
56 var k: i64 = 0
57 while k < 5 {
58 pub_copy(src2, typopath) // NAIVE blind deploy (writes to wrong served path), "succeeds"
59 let nn: i64 = pub_http_get(port, "page.html" as *u8, resp, 262144)
60 if pub_substr(resp, nn, "SHIPPED-V2" as *u8) == 0 { naive_false = naive_false + 1 } // claimed success but URL has no V2
61 k = k + 1
62 }
63 var pub_false: i64 = 0
64 k = 0
65 while k < 5 {
66 let rb: i64 = pub_deploy_smoke(sha2, src2, stagetypo, typopath, port, "page.html" as *u8)
67 let mm: i64 = pub_http_get(port, "page.html" as *u8, resp, 262144)
68 let serves_v2: i64 = pub_substr(resp, mm, "SHIPPED-V2" as *u8)
69 if rb == 1 { if serves_v2 == 0 { pub_false = pub_false + 1 } } // false success = reported PUBLISHED but URL can't serve it
70 k = k + 1
71 }
72 // after the broken scenario, the live URL must STILL serve the last-good C1 (never left broken)
73 let nf: i64 = pub_http_get(port, "page.html" as *u8, resp, 262144)
74 let url_still_good: i64 = pub_substr(resp, nf, "LASTGOOD-V1" as *u8)
75
76 __syscall(129, pid, 9, 0, 0, 0, 0) // kill the server -- rv64 kill=129; raw x86 62 is an RV64 KEY translated to lseek(8) (debt idx 2277)
77 let st: *i64 = sys_mmap(8) as *i64; var rr: i64 = 0; while rr < 20 { sys_wait4(0 - 1, st, 1); rr = rr + 1 }
78
79 g_w(" port=" as *u8); g_n(port); g_w(" r_good=" as *u8); g_n(r_good); g_w(" naive_false_success=" as *u8); g_n(naive_false); g_w("/5 publisher_false_success=" as *u8); g_n(pub_false); g_w("/5\n" as *u8)
80 g_row("GOOD: pub_deploy_smoke PUBLISHED + smoke-verified the happy path (r_good==1)" as *u8, (r_good==1) as i64, pass)
81 g_row("GOOD: the live URL actually serves the new artifact (C2) end-to-end" as *u8, good_serves_v2, pass)
82 g_row("BASELINE REAL: naive blind deploy ships broken-but-claims-success (>0, no strawman)" as *u8, (naive_false>0) as i64, pass)
83 g_row("PUBLISHER: never falsely reports a publish the URL cannot serve (false_success==0)" as *u8, (pub_false==0) as i64, pass)
84 g_row("SAFETY: after the broken scenario the live URL STILL serves the last-good page" as *u8, url_still_good, pass)
85
86 let exceeds: i64 = ((naive_false>0) as i64) & ((pub_false==0) as i64)
87 g_w("\n HEAD-TO-HEAD: naive false-successes=" as *u8); g_n(naive_false); g_w(" vs publisher=" as *u8); g_n(pub_false)
88 if exceeds==1 { g_w(" => EXCEEDS (measured, liar-kill: naive gap is real)\n" as *u8) } else { g_w(" => NOT EXCEEDS\n" as *u8) }
89 g_row("MEASURED EXCEEDS on end-to-end served verification + auto-rollback" as *u8, exceeds, pass)
90
91 g_w("NX-PUB-SMOKE rows=6 pass=" as *u8); g_n(pass[0])
92 if pass[0]==6 { g_w(" verdict=GREEN\n" as *u8); sys_exit(0); return 0 }
93 g_w(" verdict=RED\n" as *u8); sys_exit(1); return 1
94}