code wiki / _hdl_build / nx_survey_quality_gate.nx

nx_survey_quality_gate.nx source

↩ module page · 164 lines · 7822 B

1import "nx_gate_gn.nx" 2// nx_survey_quality_gate.nx -- GATE for the C/IER data-quality detector. Hand-KAT'd, with the ADVERSARY that 3// matters for welfare: a genuinely struggling family (varied LOW scores) must NOT be flagged careless, while a 4// straight-liner (identical answers) and an attention-check failer MUST be. Ballots built directly (canon_encode 5// a_<qid> fields = what se_ballots yields). Exits 0 iff ALL pass. license_tier: ORIGINAL expect_exit: 0 6import "nx_syscalls.nx" 7import "nx_survey_quality.nx" 8 9func gp(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 } 10func chk(name: *u8, got: i64, want: i64, st: *i64) -> i64 { 11 if got == want { st[0] = st[0] + 1; gp(" PASS " as *u8); gp(name); gp("\n" as *u8) } 12 else { st[1] = st[1] + 1; gp(" FAIL " as *u8); gp(name); gp(" got=" as *u8); gn(got); gp(" want=" as *u8); gn(want); gp("\n" as *u8) } 13 return 0 14} 15// build one ballot from parallel qid-name / value arrays (value <0 => omit that answer). ptr into outp[0], returns len. 16func mkballot(qids: *i64, vals: *i64, n: i64, outp: *i64) -> i64 { 17 let ks: *i64 = sys_mmap(8 * (n + 4)) as *i64 18 let vs: *i64 = sys_mmap(8 * (n + 4)) as *i64 19 var nf: i64 = 0 20 ks[nf] = "type" as *u8 as i64 21 vs[nf] = "rsp" as *u8 as i64 22 nf = nf + 1 23 var i: i64 = 0 24 while i < n { 25 if vals[i] >= 0 { 26 let fk: *u8 = sys_mmap(40) 27 var o: i64 = se_cat(fk, 0, "a_" as *u8) 28 o = se_cat(fk, o, qids[i] as *u8) 29 fk[o] = 0 as u8 30 let vb: *u8 = sys_mmap(16) 31 se_catn(vb, 0, vals[i]) 32 ks[nf] = fk as i64 33 vs[nf] = vb as i64 34 nf = nf + 1 35 } 36 i = i + 1 37 } 38 let rec: *u8 = sys_mmap(8192) 39 let rl: i64 = canon_encode(ks, vs, nf, rec) 40 outp[0] = rec as i64 41 return rl 42} 43 44func main() -> i64 { 45 let st: *i64 = sys_mmap(16) as *i64 46 st[0] = 0 47 st[1] = 0 48 gp("=== nx_survey_quality_gate (attention checks + longstring + consistency; adversary: genuine low-scorer NOT flagged) ===\n" as *u8) 49 50 // qid block: q2 = attention-check (choice), q1/q3/q5 = scale items (the straight-line block) 51 let qn: *i64 = sys_mmap(8 * 8) as *i64 52 qn[0] = "q1" as *u8 as i64 53 qn[1] = "q2" as *u8 as i64 54 qn[2] = "q3" as *u8 as i64 55 qn[3] = "q5" as *u8 as i64 56 let sqids: *i64 = sys_mmap(8 * 4) as *i64 57 sqids[0] = "q1" as *u8 as i64 58 sqids[1] = "q3" as *u8 as i64 59 sqids[2] = "q5" as *u8 as i64 60 let checks: *u8 = "q2:1," as *u8 61 let vals: *i64 = sys_mmap(8 * 8) as *i64 62 let op: *i64 = sys_mmap(16) as *i64 63 let ao: *i64 = sys_mmap(16) as *i64 64 let reason: *i64 = sys_mmap(32) as *i64 65 66 // ---- Q1 attention check ---- 67 // clean: q2=1 (expected) -> 0 failed of 1 68 vals[0] = 8; vals[1] = 1; vals[2] = 6; vals[3] = 7 69 let l1: i64 = mkballot(qn, vals, 4, op) 70 sq_attention(op[0] as *u8, l1, checks, ao) 71 var q1: i64 = 0 72 if ao[0] == 0 { if ao[1] == 1 { q1 = 1 } } 73 chk("Q1 attention pass: 0 failed of 1" as *u8, q1, 1, st) 74 // wrong: q2=0 -> 1 failed 75 vals[1] = 0 76 let l2: i64 = mkballot(qn, vals, 4, op) 77 sq_attention(op[0] as *u8, l2, checks, ao) 78 chk("Q1b attention WRONG answer -> 1 failed" as *u8, ao[0], 1, st) 79 // absent: omit q2 -> 1 failed (not reading = didn't answer the instructed item) 80 vals[1] = 0 - 1 81 let l3: i64 = mkballot(qn, vals, 4, op) 82 sq_attention(op[0] as *u8, l3, checks, ao) 83 chk("Q1c attention ABSENT answer -> 1 failed" as *u8, ao[0], 1, st) 84 // two checks 85 vals[1] = 1 86 let l4: i64 = mkballot(qn, vals, 4, op) 87 sq_attention(op[0] as *u8, l4, "q2:1,q1:8," as *u8, ao) 88 var q1d: i64 = 0 89 if ao[0] == 0 { if ao[1] == 2 { q1d = 1 } } 90 chk("Q1d two checks both pass -> 0 of 2" as *u8, q1d, 1, st) 91 92 // ---- Q2 longstring ---- 93 vals[0] = 5; vals[1] = 1; vals[2] = 5; vals[3] = 5 94 let l5: i64 = mkballot(qn, vals, 4, op) 95 chk("Q2 straight-line q1=q3=q5=5 -> longstring 3" as *u8, sq_longstring(op[0] as *u8, l5, sqids, 3), 3, st) 96 vals[0] = 5; vals[2] = 3; vals[3] = 7 97 let l6: i64 = mkballot(qn, vals, 4, op) 98 chk("Q2b varied 5,3,7 -> longstring 1" as *u8, sq_longstring(op[0] as *u8, l6, sqids, 3), 1, st) 99 vals[0] = 5; vals[2] = 5; vals[3] = 3 100 let l7: i64 = mkballot(qn, vals, 4, op) 101 chk("Q2c 5,5,3 -> longstring 2" as *u8, sq_longstring(op[0] as *u8, l7, sqids, 3), 2, st) 102 103 // ---- Q3 consistency ---- 104 vals[0] = 8; vals[2] = 9 105 let l8: i64 = mkballot(qn, vals, 4, op) 106 chk("Q3 consistent 8 vs 9 (maxdiff 2) -> 0" as *u8, sq_consistency(op[0] as *u8, l8, "q1" as *u8, "q3" as *u8, 2), 0, st) 107 vals[0] = 8; vals[2] = 2 108 let l9: i64 = mkballot(qn, vals, 4, op) 109 chk("Q3b inconsistent 8 vs 2 (maxdiff 2) -> 1" as *u8, sq_consistency(op[0] as *u8, l9, "q1" as *u8, "q3" as *u8, 2), 1, st) 110 111 // ---- Q4 composite careless (checks=q2:1, block=q1/q3/q5, ls_thresh=3) ---- 112 // CLEAN: attention pass + varied 113 vals[0] = 8; vals[1] = 1; vals[2] = 6; vals[3] = 7 114 let la: i64 = mkballot(qn, vals, 4, op) 115 chk("Q4 clean respondent NOT flagged" as *u8, sq_ballot_careless(op[0] as *u8, la, checks, sqids, 3, 3, reason), 0, st) 116 // STRAIGHT-LINER: attention pass but identical scale answers 117 vals[0] = 5; vals[1] = 1; vals[2] = 5; vals[3] = 5 118 let lb: i64 = mkballot(qn, vals, 4, op) 119 var q4b: i64 = sq_ballot_careless(op[0] as *u8, lb, checks, sqids, 3, 3, reason) 120 var q4bok: i64 = 0 121 if q4b == 1 { if reason[1] == 3 { if reason[0] == 0 { q4bok = 1 } } } 122 chk("Q4b straight-liner flagged (longstring=3, attention ok)" as *u8, q4bok, 1, st) 123 // ATTENTION-FAILER: varied answers but failed the instructed item 124 vals[0] = 8; vals[1] = 0; vals[2] = 6; vals[3] = 7 125 let lc: i64 = mkballot(qn, vals, 4, op) 126 var q4c: i64 = sq_ballot_careless(op[0] as *u8, lc, checks, sqids, 3, 3, reason) 127 var q4cok: i64 = 0 128 if q4c == 1 { if reason[0] == 1 { q4cok = 1 } } 129 chk("Q4c attention-failer flagged (attn_fails=1)" as *u8, q4cok, 1, st) 130 // ADVERSARY: a genuinely struggling family -- VARIED low scores + attention pass -> NOT careless 131 vals[0] = 2; vals[1] = 1; vals[2] = 1; vals[3] = 3 132 let ld: i64 = mkballot(qn, vals, 4, op) 133 chk("Q4d ADVERSARY genuine low-scorer (varied 2,1,3) NOT flagged" as *u8, sq_ballot_careless(op[0] as *u8, ld, checks, sqids, 3, 3, reason), 0, st) 134 135 // ---- Q5 rollup over the 4 above (2 clean, 2 flagged; 1 attention-failer, 1 straightliner) ---- 136 let vout: *i64 = sys_mmap(8 * 8) as *i64 137 let lout: *i64 = sys_mmap(8 * 8) as *i64 138 let p0: *i64 = sys_mmap(16) as *i64 139 vals[0] = 8; vals[1] = 1; vals[2] = 6; vals[3] = 7 140 lout[0] = mkballot(qn, vals, 4, p0); vout[0] = p0[0] 141 let p1: *i64 = sys_mmap(16) as *i64 142 vals[0] = 5; vals[1] = 1; vals[2] = 5; vals[3] = 5 143 lout[1] = mkballot(qn, vals, 4, p1); vout[1] = p1[0] 144 let p2: *i64 = sys_mmap(16) as *i64 145 vals[0] = 8; vals[1] = 0; vals[2] = 6; vals[3] = 7 146 lout[2] = mkballot(qn, vals, 4, p2); vout[2] = p2[0] 147 let p3: *i64 = sys_mmap(16) as *i64 148 vals[0] = 2; vals[1] = 1; vals[2] = 1; vals[3] = 3 149 lout[3] = mkballot(qn, vals, 4, p3); vout[3] = p3[0] 150 let ro: *i64 = sys_mmap(32) as *i64 151 sq_rollup(vout, lout, 4, checks, sqids, 3, 3, ro) 152 var q5: i64 = 0 153 if ro[0] == 2 { if ro[1] == 2 { if ro[2] == 1 { if ro[3] == 1 { q5 = 1 } } } } 154 chk("Q5 rollup: 2 clean, 2 flagged, 1 attention-fail, 1 straightliner" as *u8, q5, 1, st) 155 156 gp("nx_survey_quality_gate: PASS=" as *u8) 157 gn(st[0]) 158 gp(" FAIL=" as *u8) 159 gn(st[1]) 160 gp("\n" as *u8) 161 if st[1] == 0 { gp("VERDICT: verdict=GREEN (C/IER: attention checks + longstring + consistency; genuine low-scorers protected)\n" as *u8); return 0 } 162 gp("VERDICT: RED\n" as *u8) 163 return 1 164}