code wiki / _hdl_build / nx_buildq.nx

nx_buildq.nx

buildroot/runtime/_hdl_build/nx_buildq.nx

17927 B337 linesdepth 5pulls 5 transitivereach 0 importersview sourcekind tool
docsdependenciesstructsconstsfunctions

about

nx_buildq.nx -- QUEUE A BUILD FOR THE NEXT OPENING instead of re-issuing it by hand. WHY. `/api/build` under load answers REFUSED-LOAD: "NOTHING IS QUEUED for you anywhere -- re-issue it yourself once the load clears" -- and nx_build_admit's own header says its QUEUE verdict was DESIGNED to be absorbed by nx_orchestrate's wait-for-opening queue. Nothing ever wired the two: the queue had no predicate for headroom, and nothing seeded a build row. Measured 2026-08-18: five REFUSED-LOAD re-issues by hand in one session while the toolchain rung shipped -- a human acting as the retry loop. WHAT (composition, no new mechanism): one call seeds plan-build-<target>- : 1 <TAB> nx_sov_build_run <TAB> <target> <TAB> --build-only deployq- : BQ-<target> | title | headroom:[floor:max] | queued | build-<target> | note nx_orchestrate (the */5 poller) evaluates `headroom:` by forking nx_build_admit and FIRES the plan via nx_plan_run when the box GRANTS -- so the compile lands in buildroot/_build/<target>.sov.elf on the first pass after the opening, its rc + output snippet in planrun-build-<target>-, no human in the loop. The build itself still runs through nx_sov_build_run, so admission, lease, cache, canon and every other guard the build lane already has apply unchanged. Promotion is NOT queued here (a promote is a deliberate act with a digest); read the planrun result, then promote. DL9 (deploy, 2026-09-02) bq_dedupe_target: the queue was MEASURED idempotent by id (231 rows, 231 distinct ids, nx_store_put re-puts by id), so a second `add` of one target replaces the row rather than doubling it -- and this organ now SAYS so (ALREADY-QUEUED) instead of printing a second QUEUED receipt that read like a second row. The half of the rung that was genuinely open is CLOSE: a build that succeeds by another door (a sync /api/build, a hand nx_sov_build_run) left the queued row alive, so the poller rebuilt the same source on its next opening. `close <target> [rc]` marks the row closed with the reason, in place, by id; the poller fires only `queued` rows, so a closed row can never fire. Nothing to close is a named NO-ROW, never an error: a caller in a build lane must not fail because nobody had queued it. nx_buildq add <target> [floor_mb] [max_centiload] [--store <elf>] [--queue <prefix>] [--plan <prefix>] nx_buildq close <target> [rc] [--store <elf>] [--queue <prefix>] Both writes go through nx_store_put (THE plane write verb, provenanced, revision-logged) -- forked, never re-implemented. Fails CLOSED and LOUD: a refused seed prints the verb's own answer and exits 4. The --store/--queue/--plan overrides exist for the gate (fixture planes under /tmp); production callers never pass them. license_tier: ORIGINAL No hw writes (Rule 26). expect_exit: 0

dependencies 2 imports · 0 importers

nx_tool_run.nx nx_syscalls.nx nx_buildq.nx

imports: nx_tool_run.nxnx_syscalls.nx

imported by: nobody (leaf or entry point)

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

main bq_usage bq_w sys_write sys_exit bq_streq bq_safe bq_w ↻ sys_exit ↻ bq_digits 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 ↻ bq_cat bq_load sys_mmap ↻ tr_run_capture sys_mmap ↻ sys_pipe2 sys_fork sys_close sys_dup3 sys_execve_clean sys_close_inherited sys_close_inherited_proc sys_openat_rd sys_mmap ↻ sys_getdents64

structs

none

consts

39const BQ_STORE_PUT_DEFAULT: *u8 = "/volume1/homes/elderwesto/nishihost/nx_store_put.elf"
40const BQ_PLAN_PREFIX_DEFAULT: *u8 = "knowledge/store/plan-build-"
41const BQ_QUEUE_PREFIX_DEFAULT: *u8 = "knowledge/store/deployq-"
42const BQ_ACTOR: *u8 = "nx_buildq"
43const BQ_STATUS_QUEUED: *u8 = "queued"
44const BQ_STATUS_CLOSED: *u8 = "closed"
45const BQ_CAP: i64 = 65536
46const BQ_LOAD_CAP: i64 = 1048576 // a whole-plane load: 231 rows measured at ~74 KB; 1 MiB holds 14x and the brim is announced
47const BQ_PATHCAP: i64 = 512
48const BQ_NOTECAP: i64 = 1024
49const BQ_ROW_FIELDS: i64 = 6 // id title precond status plan note
50const BQ_TAB: i64 = 9
51const BQ_NL: i64 = 10
52const BQ_EXIT_USAGE: i64 = 2
53const BQ_EXIT_REFUSED: i64 = 4

functions

58func bq_w(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 }
called by 3: bq_loadbq_usagemain calls 1: sys_write
59func bq_wn(v: i64) -> i64
72func bq_len(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n }
73func bq_streq(a: *u8, b: *u8) -> i64
called by 1: main
79func bq_cat(dst: *u8, o: i64, s: *u8) -> i64 { var i: i64 = 0; var p: i64 = o; while s[i] != (0 as u8) { if p < BQ_PATHCAP - 1 { dst[p] = s[i]; p = p + 1 } i = i + 1 } dst[p] = 0 as u8; return p }
80func bq_catn(dst: *u8, o: i64, cap: i64, s: *u8) -> i64 { var i: i64 = 0; var p: i64 = o; while s[i] != (0 as u8) { if p < cap - 1 { dst[p] = s[i]; p = p + 1 } i = i + 1 } dst[p] = 0 as u8; return p }
called by 1: main
81func bq_catnum(dst: *u8, o: i64, cap: i64, v: i64) -> i64
called by 1: main calls 1: sys_mmap
94func bq_safe(s: *u8) -> i64
called by 1: main
109func bq_digits(s: *u8) -> i64
called by 1: main
116func bq_put(store: *u8, av: *i64) -> i64
124func bq_load(store: *u8, prefix: *u8, buf: *u8, cap: i64) -> i64
called by 1: main calls 3: sys_mmaptr_run_capturebq_w
142func bq_dedupe_target(dump: *u8, n: i64, target: *u8, fields: *u8) -> i64
called by 1: main calls 2: sys_mmapbq_cat
191func bq_field(fields: *u8, k: i64) -> *u8 { return ((fields as i64) + k * BQ_NOTECAP) as *u8 }
called by 1: main
193func bq_usage() -> i64
called by 1: main calls 2: bq_wsys_exit
199func main(argc: i64, argv: *i64) -> i64