nx_games_page_gate.nx source
↩ module page · 259 lines · 11926 B
1// nx_games_page_gate.nx -- proves the /games + /world/games EMITTER adopted the estate's design-token
2// SSOT (nx_brand_tokens) and that adopting it cost NO colour. Subject = the EMITTED artifacts
3// web_assets/games.html + web_assets/world_games.html, never the source: a source that says the right
4// thing and an artifact that carries it are different claims, and only the second one ships.
5//
6// WHAT IT IS FOR. Operator #1 gap: "incredible backend + dev-grade frontend". The estate's own ruler
7// nx_ui_audit scored /games 8/12 on 2026-08-25 with theme-aware 0/2 and responsive 1/3, and its
8// envelope is explicit that it MEASURES DESIGN-SYSTEM HYGIENE ONLY -- are the ingredients present --
9// and NOT beauty. This gate is held to the same honest bar: it proves the INGREDIENTS are in the
10// emitted bytes. It cannot and does not claim the page looks good.
11//
12// THE NO-REGRESSION PROOF IS MECHANICAL, NOT ASSERTED. Every colour v2 painted is re-checked as a
13// literal in the v3 artifact (T5), every themed token must appear EXACTLY TWICE (light :root + dark
14// override, T3), and every deliberately theme-INDEPENDENT token must appear EXACTLY ONCE (T4). A
15// dropped dark line therefore cannot pass, and neither can a token silently promoted out of the theme.
16// license_tier: ORIGINAL No hw writes (Rule 26). expect_exit: 0
17import "nx_gate_verdict.nx"
18
19const GP_CAP: i64 = 262144
20const GP_THEMED_N: i64 = 16
21const GP_FIXED_N: i64 = 5
22const GP_V2HEX_N: i64 = 18
23// nx_ui_audit's own published bands, restated here as the bar this gate holds the artifact to.
24// NOT tasted: read off the ruler's source 2026-08-25 -- p_tok's top band is toks>15; p_resp caps at
25// 3 media queries and is FORCED TO ZERO when viewport is absent; p_theme is 2 iff the count is >0;
26// p_type needs font-size decls >= 3.
27const GP_BAR_TOKENS: i64 = 15
28const GP_BAR_MEDIA: i64 = 3
29const GP_BAR_FONTSIZE: i64 = 3
30
31func gp_slen(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n }
32
33// non-overlapping occurrences of pat in buf[0,n). The SAME counting rule nx_ui_audit uses, so a
34// number this gate prints is directly comparable with a number the ruler prints.
35func gp_count(buf: *u8, n: i64, pat: *u8) -> i64 {
36 let pl: i64 = gp_slen(pat)
37 if pl == 0 { return 0 }
38 var c: i64 = 0
39 var i: i64 = 0
40 while i + pl <= n {
41 var k: i64 = 0
42 var m: i64 = 1
43 while k < pl { if buf[i + k] != pat[k] { m = 0; k = pl } else { k = k + 1 } }
44 if m == 1 { c = c + 1; i = i + pl } else { i = i + 1 }
45 }
46 return c
47}
48
49func gp_read(path: *u8, buf: *u8, cap: i64) -> i64 {
50 let fd: i64 = sys_openat_rd(path)
51 if fd < 0 { return 0 - 1 }
52 var tot: i64 = 0
53 while tot < cap { let r: i64 = sys_read(fd, (buf as i64 + tot) as *u8, cap - tot); if r <= 0 { break } tot = tot + r }
54 sys_close(fd)
55 return tot
56}
57
58// THE SCORER UNDER TEST, isolated so it can be bitten. Mirrors nx_ui_audit's p_theme exactly:
59// 2 points iff the page carries at least one prefers-color-scheme block, else 0.
60func gp_theme_points(buf: *u8, n: i64) -> i64 {
61 if gp_count(buf, n, "prefers-color-scheme" as *u8) > 0 { return 2 }
62 return 0
63}
64
65// The 16 tokens that FOLLOW the theme: each must be declared twice (light :root + dark override).
66func gp_themed(i: i64) -> *u8 {
67 if i == 0 { return "--nx-color-bg:" as *u8 }
68 if i == 1 { return "--nx-color-ink:" as *u8 }
69 if i == 2 { return "--nx-color-primary:" as *u8 }
70 if i == 3 { return "--nx-color-line:" as *u8 }
71 if i == 4 { return "--nx-color-muted:" as *u8 }
72 if i == 5 { return "--nx-color-panel:" as *u8 }
73 if i == 6 { return "--nx-color-cell:" as *u8 }
74 if i == 7 { return "--nx-color-raised:" as *u8 }
75 if i == 8 { return "--nx-color-fixed:" as *u8 }
76 if i == 9 { return "--nx-color-sel:" as *u8 }
77 if i == 10 { return "--nx-color-good:" as *u8 }
78 if i == 11 { return "--nx-color-good-bg:" as *u8 }
79 if i == 12 { return "--nx-color-bad:" as *u8 }
80 if i == 13 { return "--nx-color-warn:" as *u8 }
81 if i == 14 { return "--nx-color-soft-bg:" as *u8 }
82 return "--nx-color-accent-bg:" as *u8
83}
84// The 5 tokens that deliberately do NOT follow the theme: a connect-four board and its discs are a
85// physical OBJECT, not page chrome, so they carry ONE value and their contrast stays byte-identical
86// to v2's. Declared here so a future edit that helpfully themes them fails this gate instead of
87// silently repainting a game board nobody re-measured.
88func gp_fixed(i: i64) -> *u8 {
89 if i == 0 { return "--nx-color-board:" as *u8 }
90 if i == 1 { return "--nx-color-board-line:" as *u8 }
91 if i == 2 { return "--nx-color-disc-empty:" as *u8 }
92 if i == 3 { return "--nx-color-disc-r:" as *u8 }
93 return "--nx-color-disc-y:" as *u8
94}
95// Every colour literal the v2 page painted. If one of these is missing from v3 a colour was LOST,
96// which is the only kind of regression a token migration can actually commit.
97func gp_v2hex(i: i64) -> *u8 {
98 if i == 0 { return "#0b0f14" as *u8 }
99 if i == 1 { return "#e6edf3" as *u8 }
100 if i == 2 { return "#4cc2ff" as *u8 }
101 if i == 3 { return "#243140" as *u8 }
102 if i == 4 { return "#8aa0b4" as *u8 }
103 if i == 5 { return "#131b24" as *u8 }
104 if i == 6 { return "#0e1722" as *u8 }
105 if i == 7 { return "#1b2733" as *u8 }
106 if i == 8 { return "#0b1219" as *u8 }
107 if i == 9 { return "#1b3346" as *u8 }
108 if i == 10 { return "#3fb950" as *u8 }
109 if i == 11 { return "#10261a" as *u8 }
110 if i == 12 { return "#f85149" as *u8 }
111 if i == 13 { return "#f5c518" as *u8 }
112 if i == 14 { return "#1b2230" as *u8 }
113 if i == 15 { return "#0e2233" as *u8 }
114 if i == 16 { return "#0e2a4a" as *u8 }
115 return "#16385e" as *u8
116}
117
118func main() -> i64 {
119 let ctr: *i64 = gv_ctr()
120 gv_head("nx_games_page_gate -- the /games emitter adopted the design-token SSOT, and it cost no colour" as *u8)
121
122 let pb: *u8 = sys_mmap(GP_CAP)
123 let sb: *u8 = sys_mmap(GP_CAP)
124 let pn: i64 = gp_read("web_assets/games.html" as *u8, pb, GP_CAP)
125 let sn: i64 = gp_read("web_assets/world_games.html" as *u8, sb, GP_CAP)
126
127 var have: i64 = 0
128 if pn > 0 { if sn > 0 { have = 1 } }
129 // A missing artifact is "I could not look", never "it is broken": run nx_games_page first.
130 if gv_need("both emitted artifacts present (run nx_games_page first)" as *u8, have, ctr) == 0 {
131 return gv_verdict("GAMES-PAGE-DS" as *u8, ctr, "artifacts absent -- SKIP, which is not a pass" as *u8)
132 }
133 // Bind every aggregate below to a non-zero denominator, and PRINT it.
134 gv_subjects("emitted pages under test" as *u8, 2, ctr)
135
136 let toks: i64 = gp_count(pb, pn, "var(--" as *u8)
137 let media: i64 = gp_count(pb, pn, "@media" as *u8)
138 let vport: i64 = gp_count(pb, pn, "viewport" as *u8)
139 let stub_media: i64 = gp_count(sb, sn, "@media" as *u8)
140 let stub_fsz: i64 = gp_count(sb, sn, "font-size" as *u8)
141 gv_puts(" MEASURED portal: var(--)=" as *u8)
142 gv_num(toks)
143 gv_puts(" @media=" as *u8)
144 gv_num(media)
145 gv_puts(" viewport=" as *u8)
146 gv_num(vport)
147 gv_puts(" | stub: @media=" as *u8)
148 gv_num(stub_media)
149 gv_puts(" font-size=" as *u8)
150 gv_num(stub_fsz)
151 gv_puts("\n" as *u8)
152
153 var t1: i64 = 0
154 if gp_theme_points(pb, pn) == 2 { t1 = 1 }
155 gv_check("T1 portal carries a prefers-color-scheme block (ruler theme-aware 2/2)" as *u8, t1, ctr)
156
157 var t2: i64 = 0
158 if media >= GP_BAR_MEDIA { if vport > 0 { t2 = 1 } }
159 gv_check("T2 portal has >=3 @media AND declares viewport -- both conjuncts load-bearing, the ruler ZEROES responsive without a viewport" as *u8, t2, ctr)
160
161 var t2b: i64 = 0
162 if toks > GP_BAR_TOKENS { t2b = 1 }
163 gv_check("T2b portal token uses clear the ruler top band (>15)" as *u8, t2b, ctr)
164
165 // T3: themed tokens must appear EXACTLY twice -- once in :root, once in the dark override.
166 var t3: i64 = 1
167 var i: i64 = 0
168 while i < GP_THEMED_N {
169 let p: *u8 = gp_themed(i)
170 let c: i64 = gp_count(pb, pn, p)
171 if c != 2 {
172 t3 = 0
173 gv_puts(" THEMED-TOKEN-NOT-DECLARED-TWICE " as *u8)
174 gv_puts(p)
175 gv_puts(" count=" as *u8)
176 gv_num(c)
177 gv_puts(" expected=2\n" as *u8)
178 }
179 i = i + 1
180 }
181 gv_check("T3 all 16 themed tokens declared exactly twice (light :root + dark override)" as *u8, t3, ctr)
182
183 // T4: theme-INDEPENDENT tokens must appear exactly once. The tooth that stops a future edit from
184 // theming the game board without re-measuring its contrast.
185 var t4: i64 = 1
186 var j: i64 = 0
187 while j < GP_FIXED_N {
188 let q: *u8 = gp_fixed(j)
189 let c2: i64 = gp_count(pb, pn, q)
190 if c2 != 1 {
191 t4 = 0
192 gv_puts(" OBJECT-TOKEN-NOT-SINGLE-VALUED " as *u8)
193 gv_puts(q)
194 gv_puts(" count=" as *u8)
195 gv_num(c2)
196 gv_puts(" expected=1\n" as *u8)
197 }
198 j = j + 1
199 }
200 gv_check("T4 all 5 object tokens are single-valued (board and discs do not follow the theme, by design)" as *u8, t4, ctr)
201
202 // T5: NO COLOUR LOST. Every literal v2 painted must still be present in the artifact.
203 var t5: i64 = 1
204 var k: i64 = 0
205 var lost: i64 = 0
206 while k < GP_V2HEX_N {
207 let hx: *u8 = gp_v2hex(k)
208 if gp_count(pb, pn, hx) < 1 {
209 t5 = 0
210 lost = lost + 1
211 gv_puts(" V2-COLOUR-LOST " as *u8)
212 gv_puts(hx)
213 gv_puts("\n" as *u8)
214 }
215 k = k + 1
216 }
217 gv_puts(" MEASURED v2 colours checked=" as *u8)
218 gv_num(GP_V2HEX_N)
219 gv_puts(" lost=" as *u8)
220 gv_num(lost)
221 gv_puts("\n" as *u8)
222 gv_check("T5 every colour the v2 page painted survives into v3 (tokenising lost no colour)" as *u8, t5, ctr)
223
224 var t6: i64 = 0
225 if gp_theme_points(sb, sn) == 2 { t6 = 1 }
226 gv_check("T6 the /world/games stub got the SAME palette from the same brand (v1 shipped two rival portals that drifted)" as *u8, t6, ctr)
227
228 var t7: i64 = 0
229 if stub_fsz >= GP_BAR_FONTSIZE { t7 = 1 }
230 gv_check("T7 stub carries >=3 font-size decls via the SSOT type scale (ruler type-scale 2/2)" as *u8, t7, ctr)
231
232 // NEG-CONTROL / BITE. A scorer that always answered 2 would pass every tooth above. Fire the SAME
233 // function at a page that has the block and one that does not, both built HERE AT RUNTIME so the
234 // fixture can never be mistaken for the subject, cannot be found by a source scanner, and cannot
235 // be silently deleted from a directory.
236 let good: *u8 = sys_mmap(256)
237 let bad: *u8 = sys_mmap(256)
238 var go: i64 = 0
239 go = gv_cat(good, go, "<style>@media (prefers-color-scheme:dark){:root{--a:#000}}</style>" as *u8)
240 var bo: i64 = 0
241 bo = gv_cat(bad, bo, "<style>:root{--a:#000}body{background:var(--a)}</style>" as *u8)
242 var fires_on_blind: i64 = 0
243 if gp_theme_points(bad, bo) == 0 { fires_on_blind = 1 }
244 var fires_on_themed: i64 = 1
245 if gp_theme_points(good, go) == 2 { fires_on_themed = 0 }
246 gv_bite("neg-control-theme-scorer-answers-0-for-a-theme-blind-page-and-2-for-a-themed-one" as *u8, fires_on_blind, fires_on_themed, ctr)
247
248 // Second neg-control: the colour-loss detector must FIND a planted loss, or T5 is decoration.
249 let plant: *u8 = sys_mmap(256)
250 var po: i64 = 0
251 po = gv_cat(plant, po, ":root{--nx-color-bg:#0b0f14}" as *u8)
252 var loss_fires: i64 = 0
253 if gp_count(plant, po, "#4cc2ff" as *u8) < 1 { loss_fires = 1 }
254 var loss_quiet: i64 = 1
255 if gp_count(pb, pn, "#4cc2ff" as *u8) >= 1 { loss_quiet = 0 }
256 gv_bite("neg-control-colour-loss-detector-fires-on-a-page-missing-the-accent-and-is-silent-on-the-real-one" as *u8, loss_fires, loss_quiet, ctr)
257
258 return gv_verdict("GAMES-PAGE-DS" as *u8, ctr, "SSOT adopted and no colour lost -- design-system HYGIENE ingredients present in the emitted bytes, NOT a claim about beauty" as *u8)
259}