ReviewOS

home-lang/home

Native CLI spawn helper: complete IPC, detached and input option semantics

#509
Closed chris opened this 9 days ago ·
9 days ago

Follow-up to #66 and #497. This concerns the internal packages/runtime/src/spawn_sync.zig CLI/package-manager helper, not the separate JavaScript Bun.spawnSync implementation.

The native package-script work replaces buffered replay with actual inherited stdin/stdout/stderr, preserves process termination signals, and retains concurrent capture for buffered outputs. The helper still lacks three requested option variants: ipc, detached, and .stdin = .buffer. These now return explicit unsupported-option errors instead of silently ignoring the request. argv0/use_execve_on_macos are also not fully represented by its std.Io spawn path.

Port the remaining helper contract from the pinned native sync-spawn implementation. In particular, preserve a requested IPC descriptor across exec without changing unrelated descriptor inheritance, maintain correct detached/session behavior, handle stdin-buffer semantics, and distinguish the executable path from argv[0]. Keep failure ownership, live inherited output, and actual signal propagation intact. Add focused native parent/child checks and run the applicable unchanged CLI/package-manager corpus. Do not substitute the JS API's already passing results as proof that this internal helper is complete.

Source inspection establishes these gaps; this issue does not claim Linux/Windows execution or cross-compilation. CLI corpus residuals are tracked in #508, and dotenv integration in #506.

9 days ago

Published source checkpoint: 06a212514 on codex/runtime-port. This follow-up remains unresolved; the passing package-script checkpoint does not complete its acceptance criteria. Verification and related gaps are linked in #497 and #66.

9 days ago

Completed and published on main in bbe6133f4 (fix(runtime): activate complete synchronous spawn helper).

The reduced packages/runtime/src/spawn_sync.zig backend is gone. Its stable import path now delegates directly to the pinned full process.sync implementation, so inherited/ignored/buffered stdio, IPC fd adoption, detached spawning, independent argv0, and macOS spawn-as-exec all use the same ownership, wait, signal-forwarding, no-orphans, and cleanup paths. This removes the explicit UnsupportedIpcDescriptor, UnsupportedDetachedSpawn, and UnsupportedStdinBuffer exits rather than layering partial behavior on top of them. Small compatibility changes migrate the previously dormant path to the current pinned Zig APIs and make the full Status union exhaustive at existing callers.

The new native parent/child regression creates a package script that writes ipc-preserved\n to fd 3, launches nested Home with NODE_CHANNEL_FD=3, and reads the extra pipe from the parent. The pre-change binary returned code 1 with UnsupportedIpcDescriptor; the completed path returns exact { code: 0, stdout: "", stderr: "", ipc: "ipc-preserved\\n" }.

Verification:

  • JSC-enabled native build: 18/18 steps
  • JSC-disabled native build: 5/5 steps
  • focused home_rt: 1,815 passed / 19 skipped / 0 failed, 20/20 build steps
  • new sync IPC/exec regression: pass
  • native node-core CLI regression: pass
  • native bunx regression: pass
  • isolated test --changed: clean 0/0 case and modified 1/1 case both correct, exercising synchronous buffered output
  • scoped Pickier and git diff --check: pass

This execution evidence is Darwin-only. Linux/Windows runtime execution and the full Bun-suite ledger remain tracked by #66; those platform limits are not being counted as verified here.

Sign in to comment on this issue.