code wiki / (root) / nx_companion_rel_gate.nx

nx_companion_rel_gate.nx source

↩ module page · 106 lines · 7078 B

1// nx_companion_rel_gate.nx -- GATE for R1d (nx_companion_rel): relationship state evolves correctly and safely. 2// Proves: (T1) round-trip; (T2) facts APPEND additively (a new fact never erases a prior one); (T3) trust is 3// CLAMPED to 0..100 at both ends (never-brick numeric bound); (T4) a mutation preserves the other fields 4// (read-modify-write is lossless); (T5) the projected context carries stage + facts; (T6) neg -- unknown 5// (persona,user) yields empty context; (T7) ISOLATION -- one persona's relationship with a user is independent 6// of another persona's. Timestamp-fresh /tmp store -> deterministic re-runs. license_tier: ORIGINAL expect_exit: 0 7import "nx_companion_rel.nx" 8import "nx_gate_verdict.nx" 9 10func rw(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 } 11func rn(v: i64) -> i64 { let bb: *u8=sys_mmap(28); var m: i64=v; if m<0{sys_write(1,"-" as *u8,1);m=0-m} let t: *u8=sys_mmap(28); var k: i64=0; if m==0{t[0]=48 as u8;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(1,bb,k); return 0 } 12func r_streq(a: *u8, b: *u8) -> i64 { var i: i64=0; while a[i]!=(0 as u8){ if a[i]!=b[i]{return 0} i=i+1 } if b[i]!=(0 as u8){return 0} return 1 } 13func r_find(hay: *u8, hlen: i64, needle: *u8) -> i64 { 14 var nl: i64=0; while needle[nl]!=(0 as u8){nl=nl+1} 15 if nl==0 { return 1 } 16 if hlen<nl { return 0 } 17 var i: i64=0 18 while i<=hlen-nl { var m: i64=1; var c: i64=0; while c<nl { if hay[i+c]!=needle[c]{m=0;c=nl} else {c=c+1} } if m==1 {return 1} i=i+1 } 19 return 0 20} 21func r_slen(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} return n } 22 23func main() -> i64 { 24 rw("=== nx_companion_rel_gate (R1d: relationship state -- evolving, additive, clamped, isolated) ===\n" as *u8) 25 let EPT: *u8 = sys_mmap(256) 26 var po: i64 = 0 27 var i: i64=0; let pre: *u8="/tmp/rel-test-" as *u8; while pre[i]!=(0 as u8){EPT[po]=pre[i];po=po+1;i=i+1} 28 var ms: i64 = sys_now_ms() % 100000000; var d: i64=7 29 while d>=0 { EPT[po+d]=(48+(ms%10)) as u8; ms=ms/10; d=d-1 } po=po+8 30 EPT[po]=0x2D as u8; po=po+1; EPT[po]=0 as u8 31 32 let cap: i64 = 8192 33 let sb: *u8 = sys_mmap(cap); let fb: *u8 = sys_mmap(cap); let mb: *u8 = sys_mmap(cap); let hb: *u8 = sys_mmap(cap) 34 var pass: i64 = 0 35 var tot: i64 = 0 36 37 // seed the (aria, ellery) relationship 38 rel_update_pfx(EPT, "aria" as *u8, "ellery" as *u8, "acquaintance" as *u8, 20, "likes gardenias" as *u8, "content" as *u8, "met in spring" as *u8) 39 40 // T1 round-trip 41 tot = tot + 1 42 var t1: i64 = 0 43 var tr: i64 = rel_read5(EPT, "aria" as *u8, "ellery" as *u8, sb, fb, mb, hb, cap) 44 if tr == 20 { if r_streq(sb, "acquaintance" as *u8) == 1 { t1 = 1 } } 45 if t1 == 1 { pass=pass+1; rw("PASS T1 round-trip: stage=acquaintance, trust=20\n" as *u8) } else { rw("FAIL T1 tr=" as *u8); rn(tr); rw(" stage=" as *u8); rw(sb); rw("\n" as *u8) } 46 47 // T2 additive facts 48 rel_note_fact_pfx(EPT, "aria" as *u8, "ellery" as *u8, "has a dog named Max" as *u8) 49 tot = tot + 1 50 rel_read5(EPT, "aria" as *u8, "ellery" as *u8, sb, fb, mb, hb, cap) 51 var t2: i64 = 0 52 if r_find(fb, r_slen(fb), "gardenias" as *u8) == 1 { if r_find(fb, r_slen(fb), "Max" as *u8) == 1 { t2 = 1 } } 53 if t2 == 1 { pass=pass+1; rw("PASS T2 additive facts: both 'gardenias' and 'Max' retained (no loss)\n" as *u8) } else { rw("FAIL T2 facts=" as *u8); rw(fb); rw("\n" as *u8) } 54 55 // T3 trust clamp -- high then low 56 rel_bump_trust_pfx(EPT, "aria" as *u8, "ellery" as *u8, 90) // 20+90=110 -> 100 57 tot = tot + 1 58 var thi: i64 = rel_read5(EPT, "aria" as *u8, "ellery" as *u8, sb, fb, mb, hb, cap) 59 rel_bump_trust_pfx(EPT, "aria" as *u8, "ellery" as *u8, 0 - 500) // ->0 60 var tlo: i64 = rel_read5(EPT, "aria" as *u8, "ellery" as *u8, sb, fb, mb, hb, cap) 61 if thi == 100 { if tlo == 0 { pass=pass+1; rw("PASS T3 trust clamp: +90 -> 100 (max), -500 -> 0 (min)\n" as *u8) } else { rw("FAIL T3 tlo=" as *u8); rn(tlo); rw("\n" as *u8) } } else { rw("FAIL T3 thi=" as *u8); rn(thi); rw("\n" as *u8) } 62 63 // restore a realistic trust, then change stage -- proving RMW preserves the other fields 64 rel_bump_trust_pfx(EPT, "aria" as *u8, "ellery" as *u8, 75) // 0+75=75 65 rel_set_stage_pfx(EPT, "aria" as *u8, "ellery" as *u8, "close" as *u8) 66 tot = tot + 1 67 var tfin: i64 = rel_read5(EPT, "aria" as *u8, "ellery" as *u8, sb, fb, mb, hb, cap) 68 var t4: i64 = 0 69 if r_streq(sb, "close" as *u8) == 1 { if tfin == 75 { if r_find(fb, r_slen(fb), "gardenias" as *u8) == 1 { if r_find(fb, r_slen(fb), "Max" as *u8) == 1 { t4 = 1 } } } } 70 if t4 == 1 { pass=pass+1; rw("PASS T4 lossless RMW: set stage=close, trust=75 preserved, facts intact\n" as *u8) } else { rw("FAIL T4 stage=" as *u8); rw(sb); rw(" trust=" as *u8); rn(tfin); rw("\n" as *u8) } 71 72 // T5 context projection 73 tot = tot + 1 74 let ctx: *u8 = sys_mmap(4096) 75 let cl: i64 = rel_context_pfx(EPT, "aria" as *u8, "ellery" as *u8, ctx, 4096) 76 var t5: i64 = 0 77 if cl > 0 { if r_find(ctx, cl, "close" as *u8) == 1 { if r_find(ctx, cl, "gardenias" as *u8) == 1 { if r_find(ctx, cl, "Max" as *u8) == 1 { t5 = 1 } } } } 78 if t5 == 1 { pass=pass+1; rw("PASS T5 context projection: carries stage + durable facts\n" as *u8) } else { rw("FAIL T5 ctx=" as *u8); rw(ctx); rw("\n" as *u8) } 79 80 // T6 neg -- unknown relationship 81 tot = tot + 1 82 let cl2: i64 = rel_context_pfx(EPT, "vera" as *u8, "nobody" as *u8, ctx, 4096) 83 if cl2 == 0 { pass=pass+1; rw("PASS T6 neg-control: unknown (persona,user) -> empty context\n" as *u8) } else { rw("FAIL T6 cl2=" as *u8); rn(cl2); rw("\n" as *u8) } 84 85 // T7 ISOLATION -- vera's relationship with ellery is independent of aria's 86 rel_update_pfx(EPT, "vera" as *u8, "ellery" as *u8, "stranger" as *u8, 5, "guards her privacy" as *u8, "reserved" as *u8, "just met" as *u8) 87 tot = tot + 1 88 var t7: i64 = 0 89 rel_read5(EPT, "aria" as *u8, "ellery" as *u8, sb, fb, mb, hb, cap) // aria unchanged? 90 if r_streq(sb, "close" as *u8) == 1 { 91 rel_read5(EPT, "vera" as *u8, "ellery" as *u8, sb, fb, mb, hb, cap) 92 if r_streq(sb, "stranger" as *u8) == 1 { t7 = 1 } 93 } 94 if t7 == 1 { pass=pass+1; rw("PASS T7 isolation: (aria,ellery)=close is independent of (vera,ellery)=stranger\n" as *u8) } else { rw("FAIL T7 stage=" as *u8); rw(sb); rw("\n" as *u8) } 95 96 rw("nx_companion_rel_gate pass=" as *u8); rn(pass); rw("/" as *u8); rn(tot) 97 // MIGRATED onto nx_gate_verdict by nx_gate_dry_apply (D001, minimal form): every check 98 // row above is untouched, so the PASS/FAIL vector cannot change; only the hand-rolled 99 // verdict emission is replaced by the ONE shared base class. Proven by nx_gate_migrate verify. 100 let ctr__dry: *i64 = gv_ctr() 101 ctr__dry[0] = pass 102 ctr__dry[1] = tot 103 let rc__dry: i64 = gv_verdict("COMPANION-REL-GATE" as *u8, ctr__dry, "Elder's relationship state evolves per-user: additive facts, clamped trust, lossless, isolated)" as *u8) 104 sys_exit(rc__dry) 105 return rc__dry 106}