code wiki / (root) / nx_capres.nx

nx_capres.nx source

↩ module page · 192 lines · 8518 B

1// nx_capres.nx -- CLI for the CAPTURE-RESOLUTION RULER (core = nx_capres_lib, gate = nx_capres_gate). 2// Operator standing order 2026-08-28: full resolution everywhere, and the cost is accepted. 3// 4// ONE QUESTION THIS ESTATE COULD NOT ANSWER BEFORE: "is this capture full resolution?" Every capture 5// organ announced w= and h=; not one said what FULL was, so a 240x150 frame and a 1920x1200 frame read 6// identically to every downstream consumer and to every reader of a verdict built on them. 7// 8// VERBS 9// nx_capres dims <artifact> what resolution IS this file (PNG or NXFH1) 10// nx_capres check <artifact> <subject> is it the subject's declared FULL resolution 11// nx_capres judge <artifact> <judge-organ> can that judge SEE this many pixels 12// nx_capres selftest KATs over the pure predicates 13// 14// EXIT CODES ARE THE VERDICT, one scale shared with the lib: 15// 0 FULL / JUDGE-SEES-ALL 1 REDUCED / UNJUDGED-AT-RESOLUTION 2 usage 3 UNPROVEN 16// UNPROVEN covers unreadable artifact, unknown subject and unknown judge. Abstaining is not acquitting: 17// a caller must never be able to read "I could not look" as "it is fine". 18// 19// The final line is always "verdict=<TOKEN>" so a reader can anchor BY POSITION rather than by 20// matching text that also appears in the diagnostics above it. 21// license_tier: ORIGINAL No hw writes (Rule 26). 22import "nx_syscalls.nx" 23import "nx_capres_lib.nx" 24 25const CX_OUT_BYTES: i64 = 64 26const CX_KEY_BYTES: i64 = 256 27const CX_USAGE: i64 = 2 28const CX_JUDGE_PREFIX: *u8 = "judge." as *u8 29const CX_KAT_TOTAL: i64 = 12 30 31func cx_p(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 } 32func cx_n(v: i64) -> i64 { 33 if v == 0 { sys_write(1, "0" as *u8, 1); return 0 } 34 var m: i64 = v 35 if m < 0 { sys_write(1, "-" as *u8, 1); m = 0 - m } 36 let t: *u8 = sys_mmap(32) 37 var k: i64 = 0 38 while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 } 39 let o: *u8 = sys_mmap(32) 40 var i: i64 = 0 41 while i < k { o[i] = t[k-1-i]; i = i + 1 } 42 sys_write(1, o, k) 43 return 0 44} 45func cx_streq(a: *u8, b: *u8) -> i64 { 46 var i: i64 = 0 47 while a[i] != (0 as u8) { 48 if a[i] != b[i] { return 0 } 49 i = i + 1 50 } 51 if b[i] != (0 as u8) { return 0 } 52 return 1 53} 54func cx_cat(d: *u8, o: i64, s: *u8) -> i64 { 55 var i: i64 = 0 56 var p: i64 = o 57 while s[i] != (0 as u8) { d[p] = s[i]; p = p + 1; i = i + 1 } 58 d[p] = 0 as u8 59 return p 60} 61func cx_kind_name(k: i64) -> i64 { 62 if k == CR_KIND_PNG { cx_p("PNG" as *u8); return 0 } 63 if k == CR_KIND_NXFH1 { cx_p("NXFH1" as *u8); return 0 } 64 cx_p("UNKNOWN" as *u8) 65 return 0 66} 67func cx_usage() -> i64 { 68 cx_p("usage: nx_capres dims <artifact>\n" as *u8) 69 cx_p(" nx_capres check <artifact> <subject> 0 FULL / 1 REDUCED / 3 UNPROVEN\n" as *u8) 70 cx_p(" nx_capres judge <artifact> <judge-organ> 0 SEES-ALL / 1 UNJUDGED-AT-RESOLUTION / 3 UNPROVEN\n" as *u8) 71 cx_p(" nx_capres selftest\n" as *u8) 72 cx_p("subjects and judge ceilings are declared in knowledge/capres.conf -- never in this binary\n" as *u8) 73 return CX_USAGE 74} 75 76// KATs over the PURE predicates. They take numbers, not files, precisely so this cannot pass by 77// accident on a fixture that never reached the condition. 78func cx_selftest() -> i64 { 79 var pass: i64 = 0 80 // cr_permil: identical extents are exactly full 81 if cr_permil(1920, 1200, 1920, 1200) == CR_PERMIL { pass = pass + 1 } 82 // the measured world defect: 240x150 of 1920x1200 is 15 permil, not "a bit smaller" 83 if cr_permil(240, 150, 1920, 1200) == 15 { pass = pass + 1 } 84 // a zero denominator is UNPROVEN, never a pass 85 if cr_permil(100, 100, 0, 100) < 0 { pass = pass + 1 } 86 if cr_permil(0, 100, 100, 100) < 0 { pass = pass + 1 } 87 // cr_verdict maps the fraction onto the exit scale 88 if cr_verdict(CR_PERMIL) == CR_V_FULL { pass = pass + 1 } 89 if cr_verdict(CR_PERMIL - 1) == CR_V_REDUCED { pass = pass + 1 } 90 if cr_verdict(15) == CR_V_REDUCED { pass = pass + 1 } 91 if cr_verdict(0 - 1) == CR_V_UNPROVEN { pass = pass + 1 } 92 // a SUPERSET capture is still full: more pixels than declared is not a reduction 93 if cr_verdict(cr_permil(3840, 2400, 1920, 1200)) == CR_V_FULL { pass = pass + 1 } 94 // cr_judge: the measured nx_percept case -- a 400x240 judge handed a 1920x1200 frame is BLIND 95 if cr_judge(1920, 1200, 400, 240) == CR_J_BLIND { pass = pass + 1 } 96 if cr_judge(400, 240, 400, 240) == CR_J_SEES { pass = pass + 1 } 97 // one axis over the ceiling is enough to blind it -- the failure is not area, it is extent 98 if cr_judge(401, 240, 400, 240) == CR_J_BLIND { pass = pass + 1 } 99 cx_p("CAPRES-SELFTEST passed=" as *u8); cx_n(pass) 100 cx_p(" of=" as *u8); cx_n(CX_KAT_TOTAL); cx_p("\n" as *u8) 101 if pass == CX_KAT_TOTAL { cx_p("verdict=SELFTEST-GREEN\n" as *u8); return 0 } 102 cx_p("verdict=SELFTEST-RED\n" as *u8) 103 return 1 104} 105 106func main(argc: i64, argv: *i64) -> i64 { 107 if argc < 2 { return cx_usage() } 108 let verb: *u8 = argv[1] as *u8 109 if cx_streq(verb, "selftest" as *u8) == 1 { return cx_selftest() } 110 if argc < 3 { return cx_usage() } 111 let path: *u8 = argv[2] as *u8 112 let d: *i64 = sys_mmap(CX_OUT_BYTES) as *i64 113 let kind: i64 = cr_dims_of_file(path, d) 114 let cw: i64 = d[1] 115 let ch: i64 = d[2] 116 117 cx_p("CAPRES artifact=" as *u8); cx_p(path) 118 cx_p(" kind=" as *u8); cx_kind_name(kind) 119 cx_p(" w=" as *u8); cx_n(cw) 120 cx_p(" h=" as *u8); cx_n(ch) 121 122 if cx_streq(verb, "dims" as *u8) == 1 { 123 cx_p("\n" as *u8) 124 if kind == CR_KIND_UNKNOWN { cx_p("verdict=UNREADABLE\n" as *u8); return CR_V_UNPROVEN } 125 cx_p("verdict=DIMS-READ\n" as *u8) 126 return 0 127 } 128 if argc < 4 { cx_p("\n" as *u8); return cx_usage() } 129 let key: *u8 = argv[3] as *u8 130 131 // AN UNREADABLE ARTIFACT ENDS EVERY VERB THE SAME WAY. It is not a small capture and it is not a 132 // failing subject -- it is the absence of evidence, and the exit code says so. 133 if kind == CR_KIND_UNKNOWN { 134 cx_p(" subject=" as *u8); cx_p(key) 135 cx_p("\nverdict=UNREADABLE\n" as *u8) 136 return CR_V_UNPROVEN 137 } 138 139 if cx_streq(verb, "check" as *u8) == 1 { 140 let f: *i64 = sys_mmap(CX_OUT_BYTES) as *i64 141 let got: i64 = cr_conf_res(CR_CONF, key, f) 142 cx_p(" subject=" as *u8); cx_p(key) 143 if got == 0 { 144 cx_p(" declared=NONE\nverdict=UNKNOWN-SUBJECT\n" as *u8) 145 return CR_V_UNPROVEN 146 } 147 let permil: i64 = cr_permil(cw, ch, f[0], f[1]) 148 let v: i64 = cr_verdict(permil) 149 cx_p(" full_w=" as *u8); cx_n(f[0]) 150 cx_p(" full_h=" as *u8); cx_n(f[1]) 151 cx_p(" res_permil=" as *u8); cx_n(permil) 152 cx_p("\n" as *u8) 153 if v == CR_V_FULL { cx_p("verdict=FULL\n" as *u8); return CR_V_FULL } 154 if v == CR_V_REDUCED { 155 cx_p("verdict=REDUCED\n" as *u8) 156 return CR_V_REDUCED 157 } 158 cx_p("verdict=UNPROVEN\n" as *u8) 159 return CR_V_UNPROVEN 160 } 161 162 if cx_streq(verb, "judge" as *u8) == 1 { 163 // the conf key for a judge ceiling is "judge.<organ>" -- one namespace, so a subject and a 164 // judge of the same name can never be confused for one another 165 let jk: *u8 = sys_mmap(CX_KEY_BYTES) 166 let e: i64 = cx_cat(jk, 0, CX_JUDGE_PREFIX) 167 cx_cat(jk, e, key) 168 let j: *i64 = sys_mmap(CX_OUT_BYTES) as *i64 169 let got: i64 = cr_conf_res(CR_CONF, jk, j) 170 cx_p(" judge=" as *u8); cx_p(key) 171 if got == 0 { 172 cx_p(" ceiling=NONE\nverdict=UNKNOWN-JUDGE\n" as *u8) 173 return CR_V_UNPROVEN 174 } 175 cx_p(" ceiling_w=" as *u8); cx_n(j[0]) 176 cx_p(" ceiling_h=" as *u8); cx_n(j[1]) 177 let jv: i64 = cr_judge(cw, ch, j[0], j[1]) 178 cx_p("\n" as *u8) 179 if jv == CR_J_SEES { cx_p("verdict=JUDGE-SEES-ALL\n" as *u8); return CR_J_SEES } 180 if jv == CR_J_BLIND { 181 // NOT a low score. NO score. The judge cannot examine this many pixels, so whatever it 182 // prints is about a downsample, a crop or a prefix -- and reading that as a quality 183 // verdict is how a resolution ceiling gets mistaken for a quality ceiling. 184 cx_p("verdict=UNJUDGED-AT-RESOLUTION\n" as *u8) 185 return CR_J_BLIND 186 } 187 cx_p("verdict=UNPROVEN\n" as *u8) 188 return CR_V_UNPROVEN 189 } 190 cx_p("\n" as *u8) 191 return cx_usage() 192}