nx_elder_registry.nx
buildroot/runtime/nx_elder_registry.nx
about
nx_elder_registry.nx -- Elder AI service registry (bits-up).
Sovereign service registry for the Stage B Elder AI off-Docker
port. Holds the (service_name, port, exec_path, args_blob,
healthcheck_url, supervisor_state) tuple per service; the
platform-specific launcher (PowerShell on Windows; nx_container
on Linux) reads the registry to know what to spawn.
V1 mechanics: pure-NishiLang registry with canary-bracketed
records. String fields are caller-owned *u8 blobs with byte
lengths -- the registry doesn't copy strings, it holds pointers
(matches H10 nx_modality_router opacity pattern). Supervisor
state per service is a sealed enum mirroring nx_supervisor.nx
(HEALTHY / BACKING_OFF / ESCALATING / TERMINATED).
Composition path:
- register_service(name, port, exec, args, healthcheck_url)
once per service at supervisor bootstrap
- lookup_by_name(name) at routing time -- caller hashes name
to a stable index OR linearly scans (V1 is linear; Elder AI
has ~80 services, scan is fine)
- lookup_by_port(port) for reverse-lookup (debugging,
health-page generation)
- mark_state(name, state) when the launcher reports a child
crashed / exited / recovered
Cardinal honesty: spawning a Win32 process requires CreateProcessW
from kernel32.dll. That OS boundary is irreducible -- the
substrate cannot fork() on Windows. This file owns ONLY the
registry data structure and the supervisor-state bookkeeping.
The PowerShell launcher (or future nx_win_spawn primitive) reads
the registry's exposed accessors and does the actual CreateProcessW
call. Substrate stays bits-up; OS boundary stays thin.
genealogy_id: docker_compose_v3_2021 + erlang_otp_supervisor_1996 +
cardinal_2026-05-21_elder_ai_windows_native_docker_replacement +
cardinal_2026-05-20_bits_up_nishi_not_linux
lineage_id: substrate_elder_registry_v1
nx_capability_manifest:
dependencies 1 imports · 2 importers
imports: nx_syscalls.nx
imported by: nx_elder_registry_test.nxnx_elder_supervisor_main.nx
structs
| 108 | struct NxElderService |
| 125 | struct NxElderRegistry |
consts
| 63 | const NX_MAGIC_65535: i64 = 65535 |
| 66 | const NX_ELDER_MAX_SERVICES: i64 = 256 |
| 70 | const NX_ELDER_STATE_REGISTERED: i64 = 0 // known but not yet started |
| 71 | const NX_ELDER_STATE_STARTING: i64 = 1 // launcher invoked, awaiting healthy |
| 72 | const NX_ELDER_STATE_HEALTHY: i64 = 2 // healthcheck OK |
| 73 | const NX_ELDER_STATE_BACKING_OFF: i64 = 3 // crashed, waiting before restart |
| 74 | const NX_ELDER_STATE_ESCALATING: i64 = 4 // exceeded max_restarts |
| 75 | const NX_ELDER_STATE_TERMINATED: i64 = 5 // explicit stop |
| 76 | const NX_ELDER_STATE_N_STATES: i64 = 6 |
| 85 | const NX_ELDER_OK: i64 = 0 |
| 86 | const NX_ELDER_BAD_INPUT: i64 = 1 |
| 87 | const NX_ELDER_NOT_FOUND: i64 = 2 |
| 88 | const NX_ELDER_DUPLICATE_NAME: i64 = 3 |
| 89 | const NX_ELDER_DUPLICATE_PORT: i64 = 4 |
| 90 | const NX_ELDER_FULL: i64 = 5 |
| 91 | const NX_ELDER_BAD_STATE: i64 = 6 |
| 92 | const NX_ELDER_TAMPER: i64 = 7 |
| 93 | const NX_ELDER_N_VERDICTS: i64 = 8 |
| 102 | const NX_ELDER_SVC_CANARY_PRE: i64 = 0x456C6453766350A1 // "EldSvcP!" |
| 103 | const NX_ELDER_SVC_CANARY_POST: i64 = 0x53766345314434A2 // "SvcE1D4 " |
| 104 | const NX_ELDER_REG_CANARY_PRE: i64 = 0x456C645265675001 // "EldRegP." |
| 105 | const NX_ELDER_REG_CANARY_POST: i64 = 0x52656745314435A3 // "RegE1D5." |
functions
| 78 | func nx_elder_state_is_valid(s: i64) -> i64 |
| 95 | func nx_elder_verdict_is_valid(v: i64) -> i64 called by 1: main |
| 134 | func nx_elder_service_is_valid(s: *NxElderService) -> i64 |
| 147 | func nx_elder_registry_is_valid(r: *NxElderRegistry) -> i64 |
| 159 | func nx_elder_registry_new(max_services: i64) -> *NxElderRegistry |
| 179 | func _elder_bytes_equal(a: *u8, a_len: i64, b: *u8, b_len: i64) -> i64 called by 1: _elder_find_by_name |
| 190 | func _elder_find_by_name(r: *NxElderRegistry, name: *u8, name_len: i64) -> i64 called by 3: nx_elder_registernx_elder_lookup_by_namenx_elder_mark_state calls 1: _elder_bytes_equal |
| 205 | func _elder_find_by_port(r: *NxElderRegistry, port: i64) -> i64 |
| 219 | func nx_elder_register(r: *NxElderRegistry, service_id: i64, name: *u8, name_len: i64, port: i64, exec_path: *u8, exec_path_len: i64, args_blob: *u8, args_blob_len: i64, healthcheck_url: *u8, healthcheck_len: i64) -> i64 called by 2: main_build_registry calls 4: nx_elder_registry_is_valid_elder_find_by_name_elder_find_by_portsys_mmap |
| 257 | func nx_elder_lookup_by_name(r: *NxElderRegistry, name: *u8, name_len: i64) -> *NxElderService |
| 264 | func nx_elder_lookup_by_port(r: *NxElderRegistry, port: i64) -> *NxElderService |
| 271 | func nx_elder_lookup_by_index(r: *NxElderRegistry, idx: i64) -> *NxElderService |
| 279 | func nx_elder_mark_state(r: *NxElderRegistry, name: *u8, name_len: i64, new_state: i64) -> i64 |
| 298 | func nx_elder_service_port(s: *NxElderService) -> i64 |
| 303 | func nx_elder_service_state(s: *NxElderService) -> i64 |
| 308 | func nx_elder_service_id(s: *NxElderService) -> i64 |
| 313 | func nx_elder_service_restart_count(s: *NxElderService) -> i64 |
| 318 | func nx_elder_n_services(r: *NxElderRegistry) -> i64 |
| 324 | func nx_elder_n_healthy(r: *NxElderRegistry) -> i64 |