nx_substrate_python_spawn_test.nx source
↩ module page · 130 lines · 4783 B
1// nx_substrate_python_spawn.nx -- substrate IS a Python supervisor.
2//
3// Cardinal 2026-05-21 ("bits up top down bottom up everything till
4// we own silicon"): this is the bottom-up convergence witness. A
5// NishiLang ELF, compiled by nxc2 and running under qemu/WSL2,
6// becomes the PARENT process of /usr/bin/python3. No bash spawn
7// step. Substrate calls nx_hal_spawn -> sys_fork + sys_execve;
8// child runs Python; parent reaps via nx_hal_wait.
9//
10// What this proves end-to-end:
11// - nx_hal_spawn handles real-world execve (Python interpreter is
12// a much larger / more complex binary than /bin/echo + /bin/true
13// in the prior smoke 10bc9d89)
14// - argv marshalling works for multi-arg invocations (-c "code")
15// - exit-code propagation works for arbitrary 0..255 codes (test
16// specifically requests exit 42 to prove the value reaches the
17// substrate parent and isn't masked to 0/1)
18// - Substrate can supervise a Python lifecycle the same way a
19// container runtime does: spawn + observe + reap
20//
21// Gap left open after this commit:
22// - WSL2 Python (3.12) has NO fastapi/uvicorn/pydantic installed
23// today. Wiring substrate-spawn into the real Elder AI service
24// path requires installing those Python deps in WSL2 OR adding
25// a Windows backend to nxc2 (multi-session) so the substrate
26// ELF runs natively on Windows and spawns Win32 python.exe.
27// - This smoke is the proof-of-concept; production Elder AI
28// services still launch via bash adapter today (commits
29// 4551a0d5 / 5e203032 / 6d43d14e / 18f567d3).
30//
31// genealogy_id: docker_runc_init_2014 + systemd_lifespan_2010 +
32// cardinal_2026-05-21_top_down_bottom_up_dual_mandate
33// lineage_id: substrate_python_supervisor_v0_smoke
34
35import "nx_syscalls.nx"
36import "nx_hal.nx"
37
38func _emit_stdout(buf: *u8, len: i64) -> i64 {
39 return sys_write(1, buf, len)
40}
41
42func main() -> i64 {
43 // ----- Test 1: spawn python3 -c "exit(42)"; reap exit code -----
44 let py_path: *u8 = "/usr/bin/python3" as *u8
45 let py_dash_c: *u8 = "-c" as *u8
46 let py_code: *u8 = "import sys; sys.exit(42)" as *u8
47
48 let argv: *i64 = (sys_mmap(32)) as *i64
49 argv[0] = py_path as i64
50 argv[1] = py_dash_c as i64
51 argv[2] = py_code as i64
52 argv[3] = 0
53
54 let null_envp: *i64 = (0 as i64) as *i64
55
56 let banner_a: *u8 = "[substrate] spawning python3 -c 'sys.exit(42)'...\n" as *u8
57 _emit_stdout(banner_a, 50)
58
59 let pid: i64 = nx_hal_spawn(py_path, argv, null_envp)
60 if pid <= 0 {
61 let err: *u8 = "[substrate] spawn FAILED\n" as *u8
62 _emit_stdout(err, 25)
63 return 1
64 }
65
66 let exit_out: *i64 = (sys_mmap(8)) as *i64
67 exit_out[0] = -1
68
69 let wait_rc: i64 = nx_hal_wait(pid, exit_out)
70 if wait_rc != NX_HAL_OK {
71 let err: *u8 = "[substrate] wait FAILED\n" as *u8
72 _emit_stdout(err, 24)
73 return 2
74 }
75
76 if exit_out[0] != 42 {
77 let err: *u8 = "[substrate] wrong exit code\n" as *u8
78 _emit_stdout(err, 28)
79 return 3
80 }
81
82 let ok1: *u8 = "[substrate] python3 exit 42 reaped OK\n" as *u8
83 _emit_stdout(ok1, 38)
84
85 // ----- Test 2: spawn python3 -c that writes a real message -----
86 let py_print: *u8 = "import sys; sys.stdout.write('[child py] hi from substrate-parented python\\n'); sys.exit(0)" as *u8
87
88 argv[0] = py_path as i64
89 argv[1] = py_dash_c as i64
90 argv[2] = py_print as i64
91 argv[3] = 0
92
93 let banner_b: *u8 = "[substrate] spawning python3 -c 'print hello'...\n" as *u8
94 _emit_stdout(banner_b, 50)
95
96 let pid2: i64 = nx_hal_spawn(py_path, argv, null_envp)
97 if pid2 <= 0 { return 4 }
98 exit_out[0] = -1
99 if nx_hal_wait(pid2, exit_out) != NX_HAL_OK { return 5 }
100 if exit_out[0] != 0 { return 6 }
101
102 let ok2: *u8 = "[substrate] python3 child completed OK\n" as *u8
103 _emit_stdout(ok2, 39)
104
105 // ----- Test 3: rapid succession -- spawn 5 pythons in a loop -----
106 let banner_c: *u8 = "[substrate] spawning 5 python3 children in sequence...\n" as *u8
107 _emit_stdout(banner_c, 55)
108
109 let py_quick: *u8 = "import sys; sys.exit(0)" as *u8
110 var i: i64 = 0
111 while i < 5 {
112 argv[0] = py_path as i64
113 argv[1] = py_dash_c as i64
114 argv[2] = py_quick as i64
115 argv[3] = 0
116 let pid_n: i64 = nx_hal_spawn(py_path, argv, null_envp)
117 if pid_n <= 0 { return 7 }
118 exit_out[0] = -1
119 if nx_hal_wait(pid_n, exit_out) != NX_HAL_OK { return 8 }
120 if exit_out[0] != 0 { return 9 }
121 i = i + 1
122 }
123 let ok3: *u8 = "[substrate] 5/5 sequential python spawns OK\n" as *u8
124 _emit_stdout(ok3, 44)
125
126 let final: *u8 = "[substrate] PROOF: NishiLang ELF is parenting Python processes via HAL\n" as *u8
127 _emit_stdout(final, 72)
128
129 return 0
130}