code wiki / (root) / nx_game_chat_gate.nx

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}