code wiki / _hdl_build / nx_pub_reader_receipt_gate.nx
nx_pub_reader_receipt_gate.nx source
↩ module page · 81 lines · 5038 B
1import "nx_gate_gn.nx"
2// nx_pub_reader_receipt_gate.nx -- liar-kill gate: passing the reader/shelf to the publisher yields a SIGNED,
3// VERIFIABLE deployment receipt (operator "get a receipt it deployed"). Self-contained + sovereign (fork/exec):
4// render -> shelf -> handoff (publish) -> reader-receipt (emit+verify signed receipts), then assert the receipts
5// are PUBLISHED, keyed by the real content-sha, live-bytes==ledger (MATCH), and the receipt organ self-reports
6// 4/4 (which it only does when every Ed25519 signature verifies). Teeth: a bogus dest has NO receipt.
7// expect_exit: 0
8import "nx_syscalls.nx"
9import "nx_gate_verdict.nx"
10
11func gp(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 }
12func gslen(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} return n }
13func gfind(hay: *u8, hl: i64, needle: *u8) -> i64 {
14 let nl: i64 = gslen(needle); if nl == 0 { return 0-1 }
15 var i: i64 = 0
16 while i + nl <= hl { var k: i64=0; var hit: i64=1; while k<nl { if hay[i+k]!=needle[k]{hit=0;k=nl}else{k=k+1} } if hit==1 {return i} i=i+1 }
17 return 0-1
18}
19func ghas(hay: *u8, hl: i64, needle: *u8) -> i64 { if gfind(hay, hl, needle) >= 0 { return 1 } return 0 }
20func spawn(path: *u8, a0: *u8, a1: *u8, redir: *u8) -> i64 {
21 let pid: i64 = sys_fork()
22 if pid == 0 {
23 let fd: i64 = sys_openat_wr(redir, 420)
24 if fd >= 0 { sys_dup3(fd, 1, 0); sys_dup3(fd, 2, 0) }
25 let argv: *i64 = sys_mmap(64) as *i64
26 var n: i64 = 0
27 argv[0] = path as i64; n = 1
28 if (a0 as i64) != 0 { argv[n] = a0 as i64; n = n + 1 }
29 if (a1 as i64) != 0 { argv[n] = a1 as i64; n = n + 1 }
30 argv[n] = 0
31 let envp: *i64 = sys_mmap(16) as *i64
32 envp[0] = "PATH=/usr/bin:/bin\x00" as *u8 as i64; envp[1] = 0
33 sys_execve(path, argv, envp)
34 sys_exit(127)
35 }
36 let st: *i64 = sys_mmap(16) as *i64
37 sys_wait4(pid, st, 0)
38 return (st[0] >> 8) & 0xff
39}
40
41func main() -> i64 {
42 gp("=== nx_pub_reader_receipt_gate: signed deployment receipt from the publisher (return-and-report) ===\n" as *u8)
43 let RUNNER: *u8 = "_offc/nx_sov_build_run.elf\x00" as *u8
44 let SC: *u8 = "knowledge/status/pub_reader_receipt_gate_scratch.log\x00" as *u8
45
46 spawn("_offc/nx_epub_book.elf\x00" as *u8, "knowledge/fixtures/nishi_fixture.epub\x00" as *u8, "nishi_fixture\x00" as *u8, SC)
47 spawn(RUNNER, "nx_reader_render\x00" as *u8, 0 as *u8, SC)
48 spawn(RUNNER, "nx_library_shelf\x00" as *u8, 0 as *u8, SC)
49 spawn(RUNNER, "nx_pub_reader_handoff\x00" as *u8, 0 as *u8, SC)
50 let rrc: i64 = spawn(RUNNER, "nx_pub_reader_receipt\x00" as *u8, 0 as *u8, SC)
51 gp(" receipt organ runner-exit=" as *u8); gn(rrc); gp(" (0 => all 4 PUBLISHED + live==ledger + signature verified)\n" as *u8)
52
53 var pass: i64 = 0; var fail: i64 = 0
54 // the receipt organ exits 0 ONLY if every artifact is PUBLISHED, live-bytes==ledger-sha, AND its Ed25519 sig verifies
55 if rrc == 0 { pass=pass+1 } else { fail=fail+1; gp(" FAIL receipt-not-4of4\n" as *u8) }
56
57 // durable signed receipts on disk, keyed by content-sha + dest
58 let lp: *i64 = sys_mmap(8) as *i64; lp[0]=0
59 let rc: *u8 = sys_read_file("knowledge/publish/reader-receipts.tsv\x00" as *u8, lp)
60 if (rc as i64) == 0 { gp("PUB-READER-RECEIPT-GATE verdict=RED reason=receipts-missing\n" as *u8); sys_exit(1); return 1 }
61 let n: i64 = lp[0]
62 if ghas(rc, n, "PUBLISHED" as *u8) == 1 { pass=pass+1 } else { fail=fail+1; gp(" FAIL no-PUBLISHED\n" as *u8) }
63 if ghas(rc, n, "library_shelf.html" as *u8) == 1 { pass=pass+1 } else { fail=fail+1; gp(" FAIL no-shelf-receipt\n" as *u8) }
64 if ghas(rc, n, "reader/nishi_fixture/cover.png" as *u8) == 1 { pass=pass+1 } else { fail=fail+1; gp(" FAIL no-cover-receipt\n" as *u8) }
65 if ghas(rc, n, "MATCH" as *u8) == 1 { pass=pass+1 } else { fail=fail+1; gp(" FAIL no-MATCH(live==ledger)\n" as *u8) }
66 // keyed by the REAL content sha (cross-check vs the ledger's shelf sha)
67 if ghas(rc, n, "b2de5dfb8652484e182b42d6b2a24211f662c3c487eeaabd31d64bcad21976dc" as *u8) == 1 { pass=pass+1 } else { fail=fail+1; gp(" FAIL receipt-not-keyed-by-content-sha\n" as *u8) }
68 // teeth: no receipt for a bogus dest
69 if gfind(rc, n, "reader/bogus_xyz/none.png" as *u8) < 0 { pass=pass+1 } else { fail=fail+1; gp(" FAIL teeth\n" as *u8) }
70
71 gp("PUB-READER-RECEIPT-GATE pass=" as *u8); gn(pass); gp(" fail=" as *u8); gn(fail)
72 // MIGRATED onto nx_gate_verdict by nx_gate_dry_apply (D001, minimal form): every check
73 // row above is untouched, so the PASS/FAIL vector cannot change; only the hand-rolled
74 // verdict emission is replaced by the ONE shared base class. Proven by nx_gate_migrate verify.
75 let ctr__dry: *i64 = gv_ctr()
76 ctr__dry[0] = pass
77 ctr__dry[1] = pass + fail
78 let rc__dry: i64 = gv_verdict("PUB-READER-RECEIPT-GATE" as *u8, ctr__dry, "publisher returned signed PUBLISHED receipts; live-bytes==ledger; Ed25519 verified)" as *u8)
79 sys_exit(rc__dry)
80 return rc__dry
81}