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}