nx_campaign_gate.nx source
↩ module page · 140 lines · 7379 B
1// nx_campaign_gate.nx -- REFEREE for WRITING rung W-CAMP-1 (nx_campaign).
2//
3// [T1] session/encounter counts on a 2-session, 3-encounter campaign.
4// [T2] header + encounter-0 field extraction (whole-key parser on sub-ranges).
5// [T3] validation: complete campaign -> 0 missing; header w/o quest + an
6// encounter w/o kind/goal -> 3 missing (NEG-CONTROL).
7// [T4] GM brief emit equals the expected string exactly.
8// [T5] image-prompt seed emit equals the expected string exactly.
9// [T6] CONTINUITY time tooth: sound timeline -> 0; time 3 then 2 -> 1 (NEG).
10// [T7] CONTINUITY transit tooth: moves with transit -> 0; same location w/o
11// transit -> 0 (no false positive); move w/o transit = TELEPORT -> 1 (NEG).
12// [T8] whole-key: the word goal inside a value does NOT satisfy the goal key.
13//
14// Evidence -> stdout + knowledge/status/campaign_gate.log. Exit 0 GREEN / 1 RED.
15// Sovereign x86_64. license_tier: ORIGINAL
16import "nx_syscalls_x86_64.nx"
17import "nx_campaign.nx"
18import "nx_scenario.nx"
19
20func gp(logfd: i64, s: *u8) -> i64 {
21 var n: i64 = 0
22 while s[n] != (0 as u8) { n = n + 1 }
23 sys_write(1, s, n)
24 if logfd > 0 { sys_write(logfd, s, n) }
25 return 0
26}
27func gn(logfd: i64, v: i64) -> i64 {
28 var m: i64 = v
29 if m < 0 {
30 sys_write(1, "-\x00" as *u8, 1)
31 if logfd > 0 { sys_write(logfd, "-\x00" as *u8, 1) }
32 m = 0 - m
33 }
34 let bb: *u8 = sys_mmap(32)
35 let t: *u8 = sys_mmap(32)
36 var k: i64 = 0
37 if m == 0 { t[0] = 48 as u8; k = 1 }
38 while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 }
39 var i: i64 = 0
40 while i < k { bb[i] = t[k - 1 - i]; i = i + 1 }
41 sys_write(1, bb, k)
42 if logfd > 0 { sys_write(logfd, bb, k) }
43 return 0
44}
45func slen(s: *u8) -> i64 {
46 var n: i64 = 0
47 while s[n] != (0 as u8) { n = n + 1 }
48 return n
49}
50func pr_kv(logfd: i64, label: *u8, got: i64, exp: i64) -> i64 {
51 gp(logfd, label)
52 gp(logfd, " got=\x00" as *u8); gn(logfd, got)
53 gp(logfd, " exp=\x00" as *u8); gn(logfd, exp)
54 if got == exp { gp(logfd, " OK\n\x00" as *u8); return 1 }
55 gp(logfd, " FAIL\n\x00" as *u8)
56 return 0
57}
58func pr_streq(logfd: i64, label: *u8, got: *u8, exp: *u8) -> i64 {
59 gp(logfd, label)
60 gp(logfd, " got=\"\x00" as *u8); gp(logfd, got); gp(logfd, "\"\x00" as *u8)
61 if cg_streq(got, exp) == 1 { gp(logfd, " OK\n\x00" as *u8); return 1 }
62 gp(logfd, " FAIL\n\x00" as *u8)
63 return 0
64}
65
66func main() -> i64 {
67 let logfd: i64 = sys_openat_append("knowledge/status/campaign_gate.log\x00" as *u8, 0x1a4)
68 gp(logfd, "CAMPAIGN-GATE W-CAMP-1 (counts / fields / validate / brief / img / time / transit / whole-key)\n\x00" as *u8)
69
70 let buf: *u8 = sys_mmap(1024)
71 let sa: *u8 = sys_mmap(256)
72 let sb: *u8 = sys_mmap(256)
73 var ok: i64 = 1
74
75 let good: *u8 = "system: dnd5e\nsetting: the drowned marches\nparty: Kael, Yara, Brint\nquest: recover the tidebound crown\n\nSESSION\ntitle: the salt road\nENCOUNTER\nkind: social\ntime: 1\nlocation: brackwater inn\nnpcs: Maro the fence\ngoal: learn where the crown sank\nENCOUNTER\nkind: combat\ntime: 2\nlocation: salt road\ntransit: wagon south at dawn\nnpcs: reef bandits\ngoal: survive the ambush\n\nSESSION\ntitle: the wreck\nENCOUNTER\nkind: exploration\ntime: 3\nlocation: sunken wreck\ntransit: hired skiff\nnpcs: none\ngoal: find the crown vault\n\x00" as *u8
76 let gn2: i64 = slen(good)
77
78 // ---- T1: counts ----
79 gp(logfd, " [T1] session/encounter counts\n\x00" as *u8)
80 if pr_kv(logfd, " sessions\x00" as *u8, cg_count_sessions(good, gn2), 2) == 0 { ok = 0 }
81 if pr_kv(logfd, " encounters\x00" as *u8, cg_count_encounters(good, gn2), 3) == 0 { ok = 0 }
82
83 // ---- T2: header + encounter-0 extraction ----
84 gp(logfd, " [T2] header + encounter-0 extraction\n\x00" as *u8)
85 let he: i64 = cg_header_end(good, gn2)
86 sc_copy_field(good, he, "setting\x00" as *u8, buf, 1024)
87 if pr_streq(logfd, " setting\x00" as *u8, buf, "the drowned marches\x00" as *u8) == 0 { ok = 0 }
88 sc_copy_field(good, he, "party\x00" as *u8, buf, 1024)
89 if pr_streq(logfd, " party\x00" as *u8, buf, "Kael, Yara, Brint\x00" as *u8) == 0 { ok = 0 }
90 let s0: i64 = cg_enc_start(good, gn2, 0)
91 let e0: i64 = cg_enc_end(good, gn2, s0)
92 let sub0: *u8 = (good as i64 + s0) as *u8
93 sc_copy_field(sub0, e0 - s0, "kind\x00" as *u8, buf, 1024)
94 if pr_streq(logfd, " enc0 kind\x00" as *u8, buf, "social\x00" as *u8) == 0 { ok = 0 }
95
96 // ---- T3: validation + NEG-CONTROL ----
97 gp(logfd, " [T3] validation\n\x00" as *u8)
98 if pr_kv(logfd, " complete campaign missing\x00" as *u8, cg_validate(good, gn2), 0) == 0 { ok = 0 }
99 let badreq: *u8 = "setting: a keep\nparty: Ash\n\nSESSION\nENCOUNTER\nlocation: gatehouse\n\x00" as *u8
100 if pr_kv(logfd, " no-quest + bare encounter missing\x00" as *u8, cg_validate(badreq, slen(badreq)), 3) == 0 { ok = 0 }
101
102 // ---- T4: GM brief ----
103 gp(logfd, " [T4] encounter-0 GM brief\n\x00" as *u8)
104 cg_emit_brief(good, gn2, 0, buf, 1024)
105 if pr_streq(logfd, " brief\x00" as *u8, buf, "GM: social @ brackwater inn | npcs: Maro the fence | goal: learn where the crown sank\x00" as *u8) == 0 { ok = 0 }
106
107 // ---- T5: image-prompt seed ----
108 gp(logfd, " [T5] encounter-1 image seed\n\x00" as *u8)
109 cg_emit_img(good, gn2, 1, buf, 1024)
110 if pr_streq(logfd, " img\x00" as *u8, buf, "salt road, reef bandits\x00" as *u8) == 0 { ok = 0 }
111
112 // ---- T6: time monotonic + NEG ----
113 gp(logfd, " [T6] continuity: time\n\x00" as *u8)
114 if pr_kv(logfd, " sound timeline viol\x00" as *u8, cg_time_check(good, gn2), 0) == 0 { ok = 0 }
115 let badtime: *u8 = "setting: a keep\nparty: Ash\nquest: hold it\n\nSESSION\nENCOUNTER\nkind: combat\ntime: 3\nlocation: wall\ngoal: repel\nENCOUNTER\nkind: social\ntime: 2\nlocation: wall\ngoal: rally\n\x00" as *u8
116 if pr_kv(logfd, " time 3 then 2 viol\x00" as *u8, cg_time_check(badtime, slen(badtime)), 1) == 0 { ok = 0 }
117
118 // ---- T7: transit + no-false-positive + NEG ----
119 gp(logfd, " [T7] continuity: transit\n\x00" as *u8)
120 if pr_kv(logfd, " moves with transit viol\x00" as *u8, cg_transit_check(good, gn2, sa, sb, 256), 0) == 0 { ok = 0 }
121 if pr_kv(logfd, " same location no transit viol\x00" as *u8, cg_transit_check(badtime, slen(badtime), sa, sb, 256), 0) == 0 { ok = 0 }
122 let tele: *u8 = "setting: a keep\nparty: Ash\nquest: hold it\n\nSESSION\nENCOUNTER\nkind: social\nlocation: gatehouse\ngoal: parley\nENCOUNTER\nkind: combat\nlocation: throne room\ngoal: duel\n\x00" as *u8
123 if pr_kv(logfd, " teleport viol\x00" as *u8, cg_transit_check(tele, slen(tele), sa, sb, 256), 1) == 0 { ok = 0 }
124
125 // ---- T8: whole-key ----
126 gp(logfd, " [T8] whole-key: goal inside a value does not count\n\x00" as *u8)
127 let wk: *u8 = "setting: a keep\nparty: Ash\nquest: hold it\n\nSESSION\nENCOUNTER\nkind: social\nsay: the goal: is hidden\n\x00" as *u8
128 if pr_kv(logfd, " missing (goal-in-value ignored)\x00" as *u8, cg_validate(wk, slen(wk)), 1) == 0 { ok = 0 }
129
130 if ok == 1 {
131 gp(logfd, "CAMPAIGN-GATE result=ALL-PASS verdict=GREEN\n\x00" as *u8)
132 if logfd > 0 { sys_close(logfd) }
133 sys_exit(0)
134 return 0
135 }
136 gp(logfd, "CAMPAIGN-GATE result=FAIL verdict=RED\n\x00" as *u8)
137 if logfd > 0 { sys_close(logfd) }
138 sys_exit(1)
139 return 1
140}