code wiki / _hdl_build / _atomic_rewrite_gate.nx

_atomic_rewrite_gate.nx

buildroot/runtime/_hdl_build/_atomic_rewrite_gate.nx

8738 B176 linesdepth 3pulls 3 transitivereach 0 importersview sourcekind gate/prooftopic atomic
docsdependenciesstructsconstsfunctions

about

_atomic_rewrite_gate.nx -- WMS-R3 gate. PROVES the generic atomic_rewrite primitive (nx_atomic_rewrite.nx) is crash-safe, with a WORKING NEGATIVE CONTROL (the old in-place rewrite) that demonstrably tears under the SAME crash point -- so the gate can actually detect failure (no false green). All four sub-tests run on real /tmp victim files (NO mocks): (1) commit_ok -- atomic_rewrite(v1) then atomic_rewrite(v2): reader sees exactly v2, NOT v1 (clean whole-file replace works). (2) crash_safe -- establish v1 on disk; a FORKED CHILD calls ar_crashwrite (stage temp + fsync, NO rename) then exits; a FRESH reader of the live path still sees EXACTLY v1, intact (the headline crash-before-commit claim). Then a real atomic_rewrite(v2) -> reader now sees v2 (after_commit). (3) neg_torn -- NEGATIVE CONTROL: a FORKED CHILD runs the OLD unguarded ar_unsafe_inplace, which TRUNCATES the live file then writes only HALF the new bytes, then exits (crash mid-write). A fresh reader sees a TORN file: neither the intact previous content NOR the full new content. If this does NOT tear, the gate is INVALID -> RED. (4) tamper_bites -- atomic_rewrite to an UNWRITABLE path (bad dir) MUST return negative AND leave the real victim unchanged (the primitive reports failure, never half-commits). pass = commit_ok AND crash_safe AND after_commit AND neg_torn AND tamper_bites Evidence -> knowledge/status/atomic_rewrite.log (ATOMICRWGATE row). SOVEREIGN: nx_atomic_rewrite (-> nx_syscalls) only. license_tier: ORIGINAL

dependencies 1 imports · 0 importers

nx_atomic_rewrite.nx _atomic_rewrite_gate.nx

imports: nx_atomic_rewrite.nx

imported by: nobody (leaf or entry point)

call flow from main pre-order; caps 40 nodes / depth 6 declared; ↻ = already shown

main g_p sys_openat_append ar_len atomic_rewrite sys_mmap ar_tmpname sys_openat_wr sys_write sys_close sys_fsync sys_renameat ar_syncdir sys_mmap ↻ sys_openat_rd sys_fsync ↻ sys_close ↻ g_read sys_read g_eq ar_len ↻ g_has sys_fork ar_crashwrite sys_mmap ↻ ar_tmpname ↻ sys_openat_wr ↻ sys_write ↻ sys_close ↻ sys_fsync ↻ sys_wait4 ar_unsafe_inplace sys_openat_wr ↻ sys_write ↻ sys_close ↻ g_fn g_fp sys_now_realtime_sec sys_mmap ↻ sys_clock_gettime_real

structs

none

consts

31const VICTIM: *u8 = "/tmp/_arw_victim"
32const LOGP: *u8 = "knowledge/status/atomic_rewrite.log"
35const V1: *u8 = "QUEUE-V1-INTACT-row1-row2-row3-row4-row5-row6-PADDED-TO-BE-MULTI-WRITE-SIZED-XXXXXXXX"
36const V2: *u8 = "QUEUE-V2-COMMITTED"

functions

38func g_p(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 }
called by 1: main
39func g_fp(fd: i64, s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(fd,s,n); return 0 }
called by 1: main
40func g_fn(fd: i64, v: i64) -> i64 { let bb: *u8=sys_mmap(28); var m: i64=v; if m<0{m=0-m}; let t: *u8=sys_mmap(28); var k: i64=0; if m==0{t[0]=48;k=1}; while m>0{t[k]=(48+(m%10)) as u8;m=m/10;k=k+1}; var i: i64=0; while i<k{bb[i]=t[k-1-i];i=i+1}; sys_write(fd,bb,k); return 0 }
called by 1: main
43func g_read(path: *u8, buf: *u8, cap: i64) -> i64
called by 1: main calls 1: sys_read
58func g_eq(buf: *u8, n: i64, s: *u8) -> i64
called by 1: main calls 1: ar_len
67func g_has(buf: *u8, n: i64, pat: *u8, pl: i64) -> i64
called by 1: main
79func main() -> i64