code wiki / (root) / nx_manga_bubble_gate.nx

nx_manga_bubble_gate.nx source

↩ module page · 147 lines · 7435 B

1// nx_manga_bubble_gate.nx -- REFEREE for R2 (nx_manga_bubble). END-TO-END: forks the PROMOTED elf with a 2// real argv and reads the PNG it produced back through our own decoder, so it measures the shipped binary 3// and not a convenient in-process copy of the logic. 4// It proves the DONE-RULE that was pre-declared on /compare/mangagen before the organ existed: 5// "Bubble geometry + tails + sovereign TTF raster; overflow REFUSES, never silently clips." 6// TWO NEGATIVE CONTROLS, because a green that never had a red is unverified: 7// neg-control-white -- the same ink counter over a known-blank buffer must return ZERO, so the 8// drew-something teeth cannot be tautologies that pass on any image. 9// neg-control-overflow -- text that cannot fit must REFUSE (non-zero) AND leave NO output file, 10// which is the difference between refusing and clipping. 11// license_tier: ORIGINAL expect_exit: 0 12import "nx_str.nx" 13import "nx_syscalls.nx" 14import "nx_tool_run.nx" 15import "nx_img_to_rgb.nx" 16import "nx_gate_verdict.nx" 17const MBG_CAP: i64 = 65536 18const MBG_W: i64 = 900 19const MBG_H: i64 = 600 20// count pixels darker than a threshold inside a rect -- the ink detector both teeth and the control share 21func mbg_ink(rgb: *u8, w: i64, h: i64, x0: i64, y0: i64, x1: i64, y1: i64) -> i64 { 22 var c: i64 = 0 23 var y: i64 = y0 24 while y < y1 { 25 if y >= 0 { if y < h { 26 var x: i64 = x0 27 while x < x1 { 28 if x >= 0 { if x < w { 29 let o: i64 = (y * w + x) * 3 30 let r: i64 = rgb[o] as i64 31 let g: i64 = rgb[o+1] as i64 32 let b: i64 = rgb[o+2] as i64 33 if r + g + b < 300 { c = c + 1 } 34 } } 35 x = x + 1 36 } 37 } } 38 y = y + 1 39 } 40 return c 41} 42func mbg_exists(p: *u8) -> i64 { 43 let fd: i64 = sys_openat_rd(p) 44 if fd < 0 { return 0 } 45 sys_close(fd) 46 return 1 47} 48func main(argc: i64, argv: *i64) -> i64 { 49 let ctr: *i64 = gv_ctr() 50 gv_head("nx_manga_bubble -- a bubble with a tail and real lettering, and an overflow that REFUSES" as *u8) 51 // ⚠ABSOLUTE, deliberately. A relative "../" resolved against whatever CWD the runner chose, the fork 52 // failed, and EVERY run came back non-zero -- which made the two neg-controls pass VACUOUSLY while the 53 // gate measured nothing at all. ★A GUARD THAT REFUSES EVERYTHING PASSES EVERY NEGATIVE TEST; only the 54 // positive tooth (T1) could tell the difference, and it is why T1 exists. 55 // SUBJECT PATH: argv[1] when handed one, else the promoted elf. Same fix, same reason as 56 // nx_manga_script_gate (MEASURED 2026-09-05): nx_gate_bite rebuilds the SUBJECT per mutant and 57 // hands its path as argv[1]. A gate that declares argv and then forks a HARDCODED serving-root 58 // path re-tests the PRISTINE promoted binary every time, so every mutant SURVIVES and the gate 59 // reads GREEN while proving nothing. On the sibling gate that pattern measured 7 valid mutants / 60 // 0 killed; the one-line fix took it to a real KILL and verdict=GREEN non-vacuity proven. 61 // The fallback keeps every existing caller working: no argv means the promoted binary, as before. 62 var ELF: *u8 = "/volume1/homes/elderwesto/nishihost/nx_manga_bubble.elf" as *u8 63 if argc > 1 { ELF = argv[1] as *u8 } 64 let OUT: *u8 = "/tmp/mbg_fit.png" as *u8 65 let OUT2: *u8 = "/tmp/mbg_overflow.png" as *u8 66 let out: *u8 = sys_mmap(MBG_CAP) 67 let ol: *i64 = sys_mmap(16) as *i64 68 let av: *i64 = sys_mmap(256) as *i64 69 sys_unlinkat(OUT) 70 sys_unlinkat(OUT2) 71 // ---- run 1: dialogue that FITS ------------------------------------------------------------- 72 av[0] = ELF as i64 73 av[1] = "blank:900x600" as i64 74 av[2] = OUT as i64 75 av[3] = "450" as i64 76 av[4] = "240" as i64 77 av[5] = "250" as i64 78 av[6] = "150" as i64 79 av[7] = "430" as i64 80 av[8] = "520" as i64 81 av[9] = "6" as i64 82 av[10] = "22" as i64 83 av[11] = "WE SHIP" as i64 84 av[12] = "OR WE" as i64 85 av[13] = "REFUSE" as i64 86 av[14] = 0 87 let rc1: i64 = tr_run_capture(ELF, av, out, MBG_CAP, ol) 88 var t1: i64 = 0 89 if rc1 == 0 { t1 = 1 } 90 gv_check("T1 BITE: a bubble whose text fits is drawn and the organ exits clean" as *u8, t1, ctr) 91 var t2: i64 = 0 92 if mbg_exists(OUT) == 1 { t2 = 1 } 93 gv_check("T2 the page artifact actually reached disk" as *u8, t2, ctr) 94 // ---- decode the shipped artifact back through our own decoder ------------------------------ 95 let wh: *i64 = sys_mmap(32) as *i64 96 wh[0] = 0 97 wh[1] = 0 98 var rgb: *u8 = 0 as *u8 99 if t2 == 1 { rgb = nx_img_to_rgb(OUT, wh) } 100 var t3: i64 = 0 101 if (rgb as i64) != 0 { if wh[0] == MBG_W { if wh[1] == MBG_H { t3 = 1 } } } 102 gv_check("T3 it decodes at the page geometry it was asked for" as *u8, t3, ctr) 103 // ---- the drawing teeth -------------------------------------------------------------------- 104 var ring: i64 = 0 105 var letter: i64 = 0 106 var tail: i64 = 0 107 if t3 == 1 { 108 // a band across the LEFT edge of the ring: cx-rx is 200, so 190..215 straddles the stroke 109 ring = mbg_ink(rgb, MBG_W, MBG_H, 190, 230, 215, 250) 110 // the inner box, where the lettering lives 111 letter = mbg_ink(rgb, MBG_W, MBG_H, 330, 180, 570, 300) 112 // between the ring bottom (cy+ry = 390) and the tip (520): only the tail can ink this 113 tail = mbg_ink(rgb, MBG_W, MBG_H, 410, 400, 450, 500) 114 } 115 var t4: i64 = 0 116 if ring > 0 { t4 = 1 } 117 gv_check("T4 GEOMETRY: the bubble outline is inked on the ring" as *u8, t4, ctr) 118 var t5: i64 = 0 119 if letter > 0 { t5 = 1 } 120 gv_check("T5 LETTERING: sovereign glyphs are inked inside the bubble" as *u8, t5, ctr) 121 var t6: i64 = 0 122 if tail > 0 { t6 = 1 } 123 gv_check("T6 TAIL: ink between the ring and the tip -- the balloon points at its speaker" as *u8, t6, ctr) 124 // ---- neg-control-white: the SAME counter over a known-blank buffer must return ZERO --------- 125 let white: *u8 = sys_mmap(MBG_W * MBG_H * 3 + 64) 126 var i: i64 = 0 127 let n3: i64 = MBG_W * MBG_H * 3 128 while i < n3 { white[i] = 255 as u8; i = i + 1 } 129 let ctrl: i64 = mbg_ink(white, MBG_W, MBG_H, 190, 230, 215, 250) + mbg_ink(white, MBG_W, MBG_H, 330, 180, 570, 300) + mbg_ink(white, MBG_W, MBG_H, 410, 400, 450, 500) 130 var t7: i64 = 0 131 if ctrl == 0 { t7 = 1 } 132 gv_check("T7 neg-control-white: the ink counter returns ZERO on blank paper, so T4-T6 are not tautologies" as *u8, t7, ctr) 133 // ---- neg-control-overflow: text that cannot fit must REFUSE, and leave nothing behind ------- 134 av[2] = OUT2 as i64 135 av[5] = "90" as i64 136 av[6] = "60" as i64 137 av[11] = "THIS SENTENCE IS FAR TOO LONG TO EVER FIT INSIDE A BALLOON THIS SMALL AND MUST BE REFUSED" as i64 138 av[12] = 0 139 let rc2: i64 = tr_run_capture(ELF, av, out, MBG_CAP, ol) 140 var t8: i64 = 0 141 if rc2 != 0 { t8 = 1 } 142 gv_check("T8 neg-control-overflow: text that cannot fit REFUSES instead of returning success" as *u8, t8, ctr) 143 var t9: i64 = 0 144 if mbg_exists(OUT2) == 0 { t9 = 1 } 145 gv_check("T9 the refusal wrote NO page -- refusing is not clipping, and leaves no half-drawn artifact" as *u8, t9, ctr) 146 return gv_verdict("MANGA-BUBBLE-GATE" as *u8, ctr, "tails, sovereign lettering, and an overflow that refuses rather than clips" as *u8) 147}