code wiki / _hdl_build / nx_site_intake.nx
nx_site_intake.nx
buildroot/runtime/_hdl_build/nx_site_intake.nx
about
nx_site_intake.nx -- PUBLIC contact-intake route core for GENERATED SITES (uigen lane, debt 1785934266;
the buildable half of R0a "a dead form is a fake"). PURE CORE, NO MAIN -- the nx_office_serve/
nx_survey_serve discipline: a host daemon mounts si_route behind the sovereign edge, and that mount +
the edge route row are the coordinated deployment hook, NOT this file. Once mounted, a generated
site's req names contact|action|/intake/<slug> and the T15 form goes live with ZERO emitter rebuild.
PUBLIC + ANONYMOUS => hostile by default (rule 12):
- SI_MAX_BODY cap at the door (the oversized-proxied-POST class that once destabilized sites.elf)
- honeypot `website` field: a filled honeypot gets the SAME 303 as success and records NOTHING
(a rejection a bot can measure is a rejection it can learn around)
- plane-grammar defense: TAB/CR/LF in decoded fields become spaces BEFORE the append (the clockjobs
writer-vs-plane lesson enforced at write time, gate-proven)
- `back` redirect is PATH-ONLY (leading '/', no ':', no '//') so no open redirect; else "/"
Rows land append-only on the caller-supplied plane as id<TAB>slug<TAB>name<TAB>email<TAB>message
(nx_store_put-load readable; id=epoch-sec -- the BYTES are the ledger, a load view collapses
same-second ids). Caller supplies plane + log paths: the gate passes per-run /tmp fixtures
(idempotent-fixture law), the real host passes knowledge/store/siteintake- +
knowledge/status/site_intake.log. A message longer than SI_MAX_MSG reads as absent (the form must
carry maxlength); only RECORDED submissions write a log line, so a honeypot flood cannot grow the
status log. No floats, no hardware writes, nothing here binds a socket. license_tier: ORIGINAL
dependencies 2 imports · 2 importers
imports: nx_syscalls.nxnx_http_form.nx
imported by: nx_site_intake_gate.nxnx_site_intake_serve.nx
structs
| none |
consts
| 23 | const SI_MAX_BODY: i64 = 4096 |
| 24 | const SI_MAX_FIELD: i64 = 200 |
| 25 | const SI_MAX_MSG: i64 = 1000 |
| 26 | const SI_MAX_SLUG: i64 = 40 |
| 27 | const SI_ROW: i64 = 2048 |
| 28 | const SI_SCRATCH: i64 = 256 |
| 29 | const SI_MSGBUF: i64 = 1032 |
| 30 | const SI_HPBUF: i64 = 128 |
| 31 | const SI_SLUGBUF: i64 = 64 |
| 32 | const SI_TMP: i64 = 28 |
| 33 | const SI_MODE: i64 = 420 |
| 34 | const SI_TEN: i64 = 10 |
| 35 | const SI_B_TAB: i64 = 9 |
| 36 | const SI_B_LF: i64 = 10 |
| 37 | const SI_B_CR: i64 = 13 |
| 38 | const SI_B_SP: i64 = 32 |
| 39 | const SI_B_DASH: i64 = 45 |
| 40 | const SI_B_SLASH: i64 = 47 |
| 41 | const SI_B_COLON: i64 = 58 |
| 42 | const SI_B_0: i64 = 48 |
| 43 | const SI_B_9: i64 = 57 |
| 44 | const SI_B_A: i64 = 97 |
| 45 | const SI_B_Z: i64 = 122 |
functions
| 47 | func si_len(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n } |
| 48 | func si_cat(dst: *u8, off: i64, s: *u8) -> i64 |
| 54 | func si_putn(buf: *u8, off: i64, v: i64) -> i64 |
| 65 | func si_starts(buf: *u8, n: i64, lit: *u8) -> i64 |
| 73 | func si_sanitize(s: *u8) -> i64 called by 1: si_field |
| 84 | func si_field(body: *u8, bn: i64, name: *u8, out: *u8, cap: i64) -> i64 |
| 96 | func si_back_ok(b: *u8) -> i64 called by 1: si_route |
| 108 | func si_slug_ok(s: *u8) -> i64 |
| 124 | func si_resp(resp: *u8, line: *u8) -> i64 |
| 129 | func si_resp_303(resp: *u8, back: *u8) -> i64 |
| 136 | func si_streq(a: *u8, b: *u8) -> i64 called by 1: si_route |
| 144 | func si_resp_health(resp: *u8) -> i64 |
| 151 | func si_route(req: *u8, rn: i64, resp: *u8, plane: *u8, logf: *u8) -> i64 |