code wiki / _hdl_build / nx_cms_a11y_gate.nx

nx_cms_a11y_gate.nx source

↩ module page · 69 lines · 4175 B

1// nx_cms_a11y_gate.nx -- CMS ACCESSIBILITY (WCAG) gate (the accessibility-wcag class, landed HONESTLY). 2// Proves nx_cms_a11y: a compliant page passes all 4 WCAG rules AND each deliberately-broken variant is 3// DETECTED (no false-green: a checker that only ever passes is worthless). Appends "CMSGATE row=nx_cms_a11y 4// wcag ... verdict=PASS" to cms_gate.log only if every row passes. Exit 0 iff all pass. license_tier: ORIGINAL 5import "nx_cms_a11y.nx" 6import "nx_syscalls.nx" 7 8func ay_w(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 } 9func ay_num(v: i64) -> i64 { let bb: *u8=sys_mmap(28); var m: i64=v; if m<0{m=0-m}; let t: *u8=sys_mmap(28); var k: i64=0; if m==0{t[0]=48;k=1}; while m>0{t[k]=48+(m%10);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 } 10func ay_len(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} return n } 11func ay_row(id: i64, ok: i64, what: *u8) -> i64 { 12 ay_w("A11YROW " as *u8); ay_num(id); ay_w(" " as *u8) 13 if ok==1 { ay_w("PASS " as *u8) } else { ay_w("FAIL " as *u8) } 14 ay_w(what); ay_w("\n" as *u8) 15 return ok 16} 17 18func main() -> i64 { 19 var pass: i64 = 0 20 var rows: i64 = 0 21 var ok: i64 = 0 22 23 // a fully WCAG-compliant page 24 let good: *u8 = "<html lang=\"en\"><body><img src=\"logo.png\" alt=\"Andelin West logo\"><h1>Estate Planning</h1><h2>Wills and Trusts</h2><form><input type=\"text\" aria-label=\"Your name\"><input type=\"hidden\" name=\"csrf\"></form></body></html>" as *u8 25 let gn: i64 = ay_len(good) 26 27 // R0: compliant page satisfies all 4 rules 28 ok = 0; if a11y_audit(good, gn) == 4 { ok = 1 } 29 rows=rows+1; pass=pass+ay_row(0, ok, "compliant page passes all 4 WCAG rules (audit=4/4)" as *u8) 30 31 // R1: missing <html lang> -> 3.1.1 violation detected 32 let no_lang: *u8 = "<html><body><img src=\"x\" alt=\"ok\"><h1>A</h1><h2>B</h2><input aria-label=\"q\"></body></html>" as *u8 33 ok = 0; if a11y_has_lang(no_lang, ay_len(no_lang)) == 0 { ok = 1 } 34 rows=rows+1; pass=pass+ay_row(1, ok, "missing lang detected (WCAG 3.1.1)" as *u8) 35 36 // R2: <img> without alt -> 1.1.1 violation detected (and empty alt also caught) 37 let no_alt: *u8 = "<html lang=\"en\"><img src=\"x\"><img src=\"y\" alt=\"\"></html>" as *u8 38 ok = 0; if a11y_imgs_alt(no_alt, ay_len(no_alt)) == 0 { ok = 1 } 39 rows=rows+1; pass=pass+ay_row(2, ok, "missing/empty img alt detected (WCAG 1.1.1)" as *u8) 40 41 // R3: skipped heading level (h1 -> h3) -> 1.3.1 violation detected 42 let skip_h: *u8 = "<html lang=\"en\"><h1>Title</h1><h3>Sub</h3></html>" as *u8 43 ok = 0; if a11y_heading_order(skip_h, ay_len(skip_h)) == 0 { ok = 1 } 44 rows=rows+1; pass=pass+ay_row(3, ok, "skipped heading level detected (WCAG 1.3.1)" as *u8) 45 46 // R4: non-hidden <input> with no accessible name -> 4.1.2 violation detected 47 let no_label: *u8 = "<html lang=\"en\"><form><input type=\"text\" name=\"email\"></form></html>" as *u8 48 ok = 0; if a11y_inputs_labeled(no_label, ay_len(no_label)) == 0 { ok = 1 } 49 rows=rows+1; pass=pass+ay_row(4, ok, "unlabeled input detected (WCAG 4.1.2)" as *u8) 50 51 // R5: anti-false-green -- the compliant page must NOT trip any individual detector 52 ok = 0 53 if a11y_has_lang(good, gn) == 1 { if a11y_imgs_alt(good, gn) == 1 { if a11y_heading_order(good, gn) == 1 { if a11y_inputs_labeled(good, gn) == 1 { ok = 1 } } } } 54 rows=rows+1; pass=pass+ay_row(5, ok, "no false-positives on the compliant page (checker discriminates)" as *u8) 55 56 ay_w("CMS-A11Y-GATE rows=" as *u8); ay_num(rows); ay_w(" pass=" as *u8); ay_num(pass); ay_w("\n" as *u8) 57 58 if pass == rows { 59 let gf: i64 = sys_openat_append("knowledge/status/cms_gate.log" as *u8, 0x1a4) 60 if gf >= 0 { 61 let line: *u8 = "CMSGATE row=nx_cms_a11y wcag rules=4 pass=6 verdict=PASS\n" as *u8 62 sys_write(gf, line, ay_len(line)); sys_close(gf) 63 } 64 ay_w("CMS-A11Y-GATE verdict=PASS -- accessibility-wcag recorded in cms_gate.log\n" as *u8) 65 sys_exit(0); return 0 66 } 67 ay_w("CMS-A11Y-GATE verdict=FAIL -- NOT recorded (no fake-green)\n" as *u8) 68 sys_exit(1); return 1 69}