nx_game_page_artifact_gate.nx source
↩ module page · 239 lines · 17510 B
1import "nx_game_page_artifact_lib.nx"
2import "nx_gate_verdict.nx"
3const GAT_CAP: i64 = 256
4const GAT_CASES: *u8 = "same-body-twin-pair\nmemory-limits-derived\ndifferent-body-refused\ndifferent-memory-minimum-refused\nnonshared-twin-refused\nevery-truncated-twin-prefix-refused\nu32-leb-overflow-refused\npair-cli-pinned-artifacts\npair-cli-stale-pin-refused\npair-cli-missing-input-refused\nsurrounding-bytes-and-native-base64\nrepeat-composition-byte-identical\nduplicate-slot-refused\nabsent-slot-refused\nunterminated-slot-refused\ninvalid-wasm-header-refused\noutput-cap-refuses-before-writing\npinned-files-stage-exact\nsame-request-safe-retry\nstale-source-pin-refuses-unchanged-output\nstale-module-pin-retains-output\ndifferent-output-refused-and-retained\nmissing-module-creates-no-output\npinned-malformed-module-creates-no-output\nno-replace-retains-existing-output\ncompeting-writers-one-winner-no-clobber\npaired-page-updates-module-url-and-derived-limits\npaired-page-repeat-byte-identical\npaired-page-cap-refuses-with-output-retained\npaired-page-missing-twin-slot-retains-output\npaired-page-url-injection-refused\npaired-cli-stage-exact\npaired-cli-retry-identical\npaired-cli-stale-shared-pin-retains-output\npaired-cli-missing-shared-creates-no-output\nhtml-shared-dependency-declared\nhtml-shared-dependency-rebind-no-duplicate\nhtml-shared-dependency-escaped\nhtml-shared-dependency-cap-retains-output\nhtml-shared-dependency-malformed-retains-output\nmodern-tuple-updates-hash-size-url-limits\nmodern-tuple-repeat-identical\nmodern-sha-only-refused\nmodern-size-only-refused\nmodern-duplicate-sha-refused\nmodern-duplicate-size-refused\n"
5static gat_plan: *i64
6func gat_check(name: *u8, ok: i64, count: *i64) -> i64 {
7 return gv_plan_check(gat_plan,name,ok,count)
8}
9func gat_pair_checks(count: *i64) -> i64 {
10 let plain: *u8="\x00\x61\x73\x6d\x01\x00\x00\x00\x05\x03\x01\x00\x01\x00\x01\x00" as *u8
11 let twin: *u8="\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x10\x01\x03\x65\x6e\x76\x06\x6d\x65\x6d\x6f\x72\x79\x02\x03\x01\x02\x00\x01\x00" as *u8
12 let pn: i64=16
13 let tn: i64=29
14 let mem: *GpaMemory=sys_mmap(__size_of(GpaMemory)) as *GpaMemory
15 gat_check("same-body-twin-pair",gpa_pair(plain,pn,twin,tn,mem),count)
16 gat_check("memory-limits-derived",((mem.minimum==1)&&(mem.maximum==2)&&(mem.count==1)) as i64,count)
17 let changed: *u8=sys_mmap(tn)
18 var i: i64=0; while i<tn { changed[i]=twin[i]; i=i+1 }
19 changed[tn-1]=1 as u8
20 gat_check("different-body-refused",(gpa_pair(plain,pn,changed,tn,mem)==0) as i64,count)
21 changed[tn-1]=twin[tn-1]; changed[24]=2 as u8
22 gat_check("different-memory-minimum-refused",(gpa_pair(plain,pn,changed,tn,mem)==0) as i64,count)
23 changed[24]=1 as u8; changed[23]=1 as u8
24 gat_check("nonshared-twin-refused",(gpa_pair(plain,pn,changed,tn,mem)==0) as i64,count)
25 var truncated_ok: i64=1
26 i=0; while i<tn { if gpa_pair(plain,pn,twin,i,mem)!=0 { truncated_ok=0 }; i=i+1 }
27 gat_check("every-truncated-twin-prefix-refused",truncated_ok,count)
28 let overflow: *u8="\xff\xff\xff\xff\x10" as *u8
29 let c: *GpaWasmCursor=sys_mmap(__size_of(GpaWasmCursor)) as *GpaWasmCursor
30 c.data=overflow; c.size=5; c.pos=0
31 gat_check("u32-leb-overflow-refused",(gpa_u32(c)<0) as i64,count)
32 sys_munmap(c as *u8,__size_of(GpaWasmCursor))
33let page: *u8="const B=\"AGFzbQEAAAA=\";const NXMT_URL=\"old.wasm\";const NXMT_PAGES=99;const NXMT_MAX=100;" as *u8
34 let expected: *u8="const B=\"AGFzbQEAAAAFAwEAAQABAA==\";const NXMT_URL=\"new.wasm\";const NXMT_PAGES=1;const NXMT_MAX=2;" as *u8
35 let cap: i64=vw_slen(expected)+1
36 let out: *u8=sys_mmap(cap); let again: *u8=sys_mmap(cap)
37 let size: i64=gpa_compose_pair(page,vw_slen(page),plain,pn,twin,tn,"new.wasm" as *u8,out,cap)
38 gat_check("paired-page-updates-module-url-and-derived-limits",gpa_same(out,size,expected,vw_slen(expected)),count)
39 let repeated: i64=gpa_compose_pair(out,size,plain,pn,twin,tn,"new.wasm" as *u8,again,cap)
40 gat_check("paired-page-repeat-byte-identical",gpa_same(out,size,again,repeated),count)
41 again[0]=77 as u8
42 let short: i64=gpa_compose_pair(page,vw_slen(page),plain,pn,twin,tn,"new.wasm" as *u8,again,1)
43 gat_check("paired-page-cap-refuses-with-output-retained",((short<0)&&(again[0]==(77 as u8))) as i64,count)
44 let absent: *u8="const B=\"AGFzbQEAAAA=\";" as *u8
45 let missing: i64=gpa_compose_pair(absent,vw_slen(absent),plain,pn,twin,tn,"new.wasm" as *u8,again,cap)
46 gat_check("paired-page-missing-twin-slot-retains-output",((missing<0)&&(again[0]==(77 as u8))) as i64,count)
47 let inject: i64=gpa_compose_pair(page,vw_slen(page),plain,pn,twin,tn,"bad\".wasm" as *u8,again,cap)
48 gat_check("paired-page-url-injection-refused",((inject<0)&&(again[0]==(77 as u8))) as i64,count)
49 let modern:*u8="const B=\"AGFzbQEAAAA=\";const NXMT_URL=\"old.wasm\";const NXMT_PAGES=99;const NXMT_MAX=100;const NXMT_SHA256=\"stale\";const NXMT_BYTES=999;" as *u8
50 let wanted:*u8="const B=\"AGFzbQEAAAAFAwEAAQABAA==\";const NXMT_URL=\"new.wasm\";const NXMT_PAGES=1;const NXMT_MAX=2;const NXMT_SHA256=\"7841969ab82bf8aadb39929c1df25b1baf6a200c7f7656ec61c03a867995b9ed\";const NXMT_BYTES=29;" as *u8
51 let mc:i64=vw_slen(wanted)+1
52 let mo:*u8=sys_mmap(mc);let mr:*u8=sys_mmap(mc)
53 let mn:i64=gpa_compose_pair(modern,vw_slen(modern),plain,pn,twin,tn,"new.wasm",mo,mc)
54 gat_check("modern-tuple-updates-hash-size-url-limits",gpa_same(mo,mn,wanted,vw_slen(wanted)),count)
55 let rr:i64=gpa_compose_pair(mo,mn,plain,pn,twin,tn,"new.wasm",mr,mc)
56 gat_check("modern-tuple-repeat-identical",gpa_same(mo,mn,mr,rr),count)
57 let bad0:*u8="const B=\"AGFzbQEAAAA=\";const NXMT_URL=\"old.wasm\";const NXMT_PAGES=99;const NXMT_MAX=100;const NXMT_SHA256=\"stale\";" as *u8
58 mr[0]=77 as u8
59 let rc0:i64=gpa_compose_pair(bad0,vw_slen(bad0),plain,pn,twin,tn,"new.wasm",mr,mc)
60 gat_check("modern-sha-only-refused",((rc0<0)&&(mr[0]==(77 as u8))) as i64,count)
61 let bad1:*u8="const B=\"AGFzbQEAAAA=\";const NXMT_URL=\"old.wasm\";const NXMT_PAGES=99;const NXMT_MAX=100;const NXMT_BYTES=999;" as *u8
62 mr[0]=77 as u8
63 let rc1:i64=gpa_compose_pair(bad1,vw_slen(bad1),plain,pn,twin,tn,"new.wasm",mr,mc)
64 gat_check("modern-size-only-refused",((rc1<0)&&(mr[0]==(77 as u8))) as i64,count)
65 let bad2:*u8="const B=\"AGFzbQEAAAA=\";const NXMT_URL=\"old.wasm\";const NXMT_PAGES=99;const NXMT_MAX=100;const NXMT_SHA256=\"a\";const NXMT_SHA256=\"b\";const NXMT_BYTES=999;" as *u8
66 mr[0]=77 as u8
67 let rc2:i64=gpa_compose_pair(bad2,vw_slen(bad2),plain,pn,twin,tn,"new.wasm",mr,mc)
68 gat_check("modern-duplicate-sha-refused",((rc2<0)&&(mr[0]==(77 as u8))) as i64,count)
69 let bad3:*u8="const B=\"AGFzbQEAAAA=\";const NXMT_URL=\"old.wasm\";const NXMT_PAGES=99;const NXMT_MAX=100;const NXMT_SHA256=\"a\";const NXMT_BYTES=1;const NXMT_BYTES=2;" as *u8
70 mr[0]=77 as u8
71 let rc3:i64=gpa_compose_pair(bad3,vw_slen(bad3),plain,pn,twin,tn,"new.wasm",mr,mc)
72 gat_check("modern-duplicate-size-refused",((rc3<0)&&(mr[0]==(77 as u8))) as i64,count)
73 sys_munmap(mo,mc);sys_munmap(mr,mc)
74 sys_munmap(out,cap);sys_munmap(again,cap)
75 sys_munmap(mem as *u8,__size_of(GpaMemory)); sys_munmap(changed,tn)
76 return 0
77}
78func gat_declaration_checks(count: *i64) -> i64 {
79 let page: *u8="<html><head><title>Beach</title></head><body>scene</body></html>" as *u8
80 let expected: *u8="<html><head><title>Beach</title><meta name=\"nishi-wasm\" data-nishi-role=\"shared-runtime\" content=\"/world/shared.wasm\"></head><body>scene</body></html>" as *u8
81 let escaped: *u8="<html><head><title>Beach</title><meta name=\"nishi-wasm\" data-nishi-role=\"shared-runtime\" content=\"/world/a.wasm?x=1&y=2\"></head><body>scene</body></html>" as *u8
82 let cap: i64=vw_slen(expected)+vw_slen(escaped)
83 let out: *u8=sys_mmap(cap);let again: *u8=sys_mmap(cap)
84 let n: i64=gpa_declare_shared(page,vw_slen(page),"/world/shared.wasm",out,cap)
85 gat_check("html-shared-dependency-declared",gpa_same(out,n,expected,vw_slen(expected)),count)
86 let rn: i64=gpa_declare_shared(out,n,"/world/shared.wasm",again,cap)
87 gat_check("html-shared-dependency-rebind-no-duplicate",gpa_same(out,n,again,rn),count)
88 let en: i64=gpa_declare_shared(out,n,"/world/a.wasm?x=1&y=2",again,cap)
89 gat_check("html-shared-dependency-escaped",gpa_same(again,en,escaped,vw_slen(escaped)),count)
90 again[0]=77 as u8
91 let short: i64=gpa_declare_shared(page,vw_slen(page),"/world/shared.wasm",again,1)
92 gat_check("html-shared-dependency-cap-retains-output",((short<0)&&(again[0]==(77 as u8))) as i64,count)
93 let malformed: *u8="<head><head></head>" as *u8
94 let bad: i64=gpa_declare_shared(malformed,vw_slen(malformed),"/world/shared.wasm",again,cap)
95 gat_check("html-shared-dependency-malformed-retains-output",((bad<0)&&(again[0]==(77 as u8))) as i64,count)
96 sys_munmap(out,cap);sys_munmap(again,cap)
97 return 0
98}
99func gat_pair_files(count: *i64) -> i64 {
100 let plain: *u8="\x00\x61\x73\x6d\x01\x00\x00\x00\x05\x03\x01\x00\x01\x00\x01\x00" as *u8
101 let twin: *u8="\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x10\x01\x03\x65\x6e\x76\x06\x6d\x65\x6d\x6f\x72\x79\x02\x03\x01\x02\x00\x01\x00" as *u8
102 let pn: i64=16
103 let tn: i64=29
104
105 fsx_write("plain.wasm",plain,pn); fsx_write("shared.wasm",twin,tn)
106 let ph: *u8=sys_mmap(GPA_SHA_HEX+1); let th: *u8=sys_mmap(GPA_SHA_HEX+1)
107 gpa_sha(plain,pn,ph); gpa_sha(twin,tn,th)
108 let av: *i64=sys_mmap(6*__size_of(i64)) as *i64
109 av[0]="nx_game_page_emit" as *u8 as i64; av[1]="pair" as *u8 as i64
110 av[2]="plain.wasm" as *u8 as i64; av[3]="shared.wasm" as *u8 as i64
111 av[4]=ph as i64; av[5]=th as i64
112 gat_check("pair-cli-pinned-artifacts",(gpa_pair_main(6,av)==0) as i64,count)
113 av[5]="incorrect" as *u8 as i64
114 gat_check("pair-cli-stale-pin-refused",(gpa_pair_main(6,av)==GPA_RC_CONFLICT) as i64,count)
115 av[3]="absent.wasm" as *u8 as i64
116 gat_check("pair-cli-missing-input-refused",(gpa_pair_main(6,av)==GPA_RC_INPUT) as i64,count)
117let page: *u8="const B=\"AGFzbQEAAAA=\";const NXMT_URL=\"old.wasm\";const NXMT_PAGES=99;const NXMT_MAX=100;" as *u8
118 let expected: *u8="const B=\"AGFzbQEAAAAFAwEAAQABAA==\";const NXMT_URL=\"new.wasm\";const NXMT_PAGES=1;const NXMT_MAX=2;" as *u8
119 fsx_write("paired-base.html" as *u8,page,vw_slen(page))
120 let pagehash: *u8=sys_mmap(GPA_SHA_HEX+1);gpa_sha(page,vw_slen(page),pagehash)
121 let avp: *i64=sys_mmap(10*__size_of(i64)) as *i64
122 avp[0]=av[0];avp[1]="rebind" as *u8 as i64
123 avp[2]="paired-base.html" as *u8 as i64;avp[3]="plain.wasm" as *u8 as i64
124 avp[4]="paired-stage.html" as *u8 as i64;avp[5]=pagehash as i64;avp[6]=ph as i64
125 avp[7]="shared.wasm" as *u8 as i64;avp[8]=th as i64;avp[9]="new.wasm" as *u8 as i64
126 let cap: i64=vw_slen(expected)+1;let out: *u8=sys_mmap(cap)
127 let first: i64=gpa_main(10,avp)
128 var n: i64=vw_read("paired-stage.html" as *u8,out,cap)
129 gat_check("paired-cli-stage-exact",((first==0)&&(gpa_same(out,n,expected,vw_slen(expected))==1)) as i64,count)
130 gat_check("paired-cli-retry-identical",(gpa_main(10,avp)==0) as i64,count)
131 avp[8]="stale" as *u8 as i64
132 let stale: i64=gpa_main(10,avp);n=vw_read("paired-stage.html" as *u8,out,cap)
133 gat_check("paired-cli-stale-shared-pin-retains-output",((stale==GPA_RC_CONFLICT)&&(gpa_same(out,n,expected,vw_slen(expected))==1)) as i64,count)
134 avp[7]="absent-shared.wasm" as *u8 as i64;avp[4]="missing-paired-output.html" as *u8 as i64
135 let missing: i64=gpa_main(10,avp);n=vw_read("missing-paired-output.html" as *u8,out,cap)
136 gat_check("paired-cli-missing-shared-creates-no-output",((missing==GPA_RC_INPUT)&&(n<0)) as i64,count)
137 sys_munmap(out,cap);sys_munmap(avp as *u8,10*__size_of(i64));sys_munmap(pagehash,GPA_SHA_HEX+1)
138 sys_munmap(av as *u8,6*__size_of(i64))
139 sys_munmap(ph,GPA_SHA_HEX+1); sys_munmap(th,GPA_SHA_HEX+1)
140 return 0
141}
142func main(argc: i64, argv: *i64) -> i64 {
143 let count: *i64 = gv_ctr()
144 gat_plan=gv_plan_new(GAT_CASES)
145 gat_pair_checks(count)
146 gat_declaration_checks(count)
147 let wasm: *u8 = sys_mmap(GPA_HEADER_BYTES)
148 wasm[0]=0 as u8; wasm[1]=97 as u8; wasm[2]=115 as u8; wasm[3]=109 as u8
149 wasm[4]=1 as u8; wasm[5]=0 as u8; wasm[6]=0 as u8; wasm[7]=0 as u8
150 let page: *u8 = "PRE const B=\"YWJj\"; POST" as *u8
151 let expected: *u8 = "PRE const B=\"AGFzbQEAAAA=\"; POST" as *u8
152 let out: *u8 = sys_mmap(GAT_CAP)
153 let pn: i64 = vw_slen(page)
154 let n: i64 = gpa_compose(page,pn,wasm,GPA_HEADER_BYTES,out,GAT_CAP)
155 gat_check("surrounding-bytes-and-native-base64",gpa_same(out,n,expected,vw_slen(expected)),count)
156 let again: *u8 = sys_mmap(GAT_CAP)
157 let an: i64 = gpa_compose(out,n,wasm,GPA_HEADER_BYTES,again,GAT_CAP)
158 gat_check("repeat-composition-byte-identical",gpa_same(out,n,again,an),count)
159 let dup: *u8 = "const B=\"AA==\"; const B=\"BB==\";" as *u8
160 gat_check("duplicate-slot-refused",(gpa_compose(dup,vw_slen(dup),wasm,GPA_HEADER_BYTES,out,GAT_CAP)<0) as i64,count)
161 gat_check("absent-slot-refused",(gpa_compose("none" as *u8,4,wasm,GPA_HEADER_BYTES,out,GAT_CAP)<0) as i64,count)
162 let broken: *u8 = "const B=\"AA==" as *u8
163 gat_check("unterminated-slot-refused",(gpa_compose(broken,vw_slen(broken),wasm,GPA_HEADER_BYTES,out,GAT_CAP)<0) as i64,count)
164 wasm[0]=1 as u8
165 gat_check("invalid-wasm-header-refused",(gpa_compose(page,pn,wasm,GPA_HEADER_BYTES,out,GAT_CAP)<0) as i64,count)
166 wasm[0]=0 as u8
167 out[0]=99 as u8
168 let caprc: i64 = gpa_compose(page,pn,wasm,GPA_HEADER_BYTES,out,1)
169 gat_check("output-cap-refuses-before-writing",((caprc<0) && (out[0]==(99 as u8))) as i64,count)
170 // Same native CLI dispatch, isolated real files. An existing scratch directory is refused.
171 if argc != 2 { return 2 }
172 if sys_mkdir(argv[1] as *u8,0x1ed) != 0 { return 2 }
173 if sys_chdir(argv[1] as *u8) != 0 { return 2 }
174 gat_pair_files(count)
175 fsx_write("base.html" as *u8,page,pn)
176 fsx_write("module.wasm" as *u8,wasm,GPA_HEADER_BYTES)
177 let av: *i64 = sys_mmap(64) as *i64
178 let ph: *u8 = sys_mmap(GPA_SHA_HEX+1)
179 let wh: *u8 = sys_mmap(GPA_SHA_HEX+1)
180 gpa_sha(page,pn,ph);gpa_sha(wasm,GPA_HEADER_BYTES,wh)
181 av[0]="nx_game_page_emit" as *u8 as i64;av[1]="rebind" as *u8 as i64
182 av[2]="base.html" as *u8 as i64;av[3]="module.wasm" as *u8 as i64
183 av[4]="stage.html" as *u8 as i64;av[5]=ph as i64;av[6]=wh as i64
184 var io: i64 = 0
185 if gpa_main(7,av)==0 {
186 let readn: i64 = vw_read("stage.html" as *u8,out,GAT_CAP)
187 io=gpa_same(out,readn,expected,vw_slen(expected))
188 }
189 gat_check("pinned-files-stage-exact",io,count)
190 gat_check("same-request-safe-retry",(gpa_main(7,av)==0) as i64,count)
191 av[5]="wrong" as *u8 as i64
192 let conflict: i64 = gpa_main(7,av)
193 let rn: i64 = vw_read("stage.html" as *u8,out,GAT_CAP)
194 gat_check("stale-source-pin-refuses-unchanged-output",((conflict==GPA_RC_CONFLICT) && (gpa_same(out,rn,expected,vw_slen(expected))==1)) as i64,count)
195 av[5]=ph as i64;av[6]="wrong" as *u8 as i64
196 let moduleconflict: i64 = gpa_main(7,av)
197 let modulen: i64 = vw_read("stage.html" as *u8,out,GAT_CAP)
198 gat_check("stale-module-pin-retains-output",((moduleconflict==GPA_RC_CONFLICT) && (gpa_same(out,modulen,expected,vw_slen(expected))==1)) as i64,count)
199 av[6]=wh as i64;av[4]="occupied.html" as *u8 as i64
200 fsx_write("occupied.html" as *u8,"retained" as *u8,8)
201 let occupied: i64 = gpa_main(7,av)
202 let occupiedn: i64 = vw_read("occupied.html" as *u8,out,GAT_CAP)
203 gat_check("different-output-refused-and-retained",((occupied==GPA_RC_CONFLICT) && (gpa_same(out,occupiedn,"retained" as *u8,8)==1)) as i64,count)
204 av[3]="missing.wasm" as *u8 as i64;av[4]="missing-output.html" as *u8 as i64
205 let missing: i64 = gpa_main(7,av)
206 let missingn: i64 = vw_read("missing-output.html" as *u8,out,GAT_CAP)
207 gat_check("missing-module-creates-no-output",((missing==GPA_RC_INPUT) && (missingn<0)) as i64,count)
208 wasm[0]=1 as u8
209 fsx_write("malformed.wasm" as *u8,wasm,GPA_HEADER_BYTES)
210 gpa_sha(wasm,GPA_HEADER_BYTES,wh)
211 av[3]="malformed.wasm" as *u8 as i64;av[4]="malformed-output.html" as *u8 as i64
212 let malformed: i64 = gpa_main(7,av)
213 let malformedn: i64 = vw_read("malformed-output.html" as *u8,out,GAT_CAP)
214 gat_check("pinned-malformed-module-creates-no-output",((malformed==GPA_RC_SHAPE) && (malformedn<0)) as i64,count)
215 let blocked: i64 = fxc_create("stage.html" as *u8,"bad" as *u8,3)
216 let keptn: i64 = vw_read("stage.html" as *u8,out,GAT_CAP)
217 gat_check("no-replace-retains-existing-output",((blocked==FXC_EXISTS) && (gpa_same(out,keptn,expected,vw_slen(expected))==1)) as i64,count)
218 let child1: i64 = sys_fork()
219 if child1 == 0 { if fxc_create("race.html" as *u8,"AAA" as *u8,3)==3 { sys_exit(0) }; sys_exit(1);return 1 }
220 let child2: i64 = sys_fork()
221 if child2 == 0 { if fxc_create("race.html" as *u8,"BBB" as *u8,3)==3 { sys_exit(0) }; sys_exit(1);return 1 }
222 let status1: *i64 = sys_mmap(8) as *i64
223 let status2: *i64 = sys_mmap(8) as *i64
224 var raceok: i64 = 0
225 if child1 > 0 { if child2 > 0 {
226 let waited1: i64 = sys_wait4(child1,status1,0)
227 let waited2: i64 = sys_wait4(child2,status2,0)
228 let r1: i64 = wait_exit_code(status1[0])
229 let r2: i64 = wait_exit_code(status2[0])
230 let racen: i64 = vw_read("race.html" as *u8,out,GAT_CAP)
231 if waited1 == child1 { if waited2 == child2 {
232 if r1 == 0 { if r2 == 1 { raceok=gpa_same(out,racen,"AAA" as *u8,3) } }
233 if r2 == 0 { if r1 == 1 { raceok=gpa_same(out,racen,"BBB" as *u8,3) } }
234 } }
235 } }
236 gat_check("competing-writers-one-winner-no-clobber",raceok,count)
237 gv_plan_finish(gat_plan,count)
238 return gv_verdict("PAGE-ARTIFACT-GATE" as *u8,count,"pinned packaging and pair identity; browser qualification separate" as *u8)
239}