code wiki / _hdl_build / nx_pub_teacher_handoff.nx
nx_pub_teacher_handoff.nx source
↩ module page · 61 lines · 3988 B
1// nx_pub_teacher_handoff.nx -- the TEACHER -> NISHI PUBLISHER handoff (coordination, done RIGHT).
2//
3// Operator (2026-06-20): "you dont publish, you pass to nishi publisher who manages all this." The REAL
4// Nishi Publisher already exists ([[project-nishi-publisher-role-2026-06-20]], 9 gates GREEN, S-class
5// exceed) -- so the teacher does NOT reinvent publishing (BL-012 before-build check): it REQUESTS, and
6// the publisher SHIPS. This organ is the handoff: it lives in _hdl_build/ so `import "nx_publisher.nx"`
7// resolves (a runtime/ file's import path is [own-dir, runtime/] only). It imports ONLY the publisher
8// (small object -> dodges the nxasm ctx-x-output-path landmine the over-stacked import hit).
9//
10// Flow: the teacher coordinator emits web_assets/nishi-curriculum.html; THIS submits it to a teacher
11// queue (isolated -- never touches the shared queue / sibling requests) and runs the publisher's full
12// pipeline (serialize -> idempotent -> stage -> VERIFY-sha -> ATOMIC-promote -> ledger) to a LOCAL live
13// root. Outward transport live-root -> nishifamily.com = OPERATOR-GATED (publisher R6 policy). license_tier: ORIGINAL
14import "nx_publisher.nx"
15import "nx_syscalls.nx"
16
17func hp_puts(s: *u8) -> i64 { var n: i64 = 0; while s[n] != 0 as u8 { n = n + 1 } sys_write(1, s, n); return 0 }
18func hp_putn(v: i64) -> i64 {
19 if v == 0 { sys_write(1, "0" as *u8, 1); return 0 }
20 var m: i64 = v; if m < 0 { sys_write(1, "-" as *u8, 1); m = 0 - m }
21 let d: *u8 = sys_mmap(24); var k: i64 = 0
22 while m > 0 { d[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 }
23 var j: i64 = k - 1
24 while j >= 0 { sys_write(1, ((d as i64)+j) as *u8, 1); j = j - 1 }
25 return 0
26}
27func hp_exists(path: *u8) -> i64 { let fd: i64 = sys_openat_rd(path); if fd < 0 { return 0 } sys_close(fd); return 1 }
28
29func main() -> i64 {
30 hp_puts("=== NISHI PUBLISHER <- teacher handoff: REQUEST (pub_submit) then the publisher SHIPS ===\n")
31 let page: *u8 = "web_assets/nishi-curriculum.html\x00" as *u8
32 let q: *u8 = "knowledge/publish/teacher-queue.tsv\x00" as *u8
33 let led: *u8 = "knowledge/publish/teacher-ledger.tsv\x00" as *u8
34 let stageroot: *u8 = "knowledge/publish/teacher-stage\x00" as *u8
35 let liveroot: *u8 = "knowledge/publish/teacher-live\x00" as *u8
36 let dest: *u8 = "nishi-curriculum.html\x00" as *u8
37 let live: *u8 = "knowledge/publish/teacher-live/nishi-curriculum.html\x00" as *u8
38
39 if hp_exists(page) == 0 { hp_puts(" FATAL: curriculum page not emitted -- run nx_teacher_coordinate first\n"); sys_exit(1); return 1 }
40 pub_init()
41 sys_mkdir(stageroot, 0x1ed)
42 sys_mkdir(liveroot, 0x1ed)
43
44 // 1. REQUEST -- the teacher submits a publish request (sha256 of the page content); decoupled, durable, concurrency-safe.
45 let sub: i64 = pub_submit_to(q, page, dest, "nishifamily\x00" as *u8, "nishi-teacher\x00" as *u8, "internal\x00" as *u8)
46 hp_puts(" [teacher] pub_submit -> "); hp_putn(sub)
47 if sub == 1 { hp_puts(" (PENDING request enqueued to the teacher queue)\n") } else { hp_puts(" (submit FAILED)\n") }
48
49 // 2. SHIP -- the publisher OWNS this: serialize -> idempotent sha-skip -> stage -> VERIFY-sha -> ATOMIC-promote -> ledger.
50 let pubd: i64 = pub_run_full(q, led, stageroot, liveroot, "publish:teacher\x00" as *u8)
51 hp_puts(" [publisher] pub_run_full -> published_this_pass="); hp_putn(pubd); hp_puts("\n")
52
53 // 3. confirm the live artifact (the publisher already re-hashed staged bytes == approved sha before promoting).
54 if hp_exists(live) == 1 {
55 hp_puts(" LIVE (local): knowledge/publish/teacher-live/nishi-curriculum.html -- SHIPPED by the Nishi Publisher\n")
56 hp_puts(" COORDINATED: teacher REQUESTED, publisher SHIPPED (no direct push). Outward live-root -> nishifamily.com = OPERATOR-GATED (publisher R6 policy).\n")
57 sys_exit(0); return 0
58 }
59 hp_puts(" publisher did not promote (idempotent if already live, or a verify hold)\n")
60 sys_exit(1); return 1
61}