code wiki / _hdl_build / nx_sites_daemon_v2.nx

nx_sites_daemon_v2.nx source

↩ module page · 2241 lines · 155452 B

1// nx_sites_daemon_v2.nx -- sovereign multi-vhost HTTPS daemon, generation 2. 2// 3// Operator 2026-06-09: "nishi video from the hardware layer up ... hosted 4// again on nishifamily.com/video ... improve anything on the website hosting 5// path to S-class exceed" + "less lag for ukrainians/belarusians" + "record 6// circles like telegram, private/romantic ones auto-archived for review." 7// 8// What changed vs runtime/bin/nx_sites_daemon.nx (v1) and WHY (each is a 9// measured v1 defect, see gates): 10// D1 CHUNKED TLS SEND -- v1's app_send built ONE record for the whole 11// payload; RFC 8446 5.1 caps record plaintext at 16384, so v1 could 12// not serve ANY asset over ~16.3KB (the /video page is 19KB). 13// v2 sends everything through nx_tls13_app_send_fd (gated). 14// D2 RECORD-FRAMED RECEIVE -- v1 assumed one sys_read = one TLS record; 15// v2 reads with nx_tls13_read_record_from_fd and reassembles the 16// request across records until CRLFCRLF (bounded). 17// D3 HOT HOSTING WITH FALLTHROUGH -- v1's hr_serve 404'd on a missing 18// file, so nishifamily.com could not live in sites.conf without 19// killing /wiki. v2 uses hr_serve2: file hit = hot serve (keep-alive, 20// bounds-checked); MISS = fall through to the legacy baked routing. 21// andelinwest keeps REAL 404s (no placeholder bleed). 22// D4 WSS -- /signal/* upgrade requests become a TLS-terminating pump to 23// the loopback N-party signaling daemon (nx_signaling_v2 on 24// 127.0.0.1:8445). wss://nishifamily.com/signal/<room> on :8443 -- 25// no new public port, secure-origin so getUserMedia works (the root 26// cause the old :8282 HTTP video room died). 27// D5 CIRCLES -- POST /video/circle?room=R&from=F&priv=0|1 streams the 28// browser-recorded webm body (record by record) to the circles store; 29// priv=1 -> circles/private (auto-archive for later review), 30// else circles/public. GET /video/circles?room=R lists a room's 31// public circles as JSON; GET /video/circle/<name> plays one back 32// (8MB serve buffer). Storage is OUTSIDE the doc root. 33// 34// Composes (all KAT'd/gated): nx_tls13_* session + record stack, 35// nx_tls13_app_send_fd (gate: 10/10), nx_host_router v2 (gate: 14/14), 36// nx_poll, nx_sites_telemetry, wiki engine handles. 37// license_tier: ORIGINAL 38 39import "nx_syscalls.nx" 40import "nx_connect.nx" // bounded connect: a raw sys_connect hangs ~127s on a black-holed host 41import "nx_csprng.nx" 42import "nx_http_server.nx" 43import "nx_tls13_server_session.nx" 44import "nx_tls13_server_session_run.nx" 45import "nx_tls13_server_session_app_data.nx" 46import "nx_tls13_read_record_from_fd.nx" 47import "nx_sites_telemetry.nx" 48import "nx_poll.nx" 49import "nx_deadline_lib.nx" // the CONSUMER half of the deadline stamp below: dl_wait_ms is the clamp 50import "nx_itoa_lib.nx" // shared integer emitter (nxi_out): the edge had none, and a bind failure that cannot print its port is a silent exit 51import "wiki/nx_wiki_status.nx" 52import "wiki/nx_wiki_article.nx" 53import "wiki/nx_wiki_queue.nx" 54import "_hdl_build/nx_host_router.nx" 55import "_hdl_build/nx_proxy_route.nx" 56import "_hdl_build/nx_adnet_slot.nx" 57import "_hdl_build/nx_adnet_view.nx" 58import "_hdl_build/nx_adnet_dash.nx" 59import "_hdl_build/nx_adnet_submit.nx" 60import "_hdl_build/nx_adnet_campaign.nx" // advertiser INTAKE half of the ad lane (merged from the laptop authoring tree 2026-09-03) 61import "_hdl_build/nx_adnet_apply.nx" 62import "_hdl_build/nx_adnet_selfserve.nx" 63import "_hdl_build/nx_tls13_app_send_fd.nx" 64import "_hdl_build/nx_nv1.nx" 65// Route B (SNI-aware TLS, ported from the gated runtime/bin/nx_sites_daemon.nx): peek the 66// cleartext ClientHello SNI, present the matching per-domain wildcard chain. Composes the 67// gated scs_pick_from_clienthello (nx_sites_sni_cert_gate 12/12 unit + 4/4 e2e). 68import "nx_sni_cert_select.nx" 69// ONE RULER for "may this edge refusal advise a retry?", extracted 2026-09-04 so nx_edge_refusal_gate can 70// prove it. The decision shipped inline the day before, which made it correct and untestable at once: a 71// gate cannot import a top-level programme, so a lib is the only shape a referee can reach. 72import "nx_edge_refusal_lib.nx" 73const NX_MAGIC_8192: i64 = 8192 74const NX_MAGIC_8445: i64 = 8445 75const NX_MAGIC_16000: i64 = 16000 76const NX_MAGIC_65536: i64 = 65536 77const NX_MAGIC_16384: i64 = 16384 78const NX_MAGIC_60000: i64 = 60000 79const NX_MAGIC_51850: i64 = 51850 80const NX_MAGIC_4096: i64 = 4096 81const NX_MAGIC_1048576: i64 = 1048576 82const NX_MAGIC_262144: i64 = 262144 83const NX_MAGIC_131072: i64 = 131072 84const NX_MAGIC_9091: i64 = 9091 85// ---- REVERSE-PROXY BACKEND PORTS, NAMED FOR THE SERVICE THEY REACH (2026-08-14) ---- 86// These were all value-restating consts of the NX_MAGIC_<digits> shape -- names that repeat the number 87// and tell a reader nothing about which backend is on the other end. (Stated as a rule rather than as a 88// list of the old identifiers on purpose: a list goes stale, and spelling the old names here would make 89// this comment match any future sweep for them.) This is the worst place in the estate for that pattern: the 90// numbers are adjacent (18791/18792/18793/18794), they sit in adjacent routing branches, and at the 91// CALL SITE they are indistinguishable. Swapping two of them would route /hub to the torrent gateway 92// and /gen to the wiki, and a proxy call whose last argument is one of those value-named consts would 93// not look wrong to a reviewer -- while one naming the hub gateway would. 94// (This comment deliberately does NOT reproduce the old call line verbatim. Writing it out re-armed 95// the estate's documented trap on the first attempt: the rename edit came back AMBIGUOUS because the 96// explanation of the defect had become a second match for it. PROSE IS SOURCE BYTES TOO.) 97// NO GUESSING WAS INVOLVED: every purpose below is taken from the routing comment already written 98// beside its own call site. The file already knew these names; it just was not using them, and it was 99// naming NX_SD2_PORT = 8443 correctly three lines further down the whole time. 100// 101// STATE OF THIS CHANGE, STATED EXACTLY -- SOURCE ONLY, NOT PROMOTED: 102// PROVEN: the rename is COMPLETE and CONSISTENT. Zero value-named port consts remain anywhere in 103// _hdl_build (corpus_complete=1) and the file compiles, so there are no dangling references. The 104// values are unchanged by construction -- same digits, new names. 105// PROVEN: byte-neutrality, by A/B on this exact source. The baseline was not banked before editing -- 106// a real process error -- so it was recovered the only honest way: the renames were REVERTED in 107// place (comments left untouched, so the experiment isolates the rename alone) and rebuilt, then 108// re-applied and rebuilt. Both builds are sha cbf685fc, 825,784 bytes. IDENTICAL. The rename emits 109// the same machine code, and -- the part that actually mattered -- no port value was mis-transcribed, 110// because a swapped number would have been a different constant and a different sha. 111// The 10,304-byte growth over the PREVIOUSLY-BUILT artifact is therefore entirely another seat's 112// uncompiled work, not this change: that artifact already differed from the promoted binary by 113// 22,288 bytes before this edit existed. 114// STILL NOT PROMOTED, and now for a different and better reason. This change is proven inert, but the 115// staged binary also carries that other seat's uncompiled changes, which are not mine to ship on the 116// daemon that serves every site. Promoting would smuggle unreviewed work behind a proven-neutral one. 117// WHOEVER OWNS THOSE CHANGES SHIPS THEM; this rename rides along at zero risk once they do. 118const NX_SD2_PORT_GALLERY_BRIDGE: i64 = 18190 // /gallery -> bridge -> tunnel -> workstation gw:18091 -> gallery:18090 119const NX_SD2_PORT_WIKI_GATEWAY: i64 = 18791 // /wiki -> OPAQUE-gated wiki gateway 120const NX_SD2_PORT_HUB_GATEWAY: i64 = 18792 // /hub -> maturity-leveled hub gateway 121const NX_SD2_PORT_TORRENT_GATEWAY: i64 = 18793 // /torrent -> OWNER-gated acquirer gateway -> daemon:8097 122const NX_SD2_PORT_GEN_GATEWAY: i64 = 18794 // /gen -> gen gateway -> orchestrator:18795 -> laptop 5080 123const NX_SD2_PORT_STUDIO: i64 = 18099 // /studio -> NAS-local operator-only gated daemon 124const NX_SD2_PORT_READER: i64 = 8791 // /library AND /media -> the SAME auth-walled reader, keeper-supervised 125 126const NX_SD2_PORT: i64 = 8443 127const NX_SD2_BUDGET: i64 = 100000000 128const NX_SD2_MAX_CHILDREN: i64 = 64 129const NX_SD2_CERT_PATH: *u8 = "/volume1/homes/elderwesto/nishihost/certs/le_fullchain.der" as *u8 130const NX_SD2_PRIV_PATH: *u8 = "/volume1/homes/elderwesto/nishihost/certs/le_ecdsa_key.bin" as *u8 131// Route B: per-domain wildcard chains (leaf-first concat-DER + 32-byte P-256 scalar), the SAME 132// files nx_cert_autorenew writes on every renewal (le_<label>_*) -- loading them here RECONNECTS 133// the renewal outputs to the live edge. PAIRED fail-safe: if EITHER file of a pair is absent or 134// malformed, that domain serves the legacy generic pair (never a mismatched cert/key). 135const NX_SD2_CERT_NISHI: *u8 = "/volume1/homes/elderwesto/nishihost/certs/le_nishifamily_fullchain.der" as *u8 136const NX_SD2_PRIV_NISHI: *u8 = "/volume1/homes/elderwesto/nishihost/certs/le_nishifamily_ecdsa_key.bin" as *u8 137const NX_SD2_CERT_ANDELIN: *u8 = "/volume1/homes/elderwesto/nishihost/certs/le_andelinwest_fullchain.der" as *u8 138const NX_SD2_PRIV_ANDELIN: *u8 = "/volume1/homes/elderwesto/nishihost/certs/le_andelinwest_ecdsa_key.bin" as *u8 139// MSG_PEEK (recvfrom flag 0x2): read the cleartext ClientHello WITHOUT consuming it, so the 140// proven handshake re-reads the same bytes -> the SNI peek is invisible to nx_tls13_server_session_run. 141const NX_SD2_MSG_PEEK: i64 = 2 142const NX_SD2_SNI_PEEK_CAP: i64 = 8192 143// DEADLINE PROPAGATION (2026-09-03), STEP 1 OF 3 -- STAMP ONLY, NOTHING READS IT YET. 144// THE DEFECT IT EXISTS TO CLOSE, read out of the source not guessed: nx_tool_run.tr_run_capture_deadline 145// starts its budget at `let t0: i64 = sys_now_ms()` INSIDE THE WORKER at fork time, while THIS edge 146// started its window when the request ARRIVED. Under pool contention the queue-wait before the worker's 147// clock starts is unaccounted, so the backend promotes to the job lane too late and the edge has already 148// stopped reading -- the residual `503 stage=read` on a call that LANDED. 149// ★TWO CLOCKS THAT AGREE ON DURATION BUT NOT ON ORIGIN STILL DISAGREE. An ABSOLUTE deadline has no 150// origin left to disagree about, which is why this is a stamp and not another timeout. 151// 152// ⚠THE CLOCK IS MONOTONIC, AND THAT IS DELIBERATE AND CONSTRAINED. sys_now_ms is CLOCK_MONOTONIC, which 153// counts from THIS machine's boot: nx_syscalls says in its own words to use realtime, "never sys_now_us()", 154// for anything one machine writes and ANOTHER judges. That warning does not apply here and the reason is 155// structural, not a hope: sd2_proxy_to_tmo hardcodes the backend address to 127.0.0.1, so the reader is 156// always the same kernel and the same boot. Monotonic is then STRICTLY BETTER than wall clock, because an 157// NTP step cannot move a deadline that is already in flight. IF A PROXY HOP IS EVER POINTED OFF-BOX, THIS 158// HEADER MUST BECOME sys_now_realtime_ms OR BE DROPPED -- the header name says Mono so nobody can misread 159// it as an epoch, and a backend that sees Mono from a foreign boot would compute a wild budget. 160const NX_SD2_DEADLINE_HDR: *u8 = "X-Nishi-Deadline-Mono-Ms: " as *u8 161const NX_SD2_MS_PER_S: i64 = 1000 // seconds -> milliseconds for the stamped budget 162// AN INBOUND DEADLINE THAT HAS ALREADY PASSED IS A DISTINCT OUTCOME AND GETS ITS OWN VALUE. 163// -1 already means "could not connect / could not write" and 0 means "connected but sent nothing"; 164// folding a dead deadline into -1 would report the caller's own expiry as an upstream fault -- exactly 165// the wrong-stage defect debt 1788361379 was filed for. Every LEGACY caller tests `> 0`, so this extra 166// negative is handled identically to -1 by all seven of them: safe by construction, checked not assumed. 167const NX_SD2_PROXY_DEADLINE_EXPIRED: i64 = 0 - 2 168// THE UNSAFE-METHOD DISCRIMINATOR -- the first byte of the request line. No SAFE method begins with either 169// of these: GET/HEAD/OPTIONS/TRACE start G/H/O/T, while POST, PUT and PATCH all start P and DELETE starts D. 170// It decides whether an ACCEPTED-BUT-SILENT proxy read (pbr==0) is allowed to advise a retry. See the 503 171// emitter below: for a WRITE the backend already took the request, so the outcome is UNKNOWN, not unavailable. 172const NX_SD2_METH_P: i64 = 80 173const NX_SD2_METH_D: i64 = 68 174const NX_SD2_DEC_BUF: i64 = 24 // decimal digits of a u64 (20) plus slack; the size this file already uses for sd2_u64_to_dec scratch 175const NX_SD2_ADNET_APPS: *u8 = "/volume1/homes/elderwesto/nishihost/knowledge/status/adnet_applications.log" as *u8 // advertiser applications journal (staged-never-live) 176// APPLICANT FIELD CAPS (rule 11, 2026-09-03). Each is bound ONCE and used TWICE -- as the sys_mmap size AND as the 177// aap_field write cap -- because a hand-counted length beside its own buffer is a SECOND COPY OF THAT BUFFER'S 178// SHAPE: raise the mmap, forget the cap, and aap_field writes past the allocation while still compiling and still 179// appearing to work. Named for the FIELD each one bounds, never for its value. 180const NX_SD2_ADNET_CO_CAP: i64 = 256 // applicant company name 181const NX_SD2_ADNET_EM_CAP: i64 = 256 // applicant contact email 182const NX_SD2_ADNET_CU_CAP: i64 = 512 // applicant click-through url 183const NX_SD2_ADNET_NOTE_CAP: i64 = 1024 // applicant free-text note (the largest field; the ratchet flagged this pair) 184const NX_SD2_SITES_CONF: *u8 = "/volume1/homes/elderwesto/nishihost/sites.conf" as *u8 185// data-driven PROXY route table (nx_proxy_route): app routes are config rows, no recompile. 186const NX_SD2_PROXY_CONF: *u8 = "/volume1/homes/elderwesto/nishihost/proxy_routes.conf" as *u8 187// data-driven ADNET inventory (universal ad slot; nx_adnet_slot): rows id/advertiser/img/click/ 188// section/weight + @host directives. ABSENT FILE = ads OFF everywhere (kill-switch by construction); 189// a vhost without an @host row NEVER gets a slot (fail-closed). Counters are per-AD only (no visitor 190// id/cookie/IP -- the nx_ad privacy law). Rotation is TIME-based: no per-user frequency state. 191// (docroot-resident so it lands via the EXISTING /api/upload -> /api/promote_content content lane -- 192// zero mgmt-allowlist changes; public-readable is fine: it is the same data every served ad exposes) 193const NX_SD2_ADNET_CONF: *u8 = "/volume1/homes/elderwesto/nishihost/sites/nishifamily/synth/adnet_inventory.txt" as *u8 194const NX_SD2_ADNET_IMPLOG: *u8 = "/volume1/homes/elderwesto/nishihost/adnet_impressions.log" as *u8 195const NX_SD2_ADNET_CLKLOG: *u8 = "/volume1/homes/elderwesto/nishihost/adnet_clicks.log" as *u8 196// served-slot rotation window (us). NAMED code-default tier; store migration = follow-on. 197const NX_SD2_ADNET_ROT_US: i64 = 60000000 198const NX_SD2_TELEMETRY_PATH: *u8 = "/volume1/homes/elderwesto/nishihost/sites_telemetry.log" as *u8 199const NX_SD2_CIRCLES_DIR: *u8 = "/volume1/homes/elderwesto/nishihost/circles" as *u8 200const NX_SD2_MAX_REQ_PER_CONN: i64 = 64 201// KEEP-ALIVE IDLE BUDGET -- deliberately SEPARATE from the 10s handshake/first-request timeout. 202// THE BUG THIS FIXES (2026-07-31): the child set ONE 10s SO_RCVTIMEO before the handshake and then 203// reused it as the keep-alive idle budget. Every response advertises `Connection: keep-alive` with no 204// timeout hint, so a browser parks the socket for minutes -- but the server dropped it after 10s of 205// silence and tore it down with a bare close. Read any page for >10s, click a link, and the browser 206// writes the request into a connection the server already abandoned, then eats a timeout before 207// retrying on a fresh one. Opening in a NEW TAB was instant because that took a fresh connection. 208// 65s matches the nginx default idle window and is advertised to the client in hr_emit_b, so the 209// client retires the socket BEFORE the server does -- which is what actually closes the race. 210const NX_SD2_KA_IDLE_S: i64 = 65 211// VIEWABLE-impression journal, deliberately SEPARATE from the served-impression journal. Both are kept: 212// served/viewable is the honest delivery ratio for an advertiser, and collapsing them would destroy it. 213const NX_SD2_ADNET_VIEWLOG: *u8 = "/volume1/homes/elderwesto/nishihost/knowledge/status/adnet_viewable.log" as *u8 214// One TLS record (max 16384 payload + header/tag slack) for reads + sends. 215const NX_SD2_RECCAP: i64 = 20480 216// Request plaintext reassembly cap (headers + POST bodies). 2MiB (was 64KB): the PROXIED-route body fill 217// (sd2_fill_body) buffers a full upload chunk here before forwarding, so API clients can send ~1MB chunks 218// instead of 8KB (80MB tree sync: ~10k requests -> ~80). mmap = virtual; only touched pages cost RAM. 219// Mirrors the mgmt daemon's MA_UPLOAD_REQCAP=2MiB so edge and backend agree on the per-request ceiling. 220const NX_SD2_PLAINCAP: i64 = 2097152 221// Out-record scratch for the chunked sender (one wire record). 222const NX_SD2_OUTREC: i64 = 17408 223// Dynamic/file serve buffer: 8MB so a 60s circle webm can be played back. 224const NX_SD2_DYN_CAP: i64 = 8388608 // assembled-response buffer (dynamic pages). Oversize STATICS no longer bound by this: they take the HR_S2_STREAM zero-ceiling path (debt 1785879638 root fix; the interim 32MiB bump is REVERTED -- no magic ceilings) 225const NX_SD2_HDR_RESERVE: i64 = 1024 // baked-page buffer header reserve: must exceed sd2_build_resp's header size (status+ctype+len+SOTA security-header set) 226// SOTA response security headers (OWASP secure-headers set), shared by every sd2-emitted page. Held as a 227// named const so the HSTS max-age is config, not an inline magic (rule 11). Mirrors the hr_emit_b file-serve path. 228const NX_SD2_SEC_HDRS: *u8 = "\r\nX-Content-Type-Options: nosniff\r\nX-Frame-Options: SAMEORIGIN\r\nReferrer-Policy: strict-origin-when-cross-origin\r\nStrict-Transport-Security: max-age=63072000; includeSubDomains\r\nContent-Security-Policy: default-src 'self'; img-src 'self' data: blob:; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline'; font-src 'self' data:; connect-src 'self'; media-src 'self'; frame-ancestors 'self'; base-uri 'none'; object-src 'none'" 229const NX_SD2_STREAM_CHUNK: i64 = 262144 // 256KB read/encrypt window for the streaming reverse-proxy (media) 230// Circle upload hard cap (policy; keep in sync with client MAX_CIRCLE_SECS). 231const NX_SD2_CIRCLE_MAX: i64 = 33554432 232// seq332 edge-DoS guard: a proxied body larger than the reassembly cap CANNOT be buffered whole, so the old 233// path truncated it + forwarded a partial body -> the backend blocked on bytes that never came, each child 234// pinned ~10MB for its 30s upstream timeout, and repeated oversize POSTs saturated MAX_CHILDREN -> OOM crash 235// loop (sig=9 reaps). Reject beyond-capacity bodies fast with 413 + close. Bodies <= PLAINCAP are unchanged; 236// bodies > PLAINCAP were already broken (truncated), so no legitimate upload regresses. 237const RESP2_413: *u8 = "HTTP/1.1 413 Payload Too Large\r\nContent-Length: 0\r\nConnection: close\r\n\r\n" 238// WS pump idle cap (ms): no traffic either direction for this long -> close. 239const NX_SD2_WS_IDLE_MS: i64 = 180000 240const NX_SD2_STATUS_CAP: i64 = 65536 241const NX_SD2_ART_CAP: i64 = 65536 242const RESP2_FAVICON: *u8 = "HTTP/1.1 204 No Content\r\nConnection: keep-alive\r\n\r\n" as *u8 243// Bare /video (no trailing slash) -> /video/ so hr_resolve serves index.html. 244const RESP2_VIDEO_301: *u8 = "HTTP/1.1 301 Moved Permanently\r\nLocation: /video/index.html\r\nContent-Length: 0\r\nConnection: keep-alive\r\n\r\n" as *u8 245// top-level /advertising -> 301 to the OPAQUE-gated census page (operator-only; never a public byte -- the 246// target lives behind the wiki OPAQUE wall). Added 2026-06-20. 247const RESP2_ADV_301: *u8 = "HTTP/1.1 301 Moved Permanently\r\nLocation: /wiki/advertising.html\r\nContent-Length: 0\r\nConnection: keep-alive\r\n\r\n" as *u8 248// FAIL-CLOSED bounce for gated branches (/wiki, /hub) when their OPAQUE gateway is unreachable: redirect to the 249// login page rather than EVER falling through to the unguarded :51850 wiki engine or static wiki files. Operator 250// law: a gated area must never leak content without the OPAQUE gate, even when the backend is momentarily down. 251const RESP2_GATE_LOGIN: *u8 = "HTTP/1.1 302 Found\r\nLocation: /login\r\nContent-Length: 0\r\nConnection: keep-alive\r\n\r\n" as *u8 252// bare /status and /status/ -> the live status dashboard (the supervisor emits status.html every poll). 253const RESP2_STATUS_301: *u8 = "HTTP/1.1 301 Moved Permanently\r\nLocation: /status.html\r\nContent-Length: 0\r\nConnection: keep-alive\r\n\r\n" as *u8 254 255const BODY2_ANDELIN: *u8 = "<!DOCTYPE html>\n<html lang=\"en\"><head><meta charset=\"utf-8\"><meta name=\"viewport\" content=\"width=device-width, initial-scale=1\"><title>Andelin West Law - Coming Soon</title><style>body{font-family:Georgia,serif;max-width:680px;margin:8vh auto;padding:0 24px;color:#1a1a2e;line-height:1.6}h1{font-size:2rem}.tag{color:#555}.note{margin-top:2rem;padding:16px 20px;background:#f4f4f8;border-left:4px solid #2a4d8f;font-size:.95rem}.foot{margin-top:3rem;font-size:.8rem;color:#888}</style></head><body><h1>Andelin West Law</h1><p class=\"tag\">A modern legal practice. Site launching soon.</p><div class=\"note\"><strong>Placeholder page.</strong> Served by the sovereign Nishi substrate. The full site is pending attorney review of state-bar advertising rules, ADA accessibility conformance, and the privacy notice before any client-facing or intake content goes live.</div><p class=\"foot\">Served bits-up by the Nishi stack &mdash; TLS 1.3, no third-party web server.</p></body></html>\n" as *u8 256 257const BODY2_WIKI: *u8 = "<!DOCTYPE html>\n<html lang=\"en\"><head><meta charset=\"utf-8\"><meta name=\"viewport\" content=\"width=device-width, initial-scale=1\"><title>Nishi Ecosystem Wiki</title><style>body{font-family:-apple-system,Segoe UI,Roboto,sans-serif;max-width:760px;margin:6vh auto;padding:0 24px;color:#161622;line-height:1.65}h1{font-size:2.1rem}h2{font-size:1.1rem;margin-top:2rem;color:#2a4d8f}ul{padding-left:1.2rem}li{margin:.35rem 0}.note{padding:14px 18px;background:#eef2fb;border-left:4px solid #2a4d8f;border-radius:4px;font-size:.95rem}code{background:#f0f0f4;padding:1px 5px;border-radius:3px;font-size:.9em}.foot{margin-top:3rem;font-size:.8rem;color:#888}</style></head><body><h1>Nishi Ecosystem Wiki</h1><p class=\"note\"><strong>Launch placeholder &mdash; the live wiki engine is coming online.</strong> What you are reading is itself served bits-up by the substrate below: no nginx, no OpenSSL, no libc.</p><p style=\"margin:1.2rem 0\"><a href=\"/wiki/status\"><strong>&#9656; Live stack scorecard &rarr;</strong></a> &nbsp; <a href=\"/wiki/components\"><strong>&#9656; Component articles (Gitea&times;Wikipedia) &rarr;</strong></a></p><h2>Shipped substrate</h2><ul><li>Self-hosting NishiLang compiler (RV64 + x86_64), bits-up from C bootstrap</li><li>TLS 1.3 server &mdash; serving this page now</li><li>SHA-256/512, ChaCha20-Poly1305, AES-GCM, HKDF, Argon2id &mdash; all KAT-verified</li><li>Sovereign secrets vault (HashiCorp-class, ChaCha20-Poly1305 at rest)</li><li>Multi-vhost HTTPS daemon + N-party video signaling (wss) + circles store</li></ul><h2>In progress</h2><ul><li>Full wiki engine (search index, doc store, markdown render)</li><li>Modern auth (OPAQUE PAKE + BIP39 recovery, no cookies)</li><li>Multi-agent concurrent editing (CRDT, sovereign)</li></ul><p class=\"foot\">nishifamily.com/wiki &mdash; bits-up sovereign hosting on the west NAS.</p></body></html>\n" as *u8 258 259// Return-aware bootstrap for a TOP-LEVEL /wiki navigation with NO session header (no-cookie model: a nav 260// never carries X-Nishi-Session). If a token is in sessionStorage -> fetch the same path WITH the header 261// (-> proxied to the wiki gateway -> renders content in place); else -> /login?return=<path> so the fixed 262// login() lands the member back EXACTLY where they were. Replaces the wiki gateway's stale board()->hub login. 263const BODY2_WIKI_BOOTSTRAP: *u8 = "<!doctype html><html><head><meta charset=utf-8><meta name=viewport content='width=device-width,initial-scale=1'><title>Nishi</title></head><body><script>var t=sessionStorage.getItem('nsess');function go(){location='/login?return='+encodeURIComponent(location.pathname+location.search)}function R(h){document.open();document.write(h);document.close()}function F(p,nx){fetch(p,{headers:{'X-Nishi-Session':t}}).then(function(r){return r.ok?r.text():null}).then(function(h){if(h){R(h)}else{nx()}}).catch(go)}if(t){var p=location.pathname,s=location.search;F(p+s,function(){F(p+'.html'+s,go)})}else{go()}</script></body></html>" as *u8 264 265const BODY2_FAMILY: *u8 = "<!DOCTYPE html>\n<html lang=\"en\"><head><meta charset=\"utf-8\"><meta name=\"viewport\" content=\"width=device-width, initial-scale=1\"><title>Nishi Family</title><style>body{font-family:-apple-system,Segoe UI,Roboto,sans-serif;max-width:680px;margin:8vh auto;padding:0 24px;color:#161622;line-height:1.65;text-align:center}h1{font-size:2.3rem}.tag{color:#555;font-size:1.05rem}a{color:#2a4d8f}.links a{display:inline-block;margin:8px 14px;font-size:1.1rem}.foot{margin-top:3rem;font-size:.8rem;color:#888}</style></head><body><h1>Nishi Family</h1><p class=\"tag\">The family hub &mdash; home of the Nishi sovereign ecosystem.</p><p class=\"links\"><a href=\"/video\">&#127909; Family Video &rarr;</a> <a href=\"/wiki\">Wiki &rarr;</a></p><p class=\"foot\">Served bits-up by the Nishi stack &mdash; TLS 1.3, no third-party web server.</p></body></html>\n" as *u8 266 267func sd2_strlen(s: *u8) -> i64 { 268 var n: i64 = 0 269 while s[n] != 0 { n = n + 1 } 270 return n 271} 272 273// Load a concat-DER fullchain; 0 if absent or implausibly short (mirrors the gated sd_load_chain). 274func sd2_load_chain(path: *u8, len_box: *i64) -> *u8 { 275 len_box[0] = 0 276 let p: *u8 = sys_read_file(path, len_box) 277 if (p as i64) == 0 { return 0 as *u8 } 278 if len_box[0] < 100 { return 0 as *u8 } 279 return p 280} 281 282// Load a 32-byte P-256 ECDSA private scalar; 0 if absent / wrong size (mirrors sd_load_key). 283func sd2_load_key(path: *u8) -> *u8 { 284 let lb: *i64 = (sys_mmap(8)) as *i64 285 lb[0] = 0 286 let p: *u8 = sys_read_file(path, lb) 287 if (p as i64) == 0 { return 0 as *u8 } 288 if lb[0] != 32 { return 0 as *u8 } 289 return p 290} 291 292// ---- DATA-DRIVEN SNI cert table (R1b 2026-07-15) ------------------------------------------------- 293// Every HTTPS domain = one manifest row (suffix + fullchain-der + ecdsa-key). Add a domain = drop its 294// le_<domain>_* + a manifest line; NEVER an edge recompile. Row 0 = the DEFAULT cert. 295const NX_SD2_CERT_MANIFEST: *u8 = "/volume1/homes/elderwesto/nishihost/certs/sni_certs.manifest" as *u8 296const NX_SD2_CERT_MAX: i64 = 32 297 298// Copy one whitespace-delimited field from buf[pos..end) into out (NUL-terminated). Skips leading 299// spaces/tabs. Returns the position past the field, or -1 if the line has no field (blank/'#'/EOL). 300func sd2_field(buf: *u8, pos: i64, end: i64, out: *u8, out_cap: i64) -> i64 { 301 var p: i64 = pos 302 var skip: i64 = 1 303 while skip == 1 { 304 if p >= end { skip = 0 } 305 else { 306 let c: i64 = buf[p] as i64 307 if c == 32 { p = p + 1 } 308 else { if c == 9 { p = p + 1 } else { skip = 0 } } 309 } 310 } 311 if p >= end { return 0 - 1 } 312 let c0: i64 = buf[p] as i64 313 if c0 == 10 { return 0 - 1 } 314 if c0 == 13 { return 0 - 1 } 315 if c0 == 35 { return 0 - 1 } 316 var o: i64 = 0 317 var cp: i64 = 1 318 while cp == 1 { 319 if p >= end { cp = 0 } 320 else { 321 let c: i64 = buf[p] as i64 322 if c == 32 { cp = 0 } 323 else { if c == 9 { cp = 0 } 324 else { if c == 10 { cp = 0 } 325 else { if c == 13 { cp = 0 } 326 else { 327 if o < out_cap - 1 { out[o] = buf[p] as u8; o = o + 1 } 328 p = p + 1 329 } } } } 330 } 331 } 332 out[o] = 0 as u8 333 return p 334} 335 336// Advance past the current line (to the byte after the next '\n', or to end). 337func sd2_next_line(buf: *u8, pos: i64, end: i64) -> i64 { 338 var p: i64 = pos 339 var go: i64 = 1 340 while go == 1 { 341 if p >= end { go = 0 } 342 else { if (buf[p] as i64) == 10 { p = p + 1; go = 0 } else { p = p + 1 } } 343 } 344 return p 345} 346 347// Parse the manifest into parallel arrays; load each row's cert+key. Rows whose cert/key fail to load 348// are skipped (fail-safe). Returns rows loaded (0 => caller uses the legacy fallback). 349func sd2_load_cert_table(man: *u8, man_n: i64, 350 suf_ptrs: *i64, suf_lens: *i64, 351 cert_ptrs: *i64, cert_lens: *i64, key_ptrs: *i64, 352 max: i64) -> i64 { 353 var count: i64 = 0 354 var pos: i64 = 0 355 while pos < man_n { 356 if count >= max { pos = man_n } 357 else { 358 let sufb: *u8 = sys_mmap(256) 359 let p1: i64 = sd2_field(man, pos, man_n, sufb, 256) 360 if p1 < 0 { pos = sd2_next_line(man, pos, man_n) } 361 else { 362 let certp: *u8 = sys_mmap(512) 363 let p2: i64 = sd2_field(man, p1, man_n, certp, 512) 364 if p2 < 0 { pos = sd2_next_line(man, pos, man_n) } 365 else { 366 let keyp: *u8 = sys_mmap(512) 367 let p3: i64 = sd2_field(man, p2, man_n, keyp, 512) 368 if p3 < 0 { pos = sd2_next_line(man, pos, man_n) } 369 else { 370 let clb: *i64 = (sys_mmap(8)) as *i64 371 clb[0] = 0 372 let cbuf: *u8 = sd2_load_chain(certp, clb) 373 let kbuf: *u8 = sd2_load_key(keyp) 374 if (cbuf as i64) == 0 { pos = sd2_next_line(man, pos, man_n) } 375 else { if (kbuf as i64) == 0 { pos = sd2_next_line(man, pos, man_n) } 376 else { 377 var sl: i64 = 0 378 while sufb[sl] != (0 as u8) { sl = sl + 1 } 379 suf_ptrs[count] = sufb as i64 380 suf_lens[count] = sl 381 cert_ptrs[count] = cbuf as i64 382 cert_lens[count] = clb[0] 383 key_ptrs[count] = kbuf as i64 384 count = count + 1 385 pos = sd2_next_line(man, pos, man_n) 386 } } 387 } 388 } 389 } 390 } 391 } 392 return count 393} 394 395// (mtime,size) signature for HOT-RELOAD change detection. out2[0]=st_mtime out2[1]=st_size 396// (x86_64 struct stat: mtime byte 88 = i64[11], size byte 48 = i64[6] -- same convention as 397// nx_torrent_up/nx_torrent_daemon). Returns 0 ok / -1 stat-fail. Comparing BOTH catches a 398// same-second rewrite (mtime granularity) via the size delta. 399func sd2_statsig(path: *u8, statb: *u8, out2: *i64) -> i64 { 400 if sys_fstatat(path, statb) != 0 { out2[0] = 0 - 1; out2[1] = 0 - 1; return 0 - 1 } 401 let sb: *i64 = statb as *i64 402 out2[0] = sb[11] 403 out2[1] = sb[6] 404 return 0 405} 406 407func sd2_contains(hay: *u8, hlen: i64, needle: *u8, nlen: i64) -> i64 { 408 if nlen <= 0 { return 0 } 409 if hlen < nlen { return 0 } 410 var i: i64 = 0 411 let last: i64 = hlen - nlen 412 while i <= last { 413 var j: i64 = 0 414 var ok: i64 = 1 415 while j < nlen { 416 if hay[i + j] != needle[j] { ok = 0; j = nlen } else { j = j + 1 } 417 } 418 if ok == 1 { return 1 } 419 i = i + 1 420 } 421 return 0 422} 423 424func sd2_lower(c: u8) -> u8 { 425 if c >= (65 as u8) { if c <= (90 as u8) { return (c + (32 as u8)) } } 426 return c 427} 428 429// case-insensitive contains (Upgrade/upgrade, WebSocket/websocket...) 430func sd2_contains_ci(hay: *u8, hlen: i64, needle: *u8, nlen: i64) -> i64 { 431 if nlen <= 0 { return 0 } 432 if hlen < nlen { return 0 } 433 var i: i64 = 0 434 let last: i64 = hlen - nlen 435 while i <= last { 436 var j: i64 = 0 437 var ok: i64 = 1 438 while j < nlen { 439 if sd2_lower(hay[i + j]) != sd2_lower(needle[j]) { ok = 0; j = nlen } else { j = j + 1 } 440 } 441 if ok == 1 { return 1 } 442 i = i + 1 443 } 444 return 0 445} 446 447func sd2_body_start(hay: *u8, hlen: i64) -> i64 { 448 if hlen < 4 { return hlen } 449 var i: i64 = 0 450 let last: i64 = hlen - 4 451 while i <= last { 452 if hay[i] == (0x0D as u8) { if hay[i + 1] == (0x0A as u8) { if hay[i + 2] == (0x0D as u8) { if hay[i + 3] == (0x0A as u8) { 453 return i + 4 454 } } } } 455 i = i + 1 456 } 457 return hlen 458} 459 460func sd2_u64_to_dec(n: i64, buf: *u8) -> i64 { 461 if n == 0 { buf[0] = 48; return 1 } 462 var d: i64 = 0 463 var x: i64 = n 464 while x > 0 { d = d + 1; x = x / 10 } 465 var i: i64 = d - 1 466 x = n 467 while i >= 0 { 468 buf[i] = (48 + (x % 10)) as u8 469 x = x / 10 470 i = i - 1 471 } 472 return d 473} 474 475func sd2_append(dst: *u8, off: i64, src: *u8, n: i64) -> i64 { 476 var i: i64 = 0 477 while i < n { dst[off + i] = src[i]; i = i + 1 } 478 return off + n 479} 480 481func sd2_append_str(dst: *u8, off: i64, s: *u8) -> i64 { 482 return sd2_append(dst, off, s, sd2_strlen(s)) 483} 484 485// Full HTTP/1.1 keep-alive response into out (baked pages, built at startup). 486func sd2_build_resp(out: *u8, ctype: *u8, body: *u8, body_len: i64) -> i64 { 487 var w: i64 = 0 488 w = sd2_append_str(out, w, "HTTP/1.1 200 OK\r\nContent-Type: " as *u8) 489 w = sd2_append_str(out, w, ctype) 490 w = sd2_append_str(out, w, "\r\nContent-Length: " as *u8) 491 // LEAK FIX (2026-08-08). The old body did sys_mmap(24) PER CALL and freed nothing. 492 // sd2_build_resp is NOT startup-only -- it also runs on the dynamic request path 493 // (call sites :1503 :1660 :1840), so at PAGE granularity that is 4096B leaked PER 494 // REQUEST on the live web server, measured while the host sat at swap_used_permil=954. 495 // The digits can be emitted straight into `out` at the current write offset: identical 496 // bytes, zero allocation. VERIFY THE CALL SITE, NOT THE DEFINITION -- the comment above 497 // this function says "built at startup" and that is only true of 3 of its 6 callers. 498 let dp: *u8 = ((out as i64) + w) as *u8 499 let dn: i64 = sd2_u64_to_dec(body_len, dp) 500 w = w + dn 501 // FRESHNESS (2026-08-08). Measured: this server sent NO Cache-Control, NO ETag and NO 502 // Last-Modified on any surface, so every navigation re-downloaded the whole body -- 503 // 4.4MB on /world, 67KB on /compare. `private` keeps a per-user dynamic response out of 504 // shared caches by construction; 60s is short enough that a redeploy shows up promptly. 505 w = sd2_append_str(out, w, "\r\nCache-Control: private, max-age=60" as *u8) 506 w = sd2_append_str(out, w, "\r\nConnection: keep-alive" as *u8) 507 w = sd2_append_str(out, w, NX_SD2_SEC_HDRS) 508 w = sd2_append_str(out, w, "\r\nX-Served-By: nishi-substrate-v2\r\n\r\n" as *u8) 509 w = sd2_append(out, w, body, body_len) 510 return w 511} 512 513// Parse "Content-Length:" value from the request headers; -1 if absent. 514func sd2_content_length(req: *u8, reqn: i64) -> i64 { 515 let key: *u8 = "content-length:" as *u8 516 var i: i64 = 0 517 while i + 15 <= reqn { 518 var j: i64 = 0 519 var ok: i64 = 1 520 while j < 15 { 521 if sd2_lower(req[i + j]) != key[j] { ok = 0; j = 15 } else { j = j + 1 } 522 } 523 if ok == 1 { 524 var k: i64 = i + 15 525 while k < reqn { if req[k] == (32 as u8) { k = k + 1 } else { break } } 526 var v: i64 = 0 527 var got: i64 = 0 528 // flag-style digit loop (NO continue-in-nested-if -- that 529 // construct miscompiles under the 2026-06-09 compiler, child hangs) 530 var run: i64 = 1 531 while run == 1 { 532 if k >= reqn { run = 0 } 533 else { 534 let c: i64 = req[k] as i64 535 var dig: i64 = 0 536 if c >= 48 { if c <= 57 { dig = 1 } } 537 if dig == 1 { v = v * 10 + (c - 48); got = 1; k = k + 1 } 538 else { run = 0 } 539 } 540 } 541 if got == 1 { return v } 542 return 0 - 1 543 } 544 i = i + 1 545 } 546 return 0 - 1 547} 548 549// Extract a query parameter value (sanitized to [a-z0-9-], lowercased, 550// max 32 bytes) from the request line. key like "room=". Returns length. 551// Written in strict flag style throughout -- break/continue inside nested 552// ifs miscompile under the 2026-06-09 compiler (child hangs; see the 553// wsupgrade-miscompile repro note). 554func sd2_query_param(req: *u8, reqn: i64, key: *u8, keyn: i64, out: *u8) -> i64 { 555 // only scan the first line (request line) 556 var lim: i64 = 0 557 var scanning: i64 = 1 558 while scanning == 1 { 559 if lim >= reqn { scanning = 0 } 560 else { 561 if req[lim] == (13 as u8) { scanning = 0 } 562 else { lim = lim + 1 } 563 } 564 } 565 // find "key" in the request line 566 var found: i64 = 0 - 1 567 var i: i64 = 0 568 while i + keyn <= lim { 569 if found < 0 { 570 var j: i64 = 0 571 var ok: i64 = 1 572 while j < keyn { 573 if req[i + j] != key[j] { ok = 0; j = keyn } else { j = j + 1 } 574 } 575 if ok == 1 { found = i + keyn } 576 } 577 i = i + 1 578 } 579 if found < 0 { return 0 } 580 // copy sanitized value 581 var k: i64 = found 582 var w: i64 = 0 583 var run: i64 = 1 584 while run == 1 { 585 if k >= lim { run = 0 } 586 else { 587 if w >= 32 { run = 0 } 588 else { 589 let c: u8 = sd2_lower(req[k]) 590 var keepc: i64 = 0 591 if c >= (97 as u8) { if c <= (122 as u8) { keepc = 1 } } 592 if c >= (48 as u8) { if c <= (57 as u8) { keepc = 1 } } 593 if c == (45 as u8) { keepc = 1 } 594 if keepc == 0 { run = 0 } 595 else { out[w] = c; w = w + 1; k = k + 1 } 596 } 597 } 598 } 599 return w 600} 601 602// Receive one HTTP request: read TLS records and reassemble plaintext until the headers (CRLFCRLF) AND, for a 603// POST/PUT carrying a Content-Length, the FULL body. v1 returned at CRLFCRLF and NEVER read the body -- so a 604// client that put the POST body in a separate TLS record (HttpWebRequest, and some mobile browsers) had its 605// body DROPPED: the OPAQUE login daemon then saw an empty handle+pw -> 400/401, making login impossible for 606// EVERY gated service (gallery/wiki/hub/torrent). GETs (no body) still return at the headers. SMALL bodies 607// (login/register/forms) are completed here; LARGE bodies (uploads) are left for their streaming handler so 608// we never force-buffer a multi-MB upload. Returns plaintext length, <=0 on error/EOF. 609func sd2_recv_request(s: *Tls13ServerSession, cfd: i64, rec_buf: *u8, plain: *u8, plain_cap: i64) -> i64 { 610 var total: i64 = 0 611 var recs: i64 = 0 612 var need: i64 = 0 // 0 until headers seen; then = body_start + Content-Length (the full-request byte target) 613 while recs < 8 { 614 let rn: i64 = nx_tls13_read_record_from_fd(cfd, rec_buf, NX_SD2_RECCAP) 615 if rn <= 0 { if total > 0 { return total } return 0 - 1 } 616 let pn: i64 = nx_tls13_server_session_app_recv(s, rec_buf, rn, (plain as i64 + total) as *u8, plain_cap - total) 617 if pn <= 0 { if total > 0 { return total } return 0 - 1 } 618 total = total + pn 619 if need == 0 { 620 // headers complete yet? (CRLFCRLF present) 621 if sd2_contains(plain, total, "\r\n\r\n" as *u8, 4) == 1 { 622 let bs: i64 = sd2_body_start(plain, total) 623 let cl: i64 = sd2_content_length(plain, total) 624 if cl <= 0 { return total } // GET / no body -> done at the headers 625 if cl > NX_MAGIC_8192 { return total } // large body (upload) -> its streaming handler reads the rest 626 need = bs + cl // small body -> keep reading until the whole body arrives 627 if total >= need { return total } // ... already fully present in this record 628 } 629 } else { 630 if total >= need { return total } // small body now complete across records 631 } 632 recs = recs + 1 633 } 634 return total 635} 636 637// Complete a PROXIED request's body in `plain` before forwarding: sd2_recv_request stops at the headers for 638// bodies >8KB (streaming handlers read their own body), but the buffered reverse-proxy is NOT such a handler -- 639// it forwarded whatever was buffered, TRUNCATING any body spanning >1 TLS record (the hard 8KB upload-chunk cap; 640// backends then waited on bytes that never came). This reads TLS records until body_start+Content-Length, bounded 641// by plain_cap and a record budget. FAIL-SAFE BY CONSTRUCTION: on any error/timeout/oversize it returns what is 642// buffered -- exactly the old forward-partial behavior, so no failure mode is NEW; the backend's own 643// Content-Length handling still applies. Pump pattern mirrors the proven sd2_circle_upload reader. 644func sd2_fill_body(s: *Tls13ServerSession, cfd: i64, rec_buf: *u8, plain: *u8, have: i64, plain_cap: i64) -> i64 { 645 if sd2_contains(plain, have, "\r\n\r\n" as *u8, 4) == 0 { return have } // headers incomplete -> old behavior 646 let cl: i64 = sd2_content_length(plain, have) 647 if cl <= 0 { return have } // GET / no declared body -> nothing to fill 648 let bs: i64 = sd2_body_start(plain, have) // CRLFCRLF proven present, so bs is the true body offset 649 var need: i64 = bs + cl 650 if need > plain_cap { need = plain_cap } // oversize: forward the first plain_cap bytes (backend refuses) 651 var total: i64 = have 652 var recs: i64 = 0 653 while total < need { 654 if recs >= 512 { return total } // budget backstop (2MiB / ~4KB-min records) 655 let rn: i64 = nx_tls13_read_record_from_fd(cfd, rec_buf, NX_SD2_RECCAP) 656 if rn <= 0 { return total } 657 let pn: i64 = nx_tls13_server_session_app_recv(s, rec_buf, rn, (plain as i64 + total) as *u8, plain_cap - total) 658 if pn <= 0 { return total } 659 total = total + pn 660 recs = recs + 1 661 } 662 return total 663} 664 665// ---- D4: TLS-terminating WebSocket pump to loopback nx_signaling_v2 ---- 666func sd2_ws_pump(s: *Tls13ServerSession, cfd: i64, first_req: *u8, first_n: i64, 667 rec_buf: *u8, out_rec: *u8, pump: *u8) -> i64 { 668 // connect 127.0.0.1:8445 669 let ufd: i64 = sys_socket(AF_INET, SOCK_STREAM, 0) 670 if ufd < 0 { return 0 - 1 } 671 let addr: *u8 = sys_mmap(16) 672 addr[0] = 2 as u8; addr[1] = 0 as u8 673 addr[2] = ((NX_MAGIC_8445 >> 8) & 0xff) as u8 674 addr[3] = (NX_MAGIC_8445 & 0xff) as u8 675 addr[4] = 127 as u8; addr[5] = 0 as u8; addr[6] = 0 as u8; addr[7] = 1 as u8 676 var zi: i64 = 8 677 while zi < 16 { addr[zi] = 0 as u8; zi = zi + 1 } 678 if nx_connect_bounded(ufd, addr, 16, NX_CONN_DEFAULT_MS) < 0 { sys_close(ufd); return 0 - 1 } 679 680 // TCP_NODELAY (IPPROTO_TCP=6, TCP_NODELAY=1) on the UPSTREAM pump socket: this hop carries 681 // every live video/audio frame to the relay. Without it, Nagle here x delayed-ACK on the 682 // relay side adds up to ~40ms per frame burst -- MEASURED live by nx_video_qoe_live 683 // 2026-07-03 (an exact ~40ms cycle floor above 25fps that client-side nodelay did NOT fix). 684 // Mirrors the nodelay this daemon already sets on its public accept sockets. 685 let pnd: *u8 = sys_mmap(4) 686 pnd[0] = 1 as u8 687 pnd[1] = 0 as u8 688 pnd[2] = 0 as u8 689 pnd[3] = 0 as u8 690 sys_setsockopt(ufd, 6, 1, pnd, 4) 691 692 // forward the decrypted upgrade request; the signaling daemon answers 101 693 if nx_tls13_sendfd_write_all(ufd, first_req, first_n) < 0 { sys_close(ufd); return 0 - 1 } 694 695 // long-lived call: lift the 10s accept-time read timeout (poll bounds idle) 696 sys_set_socket_timeout(cfd, 600) 697 let pfds: *u8 = sys_mmap(2 * NX_POLLFD_BYTES) 698 var alive: i64 = 1 699 while alive == 1 { 700 nx_pollfd_set(pfds, 0, cfd, NX_POLLIN) 701 nx_pollfd_set(pfds, 1, ufd, NX_POLLIN) 702 let nr: i64 = nx_poll(pfds, 2, NX_SD2_WS_IDLE_MS) 703 if nr <= 0 { alive = 0 } // idle cap or error -> close 704 if alive == 1 { 705 if (nx_pollfd_revents(pfds, 0) & NX_POLLIN) != 0 { 706 let rn: i64 = nx_tls13_read_record_from_fd(cfd, rec_buf, NX_SD2_RECCAP) 707 if rn <= 0 { alive = 0 } 708 else { 709 let pn: i64 = nx_tls13_server_session_app_recv(s, rec_buf, rn, pump, NX_SD2_RECCAP) 710 if pn <= 0 { alive = 0 } 711 else { 712 if nx_tls13_sendfd_write_all(ufd, pump, pn) < 0 { alive = 0 } 713 } 714 } 715 } 716 } 717 if alive == 1 { 718 if (nx_pollfd_revents(pfds, 1) & NX_POLLIN) != 0 { 719 let un: i64 = sys_read(ufd, pump, NX_MAGIC_16000) 720 if un <= 0 { alive = 0 } 721 else { 722 if nx_tls13_app_send_fd(s, pump, un, cfd, out_rec, NX_SD2_OUTREC) < 0 { alive = 0 } 723 } 724 } 725 } 726 } 727 sys_close(ufd) 728 return 0 729} 730 731// ---- D5: circles ---- 732 733// Build "<dir>/<sub>/<room>_<from>_<usec>.<ext>" into out; returns len. 734// ext_nv1=1 -> ".nv1" (NishiLossless v1 circles, see nx_nv1.nx); else ".webm" 735// (legacy MediaRecorder circles -- still served for back-compat playback). 736func sd2_circle_path(out: *u8, priv: i64, room: *u8, room_n: i64, 737 from: *u8, from_n: i64, usec: i64, ext_nv1: i64) -> i64 { 738 var w: i64 = 0 739 w = sd2_append_str(out, w, NX_SD2_CIRCLES_DIR) 740 if priv == 1 { w = sd2_append_str(out, w, "/private/" as *u8) } 741 else { w = sd2_append_str(out, w, "/public/" as *u8) } 742 w = sd2_append(out, w, room, room_n) 743 out[w] = 95; w = w + 1 // '_' 744 w = sd2_append(out, w, from, from_n) 745 out[w] = 95; w = w + 1 746 let dbuf: *u8 = sys_mmap(24) 747 let dn: i64 = sd2_u64_to_dec(usec, dbuf) 748 w = sd2_append(out, w, dbuf, dn) 749 if ext_nv1 == 1 { w = sd2_append_str(out, w, ".nv1" as *u8) } 750 else { w = sd2_append_str(out, w, ".webm" as *u8) } 751 out[w] = 0 752 return w 753} 754 755// bounded append of pn received bytes into the body buffer (clamped at the 756// declared content-length); hoisted to a helper to keep the receive loop's 757// nesting shallow (the nested-if miscompile landmine). Returns new got. 758func sd2_body_copy(body: *u8, got: i64, cl: i64, src: *u8, pn: i64) -> i64 { 759 var wn: i64 = pn 760 if got + wn > cl { wn = cl - got } 761 var pi: i64 = 0 762 while pi < wn { body[got + pi] = src[pi]; pi = pi + 1 } 763 return got + pn 764} 765 766// POST /video/circle?room=R&from=F&priv=0|1 -- stream the webm body to the 767// circles store. Response written into dyn (small JSON). Returns resp len. 768func sd2_circle_upload(s: *Tls13ServerSession, cfd: i64, plain: *u8, plain_n: i64, 769 rec_buf: *u8, pump: *u8, dyn: *u8) -> i64 { 770 let cl: i64 = sd2_content_length(plain, plain_n) 771 var bad: i64 = 0 772 if cl <= 0 { bad = 1 } 773 if cl > NX_SD2_CIRCLE_MAX { bad = 1 } 774 let room: *u8 = sys_mmap(40) 775 let from: *u8 = sys_mmap(40) 776 let pv: *u8 = sys_mmap(40) 777 let room_n: i64 = sd2_query_param(plain, plain_n, "room=" as *u8, 5, room) 778 var from_n: i64 = sd2_query_param(plain, plain_n, "from=" as *u8, 5, from) 779 let pv_n: i64 = sd2_query_param(plain, plain_n, "priv=" as *u8, 5, pv) 780 if room_n == 0 { bad = 1 } 781 if from_n == 0 { from[0] = 120; from_n = 1 } // 'x' 782 var priv: i64 = 0 783 if pv_n == 1 { if pv[0] == (49 as u8) { priv = 1 } } 784 // ext=nv1 -> NishiLossless container suffix (allowlist, not pass-through: 785 // the suffix is the ONLY client-controlled byte sequence in the path) 786 let ex: *u8 = sys_mmap(40) 787 let ex_n: i64 = sd2_query_param(plain, plain_n, "ext=" as *u8, 4, ex) 788 var ext_nv1: i64 = 0 789 if ex_n == 3 { 790 var exm: i64 = 1 791 if ex[0] != (110 as u8) { exm = 0 } // 'n' 792 if ex[1] != (118 as u8) { exm = 0 } // 'v' 793 if ex[2] != (49 as u8) { exm = 0 } // '1' 794 ext_nv1 = exm 795 } 796 if bad == 1 { 797 let b: *u8 = "{\"ok\":0,\"err\":\"bad request\"}" as *u8 798 return hr_emit_b(dyn, NX_SD2_DYN_CAP, "HTTP/1.1 400 Bad Request" as *u8, "application/json" as *u8, b, sd2_strlen(b)) 799 } 800 801 // Receive the FULL body into memory first (cl capped at 802 // NX_SD2_CIRCLE_MAX; anonymous mmap is lazy so only received pages 803 // cost RAM), VALIDATE, and only then touch the circles store: a 804 // truncated or corrupt upload never lands as a stored circle (the 805 // old stream-to-file path left truncated files behind on failure). 806 let body: *u8 = sys_mmap(cl + 64) 807 let bs: i64 = sd2_body_start(plain, plain_n) 808 var got: i64 = plain_n - bs 809 if got > 0 { sd2_body_copy(body, 0, cl, (plain as i64 + bs) as *u8, got) } 810 var fail: i64 = 0 811 while got < cl { 812 let rn: i64 = nx_tls13_read_record_from_fd(cfd, rec_buf, NX_SD2_RECCAP) 813 if rn <= 0 { fail = 1; got = cl } 814 else { 815 let pn: i64 = nx_tls13_server_session_app_recv(s, rec_buf, rn, pump, NX_SD2_RECCAP) 816 if pn <= 0 { fail = 1; got = cl } 817 else { 818 got = sd2_body_copy(body, got, cl, pump, pn) 819 } 820 } 821 } 822 if fail == 1 { 823 sys_write(2, "circle upload TRUNCATED, nothing stored\n" as *u8, 40) 824 let b3: *u8 = "{\"ok\":0,\"err\":\"upload truncated\"}" as *u8 825 return hr_emit_b(dyn, NX_SD2_DYN_CAP, "HTTP/1.1 400 Bad Request" as *u8, "application/json" as *u8, b3, sd2_strlen(b3)) 826 } 827 828 // Server-side NV1 validation (the named rung from the NV1 spec): 829 // ext=nv1 uploads must be a well-formed NLC1 container (raw 'A' or 830 // LPC 'L' audio) or they are REJECTED at the door. Legacy .webm 831 // bodies stay opaque (back-compat playback only). 832 if ext_nv1 == 1 { 833 let vinfo: *i64 = sys_mmap(64) as *i64 834 let vrc: i64 = nv1_validate(body, cl, vinfo) 835 if vrc != 0 { 836 sys_write(2, "circle nv1-invalid rc=-" as *u8, 23) 837 let vd: *u8 = sys_mmap(8) 838 vd[0] = (48 - vrc) as u8 839 sys_write(2, vd, 1) 840 sys_write(2, " rejected, nothing stored\n" as *u8, 26) 841 let b5: *u8 = "{\"ok\":0,\"err\":\"nv1 invalid\"}" as *u8 842 return hr_emit_b(dyn, NX_SD2_DYN_CAP, "HTTP/1.1 400 Bad Request" as *u8, "application/json" as *u8, b5, sd2_strlen(b5)) 843 } 844 } 845 846 // Store dirs are DEPLOY-OWNED (created once by _deploy_content, 0700 on 847 // private). No per-request sys_mkdir: that helper hardcodes rv64 34 848 // (mkdirat) and under the C-bootstrap compiler there is NO rv64->x86 849 // translation -- syscall 34 on x86_64 is pause(), which blocked the 850 // upload child forever (found live 2026-06-10 via CU breadcrumbs). 851 let path: *u8 = sys_mmap(512) 852 let path_n: i64 = sd2_circle_path(path, priv, room, room_n, from, from_n, sys_now_us(), ext_nv1) 853 let ffd: i64 = sys_openat_wr(path, 0x1a4) 854 if ffd < 0 { 855 let b2: *u8 = "{\"ok\":0,\"err\":\"store open failed\"}" as *u8 856 return hr_emit_b(dyn, NX_SD2_DYN_CAP, "HTTP/1.1 500 Internal Server Error" as *u8, "application/json" as *u8, b2, sd2_strlen(b2)) 857 } 858 nx_tls13_sendfd_write_all(ffd, body, cl) 859 sys_close(ffd) 860 // Cardinal 18: one meaningful line per stored circle (path + outcome). 861 sys_write(2, "circle stored " as *u8, 14) 862 sys_write(2, path, path_n) 863 sys_write(2, " ok\n" as *u8, 4) 864 let b4: *u8 = "{\"ok\":1}" as *u8 865 return hr_emit_b(dyn, NX_SD2_DYN_CAP, "HTTP/1.1 200 OK" as *u8, "application/json" as *u8, b4, sd2_strlen(b4)) 866} 867 868// GET /video/circles?room=R[&priv=1] -- JSON list of the room's circles, 869// newest unsorted (client sorts by the embedded usec). priv=1 lists the 870// private archive (review-later view). 871func sd2_circle_list(plain: *u8, plain_n: i64, dyn: *u8) -> i64 { 872 let room: *u8 = sys_mmap(40) 873 let pv: *u8 = sys_mmap(40) 874 let room_n: i64 = sd2_query_param(plain, plain_n, "room=" as *u8, 5, room) 875 let pv_n: i64 = sd2_query_param(plain, plain_n, "priv=" as *u8, 5, pv) 876 var priv: i64 = 0 877 if pv_n == 1 { if pv[0] == (49 as u8) { priv = 1 } } 878 let dirp: *u8 = sys_mmap(256) 879 var dw: i64 = sd2_append_str(dirp, 0, NX_SD2_CIRCLES_DIR) 880 if priv == 1 { dw = sd2_append_str(dirp, dw, "/private" as *u8) } 881 else { dw = sd2_append_str(dirp, dw, "/public" as *u8) } 882 dirp[dw] = 0 883 884 let body: *u8 = sys_mmap(NX_MAGIC_65536) 885 var bw: i64 = 0 886 body[bw] = 91; bw = bw + 1 // '[' 887 var first: i64 = 1 888 let dfd: i64 = sys_openat_rd(dirp) 889 if dfd >= 0 { 890 let dbuf: *u8 = sys_mmap(NX_MAGIC_16384) 891 var more: i64 = 1 892 while more == 1 { 893 let nread: i64 = sys_getdents64(dfd, dbuf, NX_MAGIC_16384) 894 if nread <= 0 { more = 0 } 895 else { 896 var off: i64 = 0 897 while off < nread { 898 // linux_dirent64: u64 ino, i64 off, u16 reclen, u8 type, name... 899 let reclen: i64 = ((dbuf[off + 16] as i64) | ((dbuf[off + 17] as i64) << 8)) 900 let namep: i64 = off + 19 901 var nl: i64 = 0 902 while dbuf[namep + nl] != 0 { nl = nl + 1 } 903 // match "<room>_" prefix + ".webm" suffix; skip . / .. 904 var want: i64 = 0 905 if room_n > 0 { if nl > room_n { 906 var m: i64 = 1 907 var q: i64 = 0 908 while q < room_n { 909 if dbuf[namep + q] != room[q] { m = 0; q = room_n } else { q = q + 1 } 910 } 911 if m == 1 { if dbuf[namep + room_n] == (95 as u8) { want = 1 } } 912 } } 913 if want == 1 { if bw < NX_MAGIC_60000 { 914 if first == 0 { body[bw] = 44; bw = bw + 1 } // ',' 915 body[bw] = 34; bw = bw + 1 // '"' 916 var c2: i64 = 0 917 while c2 < nl { body[bw] = dbuf[namep + c2]; bw = bw + 1; c2 = c2 + 1 } 918 body[bw] = 34; bw = bw + 1 919 first = 0 920 } } 921 if reclen <= 0 { off = nread } else { off = off + reclen } 922 } 923 } 924 } 925 sys_close(dfd) 926 } 927 body[bw] = 93; bw = bw + 1 // ']' 928 return hr_emit_b(dyn, NX_SD2_DYN_CAP, "HTTP/1.1 200 OK" as *u8, "application/json" as *u8, body, bw) 929} 930 931// GET /video/circle/<name> -- play one circle back. Name is taken from the 932// path, sanitized (no '/', no '..'); public first, then private (the 933// review-later view; honest residual: room-name capability is the only 934// auth until OPAQUE lands -- flagged in the deploy log, not hidden). 935func sd2_circle_play(plain: *u8, plain_n: i64, dyn: *u8) -> i64 { 936 // path starts after "GET /video/circle/" 937 let pfx: *u8 = "GET /video/circle/" as *u8 938 let pfxn: i64 = 18 939 var st: i64 = 0 - 1 940 var i: i64 = 0 941 while i + pfxn <= plain_n { 942 var j: i64 = 0 943 var ok: i64 = 1 944 while j < pfxn { 945 if plain[i + j] != pfx[j] { ok = 0; j = pfxn } else { j = j + 1 } 946 } 947 if ok == 1 { st = i + pfxn; i = plain_n } else { i = i + 1 } 948 } 949 if st < 0 { return hr_emit_404(dyn, NX_SD2_DYN_CAP) } 950 let name: *u8 = sys_mmap(256) 951 var nl: i64 = 0 952 while st < plain_n { 953 let c: u8 = plain[st] 954 if c == (32 as u8) { break } 955 if c == (63 as u8) { break } 956 if c == (13 as u8) { break } 957 if c == (47 as u8) { return hr_emit_404(dyn, NX_SD2_DYN_CAP) } // '/' 958 if c == (46 as u8) { if st + 1 < plain_n { if plain[st + 1] == (46 as u8) { return hr_emit_404(dyn, NX_SD2_DYN_CAP) } } } 959 if nl < 250 { name[nl] = c; nl = nl + 1 } 960 st = st + 1 961 } 962 if nl == 0 { return hr_emit_404(dyn, NX_SD2_DYN_CAP) } 963 name[nl] = 0 964 965 let path: *u8 = sys_mmap(512) 966 var w: i64 = sd2_append_str(path, 0, NX_SD2_CIRCLES_DIR) 967 w = sd2_append_str(path, w, "/public/" as *u8) 968 w = sd2_append(path, w, name, nl) 969 path[w] = 0 970 let lenbox: *i64 = (sys_mmap(8)) as *i64 971 lenbox[0] = 0 972 var data: *u8 = sys_read_file(path, lenbox) 973 if (data as i64) == 0 { 974 w = sd2_append_str(path, 0, NX_SD2_CIRCLES_DIR) 975 w = sd2_append_str(path, w, "/private/" as *u8) 976 w = sd2_append(path, w, name, nl) 977 path[w] = 0 978 lenbox[0] = 0 979 data = sys_read_file(path, lenbox) 980 } 981 if (data as i64) == 0 { return hr_emit_404(dyn, NX_SD2_DYN_CAP) } 982 let body_n: i64 = lenbox[0] 983 let w2: i64 = hr_emit_b(dyn, NX_SD2_DYN_CAP, "HTTP/1.1 200 OK" as *u8, "video/webm" as *u8, data, body_n) 984 if w2 < 0 { 985 let b: *u8 = "<!doctype html><h1>500 - circle exceeds serve buffer</h1>" as *u8 986 return hr_emit_b(dyn, NX_SD2_DYN_CAP, "HTTP/1.1 500 Internal Server Error" as *u8, "text/html; charset=utf-8" as *u8, b, sd2_strlen(b)) 987 } 988 return w2 989} 990 991// HTTP reverse-proxy to a loopback backend on 127.0.0.1:<port>. Forwards the already TLS-decrypted 992// request `plain` and reads the backend's full HTTP response into `dyn` (backend MUST close after its 993// response -- both the wiki engine :51850 and the OPAQUE login daemon :9091 send Connection: close + 994// close the fd -> read to EOF). A 15s upstream read timeout guarantees the child can never hang on a 995// stuck backend. Returns response length, or <=0 on failure (caller falls through -- ADDITIVE: a proxy 996// miss never breaks the site). license_tier: ORIGINAL (sovereign reverse proxy -- replaces nginx). 997func sd2_lc(c: i64) -> i64 { if c>=65 { if c<=90 { return c+32 } } return c } 998// THE DEADLINE SCANNER IS NOT HERE ON PURPOSE. dl_keylen / dl_is_hdr_line / dl_scan_request live in 999// nx_deadline_lib beside DL_HDR and the clamp, so the edge and every backend share ONE reader. Writing a 1000// sd2_-prefixed copy here is precisely the duplicate-ruler defect that left five gateways carrying five 1001// byte-identical gw_hdr_val bodies, and it would have put the copy on the far side of a fork boundary from 1002// the gate that proves it -- unprovable in-process, which is how a helper stops being tested at all. 1003func sd2_is_conn_line(plain: *u8, p: i64, n: i64) -> i64 { 1004 let key: *u8 = "connection:" as *u8 1005 var i: i64 = 0 1006 while i < 11 { if p+i >= n { return 0 } if sd2_lc(plain[p+i] as i64) != (key[i] as i64) { return 0 } i = i + 1 } 1007 return 1 1008} 1009// Rewrite the upstream request: drop any Connection: header line + insert "Connection: close", keep the body 1010// verbatim. ROOT-CAUSE FIX (galxauthprobe proved the gateway answers in 0ms; the hang is here): a keep-alive POST 1011// made the backend hold the socket open, so the proxy relay below BLOCKED waiting for a close that never came -> 1012// the client timed out (~10s) = "Failed to fetch". Forcing close => the backend closes after replying => clean EOF. 1013// deadline_ms <= 0 => byte-identical output to the original: no header emitted. The stamp is a NEW 1014// parameter on a NEW name, with the old name delegating, so every existing caller keeps its exact 1015// behaviour and the change cannot reach a path it was not aimed at. 1016func sd2_force_close(plain: *u8, n: i64, out: *u8) -> i64 { return sd2_force_close_dl(plain, n, out, 0) } 1017func sd2_force_close_dl(plain: *u8, n: i64, out: *u8, deadline_ms: i64) -> i64 { 1018 var he: i64 = 0 - 1 1019 var i: i64 = 0 1020 while i + 3 < n { 1021 if (plain[i] as i64)==13 { if (plain[i+1] as i64)==10 { if (plain[i+2] as i64)==13 { if (plain[i+3] as i64)==10 { he = i + 4 } } } } 1022 if he >= 0 { i = n } else { i = i + 1 } 1023 } 1024 if he < 0 { var k: i64 = 0; while k < n { out[k] = plain[k]; k = k + 1 } return n } 1025 var o: i64 = 0 1026 var p: i64 = 0 1027 let hend: i64 = he - 2 1028 while p < hend { 1029 var le: i64 = p 1030 var found: i64 = 0 1031 while found == 0 { 1032 if le + 1 >= hend { le = hend; found = 1 } 1033 else { if (plain[le] as i64)==13 { if (plain[le+1] as i64)==10 { found = 1 } else { le = le + 1 } } else { le = le + 1 } } 1034 } 1035 // DROP AN INBOUND DEADLINE WHEN WE ARE ABOUT TO WRITE OUR OWN. Without this the rewriter copied the 1036 // caller's header FIRST and appended ours after it, so a first-match reader (gw_hdr_val, in all five 1037 // gateways) returned the STALE one and our stamp was silently dead. TWO COPIES OF ONE HEADER IS NOT 1038 // A DUPLICATE, IT IS A SILENT OVERRIDE, AND THE LOSER IS WHICHEVER ONE THE READER SCANS PAST. 1039 // Guarded on deadline_ms > 0 so sd2_force_close (which passes 0) stays BYTE-IDENTICAL, exactly as 1040 // its contract above promises -- the stream path must still propagate a deadline it does not restamp. 1041 var drop: i64 = sd2_is_conn_line(plain, p, n) 1042 if deadline_ms > 0 { if dl_is_hdr_line(plain, p, n) == 1 { drop = 1 } } 1043 if drop == 0 { 1044 var c: i64 = p 1045 var cend: i64 = le + 2 1046 if cend > hend { cend = hend } 1047 while c < cend { out[o] = plain[c]; o = o + 1; c = c + 1 } 1048 } 1049 p = le + 2 1050 } 1051 let cc: *u8 = "Connection: close\r\n" as *u8 1052 var ci: i64 = 0 1053 while cc[ci] != (0 as u8) { out[o] = cc[ci]; o = o + 1; ci = ci + 1 } 1054 if deadline_ms > 0 { 1055 var di: i64 = 0 1056 while NX_SD2_DEADLINE_HDR[di] != (0 as u8) { out[o] = NX_SD2_DEADLINE_HDR[di]; o = o + 1; di = di + 1 } 1057 let dbuf: *u8 = sys_mmap(NX_SD2_DEC_BUF) 1058 let dn: i64 = sd2_u64_to_dec(deadline_ms, dbuf) 1059 var dj: i64 = 0 1060 while dj < dn { out[o] = dbuf[dj]; o = o + 1; dj = dj + 1 } 1061 out[o] = 13 as u8; o = o + 1 1062 out[o] = 10 as u8; o = o + 1 1063 } 1064 out[o] = 13 as u8; o = o + 1 1065 out[o] = 10 as u8; o = o + 1 1066 var b: i64 = he 1067 while b < n { out[o] = plain[b]; o = o + 1; b = b + 1 } 1068 return o 1069} 1070// BACKEND READ TIMEOUT -- NAMED 2026-08-06, VALUE DELIBERATELY UNCHANGED AT 15. 1071// It was a bare `15` inline: a Rule-11 magic number on the hottest path in the estate. Naming it is 1072// the fix; CHANGING it is not. 1073// 1074// ⚠THIS NUMBER IS ONE END OF A MATCHED PAIR. nx_tool_exec_allow.nx mirrors it as TEA_EDGE_WINDOW_MS 1075// and DERIVES its synchronous exec budget from it: 1076// const TEA_EDGE_WINDOW_MS: i64 = 15000 1077// const TEA_EXEC_TIMEOUT_SYNC_MS: i64 = TEA_EDGE_WINDOW_MS - 1000 1078// so the daemon always gives up ~1s INSIDE this window and can answer before the edge abandons the 1079// request. I raised this to 120 and it BROKE that pairing: the edge waited 120s while the daemon still 1080// quit at 14s, turning an honest 503 into a SILENT EMPTY 200 -- measured twice at 14.0s and 14.3s. 1081// Reverted. If this value ever must move, TEA_EDGE_WINDOW_MS MUST move in the same commit. 1082// 1083// AND DO NOT RAISE IT TO BUY TIME FOR SLOW WORK. That was tried and root-caused on 2026-07-30 1084// (ws=sev-eater): against a bounded 16-worker pool, a sync budget longer than the caller's patience 1085// saturated the agent surface for every seat -- 10 stuck handler pairs, 4 of 8 requests 503ing. Long 1086// work belongs in the detached async lane (_async=1 / nx_job_run), which returns a job id immediately. 1087// LAW, already banked here: THE TWO ENDS OF ONE PIPE ARE A MATCHED PAIR. A TIMEOUT LONGER THAN THE 1088// CALLER'S PATIENCE IS NOT SAFETY, IT IS CAPACITY BURNED ON NOBODY'S BEHALF. 1089const NX_SD2_BACKEND_TIMEOUT_S: i64 = 15 1090 1091// PER-ROUTE BACKEND TIMEOUT (search L2a, 2026-09-02): the buffered proxy loop treats the per-read socket timeout 1092// as a TOTAL deadline (a buffered backend writes nothing until its page is complete), so a cold /search that 1093// needs 16 s became a 503 at 15. The route table may now declare timeout=<s> per row (nx_proxy_route); the 1094// declared value replaces the constant ON THAT ROUTE ONLY, every other caller keeps NX_SD2_BACKEND_TIMEOUT_S. 1095func sd2_proxy_to(plain: *u8, plain_n: i64, dyn: *u8, port: i64) -> i64 { 1096 return sd2_proxy_to_tmo(plain, plain_n, dyn, port, NX_SD2_BACKEND_TIMEOUT_S) 1097} 1098func sd2_proxy_to_tmo(plain: *u8, plain_n: i64, dyn: *u8, port: i64, tmo_s: i64) -> i64 { 1099 // HONOUR AN INBOUND DEADLINE BEFORE SPENDING A SINGLE SYSCALL. This runs above sys_socket on purpose: 1100 // on a saturated box the whole value of deadline propagation is NOT starting work whose answer nobody 1101 // is still waiting for. A DEADLINE THAT IS ONLY CHECKED AFTER THE WORK IS AN AUDIT, NOT A BUDGET. 1102 // dl_wait_ms is the estate's proven clamp and can only ever SHORTEN: absent -> our own tmo unchanged, 1103 // live -> min(ours, theirs), expired -> 0. So a hop can never EXTEND a deadline it was handed, which is 1104 // the one property that makes propagation transitive across an arbitrary chain of hops. 1105 let dl_now: i64 = sys_now_ms() 1106 let dl_in: i64 = dl_scan_request(plain, plain_n) 1107 let dl_wait: i64 = dl_wait_ms(dl_in, dl_now, tmo_s * NX_SD2_MS_PER_S) 1108 if dl_wait <= 0 { return NX_SD2_PROXY_DEADLINE_EXPIRED } 1109 // Socket timeouts here are second-granular, so round the budget UP: truncating 400ms to 0 would mean 1110 // "no timeout" to sys_set_socket_timeout, turning the tightest deadline into the loosest wait -- the 1111 // failure would be in the flattering direction and invisible. DECLARED IMPRECISION: we may therefore 1112 // overrun a deadline by up to 999ms. That is the cost of a whole-second API and it is named, not hidden. 1113 var dl_tmo_s: i64 = dl_wait / NX_SD2_MS_PER_S 1114 if dl_tmo_s * NX_SD2_MS_PER_S < dl_wait { dl_tmo_s = dl_tmo_s + 1 } 1115 let ufd: i64 = sys_socket(AF_INET, SOCK_STREAM, 0) 1116 if ufd < 0 { return 0 - 1 } 1117 let addr: *u8 = sys_mmap(16) 1118 addr[0] = 2 as u8; addr[1] = 0 as u8 1119 addr[2] = ((port >> 8) & 0xff) as u8 1120 addr[3] = (port & 0xff) as u8 1121 addr[4] = 127 as u8; addr[5] = 0 as u8; addr[6] = 0 as u8; addr[7] = 1 as u8 1122 var zi: i64 = 8 1123 while zi < 16 { addr[zi] = 0 as u8; zi = zi + 1 } 1124 if nx_connect_bounded(ufd, addr, 16, NX_CONN_DEFAULT_MS) < 0 { sys_close(ufd); return 0 - 1 } 1125 sys_set_socket_timeout(ufd, dl_tmo_s) 1126 let fcbuf: *u8 = sys_mmap(NX_SD2_PLAINCAP) 1127 // Stamp the EFFECTIVE deadline, computed once above -- not a second sys_now_ms() call. Reading the 1128 // clock twice would let the stamped budget and the socket timeout disagree by the drift between them, 1129 // and TWO DERIVATIONS OF ONE QUANTITY ARE TWO QUANTITIES. 1130 let fcn: i64 = sd2_force_close_dl(plain, plain_n, fcbuf, dl_now + dl_wait) 1131 var wo: i64 = 0 1132 while wo < fcn { let w: i64 = sys_write(ufd, ((fcbuf as i64) + wo) as *u8, fcn - wo); if w <= 0 { sys_close(ufd); return 0 - 1 } wo = wo + w } 1133 var off: i64 = 0 1134 var reading: i64 = 1 1135 while reading == 1 { 1136 if off >= NX_SD2_DYN_CAP { reading = 0 } 1137 else { 1138 let r: i64 = sys_read(ufd, ((dyn as i64) + off) as *u8, NX_SD2_DYN_CAP - off) 1139 if r <= 0 { reading = 0 } else { off = off + r } 1140 } 1141 } 1142 sys_close(ufd) 1143 return off 1144} 1145 1146// STREAMING reverse-proxy (S-class media: NO 8MB buffer). Connect 127.0.0.1:port, forward the decrypted 1147// request, then read the backend response in 256KB windows and TLS-encrypt each straight to the client -- 1148// the file is NEVER buffered whole (the way real media servers serve byte-range video: read-chunk -> 1149// send-chunk, TCP backpressure paces it; cf. MDN HTTP Range requests / Media Source Extensions). Returns 1150// total bytes streamed, or -1 if the backend was unreachable (nothing sent yet -> caller may fall through). 1151// license_tier: ORIGINAL (loopback spine from sd2_proxy_to; TLS app-send from sd2_ws_pump). 1152func sd2_proxy_stream(s: *Tls13ServerSession, cfd: i64, plain: *u8, plain_n: i64, port: i64, out_rec: *u8) -> i64 { 1153 let ufd: i64 = sys_socket(AF_INET, SOCK_STREAM, 0) 1154 if ufd < 0 { return 0 - 1 } 1155 let addr: *u8 = sys_mmap(16) 1156 addr[0] = 2 as u8; addr[1] = 0 as u8 1157 addr[2] = ((port >> 8) & 0xff) as u8 1158 addr[3] = (port & 0xff) as u8 1159 addr[4] = 127 as u8; addr[5] = 0 as u8; addr[6] = 0 as u8; addr[7] = 1 as u8 1160 var zi: i64 = 8 1161 while zi < 16 { addr[zi] = 0 as u8; zi = zi + 1 } 1162 if nx_connect_bounded(ufd, addr, 16, NX_CONN_DEFAULT_MS) < 0 { sys_close(ufd); return 0 - 1 } 1163 sys_set_socket_timeout(ufd, 30) 1164 let fcbuf: *u8 = sys_mmap(NX_SD2_PLAINCAP) 1165 let fcn: i64 = sd2_force_close(plain, plain_n, fcbuf) 1166 var wo: i64 = 0 1167 while wo < fcn { let w: i64 = sys_write(ufd, ((fcbuf as i64) + wo) as *u8, fcn - wo); if w <= 0 { sys_close(ufd); return 0 - 1 } wo = wo + w } 1168 sys_write(1, "PXY-FWD\n" as *u8, 8) 1169 sys_set_socket_timeout(cfd, 600) // long-lived media stream: lift the accept-time client read timeout 1170 let chunk: *u8 = sys_mmap(NX_SD2_STREAM_CHUNK) 1171 var total: i64 = 0 1172 var go: i64 = 1 1173 var first: i64 = 1 1174 while go == 1 { 1175 let rn: i64 = sys_read(ufd, chunk, NX_SD2_STREAM_CHUNK) 1176 if first == 1 { if rn > 0 { sys_write(1, "PXY-GOT\n" as *u8, 8) } else { sys_write(1, "PXY-EOF0\n" as *u8, 9) } first = 0 } 1177 if rn <= 0 { go = 0 } else { 1178 if nx_tls13_app_send_fd(s, chunk, rn, cfd, out_rec, NX_SD2_OUTREC) < 0 { go = 0 } else { total = total + rn } 1179 } 1180 } 1181 sys_close(ufd) 1182 sys_write(1, "PXY-RET\n" as *u8, 8) 1183 return total 1184} 1185 1186// Wiki engine reverse-proxy (loopback 127.0.0.1:51850). 1187func sd2_wiki_proxy(plain: *u8, plain_n: i64, dyn: *u8) -> i64 { 1188 return sd2_proxy_to(plain, plain_n, dyn, NX_MAGIC_51850) 1189} 1190 1191// seq1306 (sev9, MEASURED 2026-07-30): route matching MUST NOT see the body. Every dispatcher match in 1192// this daemon scanned the WHOLE buffer, so a request whose BODY merely quoted a real route+query was 1193// HIJACKED by that handler (reproducer: uploading this daemon's own source 400'd, deterministic 6/6 -- 1194// the edge could not ship its own fix). It also let a body spoof header checks (X-Nishi-Session, Host, 1195// Accept). Fix: compute the header span ONCE per request and match only within it. Forwarding calls 1196// (sd2_proxy_to / sd2_fill_body) still get the FULL length -- bodies must still be proxied whole. 1197// Returns bytes up to and including the CRLFCRLF terminator, or n when no terminator is present. 1198func sd2_hdr_span(p: *u8, n: i64) -> i64 { 1199 var i: i64 = 0 1200 while i + 3 < n { 1201 if p[i] == (13 as u8) { if p[i+1] == (10 as u8) { if p[i+2] == (13 as u8) { if p[i+3] == (10 as u8) { return i + 4 } } } } 1202 i = i + 1 1203 } 1204 return n 1205} 1206// Is this request one of the OPAQUE login routes (/login, /register, /whoami, /audio)? Matched with a 1207// leading space so it fires only on the request-line path -- ⚠the leading space does NOT bound it to the 1208// request line (seq1306): callers MUST pass the header span, never the full request length. 1209func sd2_is_login_route(plain: *u8, plain_n: i64) -> i64 { 1210 if sd2_contains(plain, plain_n, " /login" as *u8, 7) == 1 { return 1 } 1211 if sd2_contains(plain, plain_n, " /register" as *u8, 10) == 1 { return 1 } 1212 if sd2_contains(plain, plain_n, " /whoami" as *u8, 8) == 1 { return 1 } 1213 if sd2_contains(plain, plain_n, " /audio" as *u8, 7) == 1 { return 1 } 1214 if sd2_contains(plain, plain_n, " /access" as *u8, 8) == 1 { return 1 } 1215 if sd2_contains(plain, plain_n, " /welcome" as *u8, 9) == 1 { return 1 } 1216 return 0 1217} 1218 1219// PUBLIC CARVE-OUT under the otherwise fully-gated /wiki tree (operator 2026-08-01: product strategy 1220// stays behind the gate, "code can exist without a gate as its fine to share that information and 1221// research as its public"). /wiki/research is the research OCEAN -- the index over every research 1222// river -- and is deliberately readable without a session. Nothing else under /wiki is affected. 1223// BOUNDARY-SAFE BY CONSTRUCTION: only the exact page and its .html / query forms are public, so a 1224// sibling file whose name merely STARTS with "research" (e.g. /wiki/research_private.html) can NOT 1225// ride this carve-out. A prefix match here would be an escape hatch, not a carve-out. 1226func sd2_wiki_public(p: *u8, n: i64) -> i64 { 1227 if sd2_contains(p, n, " /wiki/research " as *u8, 16) == 1 { return 1 } 1228 if sd2_contains(p, n, " /wiki/research.html" as *u8, 20) == 1 { return 1 } 1229 if sd2_contains(p, n, " /wiki/research?" as *u8, 16) == 1 { return 1 } 1230 return 0 1231} 1232// 1 = this request must go through the OPAQUE wiki gate; 0 = not a /wiki path at all, OR an explicitly 1233// public one, which then falls through to normal static routing. Replaces a bare /wiki substring test 1234// at the gate call site so the allowlist lives in ONE named place instead of inline at the branch. 1235func sd2_wiki_gated(p: *u8, n: i64) -> i64 { 1236 if sd2_contains(p, n, " /wiki" as *u8, 6) == 0 { return 0 } 1237 if sd2_wiki_public(p, n) == 1 { return 0 } 1238 return 1 1239} 1240 1241func sd2_atoi(s: *u8) -> i64 { var v: i64=0; var i: i64=0; while s[i]!=(0 as u8){ let c: i64=s[i] as i64; if c<48{return v} if c>57{return v} v=v*10+(c-48); i=i+1 } return v } 1242 1243func main(argc: i64, argv: *i64) -> i64 { 1244 // listen port: argv[1] overrides NX_SD2_PORT (default 8443). Lets a fresh build be 1245 // scratch-tested on a spare port without disturbing the live :8443 daemon. 1246 var listen_port: i64 = NX_SD2_PORT 1247 if argc > 1 { listen_port = sd2_atoi(argv[1] as *u8) } 1248 // ---- Route B: load the per-domain wildcard pairs; PAIRED fail-safe to the generic pair ---- 1249 // NISHI (index 0) = the default for absent/garbled/unknown SNI. If its per-domain pair is 1250 // incomplete, the legacy generic both-SAN pair serves it (exactly today's behavior). 1251 let cert_len_box: *i64 = (sys_mmap(8)) as *i64 1252 var cert_nishi: *u8 = sd2_load_chain(NX_SD2_CERT_NISHI, cert_len_box) 1253 var cert_nishi_len: i64 = cert_len_box[0] 1254 var ecdsa_nishi: *u8 = sd2_load_key(NX_SD2_PRIV_NISHI) 1255 var nishi_src: i64 = 1 // 1 = per-domain files, 0 = generic fallback 1256 if (cert_nishi as i64) == 0 { nishi_src = 0 } 1257 if (ecdsa_nishi as i64) == 0 { nishi_src = 0 } 1258 if nishi_src == 0 { 1259 cert_nishi = sd2_load_chain(NX_SD2_CERT_PATH, cert_len_box) 1260 cert_nishi_len = cert_len_box[0] 1261 ecdsa_nishi = sd2_load_key(NX_SD2_PRIV_PATH) 1262 } 1263 if (cert_nishi as i64) == 0 { return 2 } 1264 if (ecdsa_nishi as i64) == 0 { return 3 } 1265 1266 // ANDELIN (index 1). PAIRED fail-safe: any missing/short file -> serve the NISHI pair for 1267 // andelinwest hosts (a valid handshake still completes; never a mismatched cert/key). 1268 let andelin_len_box: *i64 = (sys_mmap(8)) as *i64 1269 var cert_andelin: *u8 = sd2_load_chain(NX_SD2_CERT_ANDELIN, andelin_len_box) 1270 var cert_andelin_len: i64 = andelin_len_box[0] 1271 var ecdsa_andelin: *u8 = sd2_load_key(NX_SD2_PRIV_ANDELIN) 1272 var andelin_src: i64 = 1 1273 if (cert_andelin as i64) == 0 { andelin_src = 0 } 1274 if (ecdsa_andelin as i64) == 0 { andelin_src = 0 } 1275 if andelin_src == 0 { 1276 cert_andelin = cert_nishi 1277 cert_andelin_len = cert_nishi_len 1278 ecdsa_andelin = ecdsa_nishi 1279 } 1280 1281 // ---- DATA-DRIVEN cert table: load the manifest (row 0 = default). Fall back to the legacy 1282 // nishi+andelin pair if the manifest is absent/empty so nothing regresses (rule 20 fail-safe). ---- 1283 let cert_suf_ptrs: *i64 = (sys_mmap(NX_SD2_CERT_MAX * 8)) as *i64 1284 let cert_suf_lens: *i64 = (sys_mmap(NX_SD2_CERT_MAX * 8)) as *i64 1285 let cert_buf_ptrs: *i64 = (sys_mmap(NX_SD2_CERT_MAX * 8)) as *i64 1286 let cert_buf_lens: *i64 = (sys_mmap(NX_SD2_CERT_MAX * 8)) as *i64 1287 let cert_key_ptrs: *i64 = (sys_mmap(NX_SD2_CERT_MAX * 8)) as *i64 1288 let man_box: *i64 = (sys_mmap(8)) as *i64 1289 man_box[0] = 0 1290 let man_buf: *u8 = sys_read_file(NX_SD2_CERT_MANIFEST, man_box) 1291 var cert_count: i64 = 0 1292 if (man_buf as i64) != 0 { 1293 cert_count = sd2_load_cert_table(man_buf, man_box[0], cert_suf_ptrs, cert_suf_lens, cert_buf_ptrs, cert_buf_lens, cert_key_ptrs, NX_SD2_CERT_MAX) 1294 } 1295 if cert_count == 0 { 1296 cert_suf_ptrs[0] = ("nishifamily.com" as *u8) as i64 1297 cert_suf_lens[0] = 15 1298 cert_buf_ptrs[0] = cert_nishi as i64 1299 cert_buf_lens[0] = cert_nishi_len 1300 cert_key_ptrs[0] = ecdsa_nishi as i64 1301 cert_suf_ptrs[1] = ("andelinwest.com" as *u8) as i64 1302 cert_suf_lens[1] = 15 1303 cert_buf_ptrs[1] = cert_andelin as i64 1304 cert_buf_lens[1] = cert_andelin_len 1305 cert_key_ptrs[1] = ecdsa_andelin as i64 1306 cert_count = 2 1307 } 1308 sys_write(1, "nishi sites daemon v2: SNI cert table rows=" as *u8, 43) 1309 let ccb2: *u8 = sys_mmap(24) 1310 let ccn2: i64 = sd2_u64_to_dec(cert_count, ccb2) 1311 sys_write(1, ccb2, ccn2) 1312 sys_write(1, "\n" as *u8, 1) 1313 1314 let sd_cfg_box: *i64 = (sys_mmap(8)) as *i64 1315 sd_cfg_box[0] = 0 1316 var sites_cfg: *u8 = sys_read_file(NX_SD2_SITES_CONF, sd_cfg_box) 1317 var sites_cfg_n: i64 = 0 1318 if (sites_cfg as i64) != 0 { sites_cfg_n = sd_cfg_box[0] } 1319 // load the data-driven proxy route table (absent file -> proxy_cfg_n=0 -> legacy cascade only) 1320 let pr_cfg_box: *i64 = (sys_mmap(8)) as *i64 1321 pr_cfg_box[0] = 0 1322 var proxy_cfg: *u8 = sys_read_file(NX_SD2_PROXY_CONF, pr_cfg_box) 1323 var proxy_cfg_n: i64 = 0 1324 if (proxy_cfg as i64) != 0 { proxy_cfg_n = pr_cfg_box[0] } 1325 // ANNOUNCE THE TABLE ONCE PER LOAD. pr_mode fails CLOSED on an unrecognised mode token, which 1326 // keeps a typo from downgrading a fail-closed route -- but a silent fail-closed is still a 1327 // route nobody meant. This prints the row count and NAMES the line of every offender, so the 1328 // refusal is decidable from the log instead of being discovered by a user. 1329 if proxy_cfg_n > 0 { pr_conf_announce(proxy_cfg, proxy_cfg_n) } 1330 // load the data-driven ADNET inventory (absent -> adnet_cfg_n=0 -> slots OFF + no click route) 1331 let ad_cfg_box: *i64 = (sys_mmap(8)) as *i64 1332 ad_cfg_box[0] = 0 1333 let adnet_cfg: *u8 = sys_read_file(NX_SD2_ADNET_CONF, ad_cfg_box) 1334 var adnet_cfg_n: i64 = 0 1335 if (adnet_cfg as i64) != 0 { adnet_cfg_n = ad_cfg_box[0] } 1336 var ad_imp_fd: i64 = 0 - 1 1337 var ad_clk_fd: i64 = 0 - 1 1338 if adnet_cfg_n > 0 { ad_imp_fd = sys_openat_append(NX_SD2_ADNET_IMPLOG, 420) } 1339 if adnet_cfg_n > 0 { ad_clk_fd = sys_openat_append(NX_SD2_ADNET_CLKLOG, 420) } 1340 var ad_view_fd: i64 = 0 - 1 1341 if adnet_cfg_n > 0 { ad_view_fd = sys_openat_append(NX_SD2_ADNET_VIEWLOG, 420) } 1342 if adnet_cfg_n > 0 { 1343 let adr1: *u8 = "adnet: inventory loaded, slots ON\n" as *u8 1344 sys_write(1, adr1, sd2_strlen(adr1)) 1345 } else { 1346 let adr0: *u8 = "adnet: no inventory, slots OFF\n" as *u8 1347 sys_write(1, adr0, sd2_strlen(adr0)) 1348 } 1349 1350 let addr_buf: *u8 = sys_mmap(16) 1351 nx_http_server_addr_any(addr_buf, listen_port) 1352 let lv: *i64 = (sys_mmap(8)) as *i64 1353 let lfd: i64 = nx_http_server_listen(addr_buf, 16, lv) 1354 // ⚠THIS USED TO BE A BARE `return 4` THAT PRINTED NOTHING, AND THAT SILENCE COST A WHOLE 1355 // INVESTIGATION ON 2026-09-03. A deploy of this daemon came back `ROLLED-BACK 1356 // listen=NEVER-LISTENED`: the watchdog polled 10 times over 30 s (twice the supervisor's <=15 s 1357 // respawn, so it was generous enough) and never saw a listener -- and there was no line ANYWHERE 1358 // saying why, because the one code path that knows exits mute. 1359 // ★★A DAEMON THAT FAILS TO BIND AND PRINTS NOTHING IS INDISTINGUISHABLE FROM A DAEMON THAT WAS 1360 // NEVER STARTED, AND ON THE FRONT DOOR THAT AMBIGUITY IS THE WHOLE DIAGNOSIS. The rollback is 1361 // correct and fires either way; what was missing was the sentence that names the cause. 1362 // Lengths are DERIVED via sd2_strlen, never hand-counted beside the literal -- the estate banks 1363 // that a hand-counted length is a second copy of the string's shape and the two drift silently. 1364 if lfd < 0 { 1365 let m1: *u8 = "nishi sites daemon v2: REFUSED -- could not listen on 0.0.0.0:" as *u8 1366 sys_write(1, m1, sd2_strlen(m1)) 1367 nxi_out(listen_port) 1368 let m2: *u8 = " (nx_http_server_listen rc=" as *u8 1369 sys_write(1, m2, sd2_strlen(m2)) 1370 nxi_out(lfd) 1371 let m3: *u8 = "). The port is in use, or the bind was refused. LIVE BINARY UNTOUCHED -- nothing was replaced by this process.\n" as *u8 1372 sys_write(1, m3, sd2_strlen(m3)) 1373 return 4 1374 } 1375 // ZOMBIE-REAP (2026-07-15): SO_RCVTIMEO on the listen socket -> accept() returns EAGAIN every 5s when 1376 // idle, so the wait4(WNOHANG) reap at the loop top runs promptly (not only when the next connection 1377 // arrives). Keeps the graceful fork-bomb cap intact; a real connection still returns immediately. 1378 sys_set_socket_timeout(lfd, 5) 1379 // ⚠THE PORT IN THIS BANNER USED TO BE THE LITERAL 8443 WITH A HAND-COUNTED 69 BESIDE IT, while 1380 // argv[1] has overridden the port since the day the override was added. So a scratch test on a 1381 // spare port announced ":8443" -- ★A MESSAGE THAT NAMES THE WRONG SUBJECT COSTS THE READER THE 1382 // INVESTIGATION IT WAS WRITTEN TO SAVE THEM, and it made the one facility that exists for testing 1383 // a fresh edge build (the spare-port override) unreadable in its own output. 1384 let bmsg: *u8 = "nishi sites daemon v2: vhosts + wss/video + circles on 0.0.0.0:" as *u8 1385 sys_write(1, bmsg, sd2_strlen(bmsg)) 1386 nxi_out(listen_port) 1387 let bnl: *u8 = "\n" as *u8 1388 sys_write(1, bnl, sd2_strlen(bnl)) 1389 // Route B receipt: WHICH pair each domain serves (visible in sitetest / sites_run.log). 1390 if nishi_src == 1 { sys_write(1, "sni-cert nishi=per-domain\n" as *u8, 26) } else { sys_write(1, "sni-cert nishi=generic\n" as *u8, 23) } 1391 if andelin_src == 1 { sys_write(1, "sni-cert andelin=per-domain\n" as *u8, 28) } else { sys_write(1, "sni-cert andelin=nishi-fallback\n" as *u8, 32) } 1392 1393 let ctype_html: *u8 = "text/html; charset=utf-8" as *u8 1394 let nb_andelin: i64 = sd2_strlen(BODY2_ANDELIN) 1395 let nb_wiki: i64 = sd2_strlen(BODY2_WIKI) 1396 let nb_family: i64 = sd2_strlen(BODY2_FAMILY) 1397 let resp_andelin: *u8 = sys_mmap(nb_andelin + NX_SD2_HDR_RESERVE) 1398 let resp_wiki: *u8 = sys_mmap(nb_wiki + NX_SD2_HDR_RESERVE) 1399 let resp_family: *u8 = sys_mmap(nb_family + NX_SD2_HDR_RESERVE) 1400 let n_andelin: i64 = sd2_build_resp(resp_andelin, ctype_html, BODY2_ANDELIN, nb_andelin) 1401 let n_wiki: i64 = sd2_build_resp(resp_wiki, ctype_html, BODY2_WIKI, nb_wiki) 1402 let n_family: i64 = sd2_build_resp(resp_family, ctype_html, BODY2_FAMILY, nb_family) 1403 let n_favicon: i64 = sd2_strlen(RESP2_FAVICON) 1404 1405 var resp_wstatus: *u8 = sys_mmap(NX_SD2_STATUS_CAP) 1406 let wstatus_box: *i64 = (sys_mmap(8)) as *i64 1407 wstatus_box[0] = 0 1408 let wstatus_rc: i64 = nx_wiki_status_handle(resp_wstatus, NX_SD2_STATUS_CAP, wstatus_box) 1409 var n_wstatus: i64 = wstatus_box[0] 1410 if wstatus_rc != 0 { resp_wstatus = resp_wiki; n_wstatus = n_wiki } 1411 if n_wstatus <= 0 { resp_wstatus = resp_wiki; n_wstatus = n_wiki } 1412 1413 var resp_art_crawler: *u8 = sys_mmap(NX_SD2_ART_CAP) 1414 let acr_box: *i64 = (sys_mmap(8)) as *i64 1415 acr_box[0] = 0 1416 let acr_rc: i64 = nx_wiki_article_handle("crawler" as *u8, 7, resp_art_crawler, NX_SD2_ART_CAP, acr_box) 1417 var n_art_crawler: i64 = acr_box[0] 1418 if acr_rc != 0 { resp_art_crawler = resp_wiki; n_art_crawler = n_wiki } 1419 if n_art_crawler <= 0 { resp_art_crawler = resp_wiki; n_art_crawler = n_wiki } 1420 1421 var resp_art_x25519: *u8 = sys_mmap(NX_SD2_ART_CAP) 1422 let axx_box: *i64 = (sys_mmap(8)) as *i64 1423 axx_box[0] = 0 1424 let axx_rc: i64 = nx_wiki_article_handle("x25519" as *u8, 6, resp_art_x25519, NX_SD2_ART_CAP, axx_box) 1425 var n_art_x25519: i64 = axx_box[0] 1426 if axx_rc != 0 { resp_art_x25519 = resp_wiki; n_art_x25519 = n_wiki } 1427 if n_art_x25519 <= 0 { resp_art_x25519 = resp_wiki; n_art_x25519 = n_wiki } 1428 1429 var resp_art_ranking: *u8 = sys_mmap(NX_SD2_ART_CAP) 1430 let ark_box: *i64 = (sys_mmap(8)) as *i64 1431 ark_box[0] = 0 1432 let ark_rc: i64 = nx_wiki_article_handle("ranking-math" as *u8, 12, resp_art_ranking, NX_SD2_ART_CAP, ark_box) 1433 var n_art_ranking: i64 = ark_box[0] 1434 if ark_rc != 0 { resp_art_ranking = resp_wiki; n_art_ranking = n_wiki } 1435 if n_art_ranking <= 0 { resp_art_ranking = resp_wiki; n_art_ranking = n_wiki } 1436 1437 var resp_art_wiki: *u8 = sys_mmap(NX_SD2_ART_CAP) 1438 let awe_box: *i64 = (sys_mmap(8)) as *i64 1439 awe_box[0] = 0 1440 let awe_rc: i64 = nx_wiki_article_handle("wiki-engine" as *u8, 11, resp_art_wiki, NX_SD2_ART_CAP, awe_box) 1441 var n_art_wiki: i64 = awe_box[0] 1442 if awe_rc != 0 { resp_art_wiki = resp_wiki; n_art_wiki = n_wiki } 1443 if n_art_wiki <= 0 { resp_art_wiki = resp_wiki; n_art_wiki = n_wiki } 1444 1445 var resp_components: *u8 = sys_mmap(NX_SD2_ART_CAP) 1446 let aci_box: *i64 = (sys_mmap(8)) as *i64 1447 aci_box[0] = 0 1448 let aci_rc: i64 = nx_wiki_components_handle(resp_components, NX_SD2_ART_CAP, aci_box) 1449 var n_components: i64 = aci_box[0] 1450 if aci_rc != 0 { resp_components = resp_wiki; n_components = n_wiki } 1451 if n_components <= 0 { resp_components = resp_wiki; n_components = n_wiki } 1452 1453 var resp_projects: *u8 = resp_wiki 1454 var n_projects: i64 = n_wiki 1455 1456 // CONSTANT MEMORY: hoisted per-connection buffers (see v1 rationale). 1457 let server_random: *u8 = sys_mmap(32) 1458 let server_x25519_priv: *u8 = sys_mmap(32) 1459 let rec_buf: *u8 = sys_mmap(NX_SD2_RECCAP) 1460 let plain: *u8 = sys_mmap(NX_SD2_PLAINCAP) 1461 let out_rec: *u8 = sys_mmap(NX_SD2_OUTREC) 1462 let pump: *u8 = sys_mmap(NX_SD2_RECCAP) 1463 let dyn_buf: *u8 = sys_mmap(NX_SD2_DYN_CAP) 1464 let sock_addr: *u8 = sys_mmap(64) 1465 let sock_len: *i64 = (sys_mmap(8)) as *i64 1466 let tel_buf: *u8 = sys_mmap(256) 1467 let tel_fd: i64 = sys_openat_append(NX_SD2_TELEMETRY_PATH, 420) 1468 // Route B: hoisted SNI-peek buffers (constant memory; children get a COW copy on write). 1469 let sni_peek: *u8 = sys_mmap(NX_SD2_SNI_PEEK_CAP) 1470 let sni_host: *u8 = sys_mmap(256) 1471 1472 sys_set_socket_timeout(lfd, 5) 1473 let reap_status: *i64 = (sys_mmap(8)) as *i64 1474 var served: i64 = 0 1475 var live: i64 = 0 1476 1477 // ---- HOT-RELOAD (2026-07-15): config changes go LIVE on the NEXT CONNECTION, no restart. On each 1478 // accepted connection the PARENT (single-threaded between accepts; forked children snapshot a 1479 // consistent copy) compares (mtime,size) of cert-manifest / sites.conf / proxy_routes.conf and 1480 // re-reads on change. The cert table loads into TEMP arrays and copies over ONLY on a non-empty 1481 // parse, so a half-written/broken manifest can never wipe the live table (fail-safe, rule 14/20). 1482 let hr_statb: *u8 = sys_mmap(160) 1483 let hr_sig: *i64 = (sys_mmap(16)) as *i64 1484 var man_mt: i64 = 0 - 1 1485 var man_sz: i64 = 0 - 1 1486 if sd2_statsig(NX_SD2_CERT_MANIFEST, hr_statb, hr_sig) == 0 { man_mt = hr_sig[0]; man_sz = hr_sig[1] } 1487 var sc_mt: i64 = 0 - 1 1488 var sc_sz: i64 = 0 - 1 1489 if sd2_statsig(NX_SD2_SITES_CONF, hr_statb, hr_sig) == 0 { sc_mt = hr_sig[0]; sc_sz = hr_sig[1] } 1490 var prc_mt: i64 = 0 - 1 1491 var prc_sz: i64 = 0 - 1 1492 if sd2_statsig(NX_SD2_PROXY_CONF, hr_statb, hr_sig) == 0 { prc_mt = hr_sig[0]; prc_sz = hr_sig[1] } 1493 let tmp_suf_ptrs: *i64 = (sys_mmap(NX_SD2_CERT_MAX * 8)) as *i64 1494 let tmp_suf_lens: *i64 = (sys_mmap(NX_SD2_CERT_MAX * 8)) as *i64 1495 let tmp_buf_ptrs: *i64 = (sys_mmap(NX_SD2_CERT_MAX * 8)) as *i64 1496 let tmp_buf_lens: *i64 = (sys_mmap(NX_SD2_CERT_MAX * 8)) as *i64 1497 let tmp_key_ptrs: *i64 = (sys_mmap(NX_SD2_CERT_MAX * 8)) as *i64 1498 1499 while served < NX_SD2_BUDGET { 1500 while sys_wait4(0 - 1, reap_status, 1) > 0 { live = live - 1 } 1501 1502 sock_len[0] = 16 1503 let cfd: i64 = sys_accept_with_addr(lfd, sock_addr, sock_len) 1504 if cfd < 0 { continue } 1505 1506 // hot-reload check (parent, pre-fork): the connection just accepted already sees fresh config. 1507 if sd2_statsig(NX_SD2_CERT_MANIFEST, hr_statb, hr_sig) == 0 { 1508 if hr_sig[0] != man_mt || hr_sig[1] != man_sz { 1509 man_mt = hr_sig[0] 1510 man_sz = hr_sig[1] 1511 let mb2: *i64 = (sys_mmap(8)) as *i64 1512 mb2[0] = 0 1513 let mbuf2: *u8 = sys_read_file(NX_SD2_CERT_MANIFEST, mb2) 1514 if (mbuf2 as i64) != 0 { 1515 let nc2: i64 = sd2_load_cert_table(mbuf2, mb2[0], tmp_suf_ptrs, tmp_suf_lens, tmp_buf_ptrs, tmp_buf_lens, tmp_key_ptrs, NX_SD2_CERT_MAX) 1516 if nc2 > 0 { 1517 var ci2: i64 = 0 1518 while ci2 < nc2 { 1519 cert_suf_ptrs[ci2] = tmp_suf_ptrs[ci2] 1520 cert_suf_lens[ci2] = tmp_suf_lens[ci2] 1521 cert_buf_ptrs[ci2] = tmp_buf_ptrs[ci2] 1522 cert_buf_lens[ci2] = tmp_buf_lens[ci2] 1523 cert_key_ptrs[ci2] = tmp_key_ptrs[ci2] 1524 ci2 = ci2 + 1 1525 } 1526 cert_count = nc2 1527 sys_write(1, "hot-reload: cert table\n" as *u8, 23) 1528 } 1529 } 1530 } 1531 } 1532 if sd2_statsig(NX_SD2_SITES_CONF, hr_statb, hr_sig) == 0 { 1533 if hr_sig[0] != sc_mt || hr_sig[1] != sc_sz { 1534 sc_mt = hr_sig[0] 1535 sc_sz = hr_sig[1] 1536 let scb2: *i64 = (sys_mmap(8)) as *i64 1537 scb2[0] = 0 1538 let scfg2: *u8 = sys_read_file(NX_SD2_SITES_CONF, scb2) 1539 if (scfg2 as i64) != 0 { 1540 sites_cfg = scfg2 1541 sites_cfg_n = scb2[0] 1542 sys_write(1, "hot-reload: sites.conf\n" as *u8, 23) 1543 } 1544 } 1545 } 1546 if sd2_statsig(NX_SD2_PROXY_CONF, hr_statb, hr_sig) == 0 { 1547 if hr_sig[0] != prc_mt || hr_sig[1] != prc_sz { 1548 prc_mt = hr_sig[0] 1549 prc_sz = hr_sig[1] 1550 let pcb2: *i64 = (sys_mmap(8)) as *i64 1551 pcb2[0] = 0 1552 let pcfg2: *u8 = sys_read_file(NX_SD2_PROXY_CONF, pcb2) 1553 if (pcfg2 as i64) != 0 { 1554 proxy_cfg = pcfg2 1555 proxy_cfg_n = pcb2[0] 1556 // Same announce on the HOT PATH into the table. An edit that introduces a bad 1557 // mode token arrives HERE, not at startup, so a check that only ran at startup 1558 // would never see the row that actually broke. 1559 pr_conf_announce(proxy_cfg, proxy_cfg_n) 1560 sys_write(1, "hot-reload: proxy_routes.conf\n" as *u8, 30) 1561 } 1562 } 1563 } 1564 1565 if live >= NX_SD2_MAX_CHILDREN { 1566 if sys_wait4(0 - 1, reap_status, 0) > 0 { live = live - 1 } 1567 } 1568 1569 let pid: i64 = sys_fork() 1570 if pid == 0 { 1571 // ---- CHILD ---- 1572 sys_close(lfd) 1573 let acc_lan: i64 = nx_access_is_lan(sock_addr) 1574 sys_set_socket_timeout(cfd, 10) 1575 let nodelay: *u8 = sys_mmap(4) 1576 nodelay[0] = 1 as u8; nodelay[1] = 0 as u8; nodelay[2] = 0 as u8; nodelay[3] = 0 as u8 1577 sys_setsockopt(cfd, 6, 1, nodelay, 4) 1578 nx_csprng_fill(server_random, 32) 1579 nx_csprng_fill(server_x25519_priv, 32) 1580 // ---- Route B: SNI-aware cert selection ---- 1581 // MSG_PEEK the cleartext ClientHello (non-consuming), pick the per-domain wildcard 1582 // pair by the SNI, then run the UNCHANGED handshake serving that pair. Any peek 1583 // failure / absent / unknown SNI -> the default (nishifamily) pair. 1584 let pk_n: i64 = sys_recvfrom(cfd, sni_peek, NX_SD2_SNI_PEEK_CAP, NX_SD2_MSG_PEEK, 0 as *u8, 0 as *i64) 1585 // DATA-DRIVEN: pick the cert-table row from the SNI (row 0 = default; unknown/absent -> 0). 1586 var cert_idx: i64 = 0 1587 if pk_n > 0 { cert_idx = scs_pick_from_clienthello_table(sni_peek, pk_n, sni_host, 256, cert_suf_ptrs, cert_suf_lens, cert_count) } 1588 if cert_idx < 0 { cert_idx = 0 } 1589 if cert_idx >= cert_count { cert_idx = 0 } 1590 var use_cert: *u8 = cert_buf_ptrs[cert_idx] as *u8 1591 var use_cert_len: i64 = cert_buf_lens[cert_idx] 1592 var use_priv: *u8 = cert_key_ptrs[cert_idx] as *u8 1593 let t_hs0: i64 = sys_now_us() 1594 let hs_rc: i64 = nx_tls13_server_session_run( 1595 cfd, server_random, server_x25519_priv, 1596 use_cert, use_cert_len, use_priv) 1597 let hs_us: i64 = sys_now_us() - t_hs0 1598 // hs_rc carries TWO meanings: >0 it is a Tls13ServerSession HANDLE (cast below), <=0 it is a 1599 // failure status. Telemetry wants only the status. Passing the handle into a parameter named 1600 // `rc` conflated the two -- nx_telemetry_emit already had to defend itself with `if rc > 0 { rc = 0 }`, 1601 // which is the tell that a pointer was arriving where a status was declared. Narrow it ONCE, here, 1602 // so the serving path never hands an address to something that will report it as a number. 1603 var hs_stat: i64 = hs_rc 1604 if hs_stat > 0 { hs_stat = 0 } 1605 var vhost_id: i64 = 0 1606 var served_bytes: i64 = 0 1607 if hs_rc > 0 { 1608 let s: *Tls13ServerSession = hs_rc as *Tls13ServerSession 1609 var keep: i64 = 1 1610 var nreq: i64 = 0 1611 while keep == 1 { 1612 if nreq >= NX_SD2_MAX_REQ_PER_CONN { 1613 keep = 0 1614 } else { 1615 let plain_n: i64 = sd2_recv_request(s, cfd, rec_buf, plain, NX_SD2_PLAINCAP) 1616 let hdr_n: i64 = sd2_hdr_span(plain, plain_n) // seq1306: routes match HEADERS ONLY 1617 if plain_n <= 0 { 1618 keep = 0 1619 } else { 1620 // ---- D4: wss upgrade? consumes the connection ---- 1621 var is_ws: i64 = 0 1622 if sd2_contains(plain, hdr_n, "GET /signal/" as *u8, 12) == 1 { 1623 if sd2_contains_ci(plain, plain_n, "upgrade: websocket" as *u8, 18) == 1 { is_ws = 1 } 1624 if sd2_contains_ci(plain, plain_n, "upgrade:websocket" as *u8, 17) == 1 { is_ws = 1 } 1625 } 1626 if is_ws == 1 { 1627 vhost_id = 21 1628 sd2_ws_pump(s, cfd, plain, plain_n, rec_buf, out_rec, pump) 1629 keep = 0 1630 } else { 1631 var resp: *u8 = resp_family 1632 var resp_n: i64 = n_family 1633 let is_favicon: i64 = sd2_contains(plain, hdr_n, "favicon" as *u8, 7) 1634 if is_favicon == 1 { 1635 resp = RESP2_FAVICON; resp_n = n_favicon; vhost_id = 9 1636 } else { 1637 var dyn_done: i64 = 0 1638 // ---- DEBRIS REFUSAL (2026-07-30). Rollback/backup/temp artifacts sitting in a 1639 // docroot were being SERVED 200: measured https://andelinwest.com/index.html.bak-v1 1640 // returning a whole previous CLIENT homepage, plus 65 .prev/.bak/.nxw artifacts on 1641 // nishifamily. Every one is a public duplicate-content + information-disclosure 1642 // surface. Refused FIRST, before any handler can serve them, so the guarantee does 1643 // not depend on which route would have won. Path-bounded (hr_req_path), never a 1644 // whole-header scan -- a Referer carrying .bak must not 404 a real page. 1645 let dbz: *u8 = sys_mmap(NX_MAGIC_4096) 1646 let dbn: i64 = hr_req_path(plain, hdr_n, dbz, NX_MAGIC_4096) 1647 var dbg: i64 = 0 1648 if sd2_contains(dbz, dbn, ".prev" as *u8, 5) == 1 { dbg = 1 } 1649 if sd2_contains(dbz, dbn, ".bak" as *u8, 4) == 1 { dbg = 1 } 1650 if sd2_contains(dbz, dbn, ".nxw" as *u8, 4) == 1 { dbg = 1 } 1651 if sd2_contains(dbz, dbn, ".nxtmp" as *u8, 6) == 1 { dbg = 1 } 1652 if sd2_contains(dbz, dbn, ".nxpub" as *u8, 6) == 1 { dbg = 1 } 1653 if dbg == 1 { resp_n = hr_emit_404(dyn_buf, NX_SD2_DYN_CAP); resp = dyn_buf; vhost_id = 23; dyn_done = 1 } 1654 // ---- VIEWABLE-IMPRESSION BEACON: /ad/view/<id> (MRC 50pct for 1 continuous second). 1655 // Journalled SEPARATELY from served impressions so served/viewable stays a visible, 1656 // honest delivery ratio. FAIL-CLOSED: aview_resp only fills av_id for a well-formed 1657 // inventory id, so a forged or replayed path answers 204 and journals NOTHING. 1658 if dyn_done == 0 { if aview_is_path(dbz, dbn) == 1 { 1659 let av_id: *u8 = sys_mmap(128) 1660 let avr: i64 = aview_resp(dbz, dbn, dyn_buf, NX_SD2_DYN_CAP, av_id) 1661 if avr > 0 { 1662 resp = dyn_buf; resp_n = avr; vhost_id = 26; dyn_done = 1 1663 if ad_view_fd >= 0 { if av_id[0] != (0 as u8) { 1664 let avl: *u8 = sys_mmap(160) 1665 var avn: i64 = 0 1666 while av_id[avn] != (0 as u8) { avl[avn] = av_id[avn]; avn = avn + 1 } 1667 avl[avn] = 10 as u8 1668 avn = avn + 1 1669 sys_write(ad_view_fd, avl, avn) 1670 } } 1671 } 1672 } } 1673 // ---- HOT HOME: nishifamily root ("GET / HTTP") served from a LIVING FILE 1674 // (sites/nishifamily/home.html) so the front door updates via a file push, no 1675 // recompile -- the sovereign nav landing (nx_site_chrome home). NEVER-BRICK: 1676 // an absent/empty/unreadable file leaves dyn_done=0 -> the baked resp_family 1677 // (BODY2_FAMILY) serves EXACTLY as before. Guarded to nishifamily: skip if the 1678 // andelinwest host header is present (its root is served on its own vhost). 1679 if dyn_done == 0 { if sd2_contains(plain, hdr_n, "GET / HTTP" as *u8, 10) == 1 { 1680 // Nishifamily hot-home for the nishifamily apex + the DEFAULT (unknown) host ONLY. 1681 // Any OTHER registered vhost (andelinwest, b2b.loans, ...) skips this and serves its 1682 // OWN sites.conf docroot below -- data-driven, no per-domain hardcode. 1683 let hh_known: i64 = hr_known_host(sites_cfg, sites_cfg_n, plain, plain_n) 1684 let hh_nishi: i64 = sd2_contains(plain, hdr_n, "nishifamily" as *u8, 11) 1685 // A host registered ONLY in proxy_routes.conf (a capability subdomain such as 1686 // admin.<client>.com) is NOT "unknown" -- it is declared in a DIFFERENT table. 1687 // Without this, the default landing PRE-EMPTS its route and a client's admin 1688 // portal serves OUR homepage. MEASURED 2026-08-22: admin.andelinwest.com/ 1689 // returned nishifamily home.html while /index.html correctly returned the 1690 // document portal. Only a row whose PREFIX is exactly "/" can match here, and 1691 // nishifamily.com has no such row -- so apex + unknown-host landing is unchanged. 1692 var hh_proxied: i64 = 0 1693 if proxy_cfg_n > 0 { 1694 let hh_host: *u8 = sys_mmap(256) 1695 let hh_root: *u8 = sys_mmap(8) 1696 hh_root[0] = 47 as u8; hh_root[1] = 0 as u8 1697 let hh_hn: i64 = hr_req_host(plain, plain_n, hh_host, 256) 1698 let hh_pb: *i64 = (sys_mmap(8)) as *i64 1699 let hh_mb: *i64 = (sys_mmap(8)) as *i64 1700 if pr_lookup(proxy_cfg, proxy_cfg_n, hh_host, hh_hn, hh_root, 1, hh_pb, hh_mb) == 1 { hh_proxied = 1 } 1701 } 1702 var hh_ok: i64 = 0 1703 if hh_proxied == 0 { 1704 if hh_known == 0 { hh_ok = 1 } 1705 else { if hh_nishi == 1 { hh_ok = 1 } } 1706 } 1707 if hh_ok == 1 { 1708 let hm_box: *i64 = (sys_mmap(8)) as *i64; hm_box[0] = 0 1709 let hm_buf: *u8 = sys_read_file("/volume1/homes/elderwesto/nishihost/sites/nishifamily/home.html" as *u8, hm_box) 1710 if (hm_buf as i64) != 0 { if hm_box[0] > 0 { resp = dyn_buf; resp_n = sd2_build_resp(dyn_buf, ctype_html, hm_buf, hm_box[0]); vhost_id = 33; dyn_done = 1 } } 1711 } 1712 } } 1713 // ---- DATA-DRIVEN PROXY ROUTES (nx_proxy_route): app routes are CONFIG ROWS, no 1714 // recompile. Matched BEFORE the legacy hardcoded cascade. ADDITIVE + SAFE: no match 1715 // (or proxy_routes.conf absent -> proxy_cfg_n=0) leaves dyn_done=0 -> the legacy 1716 // cascade serves exactly as before. mode buffered(0)=sd2_proxy_to, stream(1)= 1717 // sd2_proxy_stream, gated(2)=proxy + fail-closed 302 /login. Same ports/semantics as 1718 // the cascade -> a config "match" is byte-identical to the hardcoded route it shadows. 1719 if dyn_done == 0 { if proxy_cfg_n > 0 { 1720 let pr_host: *u8 = sys_mmap(256) 1721 let pr_path: *u8 = sys_mmap(NX_MAGIC_4096) 1722 let pr_hn: i64 = hr_req_host(plain, plain_n, pr_host, 256) 1723 let pr_pn: i64 = hr_req_path(plain, hdr_n, pr_path, NX_MAGIC_4096) 1724 let pr_portb: *i64 = (sys_mmap(8)) as *i64 1725 let pr_modeb: *i64 = (sys_mmap(8)) as *i64 1726 let pr_tmob: *i64 = (sys_mmap(8)) as *i64 1727 if pr_lookup_tmo(proxy_cfg, proxy_cfg_n, pr_host, pr_hn, pr_path, pr_pn, pr_portb, pr_modeb, pr_tmob) == 1 { 1728 if pr_modeb[0] == 1 { 1729 let pst: i64 = sd2_proxy_stream(s, cfd, plain, plain_n, pr_portb[0], out_rec) 1730 if pst >= 0 { served_bytes = served_bytes + pst; resp_n = 0; vhost_id = 70; dyn_done = 1; keep = 0 } 1731 } else { 1732 // buffered/gated: complete the request body FIRST (sd2_fill_body; 1733 // fail-safe no-op for GETs/complete bodies) so >8KB POST chunks 1734 // reach the backend whole -- the API bulk-upload unlock. 1735 if sd2_content_length(plain, plain_n) > NX_SD2_PLAINCAP { 1736 resp = RESP2_413; resp_n = sd2_strlen(RESP2_413); vhost_id = 13; dyn_done = 1; keep = 0 1737 } else { 1738 let pfn: i64 = sd2_fill_body(s, cfd, rec_buf, plain, plain_n, NX_SD2_PLAINCAP) 1739 var pr_tmo: i64 = pr_tmob[0] 1740 if pr_tmo <= 0 { pr_tmo = NX_SD2_BACKEND_TIMEOUT_S } 1741 let pbr: i64 = sd2_proxy_to_tmo(plain, pfn, dyn_buf, pr_portb[0], pr_tmo) 1742 if pbr > 0 { resp = dyn_buf; resp_n = pbr; vhost_id = 70; dyn_done = 1 } 1743 else { if pr_modeb[0] == 2 { resp = RESP2_GATE_LOGIN; resp_n = sd2_strlen(RESP2_GATE_LOGIN); vhost_id = 70; dyn_done = 1 } else { 1744 // seq1294 (both edge outages, 07-20 + 07-29): a PROXIED route whose backend 1745 // yielded NO bytes is an ERROR -- falling through to the static cascade served 1746 // the HOMEPAGE as a 200, and that HTML-to-a-machine-client is the retry-storm 1747 // trigger. Content-negotiated honest 503 + Retry-After instead: machines (no 1748 // text/html in Accept) get RFC-9457 problem+json; browsers get a real 503 page. 1749 var e_w: i64 = 0 1750 // A DEADLINE THAT WAS ALREADY GONE IS NOT AN UPSTREAM FAULT AND MUST NOT BE REPORTED AS ONE. 1751 // 504, because nothing upstream was even attempted -- and deliberately NO Retry-After: the clock 1752 // that expired is the CALLER's, so advising a 5s retry would be advice about the wrong clock. 1753 var est: *u8 = "HTTP/1.1 503 Service Unavailable\r\nRetry-After: 5" as *u8 1754 if pbr == NX_SD2_PROXY_DEADLINE_EXPIRED { est = "HTTP/1.1 504 Gateway Timeout" as *u8 } 1755 // AN ACCEPTED-BUT-SILENT READ ON A WRITE IS AN UNKNOWN OUTCOME, NOT AN UNAVAILABILITY, AND ADVISING A 1756 // RETRY IS ACTIVELY HARMFUL. pbr==0 means the backend ACCEPTED the request and said nothing inside the 1757 // window, so a non-idempotent write MAY ALREADY HAVE COMMITTED -- and this estate's own law is that an 1758 // insert edit is not idempotent, so a blind retry double-applies. MEASURED 2026-09-03: three /api writes 1759 // (a build that produced a 94320 B artifact, the promote that installed it, and a debt add that committed) 1760 // each returned this exact 503 with Retry-After, and each HAD ALREADY LANDED. The stage labelling shipped 1761 // 2026-09-02 named WHICH stage failed; it did not stop the response advising the one action that corrupts. 1762 // Disjoint from both arms above by construction: this requires pbr==0, connect requires pbr<0, deadline -2. 1763 // ONE CALL, ONE RULER: nx_edge_refusal_lib owns this decision and nx_edge_refusal_gate proves it. 1764 // The three lines this replaces were a second copy of the discriminator, which is the duplicate-ruler 1765 // defect in miniature -- two places that must agree about what an unsafe method is, agreeing by habit. 1766 let unsafe_w: i64 = er_read_after_accept(plain, pbr) 1767 if unsafe_w == 1 { est = "HTTP/1.1 503 Service Unavailable" as *u8 } 1768 if sd2_contains(plain, hdr_n, "text/html" as *u8, 9) == 1 { 1769 // NAME THE STAGE THAT FAILED (2026-09-02, debt 1788361379). sd2_proxy_to returns <0 when the backend could 1770 // not be CONNECTED or written to (refused: restarting or down) and 0 when it accepted the request but sent 1771 // nothing inside the edge window. Both used to print the timeout sentence; a 16h outage of a backend that 1772 // was refusing in 40ms was reported, every time, as a window overrun. 1773 var eb: *u8 = "<!doctype html><h1>503 backend unavailable</h1><p>The service behind this route did not answer inside the edge window. Retry shortly.</p>" as *u8 1774 if pbr < 0 { eb = "<!doctype html><h1>503 backend unavailable</h1><p>The service behind this route is not listening (connection refused): it is restarting or down. Retry shortly.</p>" as *u8 } 1775 // AFTER the pbr<0 arm on purpose: -2 is also < 0, so this must override it or a dead deadline 1776 // reports as a refused connection -- the wrong subject, which is the defect being fixed. 1777 if pbr == NX_SD2_PROXY_DEADLINE_EXPIRED { eb = "<!doctype html><h1>504 deadline exceeded</h1><p>This request arrived carrying a deadline that had already passed, so no upstream work was started. Nothing is wrong with the service behind this route.</p>" as *u8 } 1778 if unsafe_w == 1 { eb = "<!doctype html><h1>503 outcome unknown</h1><p>The service behind this route ACCEPTED this request and then gave no answer inside the edge window. Because this was a write, it may already have taken effect. Do not simply retry: check whether it landed first, then re-issue only if it did not.</p>" as *u8 } 1779 e_w = hr_emit_b(dyn_buf, NX_SD2_DYN_CAP, est, "text/html; charset=utf-8" as *u8, eb, sd2_strlen(eb)) 1780 } else { 1781 var ej: *u8 = "{\"type\":\"about:blank\",\"title\":\"Service Unavailable\",\"status\":503,\"stage\":\"read\",\"detail\":\"upstream backend accepted the request but gave no response inside the edge window; retry after 5s\"}" as *u8 1782 if pbr < 0 { ej = "{\"type\":\"about:blank\",\"title\":\"Service Unavailable\",\"status\":503,\"stage\":\"connect\",\"detail\":\"upstream backend refused the connection (not listening: restarting or down); retry after 5s\"}" as *u8 } 1783 if pbr == NX_SD2_PROXY_DEADLINE_EXPIRED { ej = "{\"type\":\"about:blank\",\"title\":\"Gateway Timeout\",\"status\":504,\"stage\":\"deadline\",\"detail\":\"the request arrived carrying X-Nishi-Deadline-Mono-Ms that had already expired; no upstream work was started and the backend is not implicated\"}" as *u8 } 1784 if unsafe_w == 1 { ej = "{\"type\":\"about:blank\",\"title\":\"Outcome Unknown\",\"status\":503,\"stage\":\"read-after-accept\",\"retry\":\"unsafe\",\"detail\":\"the upstream backend ACCEPTED this unsafe-method request and produced no response inside the edge window, so the OUTCOME IS UNKNOWN and the write may already have committed; do NOT blind-retry a non-idempotent call -- verify the artifact first and re-issue only if it did not land\"}" as *u8 } 1785 e_w = hr_emit_b(dyn_buf, NX_SD2_DYN_CAP, est, "application/problem+json" as *u8, ej, sd2_strlen(ej)) 1786 } 1787 if e_w > 0 { resp = dyn_buf; resp_n = e_w; vhost_id = 71; dyn_done = 1; keep = 0 } 1788 } } 1789 } 1790 } 1791 } 1792 } } 1793 // ---- ADNET first-party click redirect (/ad/click/<id>) + per-AD click counter. 1794 // No visitor id/cookie ever; unknown/invalid id -> 302 / (fail-closed). Only alive 1795 // when the inventory conf exists (adnet_cfg_n>0) -> zero behavior change otherwise. 1796 if dyn_done == 0 { if adnet_cfg_n > 0 { 1797 if sd2_contains(plain, hdr_n, "GET /ad/click/" as *u8, 14) == 1 { 1798 let ac_path: *u8 = sys_mmap(NX_MAGIC_4096) 1799 let ac_pn: i64 = hr_req_path(plain, hdr_n, ac_path, NX_MAGIC_4096) 1800 let ac_id: *u8 = sys_mmap(128) 1801 let ac_w: i64 = aslot_click_resp(adnet_cfg, adnet_cfg_n, ac_path, ac_pn, dyn_buf, NX_SD2_DYN_CAP, ac_id) 1802 if ac_w > 0 { 1803 resp = dyn_buf; resp_n = ac_w; vhost_id = 28; dyn_done = 1 1804 if ad_clk_fd >= 0 { if ac_id[0] != (0 as u8) { 1805 let ac_line: *u8 = sys_mmap(160) 1806 var ac_ln: i64 = 0 1807 while ac_id[ac_ln] != (0 as u8) { ac_line[ac_ln] = ac_id[ac_ln]; ac_ln = ac_ln + 1 } 1808 ac_line[ac_ln] = 10 as u8 1809 ac_ln = ac_ln + 1 1810 sys_write(ad_clk_fd, ac_line, ac_ln) 1811 } } 1812 } 1813 } 1814 } } 1815 // ---- ADNET public aggregate dashboard (/ad/dash): per-AD served/click counters 1816 // rendered LIVE from the append-only logs each request (BOUNDED reads, rule 21). 1817 // Aggregate-only by construction (logs carry ad ids, never visitor identity) -> 1818 // public transparency is safe; the page self-opts-out of slot injection. 1819 if dyn_done == 0 { if adnet_cfg_n > 0 { 1820 if sd2_contains(plain, hdr_n, "GET /ad/dash" as *u8, 12) == 1 { 1821 let dd_il: *u8 = sys_mmap(NX_MAGIC_1048576) 1822 let dd_iln: i64 = and_read_bounded(NX_SD2_ADNET_IMPLOG, dd_il, NX_MAGIC_1048576) 1823 let dd_cl: *u8 = sys_mmap(NX_MAGIC_1048576) 1824 let dd_cln: i64 = and_read_bounded(NX_SD2_ADNET_CLKLOG, dd_cl, NX_MAGIC_1048576) 1825 let dd_page: *u8 = sys_mmap(NX_MAGIC_262144) 1826 let dd_pn: i64 = and_page(adnet_cfg, adnet_cfg_n, dd_il, dd_iln, dd_cl, dd_cln, dd_page, NX_MAGIC_262144) 1827 if dd_pn > 0 { 1828 let dd_w: i64 = hr_emit_b(dyn_buf, NX_SD2_DYN_CAP, "HTTP/1.1 200 OK" as *u8, "text/html; charset=utf-8" as *u8, dd_page, dd_pn) 1829 if dd_w > 0 { resp = dyn_buf; resp_n = dd_w; vhost_id = 29; dyn_done = 1 } 1830 } 1831 } 1832 } } 1833 // ---- SELF-SERVE advertiser intake (/ad/submit): GET renders the zero-JS form, 1834 // POST validates (fail-closed, same validators as serving) + stages to a NON-public 1835 // operator-review journal (nishihost/adnet_submissions.log). STAGED IS NOT LIVE. 1836 if dyn_done == 0 { if adnet_cfg_n > 0 { 1837 if sd2_contains(plain, hdr_n, " /ad/submit" as *u8, 11) == 1 { 1838 let su_page: *u8 = sys_mmap(NX_MAGIC_131072) 1839 var su_pn: i64 = 0 1840 if sd2_contains(plain, hdr_n, "POST /ad/submit" as *u8, 15) == 1 { 1841 let su_bs: i64 = sd2_body_start(plain, plain_n) 1842 let su_body: *u8 = ((plain as i64) + su_bs) as *u8 1843 let su_bn: i64 = plain_n - su_bs 1844 su_pn = asf_post(su_body, su_bn, "adnet_submissions.log" as *u8, su_page, NX_MAGIC_131072) 1845 } else { 1846 su_pn = asf_form_page(su_page, NX_MAGIC_131072) 1847 } 1848 if su_pn > 0 { 1849 let su_w: i64 = hr_emit_b(dyn_buf, NX_SD2_DYN_CAP, "HTTP/1.1 200 OK" as *u8, "text/html; charset=utf-8" as *u8, su_page, su_pn) 1850 if su_w > 0 { resp = dyn_buf; resp_n = su_w; vhost_id = 31; dyn_done = 1 } 1851 } 1852 } 1853 } } 1854 // RACI: /video is OWNED solely by hr_resolve (clean URL -> video/index.html), 1855 // exactly like /games. The old bare-/video -> 301 /video/ rule here was a SECOND, 1856 // competing owner; colliding with the file server's slash handling it produced 1857 // "too many redirects". Removed per the single-owner principle -> /video falls 1858 // through to the file server (hr_serve2), which serves video/index.html directly. 1859 // /advertising (top-level, operator-only) -> 301 to the OPAQUE-gated census page 1860 if dyn_done == 0 { if sd2_contains(plain, hdr_n, "GET /advertising HTTP" as *u8, 21) == 1 { 1861 resp = RESP2_ADV_301; resp_n = sd2_strlen(RESP2_ADV_301); vhost_id = 26; dyn_done = 1 1862 } } 1863 // bare /status and /status/ -> /status.html (the live supervisor-emitted dashboard). 1864 // "GET /status HTTP"(16) matches ONLY exact /status (not /status.html -> ".html"!=" "). 1865 if dyn_done == 0 { if sd2_contains(plain, hdr_n, "GET /status HTTP" as *u8, 16) == 1 { 1866 resp = RESP2_STATUS_301; resp_n = sd2_strlen(RESP2_STATUS_301); vhost_id = 27; dyn_done = 1 1867 } } 1868 if dyn_done == 0 { if sd2_contains(plain, hdr_n, "GET /status/ HTTP" as *u8, 17) == 1 { 1869 resp = RESP2_STATUS_301; resp_n = sd2_strlen(RESP2_STATUS_301); vhost_id = 27; dyn_done = 1 1870 } } 1871 // ---- OPAQUE no-cookie login (sovereign): reverse-proxy /login,/register, 1872 // /whoami,/audio to the loopback login daemon (127.0.0.1:9091). This serves 1873 // nishifamily.com/login from the Nishi substrate itself -- NO nginx, NO third 1874 // party. ADDITIVE: a proxy miss leaves dyn_done=0 -> normal routing serves. 1875 if dyn_done == 0 { if sd2_is_login_route(plain, hdr_n) == 1 { 1876 let lpr: i64 = sd2_proxy_to(plain, plain_n, dyn_buf, NX_MAGIC_9091) 1877 if lpr > 0 { resp = dyn_buf; resp_n = lpr; vhost_id = 50; dyn_done = 1 } 1878 } } 1879 // ---- GALLERY (OPAQUE-gated, NSFW): reverse-proxy /gallery -> bridge 1880 // (127.0.0.1:18190) -> reverse-tunnel -> workstation gateway:18091 (OPAQUE 1881 // session check) -> gallery:18090. ADDITIVE: a proxy miss (bridge down) 1882 // leaves dyn_done=0 -> normal routing serves; /gallery is never a public byte 1883 // unless the OPAQUE gateway authorized it. 1884 if dyn_done == 0 { if sd2_contains(plain, hdr_n, " /gallery" as *u8, 9) == 1 { 1885 // STREAM /gallery (large video + images) chunk-by-chunk to the client -- 1886 // NO 8MB dyn_buf cap, NO buffer-then-send latency. gst>=0 => already sent 1887 // (resp_n=0 skips the buffered D1 send); gst<0 => backend down, fall through. 1888 let gst: i64 = sd2_proxy_stream(s, cfd, plain, plain_n, NX_SD2_PORT_GALLERY_BRIDGE, out_rec) 1889 if gst >= 0 { served_bytes = served_bytes + gst; resp_n = 0; vhost_id = 60; dyn_done = 1; keep = 0 } 1890 } } 1891 // ---- WIKI (OPAQUE-gated, Nishi Family): reverse-proxy /wiki -> the wiki 1892 // gateway (127.0.0.1:18791; OPAQUE session check, no session -> login page). 1893 // ADDITIVE: a proxy miss (gateway down) leaves dyn_done=0 -> normal routing serves. 1894 if dyn_done == 0 { if sd2_wiki_gated(plain, hdr_n) == 1 { 1895 // no-cookie redirect fix: a TOP-LEVEL nav (Accept: text/html, NO X-Nishi-Session) gets the 1896 // return-aware bootstrap, not the wiki gateway's stale board()->hub login. Session-fetches + 1897 // assets (no text/html) still proxy unchanged -> no asset/content regression. 1898 var wiki_done: i64 = 0 1899 if sd2_contains(plain, hdr_n, "X-Nishi-Session" as *u8, 15) == 0 { if sd2_contains(plain, hdr_n, "text/html" as *u8, 9) == 1 { 1900 resp = dyn_buf; resp_n = sd2_build_resp(dyn_buf, ctype_html, BODY2_WIKI_BOOTSTRAP, sd2_strlen(BODY2_WIKI_BOOTSTRAP)); vhost_id = 61; dyn_done = 1; wiki_done = 1 1901 } } 1902 if wiki_done == 0 { 1903 let wgpr: i64 = sd2_proxy_to(plain, plain_n, dyn_buf, NX_SD2_PORT_WIKI_GATEWAY) 1904 if wgpr > 0 { resp = dyn_buf; resp_n = wgpr; vhost_id = 61; dyn_done = 1 } 1905 else { resp = RESP2_GATE_LOGIN; resp_n = sd2_strlen(RESP2_GATE_LOGIN); vhost_id = 61; dyn_done = 1 } 1906 } 1907 } } 1908 // ---- HUB (OPAQUE-gated, maturity-flag leveled): reverse-proxy /hub -> the hub gateway 1909 // (127.0.0.1:18792; mr_route over the maturity registry; OPAQUE session -> level). 1910 // FAIL-CLOSED: a proxy miss -> 302 /login (never a public byte), mirroring /wiki. 1911 if dyn_done == 0 { if sd2_contains(plain, hdr_n, " /hub" as *u8, 5) == 1 { 1912 let hgpr: i64 = sd2_proxy_to(plain, plain_n, dyn_buf, NX_SD2_PORT_HUB_GATEWAY) 1913 if hgpr > 0 { resp = dyn_buf; resp_n = hgpr; vhost_id = 62; dyn_done = 1 } 1914 else { resp = RESP2_GATE_LOGIN; resp_n = sd2_strlen(RESP2_GATE_LOGIN); vhost_id = 62; dyn_done = 1 } 1915 } } 1916 // ---- GEN (Elder AI image generation, OPAQUE-gated owner): reverse-proxy /gen -> 1917 // the gen gateway (127.0.0.1:18794; family OPAQUE session + he_has_access(/gen) -> 1918 // orchestrator :18795 -> laptop 5080). FAIL-CLOSED: a proxy miss (gateway down) -> 1919 // 302 /login (never a public byte), mirroring /wiki,/hub. ADDITIVE: the leading-space 1920 // " /gen" matches only the request-line path, never a header, so other sites are untouched. 1921 if dyn_done == 0 { if sd2_contains(plain, hdr_n, " /gen" as *u8, 5) == 1 { 1922 let ggpr: i64 = sd2_proxy_to(plain, plain_n, dyn_buf, NX_SD2_PORT_GEN_GATEWAY) 1923 if ggpr > 0 { resp = dyn_buf; resp_n = ggpr; vhost_id = 64; dyn_done = 1 } 1924 else { resp = RESP2_GATE_LOGIN; resp_n = sd2_strlen(RESP2_GATE_LOGIN); vhost_id = 64; dyn_done = 1 } 1925 } } 1926 // ---- TORRENT/MEDIA acquirer (OPAQUE-gated, owner): reverse-proxy /torrent -> the 1927 // torrent gateway (127.0.0.1:18793; OPAQUE session -> X-Nishi-Level:OWNER -> daemon :8097). 1928 // STREAMED (the acquirer serves video). ADDITIVE: a proxy miss leaves dyn_done=0 -> normal routing. 1929 if dyn_done == 0 { if sd2_contains(plain, hdr_n, " /torrent" as *u8, 9) == 1 { 1930 let tst: i64 = sd2_proxy_stream(s, cfd, plain, plain_n, NX_SD2_PORT_TORRENT_GATEWAY, out_rec) 1931 if tst >= 0 { served_bytes = served_bytes + tst; resp_n = 0; vhost_id = 63; dyn_done = 1 } 1932 } } 1933 // ---- STUDIO (OPAQUE-gated, operator-only): reverse-proxy /studio -> NAS-local 1934 // gated daemon (127.0.0.1:18099; OPAQUE session check, no token -> 401). ADDITIVE: 1935 // a proxy miss leaves dyn_done=0 -> normal routing serves; /studio is never a 1936 // public byte unless the OPAQUE gate authorized it. [[project-image-stack-ownership-2026-06-17]] 1937 if dyn_done == 0 { if sd2_contains(plain, hdr_n, " /studio" as *u8, 8) == 1 { 1938 let spr: i64 = sd2_proxy_to(plain, plain_n, dyn_buf, NX_SD2_PORT_STUDIO) 1939 if spr > 0 { resp = dyn_buf; resp_n = spr; vhost_id = 61; dyn_done = 1 } 1940 } } 1941 // ---- LIBRARY (nishifamily.com/library): reverse-proxy /library -> the 1942 // auth-walled Calibre reader (127.0.0.1:8791, keeper-supervised). The reader 1943 // is /library-prefix-aware (input-strips /library, serves <base href=/library/>). 1944 // ADDITIVE: a proxy miss (reader down) leaves dyn_done=0 -> normal routing serves. 1945 if dyn_done == 0 { if sd2_contains(plain, hdr_n, " /library" as *u8, 9) == 1 { 1946 let lipr: i64 = sd2_proxy_to(plain, plain_n, dyn_buf, NX_SD2_PORT_READER) 1947 if lipr > 0 { resp = dyn_buf; resp_n = lipr; vhost_id = 61; dyn_done = 1 } 1948 } } 1949 // ---- MEDIA (nishifamily.com/media): the FAMILY-facing SFW library -> the SAME 1950 // auth-walled media reader (127.0.0.1:8791). The reader is /media-prefix-aware + 1951 // denies the owner-only /mnt/nas_logging (galx_media_path_ok) so family gets SFW 1952 // only; the owner-only recordings/NSFW are /gallery. ADDITIVE: a miss falls through. 1953 if dyn_done == 0 { if sd2_contains(plain, hdr_n, " /media" as *u8, 7) == 1 { 1954 let mepr: i64 = sd2_proxy_to(plain, plain_n, dyn_buf, NX_SD2_PORT_READER) 1955 if mepr > 0 { resp = dyn_buf; resp_n = mepr; vhost_id = 61; dyn_done = 1 } 1956 } } 1957 // ---- PUBLIC ADVERTISER INTAKE: the last mile of the ad network ---- 1958 // The lane could serve, measure, price, invoice and enforce campaigns, but a 1959 // prospective client had NO WAY TO APPLY -- the catalog showed what was for sale 1960 // with no door beside it. GET /advertise is that door. 1961 // STAGED-NEVER-LIVE: a submission goes to the staged journal via ass_submit and is 1962 // inert until an operator approves it. That is the safety property, not the form. 1963 if dyn_done == 0 { if sd2_contains(plain, hdr_n, "GET /advertise" as *u8, 14) == 1 { 1964 let ap_body: *u8 = sys_mmap(NX_MAGIC_8192) 1965 let ap_n: i64 = aap_page(ap_body, NX_MAGIC_8192) 1966 if ap_n > 0 { 1967 resp = dyn_buf; resp_n = sd2_build_resp(dyn_buf, ctype_html, ap_body, ap_n) 1968 vhost_id = 27; dyn_done = 1 1969 } 1970 } } 1971 if dyn_done == 0 { if sd2_contains(plain, hdr_n, "POST /advertise/apply" as *u8, 21) == 1 { 1972 // PERSIST FIRST, ACK SECOND. An acknowledgement that is emitted whether or not 1973 // the application was stored tells a prospective client they applied while the 1974 // submission is discarded -- worse than no form at all. 1975 // NOT ass_submit: that validates a COMPLETE inventory row including a 1976 // first-party creative url, which an applicant cannot have yet (the upload is 1977 // what we send them AFTER acceptance). Applications get their own journal. 1978 let ap_bs: i64 = sd2_body_start(plain, plain_n) 1979 let ap_bp: *u8 = ((plain as i64) + ap_bs) as *u8 1980 let ap_bl: i64 = plain_n - ap_bs 1981 // BODY CAP: four short form fields cannot legitimately exceed 8KB. Without 1982 // this a multi-megabyte POST is parsed and copied per request on a route 1983 // anyone on the internet can call. 1984 var ap_ok: i64 = aap_body_ok(ap_bl) 1985 let f_co: *u8 = sys_mmap(NX_SD2_ADNET_CO_CAP) 1986 let f_em: *u8 = sys_mmap(NX_SD2_ADNET_EM_CAP) 1987 let f_cu: *u8 = sys_mmap(NX_SD2_ADNET_CU_CAP) 1988 let f_nt: *u8 = sys_mmap(NX_SD2_ADNET_NOTE_CAP) 1989 aap_field(ap_bp, ap_bl, "company" as *u8, f_co, NX_SD2_ADNET_CO_CAP) 1990 aap_field(ap_bp, ap_bl, "email" as *u8, f_em, NX_SD2_ADNET_EM_CAP) 1991 aap_field(ap_bp, ap_bl, "clickurl" as *u8, f_cu, NX_SD2_ADNET_CU_CAP) 1992 aap_field(ap_bp, ap_bl, "note" as *u8, f_nt, NX_SD2_ADNET_NOTE_CAP) 1993 let ap_rowb: *u8 = sys_mmap(NX_MAGIC_4096) 1994 var ap_rn: i64 = 0 1995 if ap_ok == 1 { ap_rn = aap_row(f_co, f_em, f_cu, f_nt, sys_now_us() / SYS_MAGIC_1000000, ap_rowb, NX_MAGIC_4096) } 1996 // JOURNAL CEILING: an append-only file on a public unauthenticated route is a 1997 // disk-exhaustion primitive. Past the ceiling we refuse the APPEND but still 1998 // ack -- a spammer learns nothing from the response, and a real applicant 1999 // arriving during a flood is not shown an error we cannot explain. An 2000 // unstattable journal does NOT block a genuine applicant (fail-open here is 2001 // correct: the alternative is one bad stat silently closing the front door). 2002 let ap_stb: *u8 = sys_mmap(160) 2003 var ap_cur: i64 = 0 - 1 2004 if sys_fstatat(NX_SD2_ADNET_APPS, ap_stb) == 0 { 2005 let ap_szp: *i64 = ((ap_stb as i64) + 48) as *i64 2006 ap_cur = ap_szp[0] 2007 } 2008 if ap_rn > 0 { if aap_journal_ok(ap_cur) == 1 { 2009 // opened per request on purpose: applications are rare, and a long-lived 2010 // append fd on a public unauthenticated route is a bigger liability than 2011 // one open() on a path nobody hot-loops. 2012 let ap_fd: i64 = sys_openat_append(NX_SD2_ADNET_APPS, 420) 2013 if ap_fd >= 0 { sys_write(ap_fd, ap_rowb, ap_rn); sys_close(ap_fd) } 2014 } } 2015 let ak_body: *u8 = sys_mmap(NX_MAGIC_4096) 2016 let ak_n: i64 = aap_ack(ak_body, NX_MAGIC_4096) 2017 if ak_n > 0 { 2018 resp = dyn_buf; resp_n = sd2_build_resp(dyn_buf, ctype_html, ak_body, ak_n) 2019 vhost_id = 28; dyn_done = 1 2020 } 2021 } } 2022 // ---- D5: circles ---- 2023 if sd2_contains(plain, hdr_n, "POST /video/circle?" as *u8, 19) == 1 { 2024 resp_n = sd2_circle_upload(s, cfd, plain, plain_n, rec_buf, pump, dyn_buf) 2025 resp = dyn_buf; vhost_id = 22; dyn_done = 1 2026 } 2027 if dyn_done == 0 { if sd2_contains(plain, hdr_n, "GET /video/circles" as *u8, 18) == 1 { 2028 resp_n = sd2_circle_list(plain, plain_n, dyn_buf) 2029 resp = dyn_buf; vhost_id = 23; dyn_done = 1 2030 } } 2031 if dyn_done == 0 { if sd2_contains(plain, hdr_n, "GET /video/circle/" as *u8, 18) == 1 { 2032 resp_n = sd2_circle_play(plain, plain_n, dyn_buf) 2033 resp = dyn_buf; vhost_id = 24; dyn_done = 1 2034 } } 2035 // ---- wiki dynamic routes (v1 behaviour) ---- 2036 if dyn_done == 0 { if sd2_contains(plain, hdr_n, "POST /wiki/request" as *u8, 18) == 1 { 2037 let bstart: i64 = sd2_body_start(plain, plain_n) 2038 let dnq: *i64 = (sys_mmap(8)) as *i64 2039 dnq[0] = 0 2040 let prc: i64 = nx_wiki_request_handle((plain as i64 + bstart) as *u8, plain_n - bstart, dyn_buf, NX_SD2_DYN_CAP, dnq) 2041 if prc == 0 { resp = dyn_buf; resp_n = dnq[0]; vhost_id = 10; dyn_done = 1 } 2042 } } 2043 if dyn_done == 0 { if sd2_contains(plain, hdr_n, "/wiki/queue" as *u8, 11) == 1 { 2044 let dnq2: *i64 = (sys_mmap(8)) as *i64 2045 dnq2[0] = 0 2046 let qrc: i64 = nx_wiki_queue_handle(dyn_buf, NX_SD2_DYN_CAP, dnq2) 2047 if qrc == 0 { resp = dyn_buf; resp_n = dnq2[0]; vhost_id = 11; dyn_done = 1 } 2048 } } 2049 // ---- D3: hot file hosting with fallthrough (+ universal ADNET slot injection). 2050 // adnet_cfg_n==0 OR host not @host-enabled -> slot_n=0 -> hr_serve3_slot is 2051 // BYTE-IDENTICAL to hr_serve3 (gated do-no-harm law) -> zero behavior change. 2052 if dyn_done == 0 { 2053 let nbox: *i64 = (sys_mmap(8)) as *i64 2054 var ad_slot_n: i64 = 0 2055 let ad_slotb: *u8 = sys_mmap(NX_MAGIC_8192) 2056 let ad_sid: *u8 = sys_mmap(128) 2057 let ad_injb: *i64 = (sys_mmap(8)) as *i64 2058 ad_injb[0] = 0 2059 if adnet_cfg_n > 0 { 2060 let ad_host: *u8 = sys_mmap(256) 2061 hr_req_host(plain, plain_n, ad_host, 256) 2062 let ad_hok: i64 = aslot_host_ok(adnet_cfg, adnet_cfg_n, ad_host) 2063 if ad_hok == 1 { 2064 let ad_path: *u8 = sys_mmap(NX_MAGIC_4096) 2065 let ad_pn: i64 = hr_req_path(plain, hdr_n, ad_path, NX_MAGIC_4096) 2066 let ad_now: i64 = sys_now_us() 2067 let ad_rot: i64 = ad_now / NX_SD2_ADNET_ROT_US 2068 ad_slot_n = aslot_html(adnet_cfg, adnet_cfg_n, ad_path, ad_pn, ad_rot, ad_slotb, NX_MAGIC_8192, ad_sid) 2069 // WIRE THE VIEWABILITY OBSERVER (debt 1785512185). Appended to the slot bytes BEFORE 2070 // hr_serve3_slot merges them, so Content-Length stays correct by construction. A refused 2071 // emit (bad id / no room) leaves ad_slot_n untouched -> the slot serves exactly as before. 2072 if ad_slot_n > 0 { if ad_sid[0] != (0 as u8) { 2073 let av_n: i64 = aview_script(((ad_slotb as i64) + ad_slot_n) as *u8, NX_MAGIC_8192 - ad_slot_n, ad_sid) 2074 if av_n > 0 { ad_slot_n = ad_slot_n + av_n } 2075 } } 2076 } 2077 } 2078 let sv: i64 = hr_serve3_slot(sites_cfg, sites_cfg_n, plain, plain_n, dyn_buf, NX_SD2_DYN_CAP, nbox, ad_slotb, ad_slot_n, ad_injb) 2079 if sv == HR_S2_OK { resp = dyn_buf; resp_n = nbox[0]; vhost_id = 20; dyn_done = 1 } 2080 if sv == HR_S2_OK { if ad_injb[0] == 1 { if ad_imp_fd >= 0 { if ad_sid[0] != (0 as u8) { 2081 let ai_line: *u8 = sys_mmap(160) 2082 var ai_ln: i64 = 0 2083 while ad_sid[ai_ln] != (0 as u8) { ai_line[ai_ln] = ad_sid[ai_ln]; ai_ln = ai_ln + 1 } 2084 ai_line[ai_ln] = 10 as u8 2085 ai_ln = ai_ln + 1 2086 sys_write(ad_imp_fd, ai_line, ai_ln) 2087 } } } } 2088 if sv == HR_S2_REDIR { resp = dyn_buf; resp_n = nbox[0]; vhost_id = 20; dyn_done = 1 } 2089 if sv == HR_S2_BAD { resp = dyn_buf; resp_n = nbox[0]; vhost_id = 20; dyn_done = 1 } 2090 if sv == HR_S2_TOOBIG { resp = dyn_buf; resp_n = nbox[0]; vhost_id = 20; dyn_done = 1 } 2091 if sv == HR_S2_FILE_STREAM { 2092 let file_reader: *NxFileReadRegion=hr_take_file_reader() 2093 let file_result: *NxTlsFileSendResult=sys_mmap(__size_of(NxTlsFileSendResult)) as *NxTlsFileSendResult 2094 let file_rc: i64=nx_tls13_file_send_fd(s,file_reader,dyn_buf,nbox[0],dyn_buf,NX_SD2_DYN_CAP,cfd,out_rec,NX_SD2_OUTREC,file_result) 2095 served_bytes=served_bytes+file_result.header_bytes+file_result.body_bytes 2096 if file_rc==0 { nreq=nreq+1 } 2097 else { 2098 // Use the already-owned response buffer after transport has stopped. 2099 var report_n: i64=sd2_append_str(dyn_buf,0,"NX-SITES-FILE-STREAM stage=") 2100 report_n=sd2_append_str(dyn_buf,report_n,file_result.stage) 2101 report_n=sd2_append_str(dyn_buf,report_n," code=") 2102 report_n=_tel_dec(dyn_buf,report_n,file_result.code) 2103 report_n=sd2_append_str(dyn_buf,report_n," write_code=") 2104 report_n=_tel_dec(dyn_buf,report_n,file_result.write_code) 2105 report_n=sd2_append_str(dyn_buf,report_n," wire_bytes=") 2106 report_n=_tel_dec(dyn_buf,report_n,file_result.wire_bytes) 2107 report_n=sd2_append_str(dyn_buf,report_n," read_bytes=") 2108 report_n=_tel_dec(dyn_buf,report_n,file_result.read_bytes) 2109 report_n=sd2_append_str(dyn_buf,report_n," completed_body_send_bytes=") 2110 report_n=_tel_dec(dyn_buf,report_n,file_result.body_bytes) 2111 report_n=sd2_append_str(dyn_buf,report_n," close_code=") 2112 report_n=_tel_dec(dyn_buf,report_n,file_result.close_code) 2113 report_n=sd2_append_str(dyn_buf,report_n," next=close-connection-no-replay\n") 2114 sys_write(2,dyn_buf,report_n) 2115 } 2116 if (file_reader as i64)!=0 { sys_munmap(file_reader as *u8,__size_of(NxFileReadRegion)) } 2117 sys_munmap(file_result as *u8,__size_of(NxTlsFileSendResult)) 2118 resp=dyn_buf;resp_n=0;vhost_id=20;dyn_done=1 2119 } 2120 if sv == HR_S2_STREAM { 2121 // ZERO-CEILING STREAM (debt 1785879638): headers then the oversize body through 2122 // the SAME chunked TLS send that carries every response -- no size constant on 2123 // this path; anything the host can mmap serves. Connection closes after (exact 2124 // Content-Length + close = valid HTTP; keep-alive resumes on the next connect). 2125 let sh: i64 = nx_tls13_app_send_fd(s, dyn_buf, nbox[0], cfd, out_rec, NX_SD2_OUTREC) 2126 if sh >= 0 { 2127 let sb: i64 = nx_tls13_app_send_fd(s, hr_stream_body() as *u8, hr_stream_bodyn(), cfd, out_rec, NX_SD2_OUTREC) 2128 if sb >= 0 { served_bytes = served_bytes + nbox[0] + hr_stream_bodyn(); nreq = nreq + 1 } 2129 } 2130 resp = dyn_buf 2131 resp_n = 0 2132 vhost_id = 20 2133 dyn_done = 1 2134 } 2135 // MISS on andelinwest = REAL 404 (its real site is file-based; 2136 // never bleed the family placeholder onto it) 2137 if sv == HR_S2_MISS { 2138 if sd2_contains(plain, hdr_n, "andelinwest" as *u8, 11) == 1 { 2139 if sd2_contains(plain, hdr_n, "GET / HTTP" as *u8, 10) == 0 { 2140 resp_n = hr_emit_404(dyn_buf, NX_SD2_DYN_CAP) 2141 resp = dyn_buf; vhost_id = 20; dyn_done = 1 2142 } 2143 } 2144 } 2145 } 2146 // ---- live wiki engine proxy (imported corpus + search) ---- 2147 // GET /wiki/<slug> that hr_serve2 MISSED, isn't a .html hot file, 2148 // and isn't a baked route -> reverse-proxy to the loopback wiki 2149 // engine (127.0.0.1:51850). ADDITIVE: on any failure dyn_done stays 2150 // 0 and the existing baked placeholder serves (never breaks the site). 2151 if dyn_done == 0 { 2152 if sd2_contains(plain, hdr_n, "GET /wiki/" as *u8, 10) == 1 { 2153 var wbaked: i64 = 0 2154 if sd2_contains(plain, hdr_n, ".html" as *u8, 5) == 1 { wbaked = 1 } 2155 if sd2_contains(plain, hdr_n, "/wiki/roadmap" as *u8, 13) == 1 { wbaked = 1 } 2156 if sd2_contains(plain, hdr_n, "/wiki/status" as *u8, 12) == 1 { wbaked = 1 } 2157 if sd2_contains(plain, hdr_n, "/wiki/components" as *u8, 16) == 1 { wbaked = 1 } 2158 if sd2_contains(plain, hdr_n, "/wiki/component/" as *u8, 16) == 1 { wbaked = 1 } 2159 if sd2_contains(plain, hdr_n, "/wiki/projects" as *u8, 14) == 1 { wbaked = 1 } 2160 if sd2_contains(plain, hdr_n, "/wiki/request" as *u8, 13) == 1 { wbaked = 1 } 2161 if sd2_contains(plain, hdr_n, "/wiki/queue" as *u8, 11) == 1 { wbaked = 1 } 2162 if wbaked == 0 { 2163 let wpr: i64 = sd2_wiki_proxy(plain, plain_n, dyn_buf) 2164 if wpr > 0 { resp = dyn_buf; resp_n = wpr; vhost_id = 40; dyn_done = 1 } 2165 } 2166 } 2167 } 2168 // ---- legacy hot roadmap + baked routes (v1) ---- 2169 if dyn_done == 0 { 2170 if sd2_contains(plain, hdr_n, "/wiki/roadmap" as *u8, 13) == 1 { 2171 let rlb: *i64 = (sys_mmap(8)) as *i64 2172 rlb[0] = 0 2173 let rbuf: *u8 = sys_read_file("/volume1/homes/elderwesto/nishihost/wiki/roadmap.html" as *u8, rlb) 2174 if (rbuf as i64) != 0 { resp = dyn_buf; resp_n = sd2_build_resp(dyn_buf, ctype_html, rbuf, rlb[0]); vhost_id = 30; dyn_done = 1 } 2175 } 2176 } 2177 if dyn_done == 0 { 2178 let is_andelin: i64 = sd2_contains(plain, hdr_n, "andelinwest" as *u8, 11) 2179 let is_wiki: i64 = sd2_contains(plain, hdr_n, "/wiki" as *u8, 5) 2180 let is_wstatus: i64 = sd2_contains(plain, hdr_n, "/wiki/status" as *u8, 12) 2181 let is_cidx: i64 = sd2_contains(plain, hdr_n, "/wiki/components" as *u8, 16) 2182 let is_proj: i64 = sd2_contains(plain, hdr_n, "/wiki/projects" as *u8, 14) 2183 let is_cr: i64 = sd2_contains(plain, hdr_n, "/wiki/component/crawler" as *u8, 23) 2184 let is_xx: i64 = sd2_contains(plain, hdr_n, "/wiki/component/x25519" as *u8, 22) 2185 let is_rk: i64 = sd2_contains(plain, hdr_n, "/wiki/component/ranking-math" as *u8, 28) 2186 let is_we: i64 = sd2_contains(plain, hdr_n, "/wiki/component/wiki-engine" as *u8, 27) 2187 if is_andelin == 1 { 2188 resp = resp_andelin; resp_n = n_andelin; vhost_id = 1 2189 } else { 2190 if is_wiki == 1 { resp = resp_wiki; resp_n = n_wiki; vhost_id = 2 } 2191 if is_wstatus == 1 { resp = resp_wstatus; resp_n = n_wstatus; vhost_id = 3 } 2192 if is_cidx == 1 { resp = resp_components; resp_n = n_components; vhost_id = 8 } 2193 if is_proj == 1 { resp = resp_projects; resp_n = n_projects; vhost_id = 12 } 2194 if is_cr == 1 { resp = resp_art_crawler; resp_n = n_art_crawler; vhost_id = 4 } 2195 if is_xx == 1 { resp = resp_art_x25519; resp_n = n_art_x25519; vhost_id = 5 } 2196 if is_rk == 1 { resp = resp_art_ranking; resp_n = n_art_ranking; vhost_id = 6 } 2197 if is_we == 1 { resp = resp_art_wiki; resp_n = n_art_wiki; vhost_id = 7 } 2198 } 2199 } 2200 } 2201 // ---- SOFT-404 ROOT FIX (2026-07-30) ------------------------------------------ 2202 // MEASURED: GET /zzz-not-a-page-12345 on nishifamily.com returned 200 with the 2203 // baked 835-byte family stub. Every unmatched path did. That burns crawl budget on 2204 // infinite phantom URLs AND makes a publishing-registry status of `withdrawn` 2205 // structurally unenforceable -- the page keeps answering 200 forever. 2206 // The test is `resp is STILL the family stub`, not `dyn_done == 0`: the baked-route 2207 // block below assigns resp WITHOUT setting dyn_done, so keying on dyn_done would 2208 // 404 legitimately-served pages. Pointer identity is exact -- the ONLY state that 2209 // changes is `nothing matched at all, for a non-root path`. 2210 // The root keeps the stub: that is the never-brick fallback for an absent home.html. 2211 if (resp as i64) == (resp_family as i64) { 2212 if sd2_contains(plain, hdr_n, "GET / HTTP" as *u8, 10) == 0 { 2213 resp_n = hr_emit_404(dyn_buf, NX_SD2_DYN_CAP) 2214 resp = dyn_buf 2215 vhost_id = 22 2216 } 2217 } 2218 // ---- D1: chunked send (any size up to DYN_CAP) ---- 2219 if resp_n > 0 { 2220 let sent: i64 = nx_tls13_app_send_fd(s, resp, resp_n, cfd, out_rec, NX_SD2_OUTREC) 2221 if sent < 0 { keep = 0 } 2222 else { served_bytes = served_bytes + resp_n; nreq = nreq + 1; sys_set_socket_timeout(cfd, NX_SD2_KA_IDLE_S) } 2223 } else { keep = 0 } 2224 } 2225 } 2226 } 2227 } 2228 } 2229 sys_close(cfd) 2230 nx_telemetry_emit(tel_fd, tel_buf, sys_now_us(), acc_lan, vhost_id, 2231 hs_us, served_bytes, hs_stat) 2232 sys_exit(0) 2233 } 2234 2235 sys_close(cfd) 2236 if pid > 0 { live = live + 1 } 2237 served = served + 1 2238 } 2239 sys_close(lfd) 2240 return 0 2241}