code wiki / (root) / nx_photo_count_gate.nx

nx_photo_count_gate.nx source

↩ module page · 91 lines · 5845 B

1// nx_photo_count_gate.nx -- REFEREE for the five-pics fix and the conversation-album arithmetic (2026-08-30): a photo count 2// parses from digits AND number words but ONLY beside a photo noun, clamps to the batch cap, and is spliced out of the scene 3// the diffusion model reads (the measured defect: "send me five pics" clamped to ONE request whose prompt still said "five 4// pics", so the model painted a five-panel collage into one image); the album emitter groups tsv rows into days under a 5// clock offset with hand-derivable 1970-epoch fixtures. GPU-free, in-process (imports the orchestrator lib directly). 6// license_tier: ORIGINAL expect_exit: 0 7import "nx_syscalls.nx" 8import "nx_gate_verdict.nx" 9import "nx_gen_orchestrator.nx" 10 11const PG_TOKBUF: i64 = 32 12const PG_OUT: i64 = 8192 13const PG_ALBUM_FIXTURE: *u8 = "0\tnxc1-aa\n86399\tnxc1-bb\n86400\tnxc1-cc\n" as *u8 14 15func pg_len(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n } 16func pg_eq(a: *u8, b: *u8) -> i64 { var i: i64 = 0; while a[i] == b[i] { if a[i] == (0 as u8) { return 1 } i = i + 1 } return 0 } 17func pg_find(buf: *u8, n: i64, needle: *u8) -> i64 { 18 let nl: i64 = pg_len(needle) 19 if nl <= 0 { return 0 - 1 } 20 var i: i64 = 0 21 while i + nl <= n { 22 var j: i64 = 0 23 var same: i64 = 1 24 var scan: i64 = 1 25 while scan == 1 { if j >= nl { scan = 0 } else { if buf[i + j] != needle[j] { same = 0; scan = 0 } else { j = j + 1 } } } 26 if same == 1 { return i } 27 i = i + 1 28 } 29 return 0 - 1 30} 31func pg_count(s: *u8, tok: *i64) -> i64 { return go_parse_count_any(s, pg_len(s), tok) } 32 33func main() -> i64 { 34 gv_head("nx_photo_count_gate -- the five-pics fix: digits and number words count only beside a photo noun, clamp to the batch cap, splice out of the scene; the album groups by day under a clock offset" as *u8) 35 let ctr: *i64 = gv_ctr() 36 let tok: *i64 = sys_mmap(PG_TOKBUF) as *i64 37 let out: *u8 = sys_mmap(PG_OUT) 38 39 // T1 digits beside a noun 40 var v: i64 = pg_count("send me 5 pics" as *u8, tok) 41 gv_check("digits-beside-a-photo-noun-count" as *u8, (v == 5) & (tok[0] == 8) & (tok[1] == 1), ctr) 42 // T2 number words 43 v = pg_count("send me five pics of you at the beach" as *u8, tok) 44 gv_check("number-word-beside-a-photo-noun-counts" as *u8, (v == 5) & (tok[0] == 8) & (tok[1] == 4), ctr) 45 v = pg_count("three selfies please" as *u8, tok) 46 gv_check("word-count-works-on-selfies" as *u8, (v == 3) & (tok[0] == 0), ctr) 47 v = pg_count("a couple pics?" as *u8, tok) 48 gv_check("couple-reads-as-two" as *u8, v == 2, ctr) 49 v = pg_count("two shots" as *u8, tok) 50 gv_check("a-small-gap-between-number-and-noun-still-counts" as *u8, v == 2, ctr) 51 // T3 NEG-CONTROLS: a number away from a photo noun is NOT a count; a plain ask is one photo 52 v = pg_count("we're five friends, send a pic" as *u8, tok) 53 gv_check("neg-control-number-not-beside-a-photo-noun-is-one-photo" as *u8, (v == 1) & (tok[0] < 0), ctr) 54 v = pg_count("send me a pic" as *u8, tok) 55 gv_check("neg-control-no-number-is-one-photo" as *u8, (v == 1) & (tok[0] < 0), ctr) 56 v = pg_count("send me a pic of 3 dogs" as *u8, tok) 57 gv_check("neg-control-a-count-of-subjects-is-not-a-count-of-photos" as *u8, (v == 1) & (tok[0] < 0), ctr) 58 // T4 the clamp 59 v = pg_count("send 99 pics" as *u8, tok) 60 gv_check("count-clamps-to-the-batch-cap" as *u8, v == GEN_BATCH_CAP, ctr) 61 // T5 the scene splice: the model must never read the count 62 let s1: *u8 = "send me five pics at the beach" as *u8 63 v = pg_count(s1, tok) 64 var n1: i64 = go_scene_decount(s1, pg_len(s1), tok, out, PG_OUT) 65 gv_check("scene-splice-replaces-the-word-count-with-a" as *u8, (n1 > 0) & (pg_eq(out, "send me a pics at the beach" as *u8) == 1), ctr) 66 let s2: *u8 = "send 3 photos now" as *u8 67 v = pg_count(s2, tok) 68 n1 = go_scene_decount(s2, pg_len(s2), tok, out, PG_OUT) 69 gv_check("scene-splice-replaces-the-digit-count-with-a" as *u8, (n1 > 0) & (pg_eq(out, "send a photos now" as *u8) == 1), ctr) 70 // T6 the album: hand-derivable 1970 fixtures -- 0 and 86399 are 1970-01-01, 86400 is 1970-01-02; newest day first 71 let fx: *u8 = PG_ALBUM_FIXTURE 72 var an: i64 = go_album_emit(fx, pg_len(fx), 0, out, 0) 73 out[an] = 0 as u8 74 let p2: i64 = pg_find(out, an, "{\"day\":\"1970-01-02\",\"cids\":[\"nxc1-cc\"]}" as *u8) 75 let p1: i64 = pg_find(out, an, "{\"day\":\"1970-01-01\",\"cids\":[\"nxc1-bb\",\"nxc1-aa\"]}" as *u8) 76 gv_check("album-groups-by-utc-day-newest-first-rows-newest-first" as *u8, (p2 >= 0) & (p1 >= 0) & (p2 < p1), ctr) 77 // T7 the offset moves the midnight boundary: at -6 h, 86400 (06:00 utc-6=00:00) stays on 01-01 78 an = go_album_emit(fx, pg_len(fx), 0 - 6, out, 0) 79 out[an] = 0 as u8 80 gv_check("album-offset-moves-the-midnight-boundary" as *u8, (pg_find(out, an, "1970-01-02" as *u8) < 0) & (pg_find(out, an, "{\"day\":\"1970-01-01\",\"cids\":[\"nxc1-cc\",\"nxc1-bb\",\"nxc1-aa\"]}" as *u8) >= 0), ctr) 81 // T8 a modern date lands in the right month (the civil algorithm on a current epoch) 82 let db: *u8 = sys_mmap(PG_TOKBUF * 2) 83 go_day_str(1788145449, 0, db) 84 gv_check("civil-date-on-a-current-epoch-reads-august-2026" as *u8, pg_find(db, pg_len(db), "2026-08-3" as *u8) == 0, ctr) 85 // T9 neg-control: an empty album is exactly empty 86 an = go_album_emit("" as *u8, 0, 0, out, 0) 87 out[an] = 0 as u8 88 gv_check("neg-control-empty-album-emits-an-empty-days-array" as *u8, pg_eq(out, "{\"days\":[]}" as *u8) == 1, ctr) 89 90 return gv_verdict("PHOTO-COUNT-GATE" as *u8, ctr, "the five-pics done-rule: a count parses from digits or words only beside a photo noun, clamps to the batch cap, and is spliced out of the scene the model reads; the album groups by day under the operator's clock offset" as *u8) 91}