code wiki / (root) / nx_lorebook_gate.nx

nx_lorebook_gate.nx source

↩ module page · 111 lines · 7538 B

1// nx_lorebook_gate.nx -- the REFEREE for companionchat CC3 (em_lorebook in nx_lorebook.nx): a keyed entry is injected only when 2// the turn touches one of its triggers; the match is ASCII case-insensitive; an entry fires once per turn; a turn touching 3// nothing writes zero bytes; a malformed row is counted and never fires; and an over-budget turn REFUSES LOUDLY with the 4// numbers, injecting no partial entry. GPU-free, in-process, fixture confs under /tmp/<gate>/ written at run time. 5// license_tier: ORIGINAL expect_exit: 0 6import "nx_syscalls.nx" 7import "nx_gate_verdict.nx" 8import "nx_lorebook.nx" 9 10const LG_DIR: *u8 = "/tmp/nx_lorebook_gate" as *u8 11const LG_CONF: *u8 = "/tmp/nx_lorebook_gate/lore.conf" as *u8 12const LG_CONF_TIGHT: *u8 = "/tmp/nx_lorebook_gate/lore_tight.conf" as *u8 13const LG_CONF_NOBUDGET: *u8 = "/tmp/nx_lorebook_gate/lore_nobudget.conf" as *u8 14const LG_CONF_ABSENT: *u8 = "/tmp/nx_lorebook_gate/does_not_exist.conf" as *u8 15const LG_MODE_DIR: i64 = 511 16const LG_MODE_FILE: i64 = 420 17const LG_OUT_CAP: i64 = 8192 18const LG_STATS_CAP: i64 = 64 19const LG_ROWS: *u8 = "# fixture lorebook\n@budget 600\nbeach|beach, shore|The cove west of the house has black sand and a tide pool she loves.\ncafe|cafe,coffee|Marisol's cafe on the corner does the cardamom latte she orders.\nbroken|only two fields\n" as *u8 20const LG_ROWS_TIGHT: *u8 = "@budget 40\nbeach|beach|The cove west of the house has black sand and a tide pool she loves.\n" as *u8 21const LG_ROWS_NOBUDGET: *u8 = "beach|beach|The cove west of the house has black sand and a tide pool she loves.\n" as *u8 22const LG_BEACH_TELL: *u8 = "black sand" as *u8 23const LG_CAFE_TELL: *u8 = "cardamom" as *u8 24const LG_REFUSED_TELL: *u8 = "[WORLD refused" as *u8 25const LG_HEAD_TELL: *u8 = "[WORLD --" as *u8 26const LG_TIGHT_BUDGET_TEXT: *u8 = " budget of 40 " as *u8 27 28func lg_len(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n } 29func lg_find(buf: *u8, n: i64, needle: *u8) -> i64 { 30 let nl: i64 = lg_len(needle) 31 if nl <= 0 { return 0 - 1 } 32 var i: i64 = 0 33 while i + nl <= n { 34 var j: i64 = 0 35 var same: i64 = 1 36 var scan: i64 = 1 37 while scan == 1 { if j >= nl { scan = 0 } else { if buf[i + j] != needle[j] { same = 0; scan = 0 } else { j = j + 1 } } } 38 if same == 1 { return i } 39 i = i + 1 40 } 41 return 0 - 1 42} 43func lg_write(path: *u8, body: *u8) -> i64 { 44 let fd: i64 = sys_openat_wr(path, LG_MODE_FILE) 45 if fd < 0 { return 0 - 1 } 46 sys_write(fd, body, lg_len(body)) 47 sys_close(fd) 48 return 0 49} 50// one run of the contract against a conf and a turn; returns bytes written, out/stats filled 51func lg_run(conf: *u8, turn: *u8, out: *u8, stats: *i64) -> i64 { 52 return em_lorebook_from(conf, turn, lg_len(turn), out, LG_OUT_CAP, stats) 53} 54 55func main() -> i64 { 56 gv_head("nx_lorebook_gate -- CC3: keyed world facts injected only when touched, once per turn, under a budget that refuses loudly" as *u8) 57 let ctr: *i64 = gv_ctr() 58 sys_mkdir(LG_DIR, LG_MODE_DIR) 59 sys_unlinkat(LG_CONF_ABSENT) 60 let w1: i64 = lg_write(LG_CONF, LG_ROWS) 61 let w2: i64 = lg_write(LG_CONF_TIGHT, LG_ROWS_TIGHT) 62 let w3: i64 = lg_write(LG_CONF_NOBUDGET, LG_ROWS_NOBUDGET) 63 gv_check("setup-fixture-confs-written" as *u8, (w1 == 0) & (w2 == 0) & (w3 == 0), ctr) 64 65 let out: *u8 = sys_mmap(LG_OUT_CAP) 66 let st: *i64 = sys_mmap(LG_STATS_CAP) as *i64 67 68 // T1 a touched entry is injected, an untouched one is not, and the parse counted what the fixture holds 69 let n1: i64 = lg_run(LG_CONF, "let's go to the beach this afternoon" as *u8, out, st) 70 gv_check("fixture-reached-condition-two-rows-parsed-and-one-malformed-counted" as *u8, (st[LB_ST_ROWS] == 2) & (st[LB_ST_MALFORMED] == 1), ctr) 71 gv_check("trigger-in-turn-injects-its-entry-under-the-world-header" as *u8, (n1 > 0) & (lg_find(out, n1, LG_BEACH_TELL) >= 0) & (lg_find(out, n1, LG_HEAD_TELL) == 0), ctr) 72 gv_check("neg-control-untouched-entry-is-not-injected" as *u8, (n1 > 0) & (lg_find(out, n1, LG_CAFE_TELL) < 0) & (st[LB_ST_FIRED] == 1), ctr) 73 74 // T2 case-insensitive, and the second trigger of a row works after trimming 75 let n2: i64 = lg_run(LG_CONF, "BEACH day?" as *u8, out, st) 76 gv_check("match-is-ascii-case-insensitive" as *u8, (n2 > 0) & (st[LB_ST_FIRED] == 1) & (lg_find(out, n2, LG_BEACH_TELL) >= 0), ctr) 77 let n2b: i64 = lg_run(LG_CONF, "walk along the shore?" as *u8, out, st) 78 gv_check("second-trigger-of-a-row-matches-after-trimming" as *u8, (n2b > 0) & (st[LB_ST_FIRED] == 1) & (lg_find(out, n2b, LG_BEACH_TELL) >= 0), ctr) 79 80 // T3 NEG-CONTROLS: nothing touched, empty turn, absent conf -- all zero bytes 81 let n3: i64 = lg_run(LG_CONF, "how was your day" as *u8, out, st) 82 gv_check("neg-control-turn-touching-no-trigger-writes-zero-bytes" as *u8, (n3 == 0) & (st[LB_ST_FIRED] == 0) & (st[LB_ST_ROWS] == 2), ctr) 83 let n3b: i64 = em_lorebook_from(LG_CONF, "beach" as *u8, 0, out, LG_OUT_CAP, st) 84 gv_check("neg-control-empty-turn-writes-zero-bytes" as *u8, (n3b == 0) & (st[LB_ST_FIRED] == 0), ctr) 85 let n3c: i64 = lg_run(LG_CONF_ABSENT, "beach" as *u8, out, st) 86 gv_check("neg-control-absent-conf-writes-zero-bytes-and-parses-no-rows" as *u8, (n3c == 0) & (st[LB_ST_ROWS] == 0) & (st[LB_ST_FIRED] == 0), ctr) 87 88 // T4 two entries fire in conf order; one entry fires once when two of its triggers match 89 let n4: i64 = lg_run(LG_CONF, "coffee at the beach" as *u8, out, st) 90 let pb: i64 = lg_find(out, n4, LG_BEACH_TELL) 91 let pc: i64 = lg_find(out, n4, LG_CAFE_TELL) 92 gv_check("two-touched-entries-both-inject-in-conf-order" as *u8, (st[LB_ST_FIRED] == 2) & (pb >= 0) & (pc > pb), ctr) 93 let n4b: i64 = lg_run(LG_CONF, "beach shore beach" as *u8, out, st) 94 gv_check("an-entry-fires-once-however-many-of-its-triggers-match" as *u8, (n4b > 0) & (st[LB_ST_FIRED] == 1), ctr) 95 96 // T5 the malformed row never fires even when its own words appear in the turn 97 let n5: i64 = lg_run(LG_CONF, "only two fields" as *u8, out, st) 98 gv_check("malformed-row-is-counted-and-never-fires" as *u8, (n5 == 0) & (st[LB_ST_MALFORMED] == 1) & (st[LB_ST_FIRED] == 0), ctr) 99 100 // T6 over budget: the fixture's budget is below the one entry, the refusal names both numbers, nothing partial lands 101 let n6: i64 = lg_run(LG_CONF_TIGHT, "beach" as *u8, out, st) 102 gv_check("fixture-reached-condition-tight-budget-is-below-the-touched-entry" as *u8, (st[LB_ST_FIRED] == 1) & (st[LB_ST_WANTED] > st[LB_ST_BUDGET]) & (st[LB_ST_BUDGET] == 40), ctr) 103 gv_check("over-budget-refuses-loudly-naming-wanted-and-budget" as *u8, (n6 > 0) & (st[LB_ST_REFUSED] == 1) & (lg_find(out, n6, LG_REFUSED_TELL) == 0) & (lg_find(out, n6, LG_TIGHT_BUDGET_TEXT) >= 0), ctr) 104 gv_check("neg-control-over-budget-injects-no-partial-entry" as *u8, (n6 > 0) & (lg_find(out, n6, LG_BEACH_TELL) < 0) & (lg_find(out, n6, LG_HEAD_TELL) < 0), ctr) 105 106 // T7 the default budget applies when the conf carries no @budget row, and an in-budget turn is not refused 107 let n7: i64 = lg_run(LG_CONF_NOBUDGET, "beach" as *u8, out, st) 108 gv_check("default-budget-applies-when-no-budget-row-and-in-budget-is-not-refused" as *u8, (n7 > 0) & (st[LB_ST_BUDGET] == LB_BUDGET_DEFAULT) & (st[LB_ST_REFUSED] == 0), ctr) 109 110 return gv_verdict("LOREBOOK-GATE" as *u8, ctr, "CC3 done-rule: keyed entries as data, injected on trigger only, once per turn, zero bytes when untouched, malformed rows counted not guessed, over-budget refuses loudly with no partial injection" as *u8) 111}