code wiki / _hdl_build / nx_swarm_discover.nx
nx_swarm_discover.nx
buildroot/runtime/_hdl_build/nx_swarm_discover.nx
about
nx_swarm_discover.nx -- SF-DISCOVER: find GPU inference capacity on the LAN and register it.
WHY. The swarm's endpoint SSOT (knowledge/swarm_nodes.conf) is HAND-MAINTAINED, and that is how
the estate lost its GPU for weeks: DHCP moved the laptop .193 -> .192 and five hardcoded copies
went stale in the same instant while every swarm gate still read GREEN. Binding the five copies to
one row fixed the DUPLICATION; it did not fix the fact that a human still has to notice and type.
★★★★★A REGISTRY THAT ONLY A HUMAN CAN UPDATE GOES STALE AT EXACTLY THE MOMENT IT MATTERS -- when
hardware moves, which is the same moment nobody is watching.
MEASURED 2026-08-04, and it is the reason this exists: a sweep of every live host on 192.168.8.0/24
found EXACTLY ONE inference endpoint (the laptop 5080 at .192:7861). The "west dual 3090" row in
the SSOT pointed at 10.0.4.13 -- a different, unreachable subnet -- so the estate believed it had
48GB of VRAM it could not touch. ★A CONFIG ROW IS A CLAIM ABOUT THE WORLD, AND AN UNVERIFIED ONE
IS JUST A WISH WITH AN IP ADDRESS.
WHAT IT DOES: probe a host range for real inference endpoints, VERIFY each by asking it to
identify itself, and report capacity. With `apply`, APPEND newly-found endpoints to the SSOT.
⛔IT NEVER DELETES OR REWRITES AN EXISTING ROW. A discovery pass that can silently drop a node is
a worse failure than a stale row: the stale row fails loudly at dispatch, a deleted one vanishes.
Absent hosts are REPORTED, never auto-removed -- a host being off is not proof it is gone.
nx_swarm_discover scan [a.b.c] -- probe .1-.254, report what actually answers
nx_swarm_discover apply [a.b.c] -- same, then APPEND unregistered finds to swarm_nodes.conf
license_tier: ORIGINAL expect_exit: 0
module: nishi-core.swarm.discover
dependencies 3 imports · 0 importers
imports: nx_syscalls.nxnx_estate_path.nxnx_connect.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
| 29 | const SD_MAGIC_1024: i64 = 1024 |
| 31 | const SD_PORT_SD: i64 = 7861 // sd-server / our engine (OpenAI-shaped) |
| 32 | const SD_PORT_OLLAMA: i64 = 11434 // ollama |
| 33 | const SD_HOST_LO: i64 = 1 |
| 34 | const SD_HOST_HI: i64 = 254 |
| 35 | const SD_BUF: i64 = 65536 |
| 36 | const SD_TMO_MS: i64 = 400 // bounded: a full /24 must not take an hour |
functions
| 38 | func sw(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 } |
| 39 | func sn(v: i64) -> i64 |
| 48 | func sd_len(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n } called by 1: sd_has |
| 49 | func sd_cat(d: *u8, o: i64, s: *u8) -> i64 { var i: i64 = 0; var a: i64 = o; while s[i] != (0 as u8) { d[a] = s[i]; a = a + 1; i = i + 1 } return a } |
| 50 | func sd_catn(d: *u8, o: i64, v: i64) -> i64 |
| 62 | func sd_probe(a: i64, b: i64, c: i64, d: i64, port: i64, path: *u8, out: *u8, cap: i64) -> i64 called by 1: sd_verify calls 8: sys_socketsys_set_socket_timeoutsys_mmapnx_connect_boundedsys_closesd_cat+2 |
| 87 | func sd_has(buf: *u8, n: i64, needle: *u8) -> i64 |
| 105 | func sd_verify(a: i64, b: i64, c: i64, d: i64, port: i64, buf: *u8) -> i64 |
| 121 | func sd_registered(a: i64, b: i64, c: i64, d: i64, port: i64) -> i64 |
| 139 | func sd_append_row(a: i64, b: i64, c: i64, d: i64, port: i64, idx: i64) -> i64 |
| 159 | func main(argc: i64, argv: *i64) -> i64 |