code wiki / (root) / nx_phototwin_gate.nx

nx_phototwin_gate.nx source

↩ module page · 322 lines · 18087 B

1// nx_phototwin_gate.nx -- THE GATE FOR THE PHOTOGRAPH-TO-SUBSTRATE TWIN (nx_phototwin forked for real), 2026-08-24. 2// 3// FIXTURES ARE ASSEMBLED AT RUNTIME in /tmp/nx_phototwin_gate/: a 64x64 P6 PPM (a lossless container, so what the 4// decoder returns IS what was written -- a tooth proves it) holding a grey ramp plus the pure sRGB primaries and 5// secondaries, and a NARROW matrix/TRC ICC profile DERIVED from the mirrored sRGB2014.icc by pulling each primary 6// halfway toward the white point (rXYZ' = rXYZ/2 + wtpt/6, so the three still sum to the white point -- the ICC 7// structural invariant -- and nothing is typed in). The image is read through the sRGB profile in every run; the 8// SUBSTRATE varies: sRGB itself = positive control (inside by construction: out_permil=0, moved=0), the narrow 9// profile = the primaries are OUTSIDE and the proof must move them. That pair is the bite. The first version of this 10// gate handed ONE profile to both roles and its narrow control was VACUOUS (measured 2026-08-24, out=0 on both). 11// The wash ledger fixtures cover OK / FAIL / PARTIAL / EMPTY, and bench refuses partial coverage. 12// license_tier: ORIGINAL No hw writes (Rule 26). expect_exit: 0 13import "nx_syscalls.nx" 14import "nx_gate_verdict.nx" 15import "nx_tool_run.nx" 16import "nx_colorsci_lib.nx" 17import "nx_img_to_rgb.nx" 18 19const PG_SUBJECT_DEFAULT: *u8 = "nx_phototwin.elf" 20const PG_SRGB: *u8 = "knowledge/fetched/cmp_phototwin_srgb2014.b64" 21const PG_CONF: *u8 = "knowledge/colorsci.conf" 22const PG_DIR: *u8 = "/tmp/nx_phototwin_gate" 23const PG_OUT: *u8 = "/tmp/nx_phototwin_gate/out" 24const PG_OUT_CTRL: *u8 = "/tmp/nx_phototwin_gate/outctrl" 25const PG_IMG: *u8 = "/tmp/nx_phototwin_gate/fx.ppm" 26const PG_NARROW: *u8 = "/tmp/nx_phototwin_gate/narrow.icc" 27const PG_TWIN: *u8 = "/tmp/nx_phototwin_gate/out/twin.png" 28const PG_HEAT: *u8 = "/tmp/nx_phototwin_gate/out/heat.png" 29const PG_PROOF: *u8 = "/tmp/nx_phototwin_gate/out/proof.txt" 30const PG_LEDGER1: *u8 = "/tmp/nx_phototwin_gate/wash1.tsv" 31const PG_LEDGER2: *u8 = "/tmp/nx_phototwin_gate/wash2.tsv" 32const PG_MODE_DIR: i64 = 493 33const PG_MODE_0644: i64 = 420 34const PG_CAPTURE_CAP: i64 = 262144 35const PG_ARGV_SLOTS: i64 = 10 36const PG_SLOT: i64 = 8 37const PG_W: i64 = 64 38const PG_H: i64 = 64 39const PG_HALF: i64 = 32 40const PG_CHANNELS: i64 = 3 41const PG_CODE_MAX: i64 = 255 42const PG_BLOCKS: i64 = 6 43const PG_GREEN_X: i64 = 16 // inside block 1 (x in 10..21) of the six saturated blocks 44const PG_GREEN_Y: i64 = 48 // inside the bottom half 45const PG_PPM_HDR: *u8 = "P6\n64 64\n255\n" 46const PG_EXIT_OK: i64 = 0 47const PG_EXIT_REFUSED: i64 = 1 48const PG_EXIT_UNOBS: i64 = 3 49const PG_ICC_HDR: i64 = 128 50const PG_ICC_TAGS: i64 = 7 51const PG_ICC_ENTRY: i64 = 12 52const PG_ICC_XYZ_TAG: i64 = 20 53const PG_ICC_CURV_TAG: i64 = 12 54const PG_ICC_MAGIC_OFF: i64 = 36 55const PG_S15_SCALE: i64 = 16384 56const PG_SHRINK_DIV: i64 = 2 // primaries pulled halfway toward white 57const PG_WHITE_DIV: i64 = 6 // white/6 per primary keeps the three summing to white 58const PG_BYTE_MAX: i64 = 255 59const PG_ASCII_ZERO: i64 = 48 60const PG_ASCII_NINE: i64 = 57 61const PG_DECIMAL: i64 = 10 62 63func pg_w4(b: *u8, off: i64, v: i64) -> i64 { 64 b[off] = ((v >> 24) & PG_BYTE_MAX) as u8 65 b[off + 1] = ((v >> 16) & PG_BYTE_MAX) as u8 66 b[off + 2] = ((v >> 8) & PG_BYTE_MAX) as u8 67 b[off + 3] = (v & PG_BYTE_MAX) as u8 68 return 0 69} 70func pg_tag4(b: *u8, off: i64, t: *u8) -> i64 { b[off] = t[0]; b[off + 1] = t[1]; b[off + 2] = t[2]; b[off + 3] = t[3]; return 0 } 71func pg_write_bytes(path: *u8, b: *u8, n: i64) -> i64 { 72 let fd: i64 = sys_openat_wr(path, PG_MODE_0644) 73 if fd < 0 { return 0 - 1 } 74 let wr: i64 = sys_write(fd, b, n) 75 sys_close(fd) 76 if wr != n { return 0 - 1 } 77 return n 78} 79func pg_write_text(path: *u8, s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return pg_write_bytes(path, s, n) } 80// a matrix/TRC ICC with identity TRCs whose primaries are the given Q30 columns (rX gX bX rY gY bY rZ gZ bZ) and white 81func pg_write_icc(path: *u8, m: *i64, w: *i64) -> i64 { 82 let tagdata: i64 = PG_ICC_HDR + 4 + PG_ICC_TAGS * PG_ICC_ENTRY 83 let total: i64 = tagdata + 4 * PG_ICC_XYZ_TAG + 3 * PG_ICC_CURV_TAG 84 let b: *u8 = sys_mmap(total) 85 var i: i64 = 0 86 while i < total { b[i] = 0 as u8; i = i + 1 } 87 pg_w4(b, 0, total) 88 pg_tag4(b, PG_ICC_MAGIC_OFF, "acsp" as *u8) 89 pg_w4(b, PG_ICC_HDR, PG_ICC_TAGS) 90 var e: i64 = PG_ICC_HDR + 4 91 var d: i64 = tagdata 92 var c: i64 = 0 93 while c < 4 { 94 var sig: *u8 = "rXYZ" as *u8 95 if c == 1 { sig = "gXYZ" as *u8 } 96 if c == 2 { sig = "bXYZ" as *u8 } 97 if c == 3 { sig = "wtpt" as *u8 } 98 pg_tag4(b, e, sig); pg_w4(b, e + 4, d); pg_w4(b, e + 8, PG_ICC_XYZ_TAG) 99 pg_tag4(b, d, "XYZ " as *u8) 100 var x: i64 = 0 101 var y: i64 = 0 102 var z: i64 = 0 103 if c < 3 { x = m[c]; y = m[3 + c]; z = m[6 + c] } else { x = w[0]; y = w[1]; z = w[2] } 104 pg_w4(b, d + 8, x / PG_S15_SCALE) 105 pg_w4(b, d + 12, y / PG_S15_SCALE) 106 pg_w4(b, d + 16, z / PG_S15_SCALE) 107 e = e + PG_ICC_ENTRY 108 d = d + PG_ICC_XYZ_TAG 109 c = c + 1 110 } 111 c = 0 112 while c < 3 { 113 var sig2: *u8 = "rTRC" as *u8 114 if c == 1 { sig2 = "gTRC" as *u8 } 115 if c == 2 { sig2 = "bTRC" as *u8 } 116 pg_tag4(b, e, sig2); pg_w4(b, e + 4, d); pg_w4(b, e + 8, PG_ICC_CURV_TAG) 117 pg_tag4(b, d, "curv" as *u8) 118 pg_w4(b, d + 8, 0) 119 e = e + PG_ICC_ENTRY 120 d = d + PG_ICC_CURV_TAG 121 c = c + 1 122 } 123 return pg_write_bytes(path, b, total) 124} 125// the fixture image as P6: top half a grey ramp, bottom half six saturated blocks (R G B C M Y) 126func pg_write_image(path: *u8) -> i64 { 127 var hl: i64 = 0 128 while PG_PPM_HDR[hl] != (0 as u8) { hl = hl + 1 } 129 let total: i64 = hl + PG_W * PG_H * PG_CHANNELS 130 let buf: *u8 = sys_mmap(total) 131 var i: i64 = 0 132 while i < hl { buf[i] = PG_PPM_HDR[i]; i = i + 1 } 133 var y: i64 = 0 134 while y < PG_H { 135 var x: i64 = 0 136 while x < PG_W { 137 let o: i64 = hl + (y * PG_W + x) * PG_CHANNELS 138 if y < PG_HALF { 139 let g: i64 = (x * PG_CODE_MAX) / (PG_W - 1) 140 buf[o] = g as u8; buf[o + 1] = g as u8; buf[o + 2] = g as u8 141 } else { 142 let blk: i64 = (x * PG_BLOCKS) / PG_W 143 var r: i64 = 0 144 var g2: i64 = 0 145 var b: i64 = 0 146 if blk == 0 { r = PG_CODE_MAX } 147 if blk == 1 { g2 = PG_CODE_MAX } 148 if blk == 2 { b = PG_CODE_MAX } 149 if blk == 3 { g2 = PG_CODE_MAX; b = PG_CODE_MAX } 150 if blk == 4 { r = PG_CODE_MAX; b = PG_CODE_MAX } 151 if blk == 5 { r = PG_CODE_MAX; g2 = PG_CODE_MAX } 152 buf[o] = r as u8; buf[o + 1] = g2 as u8; buf[o + 2] = b as u8 153 } 154 x = x + 1 155 } 156 y = y + 1 157 } 158 return pg_write_bytes(path, buf, total) 159} 160func pg_run(subject: *u8, a1: *u8, a2: *u8, a3: *u8, a4: *u8, a5: *u8, a6: *u8, out: *u8, outlen: *i64) -> i64 { 161 let av: *i64 = sys_mmap(PG_SLOT * PG_ARGV_SLOTS) as *i64 162 av[0] = subject as i64 163 av[1] = a1 as i64 164 av[2] = a2 as i64 165 av[3] = a3 as i64 166 av[4] = a4 as i64 167 av[5] = a5 as i64 168 av[6] = a6 as i64 169 av[7] = 0 170 return tr_run_capture(subject, av, out, PG_CAPTURE_CAP, outlen) 171} 172// the integer after `key` in buf (first occurrence), or -1 173func pg_num_after(buf: *u8, n: i64, key: *u8) -> i64 { 174 var kl: i64 = 0 175 while key[kl] != (0 as u8) { kl = kl + 1 } 176 var i: i64 = 0 177 while i + kl <= n { 178 var same: i64 = 1 179 var j: i64 = 0 180 while j < kl { if buf[i + j] != key[j] { same = 0; j = kl } j = j + 1 } 181 if same == 1 { 182 var p: i64 = i + kl 183 var v: i64 = 0 184 var digits: i64 = 0 185 var go: i64 = 1 186 while go == 1 { 187 if p >= n { go = 0 } else { 188 let c: i64 = buf[p] as i64 189 if c < PG_ASCII_ZERO { go = 0 } 190 if c > PG_ASCII_NINE { go = 0 } 191 if go == 1 { v = v * PG_DECIMAL + (c - PG_ASCII_ZERO); digits = digits + 1; p = p + 1 } 192 } 193 } 194 if digits > 0 { return v } 195 return 0 - 1 196 } 197 i = i + 1 198 } 199 return 0 - 1 200} 201func pg_decodes(path: *u8, w: i64, h: i64) -> i64 { 202 let wh: *i64 = sys_mmap(PG_SLOT * 2) as *i64 203 wh[0] = 0 204 wh[1] = 0 205 let p: *u8 = nx_img_to_rgb(path, wh) 206 if (p as i64) == 0 { return 0 } 207 if wh[0] != w { return 0 } 208 if wh[1] != h { return 0 } 209 return 1 210} 211// the decoded fixture must return EXACTLY the bytes written (pure green at the green block) 212func pg_fixture_lossless(path: *u8) -> i64 { 213 let wh: *i64 = sys_mmap(PG_SLOT * 2) as *i64 214 wh[0] = 0 215 wh[1] = 0 216 let p: *u8 = nx_img_to_rgb(path, wh) 217 if (p as i64) == 0 { return 0 } 218 if wh[0] != PG_W { return 0 } 219 let o: i64 = (PG_GREEN_Y * PG_W + PG_GREEN_X) * PG_CHANNELS 220 if (p[o] as i64) != 0 { return 0 } 221 if (p[o + 1] as i64) != PG_CODE_MAX { return 0 } 222 if (p[o + 2] as i64) != 0 { return 0 } 223 return 1 224} 225 226func main(argc: i64, argv: *i64) -> i64 { 227 let ctr: *i64 = gv_ctr() 228 gv_head("nx_phototwin gate -- gamut report, chroma-clipped twin, dE00 proof and wash ledger, bite-proven against a derived narrow substrate" as *u8) 229 var subject: *u8 = PG_SUBJECT_DEFAULT 230 if argc >= 2 { subject = argv[1] as *u8 } 231 gv_puts(" subject: " as *u8); gv_puts(subject); gv_puts("\n\n" as *u8) 232 sys_mkdir(PG_DIR, PG_MODE_DIR) 233 sys_mkdir(PG_OUT, PG_MODE_DIR) 234 sys_mkdir(PG_OUT_CTRL, PG_MODE_DIR) 235 sys_unlinkat(PG_TWIN) 236 sys_unlinkat(PG_HEAT) 237 sys_unlinkat(PG_PROOF) 238 let cs: *i64 = cs_ctx() 239 let srgb: *i64 = cs_icc_load(cs, PG_SRGB) 240 let have_srgb: i64 = gv_need("mirrored sRGB2014 profile parses (knowledge/fetched, base64 transport)" as *u8, srgb[CS_P_OK], ctr) 241 let conf_ok: i64 = (cs_conf_int(PG_CONF, "soft_proof_max_tol_de00_micro" as *u8) != CS_CONF_MISS) as i64 242 let have_conf: i64 = gv_need("knowledge/colorsci.conf present" as *u8, conf_ok, ctr) 243 if have_srgb == 0 { return gv_verdict("phototwin" as *u8, ctr, "" as *u8) } 244 if have_conf == 0 { return gv_verdict("phototwin" as *u8, ctr, "" as *u8) } 245 let wi: i64 = pg_write_image(PG_IMG) 246 gv_check("setup-fixture-image-written-and-decodes-64x64" as *u8, (pg_decodes(PG_IMG, PG_W, PG_H) == 1) as i64, ctr) 247 gv_check("setup-fixture-decodes-losslessly (pure green block reads 0,255,0)" as *u8, pg_fixture_lossless(PG_IMG), ctr) 248 let nm: *i64 = sys_mmap(PG_SLOT * CS_MAT_N) as *i64 249 var k: i64 = 0 250 while k < CS_MAT_N { 251 let row: i64 = k / 3 252 nm[k] = srgb[CS_P_MAT + k] / PG_SHRINK_DIV + srgb[CS_P_WTPT + row] / PG_WHITE_DIV 253 k = k + 1 254 } 255 let wt: *i64 = sys_mmap(PG_SLOT * 3) as *i64 256 wt[0] = srgb[CS_P_WTPT]; wt[1] = srgb[CS_P_WTPT + 1]; wt[2] = srgb[CS_P_WTPT + 2] 257 let wicc: i64 = pg_write_icc(PG_NARROW, nm, wt) 258 let narrow: *i64 = cs_icc_load(cs, PG_NARROW) 259 gv_check("setup-derived-narrow-profile-parses-through-the-same-reader" as *u8, narrow[CS_P_OK], ctr) 260 gv_check("setup-fixture-reached-the-condition (narrow red primary has less X than sRGB red)" as *u8, (narrow[CS_P_MAT] < srgb[CS_P_MAT]) as i64, ctr) 261 gv_check("setup-fixture-outputs-absent-before-measuring (gate is idempotent)" as *u8, (pg_decodes(PG_TWIN, PG_W, PG_H) == 0) as i64, ctr) 262 263 let cap: *u8 = sys_mmap(PG_CAPTURE_CAP) 264 let olen: *i64 = sys_mmap(PG_SLOT * 2) as *i64 265 // ---- report: positive control (image sRGB, substrate sRGB) and the narrow substrate ---- 266 let rc_rs: i64 = pg_run(subject, "report" as *u8, PG_IMG, PG_SRGB, PG_SRGB, 0 as *u8, 0 as *u8, cap, olen) 267 gv_puts(" [report sRGB->sRGB] rc=" as *u8); gv_num(rc_rs); gv_puts("\n" as *u8); sys_write(1, cap, olen[0]) 268 let out_s: i64 = pg_num_after(cap, olen[0], "outside=" as *u8) 269 gv_check("report-control-exits-0-and-partition-sums" as *u8, ((rc_rs == PG_EXIT_OK) as i64) * tr_contains(cap, olen[0], "partition=SUMS" as *u8), ctr) 270 gv_check("positive-control-an-sRGB-image-is-inside-the-sRGB-gamut (outside=0, exact matrix test)" as *u8, (out_s == 0) as i64, ctr) 271 let rc_rn: i64 = pg_run(subject, "report" as *u8, PG_IMG, PG_SRGB, PG_NARROW, 0 as *u8, 0 as *u8, cap, olen) 272 gv_puts(" [report sRGB->narrow] rc=" as *u8); gv_num(rc_rn); gv_puts("\n" as *u8); sys_write(1, cap, olen[0]) 273 let out_n: i64 = pg_num_after(cap, olen[0], "outside=" as *u8) 274 let pix_n: i64 = pg_num_after(cap, olen[0], "pixels=" as *u8) 275 gv_check("report-against-the-narrow-substrate-finds-outside-pixels" as *u8, ((rc_rn == PG_EXIT_OK) as i64) * ((out_n > 0) as i64), ctr) 276 gv_check("report-pixels-equal-the-fixture (64x64)" as *u8, (pix_n == PG_W * PG_H) as i64, ctr) 277 // the fixture is top-half grey ramp, bottom-half saturated blocks: with the narrow substrate EVERY saturated pixel is 278 // outside (2048) and every grey is inside, so "greys inside" is exactly outside <= the saturated half -- `<` was an 279 // off-by-one against the fixture's own geometry (measured 2026-08-24: 2048 of 4096 read FAIL on a correct subject) 280 gv_check("report-narrow-keeps-the-grey-ramp-inside (outside <= the saturated half of the fixture)" as *u8, (out_n <= (PG_W * PG_H) / 2) as i64, ctr) 281 gv_bite("neg-control-gamut-report-fires-on-narrow-silent-on-own-profile" as *u8, (out_n > 0) as i64, (out_s != 0) as i64, ctr) 282 // ---- proof against the narrow substrate ---- 283 let rc_pn: i64 = pg_run(subject, "proof" as *u8, PG_IMG, PG_SRGB, PG_NARROW, PG_OUT, 0 as *u8, cap, olen) 284 gv_puts(" [proof sRGB->narrow] rc=" as *u8); gv_num(rc_pn); gv_puts("\n" as *u8); sys_write(1, cap, olen[0]) 285 var rc_ok: i64 = 0 286 if rc_pn == PG_EXIT_OK { rc_ok = 1 } 287 if rc_pn == PG_EXIT_REFUSED { rc_ok = 1 } 288 gv_check("proof-exits-OK-or-REFUSED-never-UNOBSERVABLE-on-a-decodable-fixture" as *u8, rc_ok, ctr) 289 gv_check("proof-writes-twin.png-that-decodes-64x64" as *u8, pg_decodes(PG_TWIN, PG_W, PG_H), ctr) 290 gv_check("proof-writes-heat.png-that-decodes-64x64" as *u8, pg_decodes(PG_HEAT, PG_W, PG_H), ctr) 291 let moved: i64 = pg_num_after(cap, olen[0], "moved=" as *u8) 292 let mean: i64 = pg_num_after(cap, olen[0], "mean_de00_micro=" as *u8) 293 let mx: i64 = pg_num_after(cap, olen[0], "max_de00_micro=" as *u8) 294 gv_check("proof-moved-exactly-the-outside-pixels" as *u8, (moved == out_n) as i64, ctr) 295 gv_check("proof-stats-consistent (max >= mean > 0)" as *u8, ((mx >= mean) as i64) * ((mean > 0) as i64), ctr) 296 gv_check("proof.txt-carries-a-canonical-verdict-line" as *u8, tr_contains(cap, olen[0], "\nverdict=PROOF-" as *u8), ctr) 297 // ---- proof control: sRGB image against its own profile moves nothing and says CONTROL ---- 298 let rc_pc: i64 = pg_run(subject, "proof" as *u8, PG_IMG, PG_SRGB, PG_SRGB, PG_OUT_CTRL, 0 as *u8, cap, olen) 299 gv_puts(" [proof control] rc=" as *u8); gv_num(rc_pc); gv_puts("\n" as *u8); sys_write(1, cap, olen[0]) 300 gv_check("control-proof-is-PROOF-OK-with-moved=0-and-labelled-CONTROL" as *u8, ((rc_pc == PG_EXIT_OK) as i64) * tr_contains(cap, olen[0], " moved=0 " as *u8) * tr_contains(cap, olen[0], "substrate=CONTROL" as *u8), ctr) 301 302 // ---- wash ledger ---- 303 pg_write_text(PG_LEDGER1, "# fixture\ns1\tA\tblank\tline\t0\t50.0\t10.0\t10.0\ns1\tA\tblank\tline\t5\t50.5\t10.2\t10.1\ns2\tB\tblank\tline\t0\t50.0\t10.0\t10.0\ns2\tB\tblank\tline\t5\t60.0\t30.0\t-10.0\ns3\tC\tblank\tline\t0\t50.0\t10.0\t10.0\n" as *u8) 304 pg_write_text(PG_LEDGER2, "s1\tA\tblank\tline\t0\t50.0\t10.0\t10.0\ns1\tA\tblank\tline\t5\t50.5\t10.2\t10.1\ns2\tB\tblank\tline\t0\t50.0\t10.0\t10.0\ns2\tB\tblank\tline\t5\t60.0\t30.0\t-10.0\n" as *u8) 305 let rc_wa: i64 = pg_run(subject, "wash" as *u8, PG_LEDGER1, "A" as *u8, 0 as *u8, 0 as *u8, 0 as *u8, cap, olen) 306 gv_puts(" [wash A] rc=" as *u8); gv_num(rc_wa); gv_puts("\n" as *u8); sys_write(1, cap, olen[0]) 307 gv_check("wash-small-shift-is-WASH-OK (exit 0)" as *u8, ((rc_wa == PG_EXIT_OK) as i64) * tr_contains(cap, olen[0], "verdict=WASH-OK" as *u8), ctr) 308 let rc_wb: i64 = pg_run(subject, "wash" as *u8, PG_LEDGER1, "B" as *u8, 0 as *u8, 0 as *u8, 0 as *u8, cap, olen) 309 gv_puts(" [wash B] rc=" as *u8); gv_num(rc_wb); gv_puts("\n" as *u8); sys_write(1, cap, olen[0]) 310 gv_check("wash-large-shift-is-WASH-FAIL (exit 1)" as *u8, ((rc_wb == PG_EXIT_REFUSED) as i64) * tr_contains(cap, olen[0], "verdict=WASH-FAIL" as *u8), ctr) 311 gv_bite("neg-control-wash-fires-on-faded-swatch-silent-on-stable-swatch" as *u8, (rc_wb == PG_EXIT_REFUSED) as i64, (rc_wa != PG_EXIT_OK) as i64, ctr) 312 let rc_wc: i64 = pg_run(subject, "wash" as *u8, PG_LEDGER1, "C" as *u8, 0 as *u8, 0 as *u8, 0 as *u8, cap, olen) 313 gv_check("wash-swatch-with-only-cycle-0-is-UNMEASURED-PARTIAL (exit 3, never a pass)" as *u8, ((rc_wc == PG_EXIT_UNOBS) as i64) * tr_contains(cap, olen[0], "UNMEASURED-PARTIAL" as *u8), ctr) 314 let rc_wd: i64 = pg_run(subject, "wash" as *u8, PG_LEDGER1, "D" as *u8, 0 as *u8, 0 as *u8, 0 as *u8, cap, olen) 315 gv_check("wash-sku-with-no-rows-is-UNMEASURED (exit 3)" as *u8, ((rc_wd == PG_EXIT_UNOBS) as i64) * tr_contains(cap, olen[0], "verdict=UNMEASURED" as *u8), ctr) 316 let rc_b1: i64 = pg_run(subject, "bench" as *u8, PG_LEDGER1, 0 as *u8, 0 as *u8, 0 as *u8, 0 as *u8, cap, olen) 317 gv_check("bench-refuses-partial-coverage (exit 3 while one swatch lacks a later cycle)" as *u8, (rc_b1 == PG_EXIT_UNOBS) as i64, ctr) 318 let rc_b2: i64 = pg_run(subject, "bench" as *u8, PG_LEDGER2, 0 as *u8, 0 as *u8, 0 as *u8, 0 as *u8, cap, olen) 319 gv_check("bench-with-full-coverage-reports-the-failing-swatch (exit 1)" as *u8, ((rc_b2 == PG_EXIT_REFUSED) as i64) * tr_contains(cap, olen[0], "failed=1" as *u8), ctr) 320 321 return gv_verdict("phototwin" as *u8, ctr, "report partitions sum, the derived narrow substrate fires and the own profile is silent, the twin and heat decode, the wash ledger refuses partial coverage" as *u8) 322}