code wiki / (root) / nx_cgmp_test.nx

nx_cgmp_test.nx source

↩ module page · 192 lines · 9649 B

1// nx_cgmp_test.nx -- gate for the 21 CFR 111 cGMP readiness checklist. 2// T3 is the discipline the whole organ exists for: a facility missing ONE 3// critical requirement is NOT audit-ready no matter how many minors it has, 4// and the gap reported is the worst one, worst-first. 5// expect_exit: 0 license_tier: ORIGINAL 6import "nx_syscalls.nx" 7import "nx_cgmp.nx" 8 9func t_puts(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 } 10func t_putn(v: i64) -> i64 { let bb: *u8 = sys_mmap(28); var m: i64 = v; if m < 0 { m = 0 - m; sys_write(1, "-" as *u8, 1) } let t: *u8 = sys_mmap(28); var k: i64 = 0; if m == 0 { t[0] = 48 as u8; k = 1 } while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 } var i: i64 = 0; while i < k { bb[i] = t[k - 1 - i]; i = i + 1 } sys_write(1, bb, k); return 0 } 11 12func main() -> i64 { 13 var pass: i64 = 0 14 var total: i64 = 0 15 16 // --- T1 a fully-compliant facility is audit-ready, score 1000, 0 gaps --- 17 total = total + 1 18 let full: *NxCgmpState = nx_cgmp_new() 19 cg_set_all(full) 20 let ready: i64 = cg_audit_ready(full) 21 let score: i64 = cg_readiness_permil(full) 22 let gaps: i64 = cg_total_gaps(full) 23 let cgap: i64 = cg_first_critical_gap(full) 24 t_puts("T1 full facility: audit_ready=" as *u8); t_putn(ready); t_puts(" score=" as *u8); t_putn(score); t_puts(" gaps=" as *u8); t_putn(gaps); t_puts(" first_critical=" as *u8); t_putn(cgap); t_puts(" want 1/1000/0/-1: " as *u8) 25 var ok1: i64 = 1 26 if ready != 1 { ok1 = 0 } 27 if score != 1000 { ok1 = 0 } 28 if gaps != 0 { ok1 = 0 } 29 if cgap != 0 - 1 { ok1 = 0 } 30 if ok1 == 1 { pass = pass + 1; t_puts("PASS\n" as *u8) } else { t_puts("FAIL\n" as *u8) } 31 32 // --- T2 an empty facility: not ready, first critical gap = specs (id 0) --- 33 total = total + 1 34 let empty: *NxCgmpState = nx_cgmp_new() 35 let e_ready: i64 = cg_audit_ready(empty) 36 let e_gap: i64 = cg_first_critical_gap(empty) 37 let e_cgaps: i64 = cg_critical_gaps(empty) 38 t_puts("T2 empty facility: audit_ready=" as *u8); t_putn(e_ready); t_puts(" first_critical_gap=" as *u8); t_putn(e_gap); t_puts(" (" as *u8); t_puts(cg_citation(e_gap)); t_puts(") critical_gaps=" as *u8); t_putn(e_cgaps); t_puts(": " as *u8) 39 var ok2: i64 = 1 40 if e_ready != 0 { ok2 = 0 } 41 if e_gap != CG_SPECIFICATIONS { ok2 = 0 } 42 if e_cgaps != 6 { ok2 = 0 } 43 if ok2 == 1 { pass = pass + 1; t_puts("PASS\n" as *u8) } else { t_puts("FAIL\n" as *u8) } 44 45 // --- T3 THE DISCIPLINE: every MINOR met but ONE critical open => 46 // still NOT audit-ready, and the gap is that critical one --- 47 total = total + 1 48 let mixed: *NxCgmpState = nx_cgmp_new() 49 cg_set_all(mixed) 50 // now "un-meet" one critical: the batch production record. (No un-set fn; 51 // rebuild the mask without BPR by setting all EXCEPT BPR.) 52 let m2: *NxCgmpState = nx_cgmp_new() 53 var i3: i64 = 0 54 while i3 < CG_N { 55 if i3 != CG_BPR { cg_set_met(m2, i3) } 56 i3 = i3 + 1 57 } 58 let m_ready: i64 = cg_audit_ready(m2) 59 let m_gap: i64 = cg_first_critical_gap(m2) 60 let m_score: i64 = cg_readiness_permil(m2) 61 t_puts("T3 all-but-BPR: audit_ready=" as *u8); t_putn(m_ready); t_puts(" gap=" as *u8); t_putn(m_gap); t_puts(" (BPR=5) score=" as *u8); t_putn(m_score); t_puts(" (high but NOT ready): " as *u8) 62 var ok3: i64 = 1 63 if m_ready != 0 { ok3 = 0 } 64 if m_gap != CG_BPR { ok3 = 0 } 65 if m_score < 900 { ok3 = 0 } 66 if ok3 == 1 { pass = pass + 1; t_puts("PASS\n" as *u8) } else { t_puts("FAIL\n" as *u8) } 67 68 // --- T4 critical gaps are reported WORST-FIRST (id order over criticals) --- 69 // Meet specs; the next critical gap must be identity testing (id 1), not 70 // some later critical. 71 total = total + 1 72 let step: *NxCgmpState = nx_cgmp_new() 73 cg_set_met(step, CG_SPECIFICATIONS) 74 let s_gap: i64 = cg_first_critical_gap(step) 75 cg_set_met(step, CG_ID_TESTING) 76 let s_gap2: i64 = cg_first_critical_gap(step) 77 t_puts("T4 after specs: next critical=" as *u8); t_putn(s_gap); t_puts(" (ID_TESTING=1) ; after +id-testing: " as *u8); t_putn(s_gap2); t_puts(" (FINISHED=3): " as *u8) 78 var ok4: i64 = 1 79 if s_gap != CG_ID_TESTING { ok4 = 0 } 80 if s_gap2 != CG_FINISHED_TESTING { ok4 = 0 } 81 if ok4 == 1 { pass = pass + 1; t_puts("PASS\n" as *u8) } else { t_puts("FAIL\n" as *u8) } 82 83 // --- T5 the CRITICAL set is exactly the 6 warning-letter requirements --- 84 total = total + 1 85 var i5: i64 = 0 86 var ncrit: i64 = 0 87 while i5 < CG_N { 88 if cg_criticality(i5) == CG_CRITICAL { ncrit = ncrit + 1 } 89 i5 = i5 + 1 90 } 91 let c_spec: i64 = cg_criticality(CG_SPECIFICATIONS) 92 let c_id: i64 = cg_criticality(CG_ID_TESTING) 93 let c_qc: i64 = cg_criticality(CG_QC_UNIT) 94 let c_comp: i64 = cg_criticality(CG_COMPLAINTS) 95 t_puts("T5 critical count=" as *u8); t_putn(ncrit); t_puts(" (specs/id/qc CRITICAL=" as *u8); t_putn(c_spec); t_putn(c_id); t_putn(c_qc); t_puts(" complaints MINOR=" as *u8); t_putn(c_comp); t_puts("): " as *u8) 96 var ok5: i64 = 1 97 if ncrit != 6 { ok5 = 0 } 98 if c_spec != CG_CRITICAL { ok5 = 0 } 99 if c_id != CG_CRITICAL { ok5 = 0 } 100 if c_qc != CG_CRITICAL { ok5 = 0 } 101 if c_comp != CG_MINOR { ok5 = 0 } 102 if ok5 == 1 { pass = pass + 1; t_puts("PASS\n" as *u8) } else { t_puts("FAIL\n" as *u8) } 103 104 // --- T6 weighted score reflects CRITICALITY, not a raw count --- 105 // Meeting the 6 criticals (weight 3 each = 18) is worth more than meeting 106 // the 2 minors (weight 1 each = 2), though 6 vs 2 by count. 107 total = total + 1 108 let crit_only: *NxCgmpState = nx_cgmp_new() 109 var i6: i64 = 0 110 while i6 < CG_N { 111 if cg_criticality(i6) == CG_CRITICAL { cg_set_met(crit_only, i6) } 112 i6 = i6 + 1 113 } 114 let minor_only: *NxCgmpState = nx_cgmp_new() 115 var i6b: i64 = 0 116 while i6b < CG_N { 117 if cg_criticality(i6b) == CG_MINOR { cg_set_met(minor_only, i6b) } 118 i6b = i6b + 1 119 } 120 let crit_score: i64 = cg_readiness_permil(crit_only) 121 let minor_score: i64 = cg_readiness_permil(minor_only) 122 t_puts("T6 criticals-only score=" as *u8); t_putn(crit_score); t_puts(" minors-only score=" as *u8); t_putn(minor_score); t_puts(" (criticals worth far more): " as *u8) 123 if crit_score > minor_score { if crit_score > 500 { pass = pass + 1; t_puts("PASS\n" as *u8) } else { t_puts("FAIL\n" as *u8) } } else { t_puts("FAIL\n" as *u8) } 124 125 // --- T7 the IDENTITY dimension maps to specs + 100% id testing --- 126 // This is the bridge that lets the plan DERIVE identity_ready. 127 total = total + 1 128 let idst: *NxCgmpState = nx_cgmp_new() 129 let id_none: i64 = cg_identity_dimension_met(idst) 130 cg_set_met(idst, CG_SPECIFICATIONS) 131 let id_half: i64 = cg_identity_dimension_met(idst) 132 cg_set_met(idst, CG_ID_TESTING) 133 let id_full: i64 = cg_identity_dimension_met(idst) 134 t_puts("T7 identity dim: none=" as *u8); t_putn(id_none); t_puts(" specs-only=" as *u8); t_putn(id_half); t_puts(" specs+id=" as *u8); t_putn(id_full); t_puts(" want 0/0/1: " as *u8) 135 var ok7: i64 = 1 136 if id_none != 0 { ok7 = 0 } 137 if id_half != 0 { ok7 = 0 } 138 if id_full != 1 { ok7 = 0 } 139 if ok7 == 1 { pass = pass + 1; t_puts("PASS\n" as *u8) } else { t_puts("FAIL\n" as *u8) } 140 141 // --- T8 fail-closed on bad ids + bitmask round-trip --- 142 total = total + 1 143 let s8: *NxCgmpState = nx_cgmp_new() 144 let bad_set: i64 = cg_set_met(s8, 99) 145 let bad_met: i64 = cg_is_met(s8, 99) 146 cg_set_met(s8, CG_MMR) 147 let mmr_met: i64 = cg_is_met(s8, CG_MMR) 148 let bpr_met: i64 = cg_is_met(s8, CG_BPR) 149 t_puts("T8 bad-id set=" as *u8); t_putn(bad_set); t_puts(" bad-id met=" as *u8); t_putn(bad_met); t_puts(" MMR-met=" as *u8); t_putn(mmr_met); t_puts(" BPR-absent=" as *u8); t_putn(bpr_met); t_puts(": " as *u8) 150 var ok8: i64 = 1 151 if bad_set != 0 { ok8 = 0 } 152 if bad_met != 0 { ok8 = 0 } 153 if mmr_met != 1 { ok8 = 0 } 154 if bpr_met != 0 { ok8 = 0 } 155 if ok8 == 1 { pass = pass + 1; t_puts("PASS\n" as *u8) } else { t_puts("FAIL\n" as *u8) } 156 157 // --- T9 every requirement has a name + a real 21 CFR citation --- 158 total = total + 1 159 var i9: i64 = 0 160 var ok9: i64 = 1 161 while i9 < CG_N { 162 let nm: *u8 = cg_name(i9) 163 let ci: *u8 = cg_citation(i9) 164 if nm[0] == (0 as u8) { ok9 = 0 } 165 // citation must start with "21 CFR" 166 if ci[0] != (50 as u8) { ok9 = 0 } 167 if cg_criticality(i9) < CG_MINOR { ok9 = 0 } 168 i9 = i9 + 1 169 } 170 t_puts("T9 all " as *u8); t_putn(CG_N); t_puts(" requirements carry a name + 21 CFR citation + criticality: " as *u8) 171 if ok9 == 1 { pass = pass + 1; t_puts("PASS\n" as *u8) } else { t_puts("FAIL\n" as *u8) } 172 173 // --- T10 readiness climbs monotonically as requirements are met --- 174 total = total + 1 175 let climb: *NxCgmpState = nx_cgmp_new() 176 var prev: i64 = 0 - 1 177 var i10: i64 = 0 178 var ok10: i64 = 1 179 while i10 < CG_N { 180 cg_set_met(climb, i10) 181 let sc: i64 = cg_readiness_permil(climb) 182 if sc < prev { ok10 = 0 } 183 prev = sc 184 i10 = i10 + 1 185 } 186 t_puts("T10 readiness monotonically non-decreasing as requirements met, ends " as *u8); t_putn(prev); t_puts(": " as *u8) 187 if ok10 == 1 { if prev == 1000 { pass = pass + 1; t_puts("PASS\n" as *u8) } else { t_puts("FAIL\n" as *u8) } } else { t_puts("FAIL\n" as *u8) } 188 189 t_puts("CGMP-GATE passed " as *u8); t_putn(pass); t_puts("/" as *u8); t_putn(total) 190 if pass == total { t_puts(" verdict=GREEN\n" as *u8); sys_exit(0); return 0 } 191 t_puts(" verdict=RED\n" as *u8); sys_exit(1); return 1 192}