code wiki / _hdl_build / nx_gate_roster_run.nx

nx_gate_roster_run.nx

buildroot/runtime/_hdl_build/nx_gate_roster_run.nx

37407 B721 linesdepth 3pulls 4 transitivereach 0 importersview sourcekind tooltopic gate
docsdependenciesstructsconstsfunctions

about

nx_gate_roster_run.nx -- THE DATA-DRIVEN GATE ROSTER BEAT: run every gate named in a conf, on the clock, with a deadline, and journal each verdict -- so a promoted gate nobody runs becomes a gate whose verdict is COLLECTED, by adding ONE LINE OF DATA rather than a rebuild. WHY (campaign lane B, 2026-08-18): nx_gateadjudicate measured 3,235 gate sources on the NAS, 919 promoted, and 780 DEPLOYED-DARK -- promoted binaries that no clock row, roster organ, .gates map, gatereg row or MCP call ever runs. The estate's law: "a gate nobody runs does not degrade to neutral -- it degrades to a false sense of coverage, because its existence is counted and its verdict is not." The wiring vehicle that already exists, nx_gfx_gates_beat, is CORRECT in shape (bounded runner, per-gate journal line, ABSENT reported never skipped) but its roster is EIGHT NAMES IN CODE, so admitting a ninth gate is a rebuild. Rule 11/17: rosters are DATA. This organ is that beat with the roster moved to a conf; nx_gfx_gates_beat is the precedent, not a duplicate -- its eight rows can migrate here whenever its owner chooses. ROSTER CONF (default knowledge/gateroster.conf), one gate per line: <gate-name> runs ./<gate-name>.elf from the estate root ; comment / blank ignored (also lines whose first byte is the hash mark) A gate is ADMITTED to the conf only after a TRIAL run has come back GREEN or SKIP -- adoption is not blind wiring, and this organ has a `trial` verb for exactly that: nx_gate_roster_run REFUSED (exit 2): argless mutates NOTHING and prints usage. The beat must NAME its verb -- every proof tool in the estate probes an organ argless, so an argless default that runs the beat makes this organ unprovable and lets a staged binary write production state. nx_gate_roster_run beat [conf] [journal] [ms] the beat. A conf OR journal other than the production defaults writes its heartbeat BESIDE its own journal (<journal>.stamp, announced) and never to the cron-watched production stamp. nx_gate_roster_run trial <listfile> [journal] [ms] run every gate in <listfile> ONCE, journal under tag "trial"; exit 0 always (a trial reports, it does not judge the fleet) nx_gate_roster_run admit <journal> <deadline_ms> [conf] [suspectlist=<conf>.suspect] The journal->conf bridge, so admission is MECHANICAL, never hand-filtered: take the LATEST row per gate; GREEN/SKIP with ms < deadline_ms -> merge-ADD into the conf (additive, rule 13: admission never removes -- a beat RED is an alarm to read, not a row to erase); GREEN with ms >= deadline_ms -> SUSPECT, written to [suspectlist] and NOT admitted. The suspect class exists because journals written before 2026-08-18 came from a runner that returned exit 0 for a watchdog-KILLED child, so a legacy at-deadline GREEN is a timeout wearing a pass; the fixed runner reports 137 and those rows say TIMEOUT, making this class empty going forward. deadline_ms is REQUIRED (it is the value the trial ran with, from its own header line) --

dependencies 3 imports · 0 importers

nx_syscalls.nx nx_gatekit_lib.nx nx_estate_path.nx nx_gate_roster_run.nx

imports: nx_syscalls.nxnx_gatekit_lib.nxnx_estate_path.nx

imported by: nobody (leaf or entry point)

call flow from main pre-order; caps 40 nodes / depth 6 declared; ↻ = already shown

main sys_now_ms sys_mmap nxa_die sys_write sys_exit nxa_lock_take nxa_lock_addr sys_write ↻ nxa_lock_give nxa_lock_addr ↻ nxa_report_overrun sys_write ↻ nxa_dump_printable sys_write ↻ nxa_dump_sizes sys_write ↻ sys_clock_gettime_mono gk_say gk_write_all sys_write ↻ gk_len gk_streq grr_admit sys_mmap ↻ gk_cat grr_num gk_say ↻ sys_read_file sys_openat_rd sys_lseek sys_mmap ↻ sys_read sys_munmap sys_close gk_eol gk_len ↻ grr_runeq gk_len ↻ grr_slot

structs

none

consts

61const GRR_MS_DEFAULT: i64 = 60000
62const GRR_CAP: i64 = 65536
63const GRR_MODE: i64 = 420 // 0644
64const GRR_NICE: i64 = 10
65const GRR_SIGKILL_RC: i64 = 137 // 128+SIGKILL: what gk_run_capture_ms returns for a child its watchdog killed
66const GRR_MAXG: i64 = 4096
67const GRR_SLOT: i64 = 128
68const GRR_LINE: i64 = 1400 // one journal line (epoch/tag/gate/verdict/exit/ms/reason)
69const GRR_REASON_MAX: i64 = 240 // reason field cap; a truncated reason still names the cause
70const GRR_MSG: i64 = 8192 // report buffers (admit summary, beat header/footer)
71const GRR_CONF: *u8 = "knowledge/gateroster.conf"
72const GRR_JRNL: *u8 = "knowledge/status/gateroster.jrnl"
76const GRR_STAMP: *u8 = "knowledge/status/gateroster.stamp"
94const GRR_DIRECTIVE_DISPATCH: *u8 = "@dispatch_deadline_ms"
95const GRR_TAG_BEAT: *u8 = "roster"

functions

97func grr_isid(c: i64) -> i64
called by 1: grr_load
108func grr_slot(t: *u8, i: i64) -> *u8 { return ((t as i64) + i * GRR_SLOT) as *u8 }
111func grr_load(path: *u8, tbl: *u8) -> i64
154func grr_directive_ms(path: *u8) -> i64
179func grr_lastrun(jrnl: *u8, tag: *u8, tbl: *u8, n: i64, last: *i64) -> i64
215func grr_order(last: *i64, n: i64, ord: *i64) -> i64
called by 1: main
227func grr_one(name: *u8, tag: *u8, jfd: i64, ms: i64) -> i64
307func grr_num(s: *u8, off: i64, endp: *i64) -> i64
321func grr_runeq(b: *u8, rs: i64, re: i64, lit: *u8) -> i64
330func grr_admit(jrnl: *u8, dls: *u8, argc: i64, argv: *i64) -> i64
524func main(argc: i64, argv: *i64) -> i64