nx_pageref_lib.nx source
↩ module page · 219 lines · 10054 B
1// nx_pageref_lib.nx -- THE ASSET-REFERENCE VOCABULARY: which attributes on a page name an artifact the
2// browser will fetch, and which file extensions must never answer HTML. ONE owner, imported by BOTH the
3// verifier (nx_page_verify) and its in-process gate (nx_pageref_gate) -- the nx_sitesweep_lib shape, for
4// the same reason: the piece of judgement must be biteable without a fork or a network.
5//
6// WHY THIS EXISTS (measured 2026-08-26, debt 1787786411). nx_page_verify reported checked=2 on the live
7// /exceed/vrm/seed-san, a page carrying FOUR data-glb= mesh references. Its extractor knew src= (both
8// quote styles, plus bare) and <link href=, and had never known data-glb= -- an attribute nx_absent shows
9// is emitted from exactly ONE site estate-wide (nx_asset_page.nx:432, matches=1 coverage_complete=1
10// corpus_complete=1). By that organ's own banked law: A REF THE EXTRACTOR CANNOT SEE IS A REF THE VERDICT
11// SILENTLY ACQUITS. Four mesh refs per asset page were being acquitted without ever being fetched.
12//
13// EVERY LENGTH HERE IS DERIVED FROM ITS LITERAL, NEVER HAND-COUNTED. A hand-counted length beside a
14// string literal is a second copy of that literal's shape and the two drift silently -- change the string,
15// forget the number, and the parser reads the wrong window while still compiling.
16//
17// THE EXTENSION MATCH IS EXACT TO END-OF-URL, NOT A PREFIX AT THE DOT. The incumbent tested
18// sw_starts(aurl, dot, ".png"), which also accepts .pngx; exactness costs one comparison and is
19// bite-proven here by a neg-control.
20// license_tier: ORIGINAL No hw writes (Rule 26).
21
22// byte constants -- named, because a bare 60 in a branch is a literal nobody can grep for
23const PR_DQ: i64 = 34 // "
24const PR_SQ: i64 = 39 // '
25const PR_DOT: i64 = 46 // .
26const PR_LT: i64 = 60 // <
27const PR_BANG: i64 = 33 // the ! that opens a doctype declaration
28
29func pr_len(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n }
30
31// does buf[i..] start with the NUL-terminated lit, without running past n?
32func pr_starts(buf: *u8, n: i64, i: i64, lit: *u8) -> i64 {
33 var k: i64 = 0
34 while lit[k] != (0 as u8) {
35 if i + k >= n { return 0 }
36 if buf[i+k] != lit[k] { return 0 }
37 k = k + 1
38 }
39 return 1
40}
41
42// ---- THE ATTRIBUTE TABLE -------------------------------------------------------------------------
43// Adding a new asset-ref attribute is a DATA change here, not a new branch in a consumer. Both consumers
44// read this table, so the vocabulary cannot be right in one organ and wrong in the other.
45func pr_nattr() -> i64 { return 2 }
46func pr_attr(k: i64) -> *u8 {
47 if k == 0 { return "src=" as *u8 }
48 if k == 1 { return "data-glb=" as *u8 }
49 return "" as *u8
50}
51
52// A QUOTED asset-ref attribute at position i?
53// returns the attribute index (>= 0), or (0 - 1) for no hit
54// out[0] = bytes to skip from i to reach the first byte of the value (attr length + the quote)
55// out[1] = the closing delimiter, i.e. whichever quote opened the attribute
56// The caller still owns the in-tag and raw-text guards: whether a byte run sits inside a tag is a
57// property of the PAGE, not of the vocabulary, and keeping it out here is what makes this pure.
58func pr_attr_hit(buf: *u8, n: i64, i: i64, out: *i64) -> i64 {
59 var k: i64 = 0
60 while k < pr_nattr() {
61 let a: *u8 = pr_attr(k)
62 if pr_starts(buf, n, i, a) == 1 {
63 let al: i64 = pr_len(a)
64 if i + al < n {
65 let q: i64 = buf[i + al] as i64
66 if q == PR_DQ { out[0] = al + 1; out[1] = PR_DQ; return k }
67 if q == PR_SQ { out[0] = al + 1; out[1] = PR_SQ; return k }
68 }
69 }
70 k = k + 1
71 }
72 return 0 - 1
73}
74
75// ---- DECLARED ASSETS (2026-09-05) ---------------------------------------------------------------------
76// A page may DECLARE the artifact its own script will fetch: <meta name="nishi-<kind>" content="/path">
77// /world/rigview declares <meta name="nishi-nxa" content="/world/ref9d.nxa"> and the verifier read it
78// GREEN having checked ONE advert PNG (measured 2026-09-05: checked=1 against a 1.7 MB script-fetched rig),
79// because nothing in this vocabulary named a script-fetched asset. A GREEN on a page whose subject was
80// never fetched is the vacuous verdict wearing the verifier's name. The rule lives here so the verifier and
81// its gate read ONE table; the caller still owns the in-tag guard.
82// at i: `content=` + a quote, and the enclosing tag (walked back to '<', bounded) is a <meta whose bytes
83// before i carry name="nishi- or name='nishi- -> PR_ATTR_DECLARED with out[0]/out[1] as pr_attr_hit
84// anything else -> (0 - 1). A description meta, an og:image meta, a div with a content attribute: none hit.
85const PR_ATTR_DECLARED: i64 = 2
86const PR_TAG_LOOKBACK: i64 = 512
87// Asset declarations are typed; identity metadata is not a URL.
88func pr_declared_type(buf: *u8, n: i64, at: i64, end: i64) -> i64 {
89 if at < 0 || end < at || end > n { return 0 }
90 let prefix: *u8 = "nishi-" as *u8
91 let pn: i64 = pr_len(prefix)
92 if pr_starts(buf,end,at,prefix) == 0 { return 0 }
93 let kind: i64 = at+pn
94 if end-kind == pr_len("asset" as *u8) {
95 if pr_starts(buf,end,kind,"asset" as *u8) == 1 { return 1 }
96 }
97 var k: i64 = 0
98 while k < pr_nbinext() {
99 let ext: *u8 = pr_binext(k)
100 let en: i64 = pr_len(ext)
101 if end-kind == en-1 {
102 if pr_starts(buf,end,kind,ext+1) == 1 { return 1 }
103 }
104 k = k+1
105 }
106 return 0
107}
108
109func pr_declared_hit(buf: *u8, n: i64, i: i64, out: *i64) -> i64 {
110 let a: *u8 = "content=" as *u8
111 if pr_starts(buf, n, i, a) == 0 { return 0 - 1 }
112 let al: i64 = pr_len(a)
113 if i + al >= n { return 0 - 1 }
114 let q: i64 = buf[i + al] as i64
115 if q != PR_DQ { if q != PR_SQ { return 0 - 1 } }
116 var b: i64 = i
117 var back: i64 = 0
118 var open: i64 = 0 - 1
119 while back < PR_TAG_LOOKBACK {
120 // read the byte BEFORE the floor check: a tag opening at offset 0 (every fixture, any page fragment) was
121 // invisible to the first cut, which exited at b == 0 without reading it -- nx_pageref_gate caught it (2026-09-05)
122 if buf[b] == (PR_LT as u8) { open = b; back = PR_TAG_LOOKBACK } else {
123 if b <= 0 { back = PR_TAG_LOOKBACK } else { b = b - 1; back = back + 1 }
124 }
125 }
126 if open < 0 { return 0 - 1 }
127 if pr_starts(buf, n, open, "<meta" as *u8) == 0 { return 0 - 1 }
128 var k: i64 = open
129 var hit: i64 = 0
130 while k < i {
131 if pr_starts(buf,i,k,"name=" as *u8) == 1 {
132 let qs: i64 = k+pr_len("name=" as *u8)
133 if qs < i {
134 let nq: i64 = buf[qs] as i64
135 if nq == PR_DQ || nq == PR_SQ {
136 var ne: i64 = qs+1
137 while ne < i { if (buf[ne] as i64) == nq { break }; ne = ne+1 }
138 if ne < i { hit = pr_declared_type(buf,n,qs+1,ne) }
139 k = ne
140 }
141 }
142 }
143 k = k+1
144 }
145 if hit == 0 { return 0 - 1 }
146 out[0] = al + 1
147 out[1] = q
148 return PR_ATTR_DECLARED
149}
150
151// ---- THE "MUST NOT ANSWER HTML" EXTENSION TABLE ---------------------------------------------------
152// A 200 that returns an HTML body where an artifact was promised is the 404-fallback class: the edge
153// serves an error page with status 200 and the browser renders nothing. The verifier already knew
154// .png/.jpg/.css/.js. Meshes and wasm were absent -- and meshes and wasm are exactly what the /exceed
155// asset pages are made of, so the one page family that needed this check was the one it could not make.
156func pr_nbinext() -> i64 { return 9 }
157func pr_binext(k: i64) -> *u8 {
158 if k == 0 { return ".png" as *u8 }
159 if k == 1 { return ".jpg" as *u8 }
160 if k == 2 { return ".css" as *u8 }
161 if k == 3 { return ".js" as *u8 }
162 if k == 4 { return ".glb" as *u8 }
163 if k == 5 { return ".vrm" as *u8 }
164 if k == 6 { return ".wasm" as *u8 }
165 if k == 7 { return ".nxdv" as *u8 }
166 if k == 8 { return ".nxa" as *u8 } // the rig container a page declares through meta nishi-nxa (2026-09-05)
167 return "" as *u8
168}
169
170// offset of the LAST dot in a NUL-terminated url, or (0 - 1) when it has none
171func pr_lastdot(url: *u8) -> i64 {
172 var j: i64 = 0
173 var dot: i64 = 0 - 1
174 while url[j] != (0 as u8) {
175 if (url[j] as i64) == PR_DOT { dot = j }
176 j = j + 1
177 }
178 return dot
179}
180
181// which extension class does this url declare? index into pr_binext, or (0 - 1) for none.
182func pr_ext_class(url: *u8) -> i64 {
183 let dot: i64 = pr_lastdot(url)
184 if dot < 0 { return 0 - 1 }
185 let ul: i64 = pr_len(url)
186 var k: i64 = 0
187 while k < pr_nbinext() {
188 let e: *u8 = pr_binext(k)
189 let el: i64 = pr_len(e)
190 if dot + el == ul {
191 if pr_starts(url, ul, dot, e) == 1 { return k }
192 }
193 k = k + 1
194 }
195 return 0 - 1
196}
197
198// does this body look like an HTML document? Structural, and deliberately NOT spelled with a doctype
199// string literal: testing for '<' followed by '!' accepts <!doctype and <!DOCTYPE from one rule instead
200// of two literals that can drift apart, and it keeps a '!' out of a string literal, which the nx_cc
201// lexer rejects.
202func pr_body_is_html(body: *u8, n: i64) -> i64 {
203 if n <= 0 { return 0 }
204 if (body[0] as i64) != PR_LT { return 0 }
205 if n < 2 { return 0 }
206 if (body[1] as i64) == PR_BANG { return 1 }
207 if pr_starts(body, n, 0, "<html" as *u8) == 1 { return 1 }
208 if pr_starts(body, n, 0, "<HTML" as *u8) == 1 { return 1 }
209 return 0
210}
211
212// THE VERDICT: an artifact url whose body is an HTML document is the 404-fallback class.
213// 1 = BROKEN-by-fallback, 0 = nothing to say. Both conjuncts are required: an .html ref that answers
214// HTML is correct, and a .glb that answers glTF bytes is correct.
215func pr_is_fallback(url: *u8, body: *u8, n: i64) -> i64 {
216 if pr_body_is_html(body, n) == 0 { return 0 }
217 if pr_ext_class(url) < 0 { return 0 }
218 return 1
219}