nx_cite_gate.nx source
↩ module page · 113 lines · 6044 B
1// nx_cite_gate.nx -- F993 INDEPENDENT GATE: the anti-hallucination tooth on real-shaped legal text.
2// Stores a statute, then proves the verifier tells the truth in every direction that matters -- and in
3// particular that a PLAUSIBLE, subtly-altered misquote (the exact 2026-benchmark failure mode) is
4// REJECTED, not waved through. This is the one test that separates a verifier from a chatbot.
5// license_tier: ORIGINAL No hw writes (Rule 26). expect_exit: 0
6
7import "nx_cite_lib.nx"
8
9func qg_puts(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 }
10func qg_putn(v: i64) -> i64 {
11 let t: *u8 = sys_mmap(32)
12 var o: i64 = 0
13 var m: i64 = v
14 if m < 0 { t[o] = 45 as u8; o = o + 1; m = 0 - m }
15 let d: *u8 = sys_mmap(32)
16 var k: i64 = 0
17 if m == 0 { d[0] = 48 as u8; k = 1 }
18 while m > 0 { d[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 }
19 var i: i64 = 0
20 while i < k { t[o] = d[k - 1 - i]; o = o + 1; i = i + 1 }
21 sys_write(1, t, o)
22 return 0
23}
24func qg_ck(cnt: *i64, name: *u8, got: i64, want: i64) -> i64 {
25 if got == want {
26 cnt[0] = cnt[0] + 1
27 qg_puts(" PASS " as *u8); qg_puts(name); qg_puts(" = " as *u8); qg_putn(got); qg_puts("\n" as *u8)
28 return 1
29 }
30 cnt[1] = cnt[1] + 1
31 qg_puts(" FAIL " as *u8); qg_puts(name); qg_puts(" got " as *u8); qg_putn(got)
32 qg_puts(" want " as *u8); qg_putn(want); qg_puts("\n" as *u8)
33 return 0
34}
35func qg_id(tag: *u8, nonce: i64, out: *u8) -> i64 {
36 var o: i64 = mt_catcopy(out, 0, tag)
37 o = mt_catn(out, o, nonce)
38 out[o] = 0 as u8
39 return o
40}
41
42func main(argc: i64, argv: *i64) -> i64 {
43 let pfx: *u8 = "knowledge/store/citegate-" as *u8
44 let nonce: i64 = sys_now_us()
45 let cnt: *i64 = sys_mmap(16) as *i64
46 cnt[0] = 0
47 cnt[1] = 0
48
49 // a real-shaped source: Utah RPC 1.15(a) paraphrase (used as fixture text, not legal advice)
50 let sid: *u8 = sys_mmap(64)
51 let missing: *u8 = sys_mmap(64)
52 qg_id("URPC-1.15-" as *u8, nonce, sid)
53 qg_id("MADE-UP-CASE-" as *u8, nonce, missing)
54 let src: *u8 = "A lawyer shall hold property of clients or third persons that is in a lawyer's possession in connection with a representation separate from the lawyer's own property. Funds shall be kept in a separate account." as *u8
55
56 qg_puts("NISHI-CITE-GATE (F993 cite-or-abstain: a fabricated citation cannot pass)\n" as *u8)
57
58 cite_source_put(pfx, sid, src)
59
60 // ---- Q1: an EXACT quote from the real source -> CITED ----
61 qg_ck(cnt, "Q1 exact quote from a real source -> CITED" as *u8,
62 cite_verify(pfx, sid, "Funds shall be kept in a separate account." as *u8), CITE_CITED)
63
64 // ---- Q2: a quote to a NON-EXISTENT source -> ABSTAIN (the made-up-case failure) ----
65 qg_ck(cnt, "Q2 quote to a non-existent source -> ABSTAIN_NO_SOURCE" as *u8,
66 cite_verify(pfx, missing, "Funds shall be kept in a separate account." as *u8), CITE_ABSTAIN_NO_SOURCE)
67
68 // ---- Q3: a wholly fabricated quote NOT in the source -> ABSTAIN ----
69 qg_ck(cnt, "Q3 fabricated quote not in the source -> ABSTAIN_NO_SPAN" as *u8,
70 cite_verify(pfx, sid, "The lawyer may commingle funds at their discretion." as *u8), CITE_ABSTAIN_NO_SPAN)
71
72 // ---- Q4: THE 2026 WALL. A subtly ALTERED quote ("separate" -> "same") -> ABSTAIN. ----
73 // A chatbot emits this confidently; the verifier rejects it because the bytes are not present.
74 qg_ck(cnt, "Q4 subtly altered quote (one word changed) -> ABSTAIN_NO_SPAN" as *u8,
75 cite_verify(pfx, sid, "Funds shall be kept in a same account." as *u8), CITE_ABSTAIN_NO_SPAN)
76
77 // ---- Q5: the EMPTY quote hole -> ABSTAIN (empty is a substring of everything; closed explicitly) ----
78 qg_ck(cnt, "Q5 empty quote -> ABSTAIN not CITED" as *u8,
79 cite_verify(pfx, sid, "" as *u8), CITE_ABSTAIN_NO_SPAN)
80
81 // ---- Q6: a quote from the MIDDLE of the source (not just a prefix) -> CITED ----
82 qg_ck(cnt, "Q6 interior span (not a prefix) -> CITED" as *u8,
83 cite_verify(pfx, sid, "separate from the lawyer's own property" as *u8), CITE_CITED)
84
85 // ---- Q7: a quote LONGER than the source -> ABSTAIN (no out-of-bounds, no crash) ----
86 qg_ck(cnt, "Q7 quote longer than source -> ABSTAIN" as *u8,
87 cite_verify(pfx, sid, "A lawyer shall hold property of clients or third persons that is in a lawyer's possession in connection with a representation separate from the lawyer's own property. Funds shall be kept in a separate account. And also many additional words that are not present." as *u8), CITE_ABSTAIN_NO_SPAN)
88
89 // ---- Q8: BYTE-EXACT floor is honest -- a case-altered quote is NOT silently normalized ----
90 // "funds" (lowercase f) is not the stored "Funds"; strict floor abstains. Declared, not a bug.
91 qg_ck(cnt, "Q8 case-altered quote abstains (byte-exact floor, normalization is opt-in)" as *u8,
92 cite_verify(pfx, sid, "funds shall be kept in a separate account." as *u8), CITE_ABSTAIN_NO_SPAN)
93
94 // ---- Q9: cite_ok is the green-light gate a drafting tool must pass before printing a citation ----
95 qg_ck(cnt, "Q9 cite_ok=1 for a real span" as *u8, cite_ok(pfx, sid, "separate account" as *u8), 1)
96 qg_ck(cnt, "Q9a cite_ok=0 for a fabricated span" as *u8, cite_ok(pfx, sid, "discretion to commingle" as *u8), 0)
97
98 // ---- Q10: round-trip -- the stored source is retrievable byte-length intact ----
99 let back: *u8 = sys_mmap(CITE_SRC_CAP)
100 let bl: i64 = cite_source_text(pfx, sid, back)
101 qg_ck(cnt, "Q10 stored source round-trips (length matches)" as *u8, bl, cite_len(src))
102
103 qg_puts("nx_cite_gate: pass=" as *u8); qg_putn(cnt[0])
104 qg_puts(" fail=" as *u8); qg_putn(cnt[1]); qg_puts("\n" as *u8)
105 if cnt[1] == 0 {
106 qg_puts("F993 nx_cite: VERDICT=GREEN (fabricated and altered citations abstain; only exact spans of real sources cite)\n" as *u8)
107 sys_exit(0)
108 return 0
109 }
110 qg_puts("F993 nx_cite: VERDICT=RED\n" as *u8)
111 sys_exit(1)
112 return 1
113}