code wiki / (root) / nx_pageref_lib.nx

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}