code wiki / _hdl_build / nx_toolatency.nx
nx_toolatency.nx
buildroot/runtime/_hdl_build/nx_toolatency.nx
about
nx_toolatency.nx -- LATENCY CENSUS FOR THE TOOL SURFACE: the evidence behind async-lane routing.
WHY THIS EXISTS (2026-08-07). The 503 class is a LATENCY problem. The edge closes its window at 15s
(NX_SD2_BACKEND_TIMEOUT_S) and the synchronous lane is budgeted at 14s (TEA_EXEC_TIMEOUT_SYNC_MS),
so a call that outruns the budget becomes a 503 WHOSE WORK MAY STILL HAVE LANDED -- the caller is
told it failed for a row that exists. async_only_tools.conf fixes that by forcing a tool onto the
detached job lane, but its membership was a HAND-WRITTEN LIST of tools somebody noticed failing.
You cannot route by a latency you never measured, and until today the daemon logged WHAT ran and
WHETHER it worked but never HOW LONG. ta_actlog now emits dur_ms (TOTAL HANDLER TIME, the quantity
the edge window actually applies -- exec time alone would understate it). This organ is the
consumer that turns those rows into a routing decision, so the lane stops being folklore.
TAIL-ANCHORED BY CONSTRUCTION. actlog.jrnl is APPEND-ONLY, so a head-anchored capped read keeps the
OLDEST bytes and silently drops the NEWEST -- exactly backwards for a gauge whose job is to notice
what got slow LATELY. Measured cost of that mistake in this same estate: nx_wirecensus read this
very ledger head-anchored and was blind to 89 invocation records.
REFUSES rather than reporting GREEN over data it never read: no-slow-tools and no-measurements are
different facts and must not share a representation.
DURABLE + ROSTERABLE (2026-08-27, 503 lane): every run appends ONE row to
knowledge/status/toolatency.log (its own file, one writer -- the rm_trend_log law), so two runs are
a TREND and a fired beat is distinguishable from a dead one. The row carries `unrouted=` -- the
over-budget tools still on the sync lane -- so the count travels with its worklist. Refusals write
a NODATA row too: an abstention that leaves no artifact is indistinguishable from a beat that never
fired.
dependencies 2 imports · 0 importers
imports: nx_syscalls.nxnx_toolatency_observation_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
| 30 | const TL_TAIL_CAP: i64 = 4194304 |
| 31 | const TL_MAXTOOLS: i64 = 512 |
| 32 | const TL_NAMELEN: i64 = 48 |
| 33 | const TL_SYNC_BUDGET_MS: i64 = 14000 |
| 34 | const TL_WARN_PERMIL: i64 = 500 |
| 35 | const TL_CONFCAP: i64 = 65536 |
| 36 | const TL_SEEK_SET: i64 = 0 |
| 37 | const TL_SEEK_END: i64 = 2 |
| 38 | const TL_EXIT_SHOULD: i64 = 4 |
| 39 | const TL_EXIT_NODATA: i64 = 5 |
| 40 | const TL_EXIT_OVER: i64 = 6 |
| 46 | const TL_MIN_BREACH: i64 = 2 |
| 50 | const TL_JRNL: *u8 = "knowledge/status/toolatency.log" as *u8 |
| 57 | const TL_RANK_PATH: *u8 = "knowledge/status/toolrank-toolreg-.tsv" as *u8 |
| 58 | const TL_RANK_TMP: *u8 = "knowledge/status/toolrank-toolreg-.tsv.tmp" as *u8 |
| 59 | const TL_RANK_ROW_EXTRA: i64 = 48 // per row beyond the name: two decimals (<=20 digits each), two tabs, a newline, slack |
| 60 | const TL_CSV_CAP: i64 = 4096 |
| 68 | const TL_CONF: *u8 = "knowledge/toolatency.conf" as *u8 |
| 69 | const TL_ACT_PERMIL_DFLT: i64 = 40 |
| 70 | const TL_ACT_AVG_MS_DFLT: i64 = 2000 |
| 77 | const TL_AUTO_ROUTE_DFLT: i64 = 0 |
| 78 | const TL_ASYNC_CONF: *u8 = "async_only_tools.conf" as *u8 |
| 79 | const TL_CONF_MODE: i64 = 420 // 0644, the mode every other append-only conf/journal in the estate uses |
functions
| 81 | func tw(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 } |
| 82 | func twe(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(2, s, n); return 0 } |
| 83 | func twn(v: i64) -> i64 |
| 101 | func tl_cat(b: *u8, o: i64, s: *u8) -> i64 |
| 107 | func tl_catn(b: *u8, o: i64, v: i64) -> i64 |
| 128 | func tl_jrnl(rows: i64, measured: i64, ntools: i64, over: i64, atrisk: i64, routed: i64, unrouted: *u8, verdict: *u8) -> i64 |
| 156 | func tl_read_tail(path: *u8, buf: *u8, cap: i64) -> i64 |
| 166 | func tl_eol(buf: *u8, n: i64, i: i64) -> i64 |
| 176 | func tl_kv(buf: *u8, s: i64, e: i64, key: *u8) -> i64 called by 1: main |
| 210 | func tl_on_lane(conf: *u8, n: i64, nm: *u8, nl: i64) -> i64 |
| 235 | func tl_auto_route_row(b: *u8, o: i64, nm: *u8, nl: i64, breaches: i64, calls: i64, avg: i64) -> i64 |
| 260 | func tl_auto_route_apply(b: *u8, n: i64, routed: i64) -> i64 |
| 276 | func tl_write_rank(names: *u8, cnt: *i64, ntools: i64, asof: i64) -> i64 |
| 309 | func main(argc: i64, argv: *i64) -> i64 |