nx_segopen_absent_gate.nx
buildroot/runtime/nx_segopen_absent_gate.nx
about
nx_segopen_absent_gate.nx -- THE REFEREE FOR ss_open2's FAIL-SAFE SEGMENT ADMISSION (2026-09-02, debt 1788361379).
WHY THIS GATE EXISTS, MEASURED: nishifamily.com/search was 503 for ~16h. The serving daemon's parent
SIGSEGV'd inside the accept-path shard refresh, and the guard's respawn then SPUN 15.9h of user CPU inside
ss_open2 with the listen port never opened (State R, voluntary ctxsw 8, nonvoluntary 26.1M). Its /proc maps
held one manifest segment with its .idx mapped and NO .docs: ss_open2 sized that segment's live map from
dsz (== 0, one page) but bounded the marks by the .post doc count, so the marks wrote past the page --
SIGSEGV when the next page was unmapped, silent table corruption and an endless probe when it was mapped.
The fix makes an index-present/docs-absent row contribute NO live docs and ANNOUNCES it on stderr.
IN-PROCESS over nx_seg_store.nx, deliberately: the subject is a library function, the fixture plane lives
in /tmp/<gate>/ (never knowledge/store, which the segguard beat sweeps), and every outcome tooth is
preceded by a fixture-reached-the-condition tooth so a setup failure cannot pass for a verdict.
STATE, NOT MESSAGE: the live-map bytes of the handle are read directly (h[1 + 8*ns + s]), because a
leaking or overflowing open answers the same bytes to every caller -- only the map can prove it.
The segment NAME is read back from the manifest the writer produced, never recomputed from the id the
gate asked for: ss_commit re-derives the id under the plane lock, so a leftover file from an earlier run
would otherwise make the gate rename the wrong file and fail its own fixture tooth.
PRE-FIX this gate reads RED on exactly the two load-bearing teeth (marks written for absent docs, no
announce) and GREEN on every fixture tooth; POST-FIX it reads GREEN throughout. That asymmetry is the bite.
dependencies 3 imports · 0 importers
imports: nx_seg_store.nxnx_syscalls.nxnx_gate_verdict.nx
imported by: nobody (leaf or entry point)
call flow from main pre-order; caps 40 nodes / depth 6 declared; ↻ = already shown
structs
| none |
consts
| 26 | const SG_DIR: *u8 = "/tmp/nx_segopen_absent_gate" |
| 27 | const SG_PREFIX: *u8 = "/tmp/nx_segopen_absent_gate/soa-" |
| 28 | const SG_ERR1: *u8 = "/tmp/nx_segopen_absent_gate/stderr-control.txt" |
| 29 | const SG_ERR2: *u8 = "/tmp/nx_segopen_absent_gate/stderr-absent.txt" |
| 30 | const SG_MODE_DIR: i64 = 493 // 0755 |
| 31 | const SG_MODE_FILE: i64 = 420 // 0644 |
| 32 | const SG_DOCS: i64 = 12 // docs in the ONE fixture segment; every one must read live in the control |
| 33 | const SG_SEGCAP: i64 = 65536 |
| 34 | const SG_KIND_LIVE: i64 = 1 |
| 35 | const SG_KEYCAP: i64 = 64 |
| 36 | const SG_VALCAP: i64 = 64 |
| 37 | const SG_PATHCAP: i64 = 512 |
| 38 | const SG_SAVED_FD: i64 = 20 // where fd 2 is parked while an open's stderr is captured |
| 39 | const SG_SUBJECTS: i64 = 3 // opens driven: control, absent-docs, restored |
functions
| 41 | func sg_key(out: *u8, i: i64) -> i64 |
| 50 | func sg_reset(prefix: *u8) -> i64 |
| 61 | func sg_marks(h: *i64, s: i64, n: i64) -> i64 called by 1: main |
| 71 | func sg_seg_path(prefix: *u8, segname: *u8, suffix: *u8, out: *u8) -> i64 |
| 79 | func sg_contains(hay: *u8, hn: i64, needle: *u8) -> i64 called by 1: main |
| 95 | func sg_open_captured(prefix: *u8, errpath: *u8) -> *i64 |
| 105 | func main(argc: i64, argv: *i64) -> i64 |