code wiki / _hdl_build / nx_worklog_append_gate.nx
nx_worklog_append_gate.nx source
↩ module page · 98 lines · 5602 B
1import "nx_gate_gn.nx"
2// nx_worklog_append_gate.nx -- hermetic gate for the live work-journal appender. Proves: every
3// action becomes exactly one newline-framed line (granular + no tear), append-only growth (robust),
4// correct TAB schema, and decoy-absence (no fabricated content). Sovereign. license_tier: ORIGINAL
5import "nx_worklog_lib.nx"
6import "nx_syscalls.nx"
7import "nx_gate_verdict.nx"
8
9const GD: *u8 = "/tmp/nx_wl_gate"
10const GP: *u8 = "/tmp/nx_wl_gate/worklog.tsv"
11
12func gp(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 }
13
14func g_read(path: *u8, buf: *u8, cap: i64) -> i64 {
15 let fd: i64 = sys_openat_rd(path)
16 if fd < 0 { return 0 - 1 }
17 var total: i64 = 0
18 var nrd: i64 = sys_read(fd, buf, cap)
19 while nrd > 0 { total = total + nrd; if total >= cap { nrd = 0 } else { nrd = sys_read(fd, ((buf as i64) + total) as *u8, cap - total) } }
20 sys_close(fd)
21 return total
22}
23func g_find(buf: *u8, n: i64, pat: *u8) -> i64 {
24 var pl: i64 = 0; while pat[pl] != (0 as u8) { pl = pl + 1 }
25 if pl == 0 { return 0 - 1 }
26 var i: i64 = 0
27 while i + pl <= n {
28 var j: i64 = 0; var ok: i64 = 1
29 while j < pl { if buf[i + j] != pat[j] { ok = 0; j = pl } else { j = j + 1 } }
30 if ok == 1 { return i }
31 i = i + 1
32 }
33 return 0 - 1
34}
35func g_count(buf: *u8, n: i64, c: i64) -> i64 {
36 var cnt: i64 = 0; var i: i64 = 0
37 while i < n { if (buf[i] as i64) == c { cnt = cnt + 1 } i = i + 1 }
38 return cnt
39}
40func g_cat(dst: *u8, off: i64, s: *u8) -> i64 { var o: i64 = off; var i: i64 = 0; while s[i] != (0 as u8) { dst[o] = s[i]; o = o + 1; i = i + 1 } return o }
41
42func main(argc: i64, argv: *i64) -> i64 {
43 gp("=== nx_worklog_append_gate (live work-journal) ===\n" as *u8)
44 wl_ensure_dir(GD)
45 // start clean: truncate any prior gate log by writing a fresh empty file via openat_wr.
46 let z: i64 = sys_openat_wr(GP, 420); if z >= 0 { sys_close(z) }
47
48 var pass: i64 = 0
49 var fail: i64 = 0
50
51 // three actions, deterministic epochs.
52 wl_append3_t(GP, 1000, "post" as *u8, "Edit" as *u8, "project-alpha-2026-06-19.md" as *u8)
53 wl_append3_t(GP, 1001, "post" as *u8, "Bash" as *u8, "build nx_ws_manifest_emit_gate" as *u8)
54 wl_append3_t(GP, 1002, "pre" as *u8, "Write" as *u8, "nx_worklog_lib.nx" as *u8)
55
56 let fbuf: *u8 = sys_mmap(65536)
57 let flen: i64 = g_read(GP, fbuf, 65536)
58
59 // T1: exactly 3 newline-framed lines (granular: one per action; no tear/merge).
60 let nl: i64 = g_count(fbuf, flen, 10)
61 if nl == 3 { pass = pass + 1; gp(" T1 three-framed-lines PASS\n" as *u8) } else { fail = fail + 1; gp(" T1 line-count FAIL got=" as *u8); gn(nl); gp("\n" as *u8) }
62
63 // T2: each action's target present (content captured).
64 if g_find(fbuf, flen, "project-alpha-2026-06-19.md" as *u8) >= 0 { if g_find(fbuf, flen, "build nx_ws_manifest_emit_gate" as *u8) >= 0 { if g_find(fbuf, flen, "nx_worklog_lib.nx" as *u8) >= 0 { pass = pass + 1; gp(" T2 all-targets-captured PASS\n" as *u8) } else { fail = fail + 1; gp(" T2 write-target MISSING FAIL\n" as *u8) } } else { fail = fail + 1; gp(" T2 bash-target MISSING FAIL\n" as *u8) } } else { fail = fail + 1; gp(" T2 edit-target MISSING FAIL\n" as *u8) }
65
66 // T3: TAB schema -- each line has >=3 tabs (4 fields). total tabs should be 9 (3 per line).
67 let tabs: i64 = g_count(fbuf, flen, 9)
68 if tabs == 9 { pass = pass + 1; gp(" T3 tab-schema(9) PASS\n" as *u8) } else { fail = fail + 1; gp(" T3 tab-count FAIL got=" as *u8); gn(tabs); gp("\n" as *u8) }
69
70 // T4: epoch+event+tool framing with REAL tab separators (NishiLang has no \t escape -> byte 9).
71 let nd: *u8 = sys_mmap(64)
72 var no: i64 = 0
73 no = g_cat(nd, no, "1000" as *u8); nd[no] = 9 as u8; no = no + 1
74 no = g_cat(nd, no, "post" as *u8); nd[no] = 9 as u8; no = no + 1
75 no = g_cat(nd, no, "Edit" as *u8); nd[no] = 9 as u8; no = no + 1
76 nd[no] = 0 as u8
77 if g_find(fbuf, flen, nd) >= 0 { pass = pass + 1; gp(" T4 epoch+event+tool framing PASS\n" as *u8) } else { fail = fail + 1; gp(" T4 framing FAIL\n" as *u8) }
78
79 // T5 (NEG): a string never appended must be absent (no fabricated content).
80 if g_find(fbuf, flen, "NEVER-APPENDED-XYZ" as *u8) < 0 { pass = pass + 1; gp(" T5 decoy-absent PASS\n" as *u8) } else { fail = fail + 1; gp(" T5 decoy-present FAIL\n" as *u8) }
81
82 // T6 (append-only growth = redundancy/robustness): a 4th action -> 4 lines, prior intact.
83 wl_append3_t(GP, 1003, "post" as *u8, "PowerShell" as *u8, "wsl build" as *u8)
84 let flen2: i64 = g_read(GP, fbuf, 65536)
85 let nl2: i64 = g_count(fbuf, flen2, 10)
86 if nl2 == 4 { if g_find(fbuf, flen2, "project-alpha-2026-06-19.md" as *u8) >= 0 { pass = pass + 1; gp(" T6 append-only-growth PASS\n" as *u8) } else { fail = fail + 1; gp(" T6 prior-line-lost FAIL\n" as *u8) } } else { fail = fail + 1; gp(" T6 grew-to FAIL got=" as *u8); gn(nl2); gp("\n" as *u8) }
87
88 gp("RESULT pass=" as *u8); gn(pass); gp(" fail=" as *u8); gn(fail)
89 // MIGRATED onto nx_gate_verdict by nx_gate_dry_apply (D001, minimal form): every check
90 // row above is untouched, so the PASS/FAIL vector cannot change; only the hand-rolled
91 // verdict emission is replaced by the ONE shared base class. Proven by nx_gate_migrate verify.
92 let ctr__dry: *i64 = gv_ctr()
93 ctr__dry[0] = pass
94 ctr__dry[1] = pass + fail
95 let rc__dry: i64 = gv_verdict("WORKLOG-APPEND-GATE" as *u8, ctr__dry, "teeth unchanged; verdict emission migrated onto the shared base class" as *u8)
96 sys_exit(rc__dry)
97 return rc__dry
98}