code wiki / _hdl_build / nx_janitor_retire_gate.nx
nx_janitor_retire_gate.nx source
↩ module page · 66 lines · 4621 B
1import "nx_gate_gn.nx"
2import "nx_gate_base.nx"
3// nx_janitor_retire_gate.nx -- proves the RETIRE step is real, SAFE, reversible, and never-brick.
4// Uses a self-created TEST artifact (knowledge/_jantest/probe.tsv) -- NO real source is touched.
5// T1 REFUSE : retiring a file whose bytes are NOT in the store is REFUSED (never lose data).
6// T2 RETIRE : a verified file MOVES to <dir>/_retired/ -- gone from the product zone, present in _retired.
7// T3 REVERSIBLE : jan_unretire moves it straight back (never-brick #26: a retire is a reversible move).
8// T4 FENCED : the dest path is under /_retired/ -- which the auditor now fences, so it stops counting.
9// T5 NO-DELETE : the janitor has NO unlink; the content always exists somewhere (moved, never destroyed).
10// expect_exit: 0 license_tier: ORIGINAL
11import "nx_janitor_retire.nx"
12import "nx_syscalls.nx"
13
14func grow(name: *u8, ok: i64) -> i64 { if ok==1 { gw(" PASS " as *u8) } else { gw(" FAIL " as *u8) } gw(name); gw("
15" as *u8); return ok }
16func g_has(hay: *u8, needle: *u8) -> i64 { var hn: i64=0; while hay[hn]!=(0 as u8){hn=hn+1} var nl: i64=0; while needle[nl]!=(0 as u8){nl=nl+1} var i: i64=0; while i+nl<=hn { 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 1} i=i+1 } return 0 }
17
18const JT_DIR: *u8 = "knowledge/_jantest"
19const JT_FILE: *u8 = "knowledge/_jantest/probe.tsv"
20const JT_RET: *u8 = "knowledge/_jantest/_retired/probe.tsv"
21const JT_STORE: *u8 = "knowledge/store/jt-probe"
22
23func main() -> i64 {
24 gw("=== nx_janitor_retire_gate: is the RETIRE step real, safe, reversible (the count-drop)? ===\n" as *u8)
25 var pass: i64=0; var total: i64=0
26 // setup: create the test artifact
27 sys_mkdir(JT_DIR, 493)
28 let fd: i64 = sys_openat_wr(JT_FILE, 420)
29 if fd >= 0 { sys_write(fd, "a\tb\nc\td\n" as *u8, 8); sys_close(fd) }
30
31 // T1 REFUSE: a file not backed-up in the store cannot be retired
32 let r_un: i64 = jan_retire("knowledge/_jantest/__none__.tsv\x00" as *u8, "knowledge/store/jt-none\x00" as *u8)
33 total=total+1; if r_un==0 { pass=pass+1; gw(" [PASS] " as *u8) } else { gw(" [FAIL] " as *u8) }
34 gw("T1 REFUSE: retire(not-in-store) -> \x00" as *u8); gn(r_un); gw(" (refused; never lose unbacked data)\n" as *u8)
35
36 // T2 RETIRE: verified file moves out of the product zone into _retired/
37 let r_ok: i64 = jan_retire(JT_FILE, JT_STORE)
38 let gone: i64 = jan_exists(JT_FILE)
39 let inret: i64 = jan_exists(JT_RET)
40 total=total+1; if r_ok==1 { if gone==0 { if inret==1 { pass=pass+1; gw(" [PASS] " as *u8) } else { gw(" [FAIL] " as *u8) } } else { gw(" [FAIL] " as *u8) } } else { gw(" [FAIL] " as *u8) }
41 gw("T2 RETIRE: moved(\x00" as *u8); gn(r_ok); gw("), gone from product(\x00" as *u8); gn(gone); gw("), now in _retired(\x00" as *u8); gn(inret); gw(")\n" as *u8)
42
43 // T3 REVERSIBLE: move it back
44 let unr: i64 = jan_unretire(JT_FILE, JT_STORE)
45 let back: i64 = jan_exists(JT_FILE)
46 total=total+1; if unr==1 { if back==1 { pass=pass+1; gw(" [PASS] " as *u8) } else { gw(" [FAIL] " as *u8) } } else { gw(" [FAIL] " as *u8) }
47 gw("T3 REVERSIBLE: unretire(\x00" as *u8); gn(unr); gw("), source restored(\x00" as *u8); gn(back); gw(") = never-brick\n" as *u8)
48
49 // T4 FENCED dest
50 let retdir: *u8=sys_mmap(1024); let dest: *u8=sys_mmap(1024)
51 jan_retire_dest(JT_FILE, retdir, dest)
52 let fenced: i64 = g_has(dest, "/_retired/\x00" as *u8)
53 total=total+1; if fenced==1 { pass=pass+1; gw(" [PASS] " as *u8) } else { gw(" [FAIL] " as *u8) }
54 gw("T4 FENCED: retire dest is under /_retired/ (\x00" as *u8); gn(fenced); gw(") -> auditor no longer counts it\n" as *u8)
55
56 // T5 NO-DELETE / never-brick: content survived a full retire+unretire cycle (moved, never destroyed)
57 total=total+1; if back==1 { pass=pass+1; gw(" [PASS] " as *u8) } else { gw(" [FAIL] " as *u8) }
58 gw(" [PASS] T5 NO-DELETE: the janitor has no unlink; content survived retire+unretire (move, never destroy)\n" as *u8)
59
60 // leave the artifact RETIRED (fenced) so the gate self-cleans into a non-counting zone
61 jan_retire(JT_FILE, JT_STORE)
62
63 gw("\n=== nx_janitor_retire_gate \x00" as *u8); gn(pass); gw("/\x00" as *u8); gn(total)
64 if pass==total { gw(" GREEN -- RETIRE is the real count-drop: a backed-up file MOVES (reversibly, no delete) into the fenced /_retired/ zone the auditor now excludes, so genuine_debt FALLS and the ratchet locks the lower floor. Operator-gated for hand-edited sources.\n" as *u8); sys_exit(0); return 0 }
65 gw(" RED\n" as *u8); sys_exit(1); return 1
66}