nx_rungclose_gate.nx
buildroot/runtime/nx_rungclose_gate.nx
about
nx_rungclose_gate.nx -- GATE for the close ruler v2 (nx_rungclose_lib, ecosystem EC57), driven IN-PROCESS on planted rows.
v2 measures every stage and signs none, so the teeth prove the EVIDENCE readers and the rules over them: the production
roster journal (a trial roster row never tests anything; a longer or prefix gate name is another gate; SKIP is neither
verdict; turns are counted only since the land), the clock's actlog rows (a process killed by a signal did not run, a
spawn that failed did not run, an MCP call is not a clock run, a prefix program is another program; a row planted EXACTLY as
clk_actlog writes it -- the forked path alone, then exit= and job= -- is witnessed by its job name, and a longer or prefix job
name is another clock row), the surface census row (each surface class; a prefix name is not the organ), the clock plane's
agent command (the LAST declaration of a name wins over a stale first one, as the scheduler applies it), every link's three states
and the rule that decided it, the issue classes and their ceilings (a ceiling never RAISES a stage; STALE is not
rework), the climb, the stage snapshot the closer diffs against (round trip, cursor wrap, prefix neg-controls), the
close-first worklist and the journal grammar, and THE ROSTERS (nx_rosterconf_lib, 2026-09-18): a roster is a (conf, journal) pair
derived from a clock plane (the runner's default pair first, then every pair a beat row runs, whatever journal it writes; a beat
naming no journal writes the production one; a trial row, an argless row, a PREFIX program and a line with no command add nothing;
a CR from another host is not part of a name); a gate is ROSTERED by any conf -- a gate only on the heavy conf is rostered BY the
heavy conf, the same gate against the default alone is not, and a gate on none is not; and THE CREDIT: a gate's roster GREEN is
read from the production journal (always) and from the journal of every pair whose conf lists it -- a gate the slow beat alone
runs is credited from the slow journal and green_in names it, a GREEN in a journal whose conf does NOT list the gate is never
credited, a trial row never credits, a journal two rosters share is read once, and a gate rostered only by a beat whose journal
cannot be read is UNOBSERVABLE, never HOLDS.
Every fixture asserts its own condition first; the neg-controls are named.
license_tier: ORIGINAL No hw writes (Rule 26).
dependencies 4 imports · 0 importers
imports: nx_syscalls.nxnx_rosterconf_lib.nxnx_rungclose_lib.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
| 27 | const G_I64: i64 = 8 |
| 28 | const G_WORK_ROWS: i64 = 9 // the worklist fixture: six well-formed rows and three malformed lines |
| 29 | const G_WORK_NAME_B: i64 = 8 // more than the longest domain plus rung name the fixture plants (fxx and B5) |
| 30 | const G_TWICE: i64 = 2 // the duplicate-id fixture declares D1 exactly twice |
| 31 | const G_WORK_NOW: i64 = 2000000 // the fixture's clock: every age is planted against it, never against the wall |
| 32 | const G_PLAN: *u8 = "rung|A1|t|sym_a|n|Organ|1|-\nrung|A2|t|-|n|Organ|2|-\nrung|A3|t|sym_c|n|Organ|1|-\nrung|A4|t|sym_zz|n|Organ|1|-\nrung|A5|t|-|n|Organ|1|-\nlog|100|A1|measure|m\nlog|200|A1|land|l\nlog|250|A1|done|a note since v2, decides nothing\nlog|300|A1|retract|r\nlog|150|A2|land|l\nlog|160|A2|done|a note\nlog|50|A3|queue|q\nlog|500|A5|land|a slice\nlog|bad|A3|land|a non-integer epoch is no land\n" |
| 33 | const G_MATRIX: *u8 = "# sym_a in a comment is not a row|runtime/wrong.nx|sym_a\nPrefix sibling|runtime/organ_ab.nx|_ABSENT_:sym_ab|0|0|0|0|0|n\nLabel one|runtime/organ_a.nx|_ABSENT_:sym_a|0|0|0|0|0|n\nLabel two|runtime/organ_c.nx|sym_c|0|0|0|0|0|n\n" |
| 34 | const G_A1_ROWS: i64 = 4 |
| 35 | const G_A1_LAND: i64 = 200 |
| 36 | const G_A1_RETRACT: i64 = 300 |
| 37 | const G_A2_LAND: i64 = 150 |
| 38 | const G_A2_COST: i64 = 20 |
| 40 | const G_GR: *u8 = "100\troster\tgx_gate\tGREEN\texit=0\tms=5\tok\n150\ttrial\tgx_gate\tRED\texit=1\tms=5\ta trial row never tests\n200\troster\tgx_gate\tRED\texit=1\tms=5\tred\n300\troster\tgx_gate\tGREEN\texit=0\tms=5\tgreen again\n310\troster\tgx_gate_x\tRED\texit=1\tms=5\ta longer name is another gate\n320\troster\tgx\tRED\texit=1\tms=5\ta prefix is another gate\n330\troster\tgy_gate\tSKIP\texit=3\tms=5\tabstained\n340\troster\tgy_gate\tRED\texit=1\tms=5\tred\nbad\troster\tgx_gate\tGREEN\texit=0\tms=5\tno epoch no row\n" |
| 41 | const G_GR_INDEXED: i64 = 7 // nine lines: the trial row and the bad epoch are not production rows |
| 42 | const G_GR_NOW: i64 = 1300 // inside the margin of every planted row |
| 46 | const G_AL_INDEXED: i64 = 6 |
| 47 | const G_AL_ROWS: i64 = 9 // the rows g_al_build writes; a tooth holds the build to it |
| 48 | const G_AL_SEPS: *u8 = "\t\t\t\t\t\n" // one row's separators, spelled, so their count is read and never typed |
| 49 | const G_AL_NOTE: *u8 = "clockjob lane=clock exit=" |
| 50 | const G_AL_JOB: *u8 = " job=" // what the clock appends to the last field: its own row's name |
| 51 | const G_AL_LONGEST_CMD: *u8 = "/volume1/x/nishihost/nx_alpha.elf" |
| 52 | const G_AL_LONGEST_JOB: *u8 = "wfbeatx" |
| 54 | const G_AL_PLAN_PATH: *u8 = "/v/x/nishihost/nx_plan_run.elf" |
| 56 | const G_CLOCK: *u8 = "wfbeat\t86400\tnx_plan_run.elf stale\nwfbeat\t86400\tnx_plan_run.elf wfx\nwfbeatx\t60\tnx_other.elf\nother\t60\tnx_other.elf\n" |
| 57 | const G_ES: *u8 = "nx_alpha\t1\t0\t0\t-\t0\t1\tclock\nnx_beta\t0\t0\t0\t-\t0\t1\tplan\nnx_gamma_gate\t0\t0\t0\t-\t1\t0\troster\nnx_delta\t0\t0\t0\t-\t0\t1\tactlog\nnx_eps\t0\t0\t0\t-\t0\t0\tref:nx_x\nnx_zeta\t0\t0\t0\tnx_caller\t0\t0\tfork:nx_caller\nnx_eta\t0\t0\t1\t-\t0\t0\tdaemon\n" |
| 62 | const G_RCLOCK: *u8 = "gateroster\t60\t/v/x/nishihost/nx_gate_roster_run.elf beat knowledge/gateroster.conf knowledge/status/gateroster.jrnl 9\ngaterosterheavy\t60\t/v/x/nishihost/nx_gate_roster_run.elf beat fx/heavy.conf knowledge/status/gateroster.jrnl 9\nrosterslow\t60\t/v/x/nishihost/nx_gate_roster_run.elf beat fx/slow.conf knowledge/status/gateroster_slow.jrnl 9\nrostertrial\t60\tnx_gate_roster_run.elf trial fx/trial.list\nrosterbare\t60\tnx_gate_roster_run.elf\nrosterprefix\t60\tnx_gate_roster_runner.elf beat fx/prefix.conf\nrosterdefault\t60\tnx_gate_roster_run beat\nheavyagain\t60\tnx_gate_roster_run.elf beat fx/heavy.conf\nno tab so no command nx_gate_roster_run.elf beat fx/notab.conf\n" |
| 63 | const G_RCRLF_ROW: *u8 = "crlf\t60\tnx_gate_roster_run.elf beat fx/crlf.conf" |
| 64 | const G_RBEATS: i64 = 6 // the main, the heavy, the slow, the bare beat, the heavy again, the CRLF beat |
| 65 | const G_ROTHER: i64 = 1 // of them writing another journal: the slow roster |
| 66 | const G_RCONFS: i64 = 4 // pairs: default/production, heavy/production, slow/slow journal, crlf/production |
| 67 | const G_RJOINED: *u8 = "knowledge/gateroster.conf,fx/heavy.conf,fx/slow.conf,fx/crlf.conf" |
| 68 | const G_RPROD: *u8 = "knowledge/status/gateroster.jrnl" |
| 69 | const G_RSLOWJ: *u8 = "knowledge/status/gateroster_slow.jrnl" |
| 70 | const G_RSLOW_PAIR: i64 = 2 |
| 71 | const G_RCRLF_PAIR: i64 = 3 |
| 73 | const G_RSLOW: *u8 = "# the slow roster\nnx_slow_gate\nnx_trial_gate\n" |
| 75 | const G_RJPROD: *u8 = "100\troster\tnx_main_gate\tGREEN\texit=0\tms=5\tok\n150\troster\tnx_left_gate\tGREEN\texit=0\tms=5\tit has since left its conf\n" |
| 78 | const G_RJSLOW: *u8 = "200\troster\tnx_slow_gate\tGREEN\texit=0\tms=5\tthe slow beat ran it\n210\troster\tnx_stray_gate\tGREEN\texit=0\tms=5\tno roster listing it writes here\n220\ttrial\tnx_trial_gate\tGREEN\texit=0\tms=5\ta trial row\n" |
| 79 | const G_RJ_SLOW_GREEN: i64 = 200 |
| 80 | const G_RJ_STRAY_GREEN: i64 = 210 |
| 81 | const G_RJ_LEFT_GREEN: i64 = 150 |
| 82 | const G_RJ_MAIN_GREEN: i64 = 100 |
| 83 | const G_RJPROD_ROWS: i64 = 2 // the production fixture's roster rows |
| 84 | const G_RJSLOW_ROWS: i64 = 2 // the slow fixture's roster rows (its third row is a trial) |
| 85 | const G_RJ_SCALE: i64 = 10 // more than either fixture's row count: two counts read as one number |
| 86 | const G_RJ_CONSULT_SLOW: i64 = 2 // a gate on the slow conf alone: the production journal, then the slow one |
| 88 | const G_LW_SCALE: i64 = 100 |
| 91 | const G_RMAIN: *u8 = "; gateroster.conf -- the main roster\n# nx_heavy_gate named in a comment is not a row\nnx_main_gate\n nx_indented_gate\nnx_tabbed_gate\ta note\n" |
| 92 | const G_RHEAVY: *u8 = "# THE HEAVY GATE ROSTER\n@dispatch_deadline_ms 9\nnx_heavy_gate\n" |
| 93 | const G_RCRLF_GATE: *u8 = "nx_crlf_gate" |
| 94 | const G_RNOBEAT: *u8 = "other\t60\tnx_other.elf beat fx/other.conf\n" |
functions
| 96 | func g_links(v0: i64, v1: i64, v2: i64, v3: i64, v4: i64, v5: i64, v6: i64) -> *i64 |
| 107 | func g_iss(red: i64, retract: i64, flaky: i64, stale: i64) -> *i64 |
| 118 | func g_lw(v: i64, w: *i64) -> i64 { return v * G_LW_SCALE + w[0] } called by 1: main |
| 119 | func g_slot(v: i64, out: *i64, k: i64, scale: i64) -> i64 { return v * scale + out[k] } called by 1: main |
| 122 | func g_al_row(b: *u8, o0: i64, ep: i64, lane: *u8, cmd: *u8, status: *u8, code: *u8, job: *u8) -> i64 |
| 143 | func g_al_row_bound() -> i64 |
| 148 | func g_al_build(b: *u8, t0: i64) -> i64 |
| 161 | func g_pick_rung_is(wb: *u8, picks: *i64, i: i64, lit: *u8, off: *i64) -> i64 |
| 167 | func g_streq(a: *u8, b: *u8) -> i64 |
| 175 | func g_has(hay: *u8, needle: *u8) -> i64 |
| 183 | func g_part_is(list: *u8, n: i64, k: i64, which: i64, lit: *u8) -> i64 |
| 189 | func g_conf_listed(list: *u8, n: i64, lit: *u8) -> i64 |
| 197 | func g_journal(jt: *i64, k: i64, text: *u8) -> i64 |
| 210 | func g_credit(jt: *i64, rt: *i64, np: i64, name: *u8, since: i64, g: *i64, out: *i64) -> i64 |
| 222 | func g_rfind(texts: *i64, k: i64, gate: *u8) -> i64 { return rcf_find(texts, k, gate, ces_slen(gate)) } |
| 224 | func main(argc: i64, argv: *i64) -> i64 |