Two new primitives in builtins.c, paralleling the Python tier shipped in
the previous commit. gpu-worker.lsp now runs on the C tier byte-identically
to the Python tier.
(spawn-process-stdio path args) → (stdin-port . stdout-port)
fork + pipe + execvp; child's stdin & stdout wired back to parent
as line-buffered FILE* ports. Accepts both strings and symbols in
the args list (matches Python tier's permissive conversion).
(flush-port port)
fflush() on the port's FILE*. No-op when fp is null.
End-to-end on 3090-ai with C-tier lumbda everywhere:
shell A: ./lumbda /tmp/launch-c.lsp
→ gpu-worker: ready cuda-shake-fanout ← ./shake256-fanout
→ gpu-worker listening on port 9091
shell B: ./lumbda smoke-bend.lsp # run 3×
=== smoke-bend ===
1. cost estimator picks local for 3 inputs: OK
2. worker available? #t
3. bend! (cuda-shake-fanout '("00" "01" "deadbeef") 32):
(b8d01df855… 94da6280b2… fa094fa86e…)
Three runs identical bytes. Same hashes as Python tier. Same hashes as
hashlib.shake_256 host reference.
Cross-tier matrix (proves wire protocol is tier-agnostic):
client tier worker tier status
─────────────────────────────────────
C tier C tier PASS — 2 sequential runs, byte-identical
Python tier C tier PASS — same hashes
C tier Python tier implicit by symmetry (same wire bytes
both directions; Python-server tested
against Python-client in prior commit)
Per-tier status after this commit:
Python tier ✓ end-to-end
C tier ✓ end-to-end + cross-tier byte-identical to Python tier
asm tier → still needs spawn-process-stdio via raw fork+pipe+
execve syscalls. Scheme files unchanged.