nx_rungclose.nx
buildroot/runtime/nx_rungclose.nx
about
nx_rungclose.nx -- CLI over nx_rungclose_lib (ecosystem EC57 v2): ONE MEASURED stage per rung, the weakest link BY NAME,
and the census that moves every rung with NO SEAT and NO SIGNATURE in the loop.
nx_rungclose check <domain> <rung> [anchor] every link with its evidence and the rule that decided it, the issues,
the stage, the weakest link and its remedy; verdict LAST
nx_rungclose census <domain> [anchor] the stage of every rung on the board, counted, the partition summing
nx_rungclose census all [anchor] every published board. Writes the fleet status line, the close-first
worklist and the STAGE SNAPSHOT whole (temp, then rename), and appends
one ledger row per rung whose stage moved since the last census --
THE CLOSER: the clock row rungclose runs it daily, nobody signs anything
nx_rungclose journal <domain> <rung> <kind> <text> [anchor] one board journal row, by grammar
nx_rungclose close|reopen <domain> <rung> <actor> [anchor] RETIRED 2026-09-18 (operator: completion needs no manual
sign-off): prints the check and writes NOTHING
exit: 0 PRODUCTION, CENSUSED or JOURNALED | 1 below PRODUCTION or REFUSED | 2 usage | 3 UNOBSERVABLE or NO-PLAN
Evidence, read once per run: the board's plan and matrix (both published trees), tool_allowlist.conf,
EVERY ROSTER as a (conf, journal) pair (nx_rosterconf_lib: the runner's default knowledge/gateroster.conf writing the production
journal RCF_JRNL, knowledge/status/gateroster.jrnl, then each pair an agent-plane row runs through nx_gate_roster_run beat -- the
heavy roster into the production journal, the slow rosters into their OWN journals, any later roster without an edit here):
every conf, the production journal always, and the journal of every pair whose conf lists the gate being judged -- so a slow
beat's GREEN is credited where that beat writes it, and printed as green_in=; the execution-surface census
knowledge/status/execsurface.tsv, the actlog's tail window (the freshness margin, read by a doubling ladder so its size is
the window's, never a guess), the clock DESIRED plane, the contract organ's source, the gate artifacts the ship loop's own
resolver finds (nx_organ_ship_lib: knowledge/organ_gate.conf, then derivation), and the published page's mtime.
A run given an [anchor] writes every artifact BESIDE that path, never production.
license_tier: ORIGINAL No hw writes (Rule 26).
dependencies 12 imports · 0 importers
diagram shows first 10 each side; +2 more imports, +0 more importers in the complete lists below.
imports: nx_syscalls.nxnx_estate_path.nxnx_barfresh_lib.nxnx_store_seed_lib.nxnx_treatment_lib.nxnx_symdecl_lib.nxnx_srcfresh.nxnx_gate.nxnx_logtail.nxnx_organ_ship_lib.nxnx_rosterconf_lib.nxnx_rungclose_lib.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
| 38 | const RP_EXIT_DONE: i64 = 0 |
| 39 | const RP_EXIT_NOT: i64 = 1 |
| 40 | const RP_EXIT_USAGE: i64 = 2 |
| 41 | const RP_EXIT_UNOBS: i64 = 3 |
| 42 | const RP_PATH_CAP: i64 = 1024 |
| 43 | const RP_MODE_644: i64 = 420 |
| 44 | const RP_ALLOW: *u8 = "tool_allowlist.conf" |
| 47 | const RP_SURFACES: *u8 = "knowledge/status/execsurface.tsv" |
| 48 | const RP_ACTLOG: *u8 = "knowledge/status/actlog.jrnl" |
| 49 | const RP_GATE_CONF: *u8 = "knowledge/organ_gate.conf" |
| 50 | const RP_BUILT_DIR: *u8 = "buildroot/_build/" |
| 51 | const RP_BUILT_SFX: *u8 = ".sov.elf" |
| 52 | const RP_LIVE_SFX: *u8 = ".elf" |
| 53 | const RP_SRC_SFX: *u8 = ".nx" |
| 54 | const RP_LIB_SFX: *u8 = "_lib" |
| 55 | const RP_TAIL_FIRST_SHARE: i64 = 64 // the actlog window's first probe reads 1/64th of the journal and the ladder DOUBLES until |
| 58 | const RP_CLOCK_PLANE: *u8 = "knowledge/store/clockjobs-" // the DESIRED plane: the treat judge reads it, as nx_treatment does |
| 59 | const RP_CLOCK_LIVE: *u8 = "knowledge/store/clocksched-" // the LIVE plane: what the scheduler actually runs |
| 60 | const RP_PLANE_CAP: i64 = 1048576 // the clock DESIRED plane read, the same reserve nx_treatment declares; a fill makes agent reads UNPROVEN |
| 61 | const RP_WF_PFX: *u8 = "knowledge/store/plan-" |
| 62 | const RP_WF_SFX: *u8 = "-manifest.txt" |
| 63 | const RP_ANCHOR_DEFAULT: *u8 = "knowledge/status/ws_sync.jrnl" // the default anchor: production artifacts keep their own names |
| 64 | const RP_LEDGER: *u8 = "knowledge/status/rungclose.jrnl" |
| 65 | const RP_LEDGER_SFX: *u8 = ".rungclose" |
| 66 | const RP_STATUS: *u8 = "knowledge/status/rungclose.status" // ONE canonical fleet line, truncate-written by census all |
| 67 | const RP_STATUS_SFX: *u8 = ".rungclose.status" |
| 68 | const RP_WORKLIST: *u8 = "knowledge/status/rungclose.worklist" // the close-first worklist, rewritten WHOLE by census all |
| 69 | const RP_WORKLIST_SFX: *u8 = ".rungclose.worklist" |
| 70 | const RP_STAGES: *u8 = "knowledge/status/rungclose.stages" // v2: every rung's stage, rewritten WHOLE; the next census diffs against it |
| 71 | const RP_STAGES_SFX: *u8 = ".rungclose.stages" |
| 72 | const RP_TMP_SFX: *u8 = ".tmp" |
| 73 | const RP_PAGE_PFX: *u8 = "sites/nishifamily/compare/" |
| 74 | const RP_PAGE_SFX: *u8 = "/index.html" |
| 75 | const RP_MATRIX_SFX: *u8 = ".matrix" |
| 76 | const RP_SRC_PFX: *u8 = "buildroot/" |
| 77 | const RP_CENSUS_ACTOR: *u8 = "census" |
| 79 | const RP_E_PLAN_P: i64 = 0 |
| 80 | const RP_E_PLAN_N: i64 = 1 |
| 81 | const RP_E_MX_P: i64 = 2 |
| 82 | const RP_E_MX_N: i64 = 3 |
| 83 | const RP_E_ALLOW_P: i64 = 4 |
| 84 | const RP_E_ALLOW_N: i64 = 5 |
| 85 | const RP_E_ROSTER_P: i64 = 6 |
| 86 | const RP_E_ROSTER_N: i64 = 7 |
| 87 | const RP_E_CLOCK_P: i64 = 8 |
| 88 | const RP_E_CLOCK_N: i64 = 9 |
| 89 | const RP_E_GR_P: i64 = 10 // the roster journal, whole |
| 90 | const RP_E_GR_N: i64 = 11 |
| 91 | const RP_E_PAGE_S: i64 = 12 |
| 92 | const RP_E_TAB_P: i64 = 13 |
| 93 | const RP_E_TAB_ROWS: i64 = 14 |
| 94 | const RP_E_GX_P: i64 = 15 // its index |
| 95 | const RP_E_GX_ROWS: i64 = 16 |
| 96 | const RP_E_ES_P: i64 = 17 // the surface census |
| 97 | const RP_E_ES_N: i64 = 18 |
| 98 | const RP_E_AL_P: i64 = 19 // the actlog window |
| 99 | const RP_E_AL_N: i64 = 20 |
| 100 | const RP_E_AX_P: i64 = 21 // its clock-lane index |
| 101 | const RP_E_AX_ROWS: i64 = 22 |
| 102 | const RP_E_AL_BYTES: i64 = 23 // the whole journal's size |
| 103 | const RP_E_AL_COVER: i64 = 24 // 1 when the window reaches back past the margin (or holds the whole file) |
| 104 | const RP_E_NOW: i64 = 25 |
| 105 | const RP_E_ROOT_A: i64 = 26 // the resolver's roots and declaration file |
| 106 | const RP_E_ROOT_B: i64 = 27 |
| 107 | const RP_E_GCONF: i64 = 28 |
| 108 | const RP_E_ES_ASOF: i64 = 29 |
| 109 | const RP_E_DOM: i64 = 30 // *u8 the board's domain name (the first half of a rung's gate key) |
| 110 | const RP_E_RT_P: i64 = 31 // *i64 each roster pair's conf text, RCF_TEXT_STRIDE slots each, in pair order (pair 0 the default) |
| 111 | const RP_E_RT_K: i64 = 32 // how many roster pairs |
| 112 | const RP_E_RL_P: i64 = 33 // *u8 the roster pair list, conf TAB journal per line |
| 113 | const RP_E_RL_N: i64 = 34 |
| 114 | const RP_E_RT_READ: i64 = 35 // how many distinct roster confs could be read |
| 115 | const RP_E_R_BEATS: i64 = 36 // how many agent-plane rows are roster beats, whatever journal they write |
| 116 | const RP_E_R_OTHER: i64 = 37 // of them, the beats writing a journal other than the production one (read from that journal) |
| 117 | const RP_E_AGP_P: i64 = 38 // *u8 THE AGENT PLANE: what the scheduler runs (the live plane), else the desired plane |
| 118 | const RP_E_AGP_N: i64 = 39 |
| 119 | const RP_E_AGP_SRC: i64 = 40 // RP_AGP_LIVE or RP_AGP_DESIRED: which one answered, printed as the evidence |
| 120 | const RP_E_RJ_P: i64 = 41 // *i64 the roster journal table, RGC_RJ_STRIDE slots per roster pair (pair 0 = production) |
| 121 | const RP_E_RJ_K: i64 = 42 // how many distinct roster journals |
| 122 | const RP_E_RJ_READ: i64 = 43 // how many of them could be read |
| 123 | const RP_E_RC_SEEN: i64 = 44 // *i64 rgc_roster_credit scratch, one slot per pair, allocated once for every rung |
| 124 | const RP_E_RC_LISTS: i64 = 45 // *i64 which pairs' confs list the name being judged |
| 125 | const RP_E_RC_GT: i64 = 46 // *i64 one journal's gate facts |
| 126 | const RP_E_RT_DISTINCT: i64 = 47 // how many distinct roster confs |
| 127 | const RP_E_SLOTS: i64 = 48 |
| 128 | const RP_AGP_LIVE: i64 = 1 |
| 129 | const RP_AGP_DESIRED: i64 = 2 |
| 132 | const RP_RUNG_KEY_SEP: *u8 = ":" |
| 135 | const RP_GW_RUNG: i64 = 0 - 2 |
| 136 | const RP_GW_RUNG_NAME: *u8 = "organ_gate.conf-rung-declaration" |
| 139 | const RP_D_SD: i64 = 0 |
| 140 | const RP_D_RESOLVED: i64 = 1 |
| 141 | const RP_D_TREAT_ROW: i64 = 2 |
| 142 | const RP_D_TREAT_V: i64 = 3 |
| 143 | const RP_D_MCP: i64 = 4 |
| 144 | const RP_D_ORGAN_O: i64 = 5 |
| 145 | const RP_D_ORGAN_L: i64 = 6 |
| 146 | const RP_D_TOOL_L: i64 = 7 |
| 147 | const RP_D_GATE_L: i64 = 8 // 0 when no gate resolves |
| 148 | const RP_D_GATE_WHY: i64 = 9 |
| 149 | const RP_D_ROSTERED: i64 = 10 |
| 150 | const RP_D_SCLASS: i64 = 11 |
| 151 | const RP_D_ES_FOUND: i64 = 12 |
| 152 | const RP_D_RUN: i64 = 13 |
| 153 | const RP_D_RUN_SRC: i64 = 14 |
| 154 | const RP_D_AGENT: i64 = 15 |
| 155 | const RP_D_CHAIN: i64 = 16 |
| 156 | const RP_D_STAGE: i64 = 17 |
| 157 | const RP_D_REWORK: i64 = 18 |
| 158 | const RP_D_WEAK: i64 = 19 |
| 159 | const RP_D_NISS: i64 = 20 |
| 160 | const RP_D_WHY: i64 = 21 // *i64 per-link why codes |
| 161 | const RP_D_GF: i64 = 22 // *i64 the gate facts |
| 162 | const RP_D_GF2: i64 = 23 // *i64 the roster facts of the subject ITSELF (a gate the roster runs) |
| 163 | const RP_D_ISS: i64 = 24 // *i64 issue flags |
| 164 | const RP_D_TOOL: i64 = 25 // *u8 the subject tool |
| 165 | const RP_D_GATE: i64 = 26 // *u8 the gate |
| 166 | const RP_D_TARGET: i64 = 27 // *u8 the name the gate is resolved for |
| 167 | const RP_D_DST: i64 = 28 // *u8 the resolver's artifact path |
| 168 | const RP_D_TRIED: i64 = 29 // *u8 the resolver's search transcript |
| 169 | const RP_D_W: i64 = 30 // *i64 one why |
| 170 | const RP_D_STOP: i64 = 31 |
| 171 | const RP_D_O2: i64 = 32 |
| 172 | const RP_D_ESOUT: i64 = 33 |
| 173 | const RP_D_OFF: i64 = 34 |
| 174 | const RP_D_GWHY: i64 = 35 |
| 175 | const RP_D_SYM: i64 = 36 // *u8 |
| 176 | const RP_D_FULL: i64 = 37 // *u8 |
| 177 | const RP_D_RULE: i64 = 38 // *i64 |
| 178 | const RP_D_ES_FO: i64 = 39 |
| 179 | const RP_D_ES_FL: i64 = 40 |
| 180 | const RP_D_ROSTER_IN: i64 = 41 // which roster conf holds the gate (its list index), RCF_NONE when none does |
| 181 | const RP_D_GREEN_IN: i64 = 42 // which roster pair's journal supplied the GREEN that TESTED holds on, RCF_NONE when none |
| 182 | const RP_D_RCOUT: i64 = 43 // *i64 rgc_roster_credit's out (RGC_RC_SLOTS) |
| 183 | const RP_D_SLOTS: i64 = 44 |
| 184 | const RP_RUN_PROGRAM: i64 = 1 // where the newest run was read: the clock ran the program itself, |
| 185 | const RP_RUN_AGENT: i64 = 2 // the clock ran the treat row's agent command, |
| 186 | const RP_RUN_ROSTER: i64 = 3 // or the roster ran the subject |
| 187 | const RP_RUN_AGENT_JOB: i64 = 4 // the clock ran the treat row's agent, witnessed by its own job= name |
| 189 | const RP_W_BUF: i64 = 0 |
| 190 | const RP_W_FILL: i64 = 1 |
| 191 | const RP_W_ROWS: i64 = 2 |
| 192 | const RP_W_SBUF: i64 = 3 // its stage rows |
| 193 | const RP_W_SFILL: i64 = 4 |
| 194 | const RP_W_MBUF: i64 = 5 // its ledger rows (moves) |
| 195 | const RP_W_MFILL: i64 = 6 |
| 196 | const RP_W_SLOTS: i64 = 8 |
| 198 | const RP_T_RUNGS: i64 = 0 |
| 199 | const RP_T_UNOBS: i64 = 1 |
| 200 | const RP_T_DUPS: i64 = 2 |
| 201 | const RP_T_REWORK: i64 = 3 |
| 202 | const RP_T_PROMOTED: i64 = 4 |
| 203 | const RP_T_DEMOTED: i64 = 5 |
| 204 | const RP_T_ENTERED: i64 = 6 // rungs that entered PRODUCTION this census |
| 205 | const RP_T_NEW: i64 = 7 |
| 206 | const RP_T_ISS0: i64 = 8 // then one count per issue class |
| 207 | const RP_T_EXTRA: i64 = 12 |
| 209 | const RP_P_BUF: i64 = 0 |
| 210 | const RP_P_N: i64 = 1 |
| 211 | const RP_P_CUR: i64 = 2 // *i64 the cursor |
| 212 | const RP_P_BASELINE: i64 = 3 // 1 when there is no previous snapshot: this census records, and moves nothing |
| 213 | const RP_P_SLOTS: i64 = 4 |
functions
| 215 | func rp_span_copy(buf: *u8, off: i64, len: i64) -> *u8 |
| 226 | func rp_span_into(dst: *u8, cap: i64, buf: *u8, off: i64, len: i64) -> i64 |
| 238 | func rp_read_estate(rel: *u8, outp: *i64) -> i64 |
| 249 | func rp_read_matrix(dom: *u8, outp: *i64) -> i64 called by 1: rp_gather_board calls 5: sys_mmapct_build_pathct_first_publishedsys_read_filect_second_published |
| 267 | func rp_read_since(rel: *u8, since: i64, outp: *i64, env: *i64, cover: *i64) -> i64 called by 1: rp_gather_shared calls 5: sys_mmapep_artifact_pathlt_read_tailsys_munmaprgc_first_epoch |
| 299 | func rp_root(out: *u8) -> i64 |
| 316 | func rp_gather_rosters(clock: *u8, cn: i64, ev: *i64) -> i64 called by 1: rp_gather_shared calls 11: sys_mmaprcf_confs_boundrcf_confsrcf_pair_originrcf_pair_confrp_span_into+5 |
| 412 | func rp_roster_evidence(ev: *i64, name: *u8, nl: i64, since: i64, g: *i64, out: *i64) -> i64 |
| 425 | func rp_roster_confs_tail(ev: *i64) -> i64 |
| 435 | func rp_gather_shared(ev: *i64) -> i64 called by 2: rp_census_allmain calls 13: sys_now_realtime_secsys_mmaprp_read_estatests_loadsys_munmaprgc_lines+7 |
| 517 | func rp_gather_board(dom: *u8, ev: *i64) -> i64 called by 2: rp_census_allmain calls 10: sys_mmapbf_read_planct_first_publishedct_second_publishedrp_read_matrixces_cat+4 |
| 547 | func rp_detail_new() -> *i64 |
| 572 | func rp_base_into(dst: *u8, cap: i64, buf: *u8, off: i64, len: i64, sfx: *u8) -> i64 |
| 583 | func rp_strip_sfx(name: *u8, sfx: *u8) -> i64 |
| 593 | func rp_gate_name(dst: *u8, path: *u8) -> i64 |
| 604 | func rp_eval(rung: *u8, ev: *i64, links: *i64, f: *i64, d: *i64) -> i64 called by 2: rp_censusmain calls 40: rgc_journalrgc_journal_linkrgc_has_contractrgc_matrix_organrp_span_intoces_cat+34 |
| 832 | func rp_epoch(v: i64) -> i64 |
| 839 | func rp_roster_part(ev: *i64, i: i64, which: i64) -> i64 |
| 849 | func rp_run_src_name(s: i64) -> *u8 called by 1: rp_print |
| 857 | func rp_agp_name(s: i64) -> *u8 |
| 863 | func rp_sclass_name(c: i64) -> *u8 called by 1: rp_print |
| 871 | func rp_verdict_word(v: i64) -> *u8 called by 1: rp_print |
| 877 | func rp_link_line(name: *u8, v: i64, w: i64) -> i64 |
| 882 | func rp_print(dom: *u8, rung: *u8, ev: *i64, links: *i64, f: *i64, d: *i64) -> i64 |
| 932 | func rp_exit_for(links: *i64, d: *i64) -> i64 called by 1: main |
| 940 | func rp_exit_word(x: i64) -> *u8 called by 1: main |
| 946 | func rp_usage() -> i64 |
| 954 | func rp_move_row_fixed() -> i64 |
| 963 | func rp_census(dom: *u8, ev: *i64, quiet: i64, tot: *i64, wk: *i64, prev: *i64, d: *i64) -> i64 called by 2: rp_census_allmain calls 25: sys_mmapces_line_endces_fieldces_span_isces_nfieldsces_slen+19 |
| 1095 | func rp_art_path(anchor: *u8, isdefault: i64, prodname: *u8, sfx: *u8) -> *u8 |
| 1101 | func rp_tmp_path(path: *u8) -> *u8 |
| 1110 | func rp_census_all(anchor: *u8, isdefault: i64) -> i64 called by 1: main calls 31: sys_mmapct_build_pathct_first_publishedsys_read_filect_second_publishedgw+25 |
| 1269 | func rp_plan_path(dom: *u8, path: *u8) -> i64 called by 1: rp_journal calls 5: ct_build_pathct_first_publishedsys_openat_rdsys_closect_second_published |
| 1282 | func rp_journal(rung: *u8, kind: *u8, text: *u8, dom: *u8, ev: *i64) -> i64 |
| 1312 | func main(argc: i64, argv: *i64) -> i64 |