nx_trial_ethics_test.nx source
↩ module page · 153 lines · 8401 B
1// nx_trial_ethics_test.nx -- gate for the ethical-partner scorecard.
2// T5 carries the reassurance that decides the strategy: several jurisdictions
3// out-score the US on integrity AND keep their data portable to FDA, so
4// choosing an ethical partner does not forfeit the US market later.
5// expect_exit: 0 license_tier: ORIGINAL
6import "nx_syscalls.nx"
7import "nx_trial_ethics.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 CPI is populated and ordered as published ---
17 total = total + 1
18 let dk: i64 = te_cpi(TE_DENMARK)
19 let nz: i64 = te_cpi(TE_NEW_ZEALAND)
20 let au: i64 = te_cpi(TE_AUSTRALIA)
21 let us: i64 = te_cpi(TE_US)
22 t_puts("T1 CPI Denmark=" as *u8); t_putn(dk); t_puts(" NZ=" as *u8); t_putn(nz); t_puts(" Australia=" as *u8); t_putn(au); t_puts(" US=" as *u8); t_putn(us); t_puts(": " as *u8)
23 var ok1: i64 = 1
24 if dk <= nz { ok1 = 0 }
25 if nz <= au { ok1 = 0 }
26 if au <= us { ok1 = 0 }
27 if ok1 == 1 { pass = pass + 1; t_puts("PASS\n" as *u8) } else { t_puts("FAIL\n" as *u8) }
28
29 // --- T2 the highest-integrity partner, COMPUTED ---
30 total = total + 1
31 let best: i64 = te_most_ethical()
32 let s_best: i64 = te_integrity_score(best)
33 t_puts("T2 highest integrity = " as *u8); t_puts(te_name(best)); t_puts(" score=" as *u8); t_putn(s_best); t_puts("/140: " as *u8)
34 if best == TE_DENMARK { if s_best == 130 { pass = pass + 1; t_puts("PASS\n" as *u8) } else { t_puts("FAIL\n" as *u8) } } else { t_puts("FAIL\n" as *u8) }
35
36 // --- T3 the US scores lowest-equal, TIED WITH CANADA at 95 ---
37 // I expected the US to rank last outright and it does not: Canada scores
38 // identically by a different route (higher CPI, but no mandatory results
39 // disclosure, where the US has disclosure and a lower CPI). Recording the
40 // computed tie rather than the tidier claim I assumed.
41 total = total + 1
42 let r_us: i64 = te_rank_of(TE_US)
43 let s_us: i64 = te_integrity_score(TE_US)
44 let s_ca: i64 = te_integrity_score(TE_CANADA)
45 let r_ca: i64 = te_rank_of(TE_CANADA)
46 let r_dk: i64 = te_rank_of(TE_DENMARK)
47 t_puts("T3 US rank=" as *u8); t_putn(r_us); t_puts(" score=" as *u8); t_putn(s_us); t_puts(" ; Canada rank=" as *u8); t_putn(r_ca); t_puts(" score=" as *u8); t_putn(s_ca); t_puts(" (TIED) ; Denmark rank=" as *u8); t_putn(r_dk); t_puts(": " as *u8)
48 var ok3: i64 = 1
49 if s_us != 95 { ok3 = 0 }
50 if s_ca != s_us { ok3 = 0 }
51 if r_us != 8 { ok3 = 0 }
52 if r_ca != 8 { ok3 = 0 }
53 if r_dk != 1 { ok3 = 0 }
54 if ok3 == 1 { pass = pass + 1; t_puts("PASS\n" as *u8) } else { t_puts("FAIL\n" as *u8) }
55
56 // --- T4 no-fault injury compensation genuinely separates them ---
57 // New Zealand's ACC covers trial injury without litigation; most do not.
58 total = total + 1
59 let nf_nz: i64 = te_no_fault_injury_compensation(TE_NEW_ZEALAND)
60 let nf_dk: i64 = te_no_fault_injury_compensation(TE_DENMARK)
61 let nf_us: i64 = te_no_fault_injury_compensation(TE_US)
62 let nf_au: i64 = te_no_fault_injury_compensation(TE_AUSTRALIA)
63 t_puts("T4 no-fault injury cover NZ=" as *u8); t_putn(nf_nz); t_puts(" DK=" as *u8); t_putn(nf_dk); t_puts(" US=" as *u8); t_putn(nf_us); t_puts(" AU=" as *u8); t_putn(nf_au); t_puts(": " as *u8)
64 var ok4: i64 = 1
65 if nf_nz != 1 { ok4 = 0 }
66 if nf_dk != 1 { ok4 = 0 }
67 if nf_us != 0 { ok4 = 0 }
68 if nf_au != 0 { ok4 = 0 }
69 if ok4 == 1 { pass = pass + 1; t_puts("PASS\n" as *u8) } else { t_puts("FAIL\n" as *u8) }
70
71 // --- T5 THE DECIDING FACT: better partners exist AND stay portable ---
72 // Choosing an ethical partner does not forfeit the US market, because
73 // ICH-compliant foreign data is accepted under 21 CFR 312.120.
74 total = total + 1
75 let better: i64 = te_count_better_and_portable(TE_US)
76 let forfeit_dk: i64 = te_ethical_choice_forfeits_us_market(TE_DENMARK)
77 let forfeit_au: i64 = te_ethical_choice_forfeits_us_market(TE_AUSTRALIA)
78 t_puts("T5 jurisdictions beating the US on integrity WITH portable data = " as *u8); t_putn(better); t_puts(" ; choosing Denmark forfeits US market=" as *u8); t_putn(forfeit_dk); t_puts(" Australia=" as *u8); t_putn(forfeit_au); t_puts(": " as *u8)
79 // 7, not 8: Canada TIES the US rather than beating it, and the count is
80 // strictly-better by design.
81 var ok5: i64 = 1
82 if better != 7 { ok5 = 0 }
83 if forfeit_dk != 0 { ok5 = 0 }
84 if forfeit_au != 0 { ok5 = 0 }
85 if ok5 == 1 { pass = pass + 1; t_puts("PASS\n" as *u8) } else { t_puts("FAIL\n" as *u8) }
86
87 // --- T6 mandatory results disclosure is a real discriminator ---
88 // Selective publication is how a risk profile stays hidden.
89 total = total + 1
90 let d_dk: i64 = te_mandatory_results_disclosure(TE_DENMARK)
91 let d_au: i64 = te_mandatory_results_disclosure(TE_AUSTRALIA)
92 let d_nz: i64 = te_mandatory_results_disclosure(TE_NEW_ZEALAND)
93 t_puts("T6 mandatory results disclosure DK=" as *u8); t_putn(d_dk); t_puts(" AU=" as *u8); t_putn(d_au); t_puts(" NZ=" as *u8); t_putn(d_nz); t_puts(" (EU CTR compels it, CTN does not): " as *u8)
94 var ok6: i64 = 1
95 if d_dk != 1 { ok6 = 0 }
96 if d_au != 0 { ok6 = 0 }
97 if d_nz != 0 { ok6 = 0 }
98 if ok6 == 1 { pass = pass + 1; t_puts("PASS\n" as *u8) } else { t_puts("FAIL\n" as *u8) }
99
100 // --- T7 the honest NON-differentiator is documented, not scored ---
101 // Fee-funded regulators are near-universal, so scoring it would
102 // manufacture a distinction that does not exist.
103 total = total + 1
104 var j7: i64 = 0
105 var allfee: i64 = 1
106 while j7 < TE_N {
107 let f: i64 = te_regulator_fee_funded(j7)
108 if f != 1 { allfee = 0 }
109 j7 = j7 + 1
110 }
111 t_puts("T7 every jurisdiction here has a fee-funded regulator (so it is documented, not scored): " as *u8)
112 if allfee == 1 { pass = pass + 1; t_puts("PASS\n" as *u8) } else { t_puts("FAIL\n" as *u8) }
113
114 // --- T8 ICH-GCP and independent ethics hold everywhere on this list ---
115 // A list where every entry passes is a list of GOOD options, which is the
116 // point: the choice is between strong and stronger, not safe and unsafe.
117 total = total + 1
118 var j8: i64 = 0
119 var allgcp: i64 = 1
120 while j8 < TE_N {
121 let g: i64 = te_ich_gcp(j8)
122 let e: i64 = te_independent_ethics(j8)
123 if g != 1 { allgcp = 0 }
124 if e != 1 { allgcp = 0 }
125 j8 = j8 + 1
126 }
127 t_puts("T8 all nine are ICH-GCP with independent ethics review: " as *u8)
128 if allgcp == 1 { pass = pass + 1; t_puts("PASS\n" as *u8) } else { t_puts("FAIL\n" as *u8) }
129
130 // --- T9 CPI is flagged as a snapshot needing annual refresh ---
131 total = total + 1
132 let refresh: i64 = te_cpi_needs_refresh(TE_DENMARK)
133 t_puts("T9 CPI flagged as needing annual refresh=" as *u8); t_putn(refresh); t_puts(": " as *u8)
134 if refresh == 1 { pass = pass + 1; t_puts("PASS\n" as *u8) } else { t_puts("FAIL\n" as *u8) }
135
136 // --- T10 fail-closed on an unknown jurisdiction ---
137 total = total + 1
138 let b_cpi: i64 = te_cpi(99)
139 let b_score: i64 = te_integrity_score(99)
140 let b_gcp: i64 = te_ich_gcp(99)
141 let b_port: i64 = te_data_portable(99)
142 t_puts("T10 unknown jurisdiction CPI=" as *u8); t_putn(b_cpi); t_puts(" score=" as *u8); t_putn(b_score); t_puts(" ICH=" as *u8); t_putn(b_gcp); t_puts(" portable=" as *u8); t_putn(b_port); t_puts(" (never assumed good): " as *u8)
143 var ok10: i64 = 1
144 if b_cpi != TE_INVALID { ok10 = 0 }
145 if b_score != TE_INVALID { ok10 = 0 }
146 if b_gcp != 0 { ok10 = 0 }
147 if b_port != 0 { ok10 = 0 }
148 if ok10 == 1 { pass = pass + 1; t_puts("PASS\n" as *u8) } else { t_puts("FAIL\n" as *u8) }
149
150 t_puts("TRIAL-ETHICS-GATE passed " as *u8); t_putn(pass); t_puts("/" as *u8); t_putn(total)
151 if pass == total { t_puts(" verdict=GREEN\n" as *u8); sys_exit(0); return 0 }
152 t_puts(" verdict=RED\n" as *u8); sys_exit(1); return 1
153}