nx_game_chat_gate.nx source
↩ module page · 273 lines · 12831 B
1// nx_game_chat_gate.nx -- REFEREE for C12 (nx_game_chat, contract gc_room_wire). END-TO-END: builds
2// isolated confs under /tmp/gcgate (game defs + a chatstore conf whose store_root is the fixture),
3// forks the PROMOTED organs, and proves the done-rule: two clients exchange moves and chat through
4// the C1 store with the game's own rules as the referee.
5// THE TOOTH THAT MATTERS IS T10: a move row injected DIRECTLY through nx_chat_store -- bypassing the
6// move verb entirely, the race/hostile-client case -- must be COUNTED AND IGNORED by the replay. A
7// wire anyone can write to is untrusted by construction; the deterministic replay is the authority.
8// Also proven: a full connect-four playthrough to a win, out-of-turn/illegal/full-column/occupied
9// refusals, chat interleaving without disturbing state, the reserved mv: prefix, byte-identical
10// deterministic emits, and the place-mode engine from the ttt conf row (data-driven: two games, one
11// engine, zero game-specific code paths beyond the conf mode).
12// license_tier: ORIGINAL expect_exit: 0
13import "nx_syscalls.nx"
14import "nx_tool_run.nx"
15import "nx_gate_verdict.nx"
16const GCG_CAP: i64 = 65536
17func gcg_len(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n }
18func gcg_write(path: *u8, s: *u8) -> i64 {
19 let fd: i64 = sys_openat_wr(path, 420)
20 if fd < 0 { return 0 - 1 }
21 let n: i64 = gcg_len(s)
22 var w2: i64 = 0
23 while w2 < n { let r: i64 = sys_write(fd, (s as i64 + w2) as *u8, n - w2); if r <= 0 { break } w2 = w2 + r }
24 sys_close(fd)
25 return 0
26}
27func gcg_read(path: *u8, buf: *u8, cap: i64) -> i64 {
28 let fd: i64 = sys_openat_rd(path)
29 if fd < 0 { return 0 - 1 }
30 var tot: i64 = 0
31 while tot < cap { let r: i64 = sys_read(fd, (buf as i64 + tot) as *u8, cap - tot); if r <= 0 { break } tot = tot + r }
32 sys_close(fd)
33 return tot
34}
35func gcg_count(buf: *u8, n: i64, needle: *u8) -> i64 {
36 let m: i64 = gcg_len(needle)
37 if m <= 0 { return 0 }
38 var c: i64 = 0
39 var i: i64 = 0
40 while i + m <= n {
41 var k: i64 = 0
42 var hit: i64 = 1
43 while k < m { if buf[i+k] != needle[k] { hit = 0; k = m } else { k = k + 1 } }
44 if hit == 1 { c = c + 1; i = i + m } else { i = i + 1 }
45 }
46 return c
47}
48func main(argc: i64, argv: *i64) -> i64 {
49 let ctr: *i64 = gv_ctr()
50 gv_head("nx_game_chat -- the log is the game: moves and chat through the C1 store, deterministic replay as the referee" as *u8)
51 let GAME: *u8 = "/volume1/homes/elderwesto/nishihost/nx_game_chat.elf" as *u8
52 let CHAT: *u8 = "/volume1/homes/elderwesto/nishihost/nx_chat_store.elf" as *u8
53 let GCONF: *u8 = "/tmp/gcgate/games.conf" as *u8
54 let CCONF: *u8 = "/tmp/gcgate/chat.conf" as *u8
55 sys_mkdir("/tmp/gcgate" as *u8, 493)
56 gcg_write(CCONF, "store_root|/tmp/gcgate/\nroom_bytes_cliff|100000\nroom_msgs_cliff|100\nbody_bytes_max|500\n" as *u8)
57 gcg_write(GCONF, "game|c4|7|6|4|drop\ngame|ttt|3|3|3|place\nchat_elf|/volume1/homes/elderwesto/nishihost/nx_chat_store.elf\nchat_conf|/tmp/gcgate/chat.conf\n" as *u8)
58 let out: *u8 = sys_mmap(GCG_CAP)
59 let ol: *i64 = sys_mmap(16) as *i64
60 let av: *i64 = sys_mmap(256) as *i64
61 let ms: i64 = sys_now_realtime_ms()
62 let s1: *u8 = sys_mmap(64)
63 var o: i64 = gv_cat(s1, 0, "s" as *u8)
64 o = gv_catn(s1, o, ms)
65 s1[o] = 0 as u8
66 let room1: *u8 = sys_mmap(96)
67 o = gv_cat(room1, 0, "g_c4_" as *u8)
68 o = gv_cat(room1, o, s1)
69 room1[o] = 0 as u8
70 var t0: i64 = 0
71 let cchk: *u8 = sys_mmap(4096)
72 if gcg_read(GCONF, cchk, 4096) > 0 { t0 = 1 }
73 gv_check("T0 fixture confs on disk, store_root isolated under /tmp/gcgate" as *u8, t0, ctr)
74 // ---- T1 start ------------------------------------------------------------------------------
75 av[0] = GAME as i64
76 av[1] = "start" as i64
77 av[2] = "c4" as i64
78 av[3] = s1 as i64
79 av[4] = "alice" as i64
80 av[5] = "bob" as i64
81 av[6] = GCONF as i64
82 av[7] = 0
83 let r1: i64 = tr_run_capture(GAME, av, out, GCG_CAP, ol)
84 var t1: i64 = 0
85 if r1 == 0 { if gcg_count(out, ol[0], "GAME-START" as *u8) == 1 { if gcg_count(out, ol[0], "cols=7" as *u8) == 1 { t1 = 1 } } }
86 gv_check("T1 BITE: gc_room_wire opens a session room and stamps the game-start row (c4 from the conf)" as *u8, t1, ctr)
87 // ---- T2 first legal move -------------------------------------------------------------------
88 av[1] = "move" as i64
89 av[2] = room1 as i64
90 av[3] = "alice" as i64
91 av[4] = "3" as i64
92 av[5] = GCONF as i64
93 av[6] = 0
94 let m1: i64 = tr_run_capture(GAME, av, out, GCG_CAP, ol)
95 var t2: i64 = 0
96 if m1 == 0 { if gcg_count(out, ol[0], "state=ongoing turn_next=bob" as *u8) == 1 { t2 = 1 } }
97 gv_check("T2 a legal move lands and the turn passes" as *u8, t2, ctr)
98 // ---- T3 out-of-turn refuses ----------------------------------------------------------------
99 let m2: i64 = tr_run_capture(GAME, av, out, GCG_CAP, ol)
100 var t3: i64 = 0
101 if m2 != 0 { if gcg_count(out, ol[0], "out-of-turn expected=bob" as *u8) == 1 { t3 = 1 } }
102 gv_check("T3 neg-control-turn: the same player moving twice REFUSES and names who was expected" as *u8, t3, ctr)
103 // ---- T4 play to a vertical win -------------------------------------------------------------
104 av[3] = "bob" as i64
105 av[4] = "4" as i64
106 tr_run_capture(GAME, av, out, GCG_CAP, ol)
107 av[3] = "alice" as i64
108 av[4] = "3" as i64
109 tr_run_capture(GAME, av, out, GCG_CAP, ol)
110 av[3] = "bob" as i64
111 av[4] = "4" as i64
112 tr_run_capture(GAME, av, out, GCG_CAP, ol)
113 av[3] = "alice" as i64
114 av[4] = "3" as i64
115 tr_run_capture(GAME, av, out, GCG_CAP, ol)
116 av[3] = "bob" as i64
117 av[4] = "4" as i64
118 tr_run_capture(GAME, av, out, GCG_CAP, ol)
119 av[3] = "alice" as i64
120 av[4] = "3" as i64
121 let mw: i64 = tr_run_capture(GAME, av, out, GCG_CAP, ol)
122 var t4: i64 = 0
123 if mw == 0 { if gcg_count(out, ol[0], "state=win winner=alice" as *u8) == 1 { t4 = 1 } }
124 gv_check("T4 PLAYTHROUGH: four in a column is detected as a win by the replay, not by any stored flag" as *u8, t4, ctr)
125 // ---- T5 moves after the win refuse ---------------------------------------------------------
126 av[3] = "bob" as i64
127 av[4] = "0" as i64
128 let m3: i64 = tr_run_capture(GAME, av, out, GCG_CAP, ol)
129 var t5: i64 = 0
130 if m3 != 0 { if gcg_count(out, ol[0], "game-over" as *u8) == 1 { t5 = 1 } }
131 gv_check("T5 neg-control-finished: a move after the win REFUSES as game-over" as *u8, t5, ctr)
132 // ---- T6 chat interleaves without touching the game -----------------------------------------
133 av[1] = "say" as i64
134 av[3] = "bob" as i64
135 av[4] = "gg well played" as i64
136 let c1r: i64 = tr_run_capture(GAME, av, out, GCG_CAP, ol)
137 av[1] = "board" as i64
138 av[3] = GCONF as i64
139 av[4] = 0
140 let b1: i64 = tr_run_capture(GAME, av, out, GCG_CAP, ol)
141 var t6: i64 = 0
142 if c1r == 0 { if b1 == 0 {
143 if gcg_count(out, ol[0], "moves_applied=7" as *u8) == 1 {
144 if gcg_count(out, ol[0], "chat_rows=1" as *u8) == 1 {
145 if gcg_count(out, ol[0], "sums=ok" as *u8) == 1 {
146 if gcg_count(out, ol[0], "state=win winner=alice" as *u8) == 1 { t6 = 1 }
147 }
148 }
149 }
150 } }
151 gv_check("T6 chat rides the same room and the partition sums: 7 moves + 1 chat, state still the win" as *u8, t6, ctr)
152 // ---- T7 reserved prefix --------------------------------------------------------------------
153 av[1] = "say" as i64
154 av[3] = "alice" as i64
155 av[4] = "mv:9 sneaky" as i64
156 let c2r: i64 = tr_run_capture(GAME, av, out, GCG_CAP, ol)
157 var t7: i64 = 0
158 if c2r != 0 { if gcg_count(out, ol[0], "reserved-prefix" as *u8) == 1 { t7 = 1 } }
159 gv_check("T7 neg-control-prefix: chat starting with mv: is refused -- the move wire cannot be spoofed through say" as *u8, t7, ctr)
160 // ---- T8 second session: illegal + column-full ----------------------------------------------
161 let s2: *u8 = sys_mmap(64)
162 o = gv_cat(s2, 0, "t" as *u8)
163 o = gv_catn(s2, o, ms)
164 s2[o] = 0 as u8
165 let room2: *u8 = sys_mmap(96)
166 o = gv_cat(room2, 0, "g_c4_" as *u8)
167 o = gv_cat(room2, o, s2)
168 room2[o] = 0 as u8
169 av[1] = "start" as i64
170 av[2] = "c4" as i64
171 av[3] = s2 as i64
172 av[4] = "alice" as i64
173 av[5] = "bob" as i64
174 av[6] = GCONF as i64
175 av[7] = 0
176 tr_run_capture(GAME, av, out, GCG_CAP, ol)
177 av[1] = "move" as i64
178 av[2] = room2 as i64
179 av[3] = "alice" as i64
180 av[4] = "99" as i64
181 av[5] = GCONF as i64
182 av[6] = 0
183 let m4: i64 = tr_run_capture(GAME, av, out, GCG_CAP, ol)
184 var t8: i64 = 0
185 if m4 != 0 { if gcg_count(out, ol[0], "illegal-move" as *u8) == 1 { t8 = 1 } }
186 gv_check("T8 neg-control-illegal: column 99 on a 7-wide board refuses by name" as *u8, t8, ctr)
187 av[4] = "1" as i64
188 var fi: i64 = 0
189 while fi < 6 {
190 if fi % 2 == 0 { av[3] = "alice" as i64 } else { av[3] = "bob" as i64 }
191 tr_run_capture(GAME, av, out, GCG_CAP, ol)
192 fi = fi + 1
193 }
194 av[3] = "alice" as i64
195 let m5: i64 = tr_run_capture(GAME, av, out, GCG_CAP, ol)
196 var t9: i64 = 0
197 if m5 != 0 { if gcg_count(out, ol[0], "column-full" as *u8) == 1 { t9 = 1 } }
198 gv_check("T9 neg-control-gravity: a full column refuses -- the drop-mode engine tracks real occupancy" as *u8, t9, ctr)
199 // ---- T10 THE REFEREE TOOTH: inject a move past the verb, replay must reject it -------------
200 av[0] = CHAT as i64
201 av[1] = "append" as i64
202 av[2] = room2 as i64
203 av[3] = "bob" as i64
204 av[4] = "1" as i64
205 av[5] = "mv:2" as i64
206 av[6] = CCONF as i64
207 av[7] = 0
208 let inj: i64 = tr_run_capture(CHAT, av, out, GCG_CAP, ol)
209 av[0] = GAME as i64
210 av[1] = "board" as i64
211 av[2] = room2 as i64
212 av[3] = GCONF as i64
213 av[4] = 0
214 let b2: i64 = tr_run_capture(GAME, av, out, GCG_CAP, ol)
215 var t10: i64 = 0
216 if inj == 0 { if b2 == 0 {
217 if gcg_count(out, ol[0], "moves_rejected=1" as *u8) == 1 {
218 if gcg_count(out, ol[0], "moves_applied=6" as *u8) == 1 { t10 = 1 }
219 }
220 } }
221 gv_check("T10 REPLAY IS THE REFEREE: a move injected straight through the C1 store (bypassing the verb, out of turn) is COUNTED and IGNORED -- the wire is untrusted by construction" as *u8, t10, ctr)
222 // ---- T11 deterministic emit ----------------------------------------------------------------
223 av[1] = "emit" as i64
224 av[2] = room1 as i64
225 av[3] = "/tmp/gcgate/match1.html" as i64
226 av[4] = GCONF as i64
227 av[5] = 0
228 let e1: i64 = tr_run_capture(GAME, av, out, GCG_CAP, ol)
229 av[3] = "/tmp/gcgate/match2.html" as i64
230 let e2: i64 = tr_run_capture(GAME, av, out, GCG_CAP, ol)
231 let h1: *u8 = sys_mmap(GCG_CAP)
232 let h2: *u8 = sys_mmap(GCG_CAP)
233 let n1: i64 = gcg_read("/tmp/gcgate/match1.html" as *u8, h1, GCG_CAP)
234 let n2: i64 = gcg_read("/tmp/gcgate/match2.html" as *u8, h2, GCG_CAP)
235 var t11: i64 = 0
236 if e1 == 0 { if e2 == 0 { if n1 > 0 { if n1 == n2 {
237 var same: i64 = 1
238 var q: i64 = 0
239 while q < n1 { if h1[q] != h2[q] { same = 0; q = n1 } else { q = q + 1 } }
240 if same == 1 { if gcg_count(h1, n1, "sovereign message store" as *u8) == 1 { t11 = 1 } }
241 } } } }
242 gv_check("T11 DETERMINISTIC EMIT: two emits of the same log are byte-identical (stamped from the log's own epoch, never the clock) and the artifact declares its provenance" as *u8, t11, ctr)
243 // ---- T12 the place-mode engine from the ttt conf row ---------------------------------------
244 let s3: *u8 = sys_mmap(64)
245 o = gv_cat(s3, 0, "u" as *u8)
246 o = gv_catn(s3, o, ms)
247 s3[o] = 0 as u8
248 let room3: *u8 = sys_mmap(96)
249 o = gv_cat(room3, 0, "g_ttt_" as *u8)
250 o = gv_cat(room3, o, s3)
251 room3[o] = 0 as u8
252 av[1] = "start" as i64
253 av[2] = "ttt" as i64
254 av[3] = s3 as i64
255 av[4] = "alice" as i64
256 av[5] = "bob" as i64
257 av[6] = GCONF as i64
258 av[7] = 0
259 tr_run_capture(GAME, av, out, GCG_CAP, ol)
260 av[1] = "move" as i64
261 av[2] = room3 as i64
262 av[3] = "alice" as i64
263 av[4] = "4" as i64
264 av[5] = GCONF as i64
265 av[6] = 0
266 let m6: i64 = tr_run_capture(GAME, av, out, GCG_CAP, ol)
267 av[3] = "bob" as i64
268 let m7: i64 = tr_run_capture(GAME, av, out, GCG_CAP, ol)
269 var t12: i64 = 0
270 if m6 == 0 { if m7 != 0 { if gcg_count(out, ol[0], "cell-occupied" as *u8) == 1 { t12 = 1 } } }
271 gv_check("T12 DATA-DRIVEN: the ttt conf row runs the place-mode engine -- centre lands, taking the same cell refuses; two games, one engine, zero per-game code" as *u8, t12, ctr)
272 return gv_verdict("GAME-CHAT-GATE" as *u8, ctr, "the log is the game: playthrough to a win, every refusal by name, injected rows ignored by replay, emits deterministic, engine data-driven" as *u8)
273}