code wiki / (root) / nx_climbout_progress_gate.nx

nx_climbout_progress_gate.nx source

↩ module page · 77 lines · 3749 B

1// nx_climbout_progress_gate.nx -- R7 GATE: proves the climb is tracked. Fresh = 0% / all steps pending; 2// mark a step done -> progress rises, it persists, and the NEXT step surfaces (the done one disappears). 3// Hermetic /tmp prefix. Exits 0 iff ALL pass. license_tier: ORIGINAL 4import "nx_syscalls.nx" 5import "nx_climbout_progress.nx" 6 7func g_puts(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 } 8func g_putn(v: i64) -> i64 { 9 if v == 0 { sys_write(1, "0" as *u8, 1); return 0 } 10 var m: i64 = v; if m < 0 { sys_write(1, "-" as *u8, 1); m = 0 - m } 11 let d: *u8 = sys_mmap(24); var k: i64 = 0 12 while m > 0 { d[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 } 13 var j: i64 = k - 1 14 while j >= 0 { sys_write(1, ((d as i64)+j) as *u8, 1); j = j - 1 } 15 return 0 16} 17func chk(name: *u8, got: i64, want: i64, st: *i64) -> i64 { 18 if got == want { st[0] = st[0] + 1; g_puts(" PASS "); g_puts(name); g_puts("\n") } 19 else { st[1] = st[1] + 1; g_puts(" FAIL "); g_puts(name); g_puts(" got="); g_putn(got); g_puts(" want="); g_putn(want); g_puts("\n") } 20 return 0 21} 22func seti(a: *i64, i: i64, v: i64) -> i64 { a[i] = v; return 0 } 23 24func main() -> i64 { 25 let st: *i64 = sys_mmap(16) as *i64 26 st[0] = 0; st[1] = 0 27 28 // hermetic prefix "/tmp/cprog_<us>-" 29 let pfx: *u8 = sys_mmap(64) 30 var pp: i64 = 0 31 let pre: *u8 = "/tmp/cprog_\x00" as *u8 32 while pre[pp] != (0 as u8) { pfx[pp] = pre[pp]; pp = pp + 1 } 33 let us: i64 = sys_now_us() 34 let tmp: *u8 = sys_mmap(32); var m: i64 = us; var kk: i64 = 0 35 if m == 0 { tmp[0] = 0x30 as u8; kk = 1 } 36 while m > 0 { tmp[kk] = (0x30 + (m % 10)) as u8; m = m / 10; kk = kk + 1 } 37 var z: i64 = kk - 1 38 while z >= 0 { pfx[pp] = tmp[z]; pp = pp + 1; z = z - 1 } 39 pfx[pp] = 0x2d as u8; pp = pp + 1; pfx[pp] = 0 as u8 40 41 let nsteps: i64 = 5 42 let order: *i64 = sys_mmap(8 * 8) as *i64 43 seti(order,0,0); seti(order,1,1); seti(order,2,2); seti(order,3,3); seti(order,4,4) 44 let done: *u8 = sys_mmap(64) 45 46 // fresh: nothing done 47 cp_get(pfx, "operator\x00" as *u8, done, nsteps) 48 chk("fresh: 0 steps done", cp_count(done, nsteps), 0, st) 49 chk("fresh: 0% complete", cp_pct(cp_count(done, nsteps), nsteps), 0, st) 50 chk("fresh: next step = 0 (stabilize)", cp_next(done, order, nsteps), 0, st) 51 52 // mark step 0 done 53 chk("mark step 0", cp_mark(pfx, "operator\x00" as *u8, 0, nsteps), 0, st) 54 cp_get(pfx, "operator\x00" as *u8, done, nsteps) 55 chk("after step 0: 1 done", cp_count(done, nsteps), 1, st) 56 chk("after step 0: 20% complete", cp_pct(cp_count(done, nsteps), nsteps), 20, st) 57 chk("step 0 is done", cp_is_done(done, 0), 1, st) 58 chk("next step now = 1 (the done one disappeared)", cp_next(done, order, nsteps), 1, st) 59 60 // mark step 1 done -> persists across a fresh read 61 cp_mark(pfx, "operator\x00" as *u8, 1, nsteps) 62 cp_get(pfx, "operator\x00" as *u8, done, nsteps) 63 chk("after step 1: 2 done (persisted)", cp_count(done, nsteps), 2, st) 64 chk("40% complete", cp_pct(cp_count(done, nsteps), nsteps), 40, st) 65 chk("next step = 2", cp_next(done, order, nsteps), 2, st) 66 chk("step 2 still pending", cp_is_done(done, 2), 0, st) 67 68 // a different respondent has independent progress (per-user) 69 let done2: *u8 = sys_mmap(64) 70 cp_get(pfx, "someone_else\x00" as *u8, done2, nsteps) 71 chk("different respondent -> independent (0 done)", cp_count(done2, nsteps), 0, st) 72 73 g_puts("nx_climbout_progress_gate: PASS="); g_putn(st[0]); g_puts(" FAIL="); g_putn(st[1]); g_puts("\n") 74 if st[1] == 0 { g_puts("SITUATION R7 nx_climbout_progress: GREEN\n"); return 0 } 75 g_puts("SITUATION R7 nx_climbout_progress: RED\n") 76 return 1 77}