nx_companion_memory_gate.nx source
↩ module page · 83 lines · 5634 B
1// nx_companion_memory_gate.nx -- GATE for R1b (nx_companion_memory): episodic memory is total + recallable +
2// per-persona isolated. Proves: (T1) TOTAL RECALL -- mem_count == every episode appended, nothing dropped;
3// (T2) ordered get -- episode 0's text is the earliest fact; (T3) PLANT-AND-PROBE -- a fact planted at turn 0
4// is found by content search after many later turns (the Replika-differentiator: a companion that structurally
5// cannot forget); (T4) ISOLATION -- Aria's memory never bleeds into Vera's; (T5) NEG -- no false recall.
6// Uses a timestamp-fresh /tmp store so re-runs are deterministic. license_tier: ORIGINAL expect_exit: 0
7import "nx_companion_memory.nx"
8import "nx_gate_verdict.nx"
9
10func mw(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 }
11func mn(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 }
12
13func main() -> i64 {
14 mw("=== nx_companion_memory_gate (R1b: episodic memory -- total, recallable, per-persona isolated) ===\n" as *u8)
15 // fresh per-run store: "/tmp/epi-test-<ms>-"
16 let EPT: *u8 = sys_mmap(256)
17 var o: i64 = 0
18 o = mem_catz(EPT, o, "/tmp/epi-test-" as *u8)
19 o = mem_pad8(EPT, o, sys_now_ms() % 100000000)
20 EPT[o] = 0x2D as u8; o = o + 1 // '-'
21 EPT[o] = 0 as u8
22
23 // --- plant Aria's history: a distinctive fact at turn 0, then 5 later turns ---
24 mem_append_pfx(EPT, "aria" as *u8, "s1" as *u8, "100" as *u8, "user" as *u8, "My mother Eleanor adores gardenias in the spring." as *u8)
25 mem_append_pfx(EPT, "aria" as *u8, "s1" as *u8, "101" as *u8, "aria" as *u8, "Gardenias for Eleanor -- I'll hold onto that, love." as *u8)
26 mem_append_pfx(EPT, "aria" as *u8, "s2" as *u8, "200" as *u8, "user" as *u8, "I got a promotion at the firm today." as *u8)
27 mem_append_pfx(EPT, "aria" as *u8, "s2" as *u8, "201" as *u8, "aria" as *u8, "That is wonderful -- I'm proud of you." as *u8)
28 mem_append_pfx(EPT, "aria" as *u8, "s3" as *u8, "300" as *u8, "user" as *u8, "Feeling a little lonely tonight." as *u8)
29 mem_append_pfx(EPT, "aria" as *u8, "s3" as *u8, "301" as *u8, "aria" as *u8, "I'm right here with you." as *u8)
30
31 // --- Vera's separate history ---
32 mem_append_pfx(EPT, "vera" as *u8, "v1" as *u8, "500" as *u8, "user" as *u8, "Tell me about number theory." as *u8)
33 mem_append_pfx(EPT, "vera" as *u8, "v1" as *u8, "501" as *u8, "vera" as *u8, "Gladly -- let us begin with the primes." as *u8)
34
35 var pass: i64 = 0
36 var tot: i64 = 0
37 let p: *i64 = sys_mmap(16) as *i64
38 let l: *i64 = sys_mmap(16) as *i64
39 let f: *i64 = sys_mmap(16) as *i64
40 let seqs: *i64 = sys_mmap(8*64) as *i64
41
42 // T1: total recall -- counts exact, per persona
43 tot = tot + 1
44 let ca: i64 = mem_count_pfx(EPT, "aria" as *u8)
45 let cv: i64 = mem_count_pfx(EPT, "vera" as *u8)
46 if ca == 6 { if cv == 2 { pass = pass + 1; mw("PASS T1 total recall: aria=6 episodes, vera=2 (nothing dropped, additive)\n" as *u8) } else { mw("FAIL T1 cv=" as *u8); mn(cv); mw("\n" as *u8) } } else { mw("FAIL T1 ca=" as *u8); mn(ca); mw("\n" as *u8) }
47
48 // T2: ordered get -- episode 0 is the earliest fact
49 tot = tot + 1
50 var t2: i64 = 0
51 if mem_get_pfx(EPT, "aria" as *u8, 0, p, l) == 1 {
52 if tr_field(p[0] as *u8, 0, l[0], MF_TEXT, f) == 1 { if mem_ci_find((p[0] + f[0]) as *u8, f[1], "Eleanor" as *u8) == 1 { t2 = 1 } }
53 }
54 if t2 == 1 { pass = pass + 1; mw("PASS T2 ordered get: episode 0 text carries the earliest fact (Eleanor)\n" as *u8) } else { mw("FAIL T2\n" as *u8) }
55
56 // T3: PLANT-AND-PROBE -- the fact planted at turn 0 is found after 5 later turns
57 tot = tot + 1
58 let m3: i64 = mem_search_pfx(EPT, "aria" as *u8, "gardenias" as *u8, seqs, 64)
59 var t3: i64 = 0
60 if m3 >= 1 { if seqs[0] == 0 { t3 = 1 } } // earliest match is turn 0
61 if t3 == 1 { pass = pass + 1; mw("PASS T3 plant-and-probe: 'gardenias' planted at turn 0 recalled after 5 later turns (matches=" as *u8); mn(m3); mw(")\n" as *u8) } else { mw("FAIL T3 matches=" as *u8); mn(m3); mw("\n" as *u8) }
62
63 // T4: ISOLATION -- Aria's fact does NOT appear in Vera's memory
64 tot = tot + 1
65 let m4: i64 = mem_search_pfx(EPT, "vera" as *u8, "gardenias" as *u8, seqs, 64)
66 if m4 == 0 { pass = pass + 1; mw("PASS T4 isolation: 'gardenias' absent from Vera's memory (no bleed)\n" as *u8) } else { mw("FAIL T4 m4=" as *u8); mn(m4); mw("\n" as *u8) }
67
68 // T5 NEG: no false recall
69 tot = tot + 1
70 let m5: i64 = mem_search_pfx(EPT, "aria" as *u8, "quantum-chromodynamics" as *u8, seqs, 64)
71 if m5 == 0 { pass = pass + 1; mw("PASS T5 neg-control: never-said phrase -> 0 matches (no false recall)\n" as *u8) } else { mw("FAIL T5 m5=" as *u8); mn(m5); mw("\n" as *u8) }
72
73 mw("nx_companion_memory_gate pass=" as *u8); mn(pass); mw("/" as *u8); mn(tot)
74 // MIGRATED onto nx_gate_verdict by nx_gate_dry_apply (D001, minimal form): every check
75 // row above is untouched, so the PASS/FAIL vector cannot change; only the hand-rolled
76 // verdict emission is replaced by the ONE shared base class. Proven by nx_gate_migrate verify.
77 let ctr__dry: *i64 = gv_ctr()
78 ctr__dry[0] = pass
79 ctr__dry[1] = tot
80 let rc__dry: i64 = gv_verdict("COMPANION-MEMORY-GATE" as *u8, ctr__dry, "Elder has total, ordered, content-searchable, per-persona memory -- the Replika-differentiator)" as *u8)
81 sys_exit(rc__dry)
82 return rc__dry
83}