code wiki / (root) / nx_craft_emit.nx

nx_craft_emit.nx source

↩ module page · 169 lines · 10009 B

1// nx_craft_emit.nx -- THE SOVEREIGN CRAFT SHIP LANE (retires _ops/nx_emit_game.sh's laptop/WSL 2// dependency for /world/craft): gate-check -> .nx -> .wat -> .wasm -> page -> live docroot, 3// every stage BYTE-ASSERTED before the next runs (the emit script's founding law, organ form: 4// a green tool on empty input is not a check -- a 0-byte .wat once shipped a 20-byte "game"). 5// The page itself is built IN-PROCESS by gpe_build (nx_game_page_emit as a LIB -- one emitter, 6// not a fork), and the deploy is tmp+rename with a READ-BACK byte+marker assert (what LANDED 7// is the claim, never what was written). Gate RED = refuses to emit anything at all. 8// usage: nx_craft_emit (runs from nishihost cwd like every registered tool) 9// exit: 0 SHIPPED | 2 gate-red | 3 wat | 4 wasm | 5 page | 6 deploy | 7 readback 10// license_tier: ORIGINAL No hw writes (Rule 26). 11import "nx_syscalls.nx" 12import "nx_game_page_emit.nx" 13 14const CE_GATE: *u8 = "nx_wasm_craft_gate.elf" 15const CE_CWAT: *u8 = "nx_compile_wat.elf" 16const CE_WATC: *u8 = "nx_wat_compiler.elf" 17const CE_SRC: *u8 = "buildroot/runtime/nx_wasm_craft.nx" 18const CE_WAT: *u8 = "buildroot/_build/nx_wasm_craft_emit.wat" 19const CE_WASM: *u8 = "buildroot/_build/nx_wasm_craft_emit.wasm" 20const CE_TMP: *u8 = "sites/nishifamily/world/craft.html.stage" 21const CE_OUT: *u8 = "sites/nishifamily/world/craft.html" 22const CE_TITLE: *u8 = "NISHI CRAFT - SOVEREIGN 3D" 23const CE_NATIVE: *u8 = "nx_desktop_craft" 24// the REVIEW STAGE (identity v2 = NISHI SHORE): same gated wasm, second spec, second page -- 25// one engine, many worlds is the emission lever actually being pulled 26const CE_TMP2: *u8 = "sites/nishifamily/world/beach.html.stage" 27const CE_OUT2: *u8 = "sites/nishifamily/world/beach.html" 28const CE_TITLE2: *u8 = "NISHI SHORE - REVIEW STAGE" 29const CE_CTRL2: *u8 = "the flat-light REVIEW STAGE: mixed beachwear across the cast (bred, stable per girl) &middot; same engine, same controls as <a href=\"craft\">NISHI CRAFT</a> &middot; ?review=1 auto-frames the nearest girl<br>ISEKAI: cross to <a href=\"craft\">NISHI CRAFT</a> or <a href=\"vale\">NISHI VALE</a> &mdash; level, ledger and party come along" 30// v3 = the medieval VALE: the third world, built from data rows alone. Your traveler carries 31// his ledger and party between all three -- the passport lives under one key for every world. 32const CE_TMP3: *u8 = "sites/nishifamily/world/vale.html.stage" 33const CE_OUT3: *u8 = "sites/nishifamily/world/vale.html" 34const CE_TITLE3: *u8 = "NISHI VALE - THE MEDIEVAL HIGHLAND" 35const CE_CTRL3: *u8 = "deep woods, cold snowline, cave-riddled stone &mdash; and wardens who hunt WIDE by day &middot; your traveler arrives with his ledger, his level and his party from <a href=\"craft\">NISHI CRAFT</a> or <a href=\"beach\">NISHI SHORE</a> &middot; <b>G</b> invites a bonded girl to your party &middot; same controls" 36const CE_CTRL: *u8 = "click canvas = MOUSELOOK (Esc frees) &middot; <b>WASD</b> move &middot; <b>SPACE</b> jump &middot; L/R-click or <b>E</b>/<b>B</b> break/place &middot; <b>Q</b> cycles 7 slots (blocks &middot; HOE &middot; SEEDS) &middot; till grass, plant, let rain or a pond do the rest, break the GOLDEN crop = harvest &middot; <b>E</b> on a girl = meet her, <b>G</b> invites her to your party &middot; nights are the wardens' &middot; <b>H</b> home &middot; gamepad + touch<br>ISEKAI: your level, ledger and party travel with you &mdash; walk into <a href=\"beach\">NISHI SHORE</a> or <a href=\"vale\">NISHI VALE</a> &middot; <a href=\"craft_immersion\">what is broken and what is next</a>" 37const CE_MIN_WAT: i64 = 500000 38const CE_MIN_WASM: i64 = 50000 39const CE_MIN_PAGE: i64 = 100000 40const CE_MODE: i64 = 0x1a4 41 42func ce_slen(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n } 43func ce_puts(s: *u8) -> i64 { sys_write(1, s, ce_slen(s)); return 0 } 44func ce_pn(v: i64) -> i64 { 45 if v == 0 { sys_write(1, "0" as *u8, 1); return 0 } 46 var m: i64 = v 47 if m < 0 { sys_write(1, "-" as *u8, 1); m = 0 - m } 48 let t: *u8 = sys_mmap(32) 49 var k: i64 = 0 50 while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 } 51 let o: *u8 = sys_mmap(32) 52 var i: i64 = 0 53 while i < k { o[i] = t[k - 1 - i]; i = i + 1 } 54 sys_write(1, o, k) 55 return 0 56} 57// the nx_aw_push fork-a-sovereign-sub-ELF pattern (spine shared with nx_emu_probe_wasm_gate) 58func ce_run(elf: *u8, a1: *u8, a2: *u8) -> i64 { 59 let pid: i64 = sys_fork() 60 if pid == 0 { 61 let argv: *i64 = sys_mmap(64) as *i64 62 argv[0] = elf as i64 63 var ai: i64 = 1 64 if (a1 as i64) != 0 { argv[ai] = a1 as i64; ai = ai + 1 } 65 if (a2 as i64) != 0 { argv[ai] = a2 as i64; ai = ai + 1 } 66 argv[ai] = 0 67 let envp: *i64 = sys_mmap(16) as *i64 68 envp[0] = "PATH=/usr/bin:/bin" as *u8 as i64 69 envp[1] = 0 70 sys_execve(elf, argv, envp) 71 sys_exit(127) 72 } 73 let st: *i64 = sys_mmap(16) as *i64 74 sys_wait4(pid, st, 0) 75 return (st[0] >> 8) & 0xff 76} 77func ce_find(hay: *u8, n: i64, needle: *u8) -> i64 { 78 let nl: i64 = ce_slen(needle) 79 if nl == 0 { return 1 } 80 var i: i64 = 0 81 while i + nl <= n { 82 var j: i64 = 0 83 var hit: i64 = 1 84 while j < nl { if hay[i + j] != needle[j] { hit = 0; j = nl } else { j = j + 1 } } 85 if hit == 1 { return 1 } 86 i = i + 1 87 } 88 return 0 89} 90func ce_fsize(p: *u8) -> i64 { 91 let box: *i64 = sys_mmap(16) as *i64 92 let b: *u8 = sys_read_file(p, box) 93 if (b as i64) == 0 { return 0 - 1 } 94 return box[0] 95} 96 97func main() -> i64 { 98 // 1) THE GATE DECIDES: a RED world ships nothing (the emit script's step-2 law) 99 ce_puts("[1/5] gate " as *u8) 100 let g: i64 = ce_run(CE_GATE, 0 as *u8, 0 as *u8) 101 if g != 0 { ce_puts("RED rc=" as *u8); ce_pn(g); ce_puts(" -- REFUSED, nothing emitted\n" as *u8); return 2 } 102 ce_puts("GREEN\n" as *u8) 103 104 // 1b) THE FEEL ORACLE: every tunable inside its banked, cited reference band (the KAT 105 // pattern applied to feel) -- out-of-band tuning cannot ship through this lane 106 ce_puts("[1b/5] feel-oracle " as *u8) 107 let g2: i64 = ce_run("nx_gamefeel_oracle_gate.elf" as *u8, 0 as *u8, 0 as *u8) 108 if g2 != 0 { ce_puts("RED rc=" as *u8); ce_pn(g2); ce_puts(" -- REFUSED, nothing emitted\n" as *u8); return 2 } 109 ce_puts("GREEN\n" as *u8) 110 111 // 2) .nx -> .wat (byte-asserted: the historic silent 0-byte .wat is the class this kills) 112 let r1: i64 = ce_run(CE_CWAT, CE_SRC, CE_WAT) 113 let wn1: i64 = ce_fsize(CE_WAT) 114 ce_puts("[2/5] wat rc=" as *u8); ce_pn(r1); ce_puts(" bytes=" as *u8); ce_pn(wn1); ce_puts("\n" as *u8) 115 if wn1 < CE_MIN_WAT { ce_puts("EMIT-FAIL: wat under floor\n" as *u8); return 3 } 116 117 // 3) .wat -> .wasm (magic-checked -- a "GREEN" assembler on empty input still writes a stub) 118 let r2: i64 = ce_run(CE_WATC, CE_WAT, CE_WASM) 119 let box: *i64 = sys_mmap(16) as *i64 120 let wasm: *u8 = sys_read_file(CE_WASM, box) 121 ce_puts("[3/5] wasm rc=" as *u8); ce_pn(r2); ce_puts(" bytes=" as *u8); ce_pn(box[0]); ce_puts("\n" as *u8) 122 if (wasm as i64) == 0 { ce_puts("EMIT-FAIL: no wasm\n" as *u8); return 4 } 123 if box[0] < CE_MIN_WASM { ce_puts("EMIT-FAIL: wasm under floor\n" as *u8); return 4 } 124 if wasm[0] != (0 as u8) { ce_puts("EMIT-FAIL: bad magic\n" as *u8); return 4 } 125 if wasm[1] != (97 as u8) { ce_puts("EMIT-FAIL: bad magic\n" as *u8); return 4 } 126 if wasm[2] != (115 as u8) { ce_puts("EMIT-FAIL: bad magic\n" as *u8); return 4 } 127 if wasm[3] != (109 as u8) { ce_puts("EMIT-FAIL: bad magic\n" as *u8); return 4 } 128 129 // 4) the page, IN-PROCESS (gpe_build is the ONE emitter; no second template can drift) 130 let out: *u8 = sys_mmap(GPE_OUT_CAP) 131 let pn: i64 = gpe_build(wasm, box[0], CE_TITLE, CE_NATIVE, CE_CTRL, 0, out) 132 ce_puts("[4/5] page bytes=" as *u8); ce_pn(pn); ce_puts("\n" as *u8) 133 if pn < CE_MIN_PAGE { ce_puts("EMIT-FAIL: page under floor\n" as *u8); return 5 } 134 135 // 5) deploy tmp+rename, then READ BACK: bytes equal AND the loader marker present in what 136 // LANDED -- the filesystem is the oracle for an evidence row 137 if ce_ship(out, pn, CE_TMP, CE_OUT) != 0 { return 6 } 138 // 5b) THE REVIEW STAGE: identity v2 over the SAME gated wasm bytes 139 let out2: *u8 = sys_mmap(GPE_OUT_CAP) 140 let pn2: i64 = gpe_build(wasm, box[0], CE_TITLE2, CE_NATIVE, CE_CTRL2, 2, out2) 141 if pn2 < CE_MIN_PAGE { ce_puts("EMIT-FAIL: shore page under floor\n" as *u8); return 5 } 142 if ce_ship(out2, pn2, CE_TMP2, CE_OUT2) != 0 { return 6 } 143 // 5c) THE THIRD WORLD, same gated wasm bytes -- one engine, three identities 144 let out3: *u8 = sys_mmap(GPE_OUT_CAP) 145 let pn3: i64 = gpe_build(wasm, box[0], CE_TITLE3, CE_NATIVE, CE_CTRL3, 3, out3) 146 if pn3 < CE_MIN_PAGE { ce_puts("EMIT-FAIL: vale page under floor\n" as *u8); return 5 } 147 if ce_ship(out3, pn3, CE_TMP3, CE_OUT3) != 0 { return 6 } 148 return 0 149} 150 151func ce_ship(out: *u8, pn: i64, tmpp: *u8, outp: *u8) -> i64 { 152 let fd: i64 = sys_openat_wr(tmpp, CE_MODE) 153 if fd < 0 { ce_puts("EMIT-FAIL: stage open\n" as *u8); return 6 } 154 var off: i64 = 0 155 while off < pn { 156 let w: i64 = sys_write(fd, ((out as i64) + off) as *u8, pn - off) 157 if w <= 0 { sys_close(fd); ce_puts("EMIT-FAIL: stage write\n" as *u8); return 6 } 158 off = off + w 159 } 160 sys_close(fd) 161 if sys_renameat(tmpp, outp) < 0 { ce_puts("EMIT-FAIL: rename\n" as *u8); return 6 } 162 let box2: *i64 = sys_mmap(16) as *i64 163 let back: *u8 = sys_read_file(outp, box2) 164 if (back as i64) == 0 { ce_puts("EMIT-FAIL: readback\n" as *u8); return 7 } 165 if box2[0] != pn { ce_puts("EMIT-FAIL: readback bytes " as *u8); ce_pn(box2[0]); ce_puts(" != " as *u8); ce_pn(pn); ce_puts("\n" as *u8); return 7 } 166 if ce_find(back, box2[0], "WebAssembly.instantiate" as *u8) == 0 { ce_puts("EMIT-FAIL: loader marker missing\n" as *u8); return 7 } 167 ce_puts("[5/5] SHIPPED " as *u8); ce_pn(pn); ce_puts(" bytes -> " as *u8); ce_puts(outp); ce_puts(" (read back, marker verified)\n" as *u8) 168 return 0 169}