code wiki / _hdl_build / nx_papers_index.nx

nx_papers_index.nx source

↩ module page · 321 lines · 20689 B

1// nx_papers_index.nx -- the Research Repository landing page, COMPILED FROM A REGISTRY (F1130). 2// 3// ★WHAT CHANGED AND WHY. This organ used to emit the index with one hardcoded paper_row() 4// call per paper, baked into the source. That is a rule-11 violation (data belongs in data, 5// not code): the list went stale on 2026-06-17, and adding a paper meant editing and 6// recompiling an organ. It also linked every paper into /wiki/, which is AUTH-GATED -- so 7// the "public research repository" was not publicly readable at all, and nothing that lives 8// only behind a login is citable. 9// 10// Now: rows come from a TSV registry and each row declares its own ACCESS. Adding a paper is 11// a data edit. Internal papers are listed honestly as access-controlled rather than rendered 12// as links that a reader cannot follow. 13// 14// nx_papers_index <registry.tsv> <out.html> 15// registry row: id \t access(public|internal) \t href \t title \t abstract \t result \t gates 16// 17// FAIL-CLOSED: an unreadable or empty registry REFUSES (exit 3) rather than emitting an empty 18// repository page -- a page saying "no papers" is indistinguishable from a broken read, and 19// silently publishing one would erase the repository. 20// 21// license_tier: ORIGINAL No hw writes (Rule 26). expect_exit: 0 22import "nx_syscalls.nx" 23import "nx_itoa_lib.nx" // shared MSB-first emitter (zero-alloc) 24 25const PX_COLS: i64 = 7 26const PX_CAP: i64 = 262144 27const PX_OUT: i64 = 524288 28const PX_TAB: i64 = 9 29const PX_NL: i64 = 10 30 31func px_len(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n } 32func px_puts(s: *u8) -> i64 { sys_write(1, s, px_len(s)); return 0 } 33// MIGRATED to the shared emitter (debt 1785563586). The old body mmapped a scratch buffer 34// per call and never freed it. At PAGE granularity that is 4096B leaked PER CALL -- the 35// defect that took 28.5GB of a 36GB host in nx_ts_lumadiff (2MB input, ~3.66M calls). 36// nxi_* is MSB-first, allocates NOTHING, and emits identical bytes including the sign. 37func px_num(v: i64) -> i64 { nxi_out(v); return 0 } 38func px_read(path: *u8, buf: *u8, cap: i64) -> i64 { 39 let fd: i64 = sys_openat_rd(path) 40 if fd < 0 { return 0 - 1 } 41 var n: i64 = 0 42 var go: i64 = 1 43 while go == 1 { 44 let base: i64 = buf as i64 45 let r: i64 = sys_read(fd, (base + n) as *u8, cap - n) 46 if r <= 0 { go = 0 } else { n = n + r } 47 if n >= cap { go = 0 } 48 } 49 sys_close(fd) 50 return n 51} 52// append a NUL-terminated literal 53func px_app(dst: *u8, off: i64, s: *u8) -> i64 { 54 var i: i64 = 0 55 var o: i64 = off 56 while s[i] != (0 as u8) { dst[o] = s[i]; o = o + 1; i = i + 1 } 57 return o 58} 59// append src[a..b) 60func px_appn(dst: *u8, off: i64, src: *u8, a: i64, b: i64) -> i64 { 61 var i: i64 = a 62 var o: i64 = off 63 while i < b { dst[o] = src[i]; o = o + 1; i = i + 1 } 64 return o 65} 66func px_eol(buf: *u8, n: i64, i: i64) -> i64 { 67 var e: i64 = i 68 var s: i64 = 1 69 while s == 1 { 70 if e >= n { s = 0 } else { if buf[e] == (PX_NL as u8) { s = 0 } else { e = e + 1 } } 71 } 72 return e 73} 74// split line [ls,le) into PX_COLS ranges; col[c*2],col[c*2+1]. Returns columns found. 75func px_cols(buf: *u8, ls: i64, le: i64, col: *i64) -> i64 { 76 var c: i64 = 0 77 var p: i64 = ls 78 while c < PX_COLS { 79 var q: i64 = p 80 var s: i64 = 1 81 while s == 1 { 82 if q >= le { s = 0 } else { if buf[q] == (PX_TAB as u8) { s = 0 } else { q = q + 1 } } 83 } 84 col[c*2] = p 85 col[c*2+1] = q 86 if q >= le { 87 c = c + 1 88 while c < PX_COLS { col[c*2] = le; col[c*2+1] = le; c = c + 1 } 89 return c 90 } 91 p = q + 1 92 c = c + 1 93 } 94 return c 95} 96func px_is(buf: *u8, a: i64, b: i64, lit: *u8) -> i64 { 97 let l: i64 = px_len(lit) 98 if b - a != l { return 0 } 99 var i: i64 = 0 100 while i < l { if buf[a+i] != lit[i] { return 0 } i = i + 1 } 101 return 1 102} 103 104// Append a non-negative integer INTO the page buffer. px_num writes to stdout, which cannot serve a 105// masthead that states the repository's own counts -- and a hand-typed count in a generated index is 106// exactly the kind of number that goes stale silently. 107func px_appnum(out: *u8, pos: i64, v: i64) -> i64 { 108 let t: *u8 = sys_mmap(28) 109 var m: i64 = v 110 var k: i64 = 0 111 if m <= 0 { t[0] = 48 as u8; k = 1 } else { 112 while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 } 113 } 114 var p: i64 = pos 115 var i: i64 = 0 116 while i < k { out[p] = t[k-1-i]; p = p + 1; i = i + 1 } 117 return p 118} 119 120// Find `lit` inside buf[a..b); returns its start index, or -1. 121// WHY THIS EXISTS: almost every findings row in the registry contains a literal HONEST: clause -- the 122// author's own statement of where the work is behind. Rendered as one undifferentiated paragraph, that 123// clause reads as a footnote to a boast. Splitting on it gives the limitation its OWN channel, which is 124// the only page decision here that could not be lifted from a generic template: it is derived from the 125// estate's cardinal discipline that a caveat is a first-class result, not a disclaimer. A paper with no 126// such clause is then conspicuous by its absence, which is the pressure we want on the next author. 127func px_find(buf: *u8, a: i64, b: i64, lit: *u8) -> i64 { 128 let l: i64 = px_len(lit) 129 if l <= 0 { return 0 - 1 } 130 if b - a < l { return 0 - 1 } 131 var i: i64 = a 132 while i <= b - l { 133 var j: i64 = 0 134 var m: i64 = 1 135 while j < l { if buf[i+j] != lit[j] { m = 0; j = l } else { j = j + 1 } } 136 if m == 1 { return i } 137 i = i + 1 138 } 139 return 0 - 1 140} 141 142func main(argc: i64, argv: *i64) -> i64 { 143 if argc < 3 { 144 px_puts("usage: nx_papers_index <registry.tsv> <out.html>\n" as *u8) 145 sys_exit(2); return 2 146 } 147 let reg: *u8 = sys_mmap(PX_CAP) 148 let rn: i64 = px_read(argv[1] as *u8, reg, PX_CAP - 16) 149 if rn <= 0 { 150 // FAIL-CLOSED: never publish an empty repository over a real one. 151 px_puts("PAPERS-INDEX REFUSED: registry unreadable or empty -> " as *u8) 152 px_puts(argv[1] as *u8) 153 px_puts("\n (an empty index is indistinguishable from a broken read; refusing to emit)\n" as *u8) 154 sys_exit(3); return 3 155 } 156 let out: *u8 = sys_mmap(PX_OUT) 157 var o: i64 = 0 158 o = px_app(out, o, "<!doctype html>\n<html lang=\"en\">\n<head>\n<meta charset=\"utf-8\">\n" as *u8) 159 o = px_app(out, o, "<meta name=\"viewport\" content=\"width=device-width,initial-scale=1\">\n" as *u8) 160 o = px_app(out, o, "<title>Nishi Research Repository</title>\n" as *u8) 161 o = px_app(out, o, "<meta name=\"description\" content=\"Papers compiled from measured gates. Every quantitative claim cites a re-runnable gate.\">\n" as *u8) 162 // ---- STYLESHEET (rebuilt 2026-08-06 to the estate's polish bar) -------------------------------- 163 // The palette is SEMANTIC, not decorative: proof/open/hold each carry a paired foreground+wash so a 164 // paper's ACCESS STATE is legible as colour and not only as words. Three type roles do real work -- 165 // a serif for reading, a sans for chrome, and a mono reserved for identifiers, labels and figures, 166 // which is what keeps a repository of measured claims from reading like a blog. Both themes are 167 // authored, and the data-theme overrides win over the media query in BOTH directions. 168 o = px_app(out, o, "<style>\n" as *u8) 169 o = px_app(out, o, ":root{--ground:#EEEFEA;--sunk:#E4E6DF;--card:#F7F8F3;--ink:#191C1A;--ink-soft:#4B4F4A;--ink-faint:#767B73;--proof:#3D6350;--proof-wash:#E0EAE4;--open:#2B3F6E;--open-wash:#E1E5EF;--hold:#8A4436;--hold-wash:#F1E3DF;--rule:#D8D5C8;--edge:#B4AF9C;--serif:\"Iowan Old Style\",\"Palatino Linotype\",Palatino,\"Book Antiqua\",Georgia,serif;--sans:ui-sans-serif,system-ui,-apple-system,\"Segoe UI\",Roboto,sans-serif;--mono:ui-monospace,\"SF Mono\",\"Cascadia Mono\",\"Roboto Mono\",Consolas,monospace;--measure:68ch;--page:1080px}\n" as *u8) 170 o = px_app(out, o, "@media (prefers-color-scheme:dark){:root{--ground:#13161A;--sunk:#0F1215;--card:#1B1E23;--ink:#E4E3DB;--ink-soft:#AEB0A7;--ink-faint:#7D807A;--proof:#84B096;--proof-wash:#19241D;--open:#94A8DC;--open-wash:#1D2534;--hold:#CE8577;--hold-wash:#2A1D1A;--rule:#33362F;--edge:#4A4D45}}\n" as *u8) 171 o = px_app(out, o, ":root[data-theme=\"dark\"]{--ground:#13161A;--sunk:#0F1215;--card:#1B1E23;--ink:#E4E3DB;--ink-soft:#AEB0A7;--ink-faint:#7D807A;--proof:#84B096;--proof-wash:#19241D;--open:#94A8DC;--open-wash:#1D2534;--hold:#CE8577;--hold-wash:#2A1D1A;--rule:#33362F;--edge:#4A4D45}\n" as *u8) 172 o = px_app(out, o, ":root[data-theme=\"light\"]{--ground:#EEEFEA;--sunk:#E4E6DF;--card:#F7F8F3;--ink:#191C1A;--ink-soft:#4B4F4A;--ink-faint:#767B73;--proof:#3D6350;--proof-wash:#E0EAE4;--open:#2B3F6E;--open-wash:#E1E5EF;--hold:#8A4436;--hold-wash:#F1E3DF;--rule:#D8D5C8;--edge:#B4AF9C}\n" as *u8) 173 o = px_app(out, o, "*{box-sizing:border-box}body{margin:0;background:var(--ground);color:var(--ink);font-family:var(--sans);font-size:17px;line-height:1.65;-webkit-font-smoothing:antialiased}\n" as *u8) 174 o = px_app(out, o, ".wrap{max-width:var(--page);margin:0 auto;padding:0 28px 110px}\n" as *u8) 175 o = px_app(out, o, ".mast{padding:72px 0 36px;border-bottom:2px solid var(--ink)}\n" as *u8) 176 o = px_app(out, o, ".mast-eyebrow{font-family:var(--mono);font-size:11px;letter-spacing:.16em;text-transform:uppercase;color:var(--ink-faint);margin:0 0 22px}\n" as *u8) 177 o = px_app(out, o, "h1{font-family:var(--serif);font-weight:400;font-size:clamp(2.3rem,5.4vw,3.9rem);line-height:1.05;letter-spacing:-.015em;text-wrap:balance;margin:0 0 22px;max-width:18ch}h1 em{font-style:italic;color:var(--open)}\n" as *u8) 178 o = px_app(out, o, ".thesis{font-family:var(--serif);font-size:clamp(1.08rem,2vw,1.3rem);line-height:1.5;color:var(--ink-soft);max-width:58ch;margin:0 0 30px}\n" as *u8) 179 o = px_app(out, o, ".mast-meta{display:flex;flex-wrap:wrap;gap:10px 30px;font-family:var(--mono);font-size:11.5px;letter-spacing:.06em;text-transform:uppercase;color:var(--ink-faint)}.mast-meta b{color:var(--ink-soft);font-weight:600}\n" as *u8) 180 o = px_app(out, o, ".paper{padding:34px 0;border-bottom:1px solid var(--rule);display:grid;grid-template-columns:92px 1fr;gap:0 20px}\n" as *u8) 181 o = px_app(out, o, ".pid{font-family:var(--mono);font-size:11px;letter-spacing:.12em;color:var(--edge);padding-top:8px}.pbody{min-width:0}\n" as *u8) 182 o = px_app(out, o, ".paper h2{font-family:var(--serif);font-weight:400;font-size:clamp(1.25rem,2.4vw,1.6rem);line-height:1.2;letter-spacing:-.01em;margin:0 0 10px;text-wrap:balance}\n" as *u8) 183 o = px_app(out, o, ".paper h2 a{color:var(--ink);text-decoration-thickness:1px;text-underline-offset:3px}.paper h2 a:hover{color:var(--open)}\n" as *u8) 184 o = px_app(out, o, ".tag{display:inline-block;font-family:var(--mono);font-size:9.5px;letter-spacing:.1em;text-transform:uppercase;font-weight:600;padding:3px 8px;border-radius:2px;margin-left:8px;vertical-align:.28em;white-space:nowrap;background:var(--hold-wash);color:var(--hold)}.tag.open{background:var(--open-wash);color:var(--open)}\n" as *u8) 185 o = px_app(out, o, ".paper p{max-width:var(--measure);margin:0 0 12px;color:var(--ink-soft);font-size:.97rem}\n" as *u8) 186 o = px_app(out, o, ".lbl{display:block;font-family:var(--mono);font-size:10px;letter-spacing:.14em;text-transform:uppercase;color:var(--ink-faint);margin-bottom:5px}\n" as *u8) 187 o = px_app(out, o, ".res{border-left:3px solid var(--proof);padding-left:16px;margin:16px 0 14px;max-width:var(--measure)}.res p{margin:0;color:var(--ink)}\n" as *u8) 188 o = px_app(out, o, ".limit{border-left:3px solid var(--hold);padding-left:16px;margin:14px 0;max-width:var(--measure)}.limit p{margin:0;color:var(--ink-soft);font-size:.93rem}.limit .lbl{color:var(--hold)}\n" as *u8) 189 o = px_app(out, o, ".nolimit{font-family:var(--mono);font-size:10px;letter-spacing:.12em;text-transform:uppercase;color:var(--edge);margin:14px 0}\n" as *u8) 190 o = px_app(out, o, ".gate{font-size:.86rem;color:var(--ink-faint)}.gate code{font-family:var(--mono);font-size:.92em}\n" as *u8) 191 o = px_app(out, o, "a{color:var(--open);text-decoration-thickness:1px;text-underline-offset:2px}a:focus-visible{outline:2px solid var(--open);outline-offset:3px;border-radius:2px}\n" as *u8) 192 o = px_app(out, o, "footer{margin-top:44px;padding-top:22px;border-top:2px solid var(--ink);color:var(--ink-faint);font-size:.86rem}footer p{max-width:var(--measure);margin:0 0 12px}footer strong{color:var(--ink-soft)}\n" as *u8) 193 o = px_app(out, o, "@media (max-width:640px){.wrap{padding:0 20px 72px}.mast{padding-top:48px}.paper{grid-template-columns:1fr;gap:8px}.pid{padding-top:0}}\n" as *u8) 194 // <main>, not <div>: nx_page_verify flagged the missing landmark when this was a bare div, and a 195 // repository that grades everyone else's honesty does not get to ship an accessibility regression. 196 o = px_app(out, o, "</style>\n</head>\n<body>\n<main class=\"wrap\">\n" as *u8) 197 let col: *i64 = sys_mmap(PX_COLS * 2 * 8) as *i64 198 199 // PRE-PASS. The masthead states the repository's OWN counts, so they must be known before it is 200 // emitted. Counting the registry twice is cheaper than buffering the header, and it keeps the 201 // figures DERIVED -- a hand-typed count inside a generated page is a number that goes stale in 202 // silence, which is the one thing this repository exists to refuse. 203 var pre_rows: i64 = 0 204 var pre_pub: i64 = 0 205 var pre_lim: i64 = 0 206 var pi: i64 = 0 207 while pi < rn { 208 let ple: i64 = px_eol(reg, rn, pi) 209 if ple > pi { 210 px_cols(reg, pi, ple, col) 211 if col[1] > col[0] { 212 pre_rows = pre_rows + 1 213 if px_is(reg, col[2], col[3], "public" as *u8) == 1 { pre_pub = pre_pub + 1 } 214 if px_find(reg, col[10], col[11], "HONEST:" as *u8) >= 0 { pre_lim = pre_lim + 1 } 215 } 216 } 217 pi = ple + 1 218 } 219 220 o = px_app(out, o, "<header class=\"mast\">\n<p class=\"mast-eyebrow\">Nishi Research &middot; compiled from measured gates</p>\n" as *u8) 221 o = px_app(out, o, "<h1>Every number here <em>re-runs</em>.</h1>\n" as *u8) 222 o = px_app(out, o, "<p class=\"thesis\">Each quantitative claim in this repository cites a re-runnable sovereign gate. No claim exceeds its measurement, every paper states plainly where it is behind, and this index is generated from a registry rather than hand-maintained.</p>\n" as *u8) 223 o = px_app(out, o, "<div class=\"mast-meta\"><span><b>Papers</b> " as *u8) 224 o = px_appnum(out, o, pre_rows) 225 o = px_app(out, o, "</span><span><b>Publicly citable</b> " as *u8) 226 o = px_appnum(out, o, pre_pub) 227 o = px_app(out, o, "</span><span><b>Declaring a limitation</b> " as *u8) 228 o = px_appnum(out, o, pre_lim) 229 o = px_app(out, o, " of " as *u8) 230 o = px_appnum(out, o, pre_rows) 231 o = px_app(out, o, "</span><span><b>Compiled by</b> nx_papers_index</span><span><b>Source</b> registry, not hand-kept</span></div>\n</header>\n" as *u8) 232 var i: i64 = 0 233 var rows: i64 = 0 234 var pub: i64 = 0 235 while i < rn { 236 let le: i64 = px_eol(reg, rn, i) 237 if le > i { 238 px_cols(reg, i, le, col) 239 if col[1] > col[0] { 240 rows = rows + 1 241 let isPublic: i64 = px_is(reg, col[2], col[3], "public" as *u8) 242 if isPublic == 1 { pub = pub + 1 } 243 // The paper ID rides its own left rail rather than being glued to the title. That is a 244 // structural device carrying real information -- a citable identifier -- not decoration, 245 // and it lets the title be read as a sentence. BOTH access states get a semantic pill; 246 // marking only the restricted ones leaves the reader inferring the default. 247 o = px_app(out, o, "<section class=\"paper\">\n<div class=\"pid\">" as *u8) 248 o = px_appn(out, o, reg, col[0], col[1]) 249 o = px_app(out, o, "</div>\n<div class=\"pbody\">\n<h2>" as *u8) 250 if isPublic == 1 { 251 o = px_app(out, o, "<a href=\"" as *u8) 252 o = px_appn(out, o, reg, col[4], col[5]) 253 o = px_app(out, o, "\">" as *u8) 254 o = px_appn(out, o, reg, col[6], col[7]) 255 o = px_app(out, o, "</a><span class=\"tag open\">public</span>" as *u8) 256 } else { 257 o = px_appn(out, o, reg, col[6], col[7]) 258 o = px_app(out, o, "<span class=\"tag\">access-controlled</span>" as *u8) 259 } 260 o = px_app(out, o, "</h2>\n<p>" as *u8) 261 o = px_appn(out, o, reg, col[8], col[9]) 262 o = px_app(out, o, "</p>\n" as *u8) 263 // Split the findings at the author's own HONEST: marker. What precedes it is the result; 264 // what follows is the limitation, and it gets its own block rather than trailing the 265 // sentence that boasts. A row with no marker prints a quiet mono line saying so -- an 266 // absent caveat should be VISIBLE, not indistinguishable from a modest one. 267 let hpos: i64 = px_find(reg, col[10], col[11], "HONEST:" as *u8) 268 var resEnd: i64 = col[11] 269 var limStart: i64 = col[11] 270 if hpos >= 0 { 271 // Trim the seam BOTH ways. Splitting on a marker leaves the result with a trailing 272 // space and the limitation with a leading one; rendered as separate blocks that reads 273 // as a typo rather than a cut. The marker is 7 bytes. 274 resEnd = hpos 275 var tw: i64 = 1 276 while tw == 1 { 277 if resEnd <= col[10] { tw = 0 } else { 278 if reg[resEnd-1] == (32 as u8) { resEnd = resEnd - 1 } else { tw = 0 } 279 } 280 } 281 limStart = hpos + 7 282 var lw: i64 = 1 283 while lw == 1 { 284 if limStart >= col[11] { lw = 0 } else { 285 if reg[limStart] == (32 as u8) { limStart = limStart + 1 } else { lw = 0 } 286 } 287 } 288 } 289 o = px_app(out, o, "<div class=\"res\"><span class=\"lbl\">Headline measured result</span><p>" as *u8) 290 o = px_appn(out, o, reg, col[10], resEnd) 291 o = px_app(out, o, "</p></div>\n" as *u8) 292 if hpos >= 0 { 293 o = px_app(out, o, "<div class=\"limit\"><span class=\"lbl\">Where this is behind</span><p>" as *u8) 294 o = px_appn(out, o, reg, limStart, col[11]) 295 o = px_app(out, o, "</p></div>\n" as *u8) 296 } else { 297 o = px_app(out, o, "<p class=\"nolimit\">No limitation clause declared</p>\n" as *u8) 298 } 299 o = px_app(out, o, "<p class=\"gate\"><span class=\"lbl\">Reproducibility</span>" as *u8) 300 o = px_appn(out, o, reg, col[12], col[13]) 301 o = px_app(out, o, " &mdash; sovereign gates (<code>nx_cc</code> to <code>nxasm</code>, no gcc); re-run to reproduce every number.</p>\n</div>\n</section>\n" as *u8) 302 } 303 } 304 i = le + 1 305 } 306 307 o = px_app(out, o, "<footer>\n<p><strong>Doctrine.</strong> Compiled from measured gates; cite-or-refuse; no claim exceeds its gate; honest about where we are behind. For a non-novel capability the bar is stricter: the implementation is fully sovereign <em>and</em> the open step is a head-to-head against an independent reference, named rather than skipped.</p>\n" as *u8) 308 o = px_app(out, o, "<p>Papers marked <em>access-controlled</em> live behind the internal wiki and are listed for completeness; they are not publicly citable until republished.</p>\n" as *u8) 309 o = px_app(out, o, "<p>Generated by <code>nx_papers_index</code> from <code>knowledge/registry/papers_index.tsv</code>. Adding a paper is a data edit, not a code change.</p>\n</footer>\n</main>\n</body>\n</html>\n" as *u8) 310 311 let fd: i64 = sys_openat_wr(argv[2] as *u8, 0x1a4) 312 if fd < 0 { px_puts("PAPERS-INDEX IO: cannot open output\n" as *u8); sys_exit(4); return 4 } 313 sys_write(fd, out, o) 314 sys_close(fd) 315 px_puts("PAPERS-INDEX OK rows=" as *u8); px_num(rows) 316 px_puts(" public=" as *u8); px_num(pub) 317 px_puts(" bytes=" as *u8); px_num(o) 318 px_puts(" -> " as *u8); px_puts(argv[2] as *u8); px_puts("\n" as *u8) 319 sys_exit(0) 320 return 0 321}