code wiki / _hdl_build / nx_ux_study_gate.nx
nx_ux_study_gate.nx source
↩ module page · 92 lines · 6600 B
1// nx_ux_study_gate.nx -- PROOF (re-runnable, adversary-controlled) that the NN/g usability scoring in
2// nx_ux_study is HONEST and cannot be gamed into a fake win, PLUS it runs the first REAL study: the
3// Nishi browser dogfood of https://nishifamily.com/experiential, graded from the actual scroll recording
4// (nishi_browser_f0..7.ppm) captured this session.
5//
6// The neg-controls are the load-bearing part: if someone "fixes" the grader to reward feature-presence,
7// T-STICKER and T-CATAS go green-when-they-should-be-red and this gate turns RED. license_tier: ORIGINAL
8// expect_exit: 0
9import "nx_ux_study.nx"
10
11func mk_study(goal: *u8, artifact: *u8, surface: i64, quant: i64, moderated: i64, ntasks: i64, nfind: i64) -> *UxStudy {
12 let s: *UxStudy = sys_mmap(UX_STUDY_BYTES as nx_size) as *UxStudy
13 s.goal = goal
14 s.artifact = artifact
15 s.surface = surface
16 s.quantitative = quant
17 s.moderated = moderated
18 s.tasks = sys_mmap((ntasks * UX_TASK_BYTES) as nx_size) as *UxTask
19 s.n_tasks = ntasks
20 s.findings = sys_mmap((nfind * UX_FINDING_BYTES) as nx_size) as *UxFinding
21 s.n_findings = nfind
22 return s
23}
24
25func chk(name: *u8, got: i64, want: i64) -> i64 {
26 ux_w(" " as *u8); ux_w(name)
27 ux_w(" got=" as *u8); ux_print_grade(got); ux_w(" want=" as *u8); ux_print_grade(want)
28 if got == want { ux_w(" PASS\n" as *u8); return 0 }
29 ux_w(" FAIL\n" as *u8); return 1
30}
31
32func main() -> i64 {
33 ux_w("=== nx_ux_study_gate -- PROOF the usability grade is bound to TASK OUTCOMES, not feature presence ===\n" as *u8)
34 var fails: i64 = 0
35
36 // T-STICKER (neg-control): a feature is "present" and the participant TRIED it, but the task FAILED.
37 // A sticker-grader would look at "feature exists" and pass. The honest grader MUST return FAIL.
38 let a: *UxStudy = mk_study("sticker attempt: feature present, task failed" as *u8, "test://sticker" as *u8, UX_SURF_NISHI_DESKTOP, 1, 0, 1, 0)
39 ux_set_task(a, 0, "use the shipped feature" as *u8, "task completes" as *u8, UX_FAIL, 3, 1)
40 fails = fails + chk("T-STICKER present-but-failed ->" as *u8, ux_grade(a), UX_GRADE_FAIL)
41
42 // T-CATAS (neg-control): every task succeeded, but there is a severity-4 catastrophe finding.
43 // MUST return FAIL -- a catastrophe cannot be stickered over by task success.
44 let b: *UxStudy = mk_study("all tasks pass but a catastrophe exists" as *u8, "test://catas" as *u8, UX_SURF_NISHI_DESKTOP, 1, 0, 1, 1)
45 ux_set_task(b, 0, "submit the form" as *u8, "form submits" as *u8, UX_SUCCESS, 2, 0)
46 ux_set_finding(b, 0, 5, 4, "data loss on submit" as *u8, 2, "make submit idempotent + confirm" as *u8)
47 fails = fails + chk("T-CATAS success+catastrophe->" as *u8, ux_grade(b), UX_GRADE_FAIL)
48
49 // T-PASS (positive control): every task succeeded, only a cosmetic (sev-1) finding -> genuinely PASS.
50 let c: *UxStudy = mk_study("clean pass" as *u8, "test://pass" as *u8, UX_SURF_NISHI_DESKTOP, 1, 0, 2, 1)
51 ux_set_task(c, 0, "read the headline" as *u8, "headline legible" as *u8, UX_SUCCESS, 1, 0)
52 ux_set_task(c, 1, "click the primary button" as *u8, "action fires" as *u8, UX_SUCCESS, 1, 0)
53 ux_set_finding(c, 0, 8, 1, "button 2px off-center" as *u8, 0, "nudge left 2px" as *u8)
54 fails = fails + chk("T-PASS allsuccess+cosmetic->" as *u8, ux_grade(c), UX_GRADE_PASS)
55
56 // T-COND (control): a PARTIAL task + a minor (sev-2) finding, no failure/major -> CONDITIONAL.
57 let d: *UxStudy = mk_study("conditional" as *u8, "test://cond" as *u8, UX_SURF_NISHI_DESKTOP, 1, 0, 1, 1)
58 ux_set_task(d, 0, "find the search box" as *u8, "search box found quickly" as *u8, UX_PARTIAL, 3, 0)
59 ux_set_finding(d, 0, 4, 2, "search icon inconsistent with the rest of the site" as *u8, 1, "use the standard search glyph" as *u8)
60 fails = fails + chk("T-COND partial+minor ->" as *u8, ux_grade(d), UX_GRADE_COND)
61
62 if fails == 0 { ux_w("\nNX-UX-GATE GREEN -- grade is bound to task outcomes + severity; sticker attempts fail as they must\n" as *u8) }
63 else { ux_w("\nNX-UX-GATE RED fails=" as *u8); ux_n(fails); ux_w("\n" as *u8) }
64
65 // ---------------- THE FIRST REAL STUDY: Nishi-browser dogfood of /experiential ----------------
66 // Grounded on the scroll recording captured this session (nishi_browser_f0..7.ppm): frame 0 showed the
67 // dark verdict block legible; frames 1..6 the table body; frame 3 the over-tall rows; frame 7 a white
68 // void past content. Every task outcome + finding below is what the pixels showed, not a guess.
69 ux_w("\n\n>>> Worked example -- the loop applied to our OWN page (honest, grades itself) <<<\n" as *u8)
70 let s: *UxStudy = mk_study(
71 "Validate /experiential census is readable + navigable on the Nishi browser" as *u8,
72 "https://nishifamily.com/experiential" as *u8,
73 UX_SURF_NISHI_DESKTOP, 1, 0, 4, 1)
74 ux_set_task(s, 0, "Read the verdict counts (GAP/PARITY/AHEAD)" as *u8, "verdict block legible on the first screen" as *u8, UX_SUCCESS, 1, 0)
75 // T2 was FAIL (19 rows across 8 screens). ROOT-FIXED: _layout_fontsize_decl_px read "13.5px" as 135px
76 // (skipped the '.') -> tscale 3 -> 3x-tall lines. Fixed + gated (nx_css_fontsize_frac_gate GREEN);
77 // page_h 4580 -> 1418; re-recording shows all 19 rows dense within frames 0-1. Now SUCCESS.
78 ux_set_task(s, 1, "Scan all 19 capability rows" as *u8, "all rows readable within 2 scroll screens" as *u8, UX_SUCCESS, 2, 0)
79 // T3 was FAIL (white void past content, frame 7 luma 236); FIXED this session by CSS background
80 // propagation in br_draw_fb_at -> frame 7 luma 15 (dark to the end). Now SUCCESS.
81 ux_set_task(s, 2, "Reach the page bottom without a visual break" as *u8, "page background stays consistent to the end" as *u8, UX_SUCCESS, 8, 0)
82 // T4 was PARTIAL (inline labels overlapped body text). ROOT-FIXED by the measure==paint unification:
83 // layout vec-measure (nx_layout_set_vec_measure, gate GREEN) + paint inherited font-size
84 // (br_comp_int_inh) + '.'-truncating int parse. Re-see: labels flow inline, table single-line 13px.
85 ux_set_task(s, 3, "Read the intro paragraph" as *u8, "intro text legible with no overlapping words" as *u8, UX_SUCCESS, 1, 0)
86 // F1/F2/F3 all RESOLVED with gates. Remaining pixel-truth: cosmetic only.
87 ux_set_finding(s, 0, 4, 1, "GAP/PARITY pills render as colored text, not pill shapes (no border-radius paint)" as *u8, 0, "paint rounded-rect backgrounds for .pill when border-radius support lands" as *u8)
88 ux_report(s)
89
90 if fails == 0 { sys_exit(0); return 0 }
91 sys_exit(1); return 1
92}