Nocter v0.30.0 Release Notes
Nocter v0.30.0 adds the first standard-library subprocess boundary for ordinary command-line
applications. An owning Command launches one exact executable path with owned arguments, inherits
the current process environment, working directory, and standard streams, waits for its child, and
returns a typed ExitStatus. The only implemented host and native target remains arm64-darwin.
Exact-path Commands
std/process now exposes:
use std/process.{Command, ExitStatus}
var command = Command.new("./helper")?
command.arg("one argument")?
let status: ExitStatus = command.status()?
Command.new and arg validate and copy their inputs. Empty executable paths, invalid UTF-8, and
embedded NUL bytes are rejected before launch; a rejected argument leaves the command unchanged.
The executable spelling is used exactly as supplied. Relative paths use the inherited working
directory, and the standard library performs no PATH search, shell parsing, or command-line text
joining.
status consumes the command, creates one child, and waits for that exact child. There is no
independently discardable child handle, so ordinary source cannot omit reaping or forget a hidden
process resource. All launch storage is prepared before child creation, and the child cannot return
to ordinary Nocter allocation, destruction, or user code after fork.
Typed Terminal Status
ExitStatus keeps ordinary exit and signal termination distinct:
if status.success() {
// The child exited with code zero.
}
let code = status.code() otherwise {
let signal = status.signal()!
}
success is true only for ordinary exit code zero. Exactly one of code and signal is present.
A nonzero child exit is a successfully observed status, not a T! failure.
Launch rejection is reported separately from child status. Missing executables, denied execution,
invalid executable or argument requests, process creation failures, and terminal-observation
failures use stable std.process.* error codes. A private close-on-exec channel prevents an
intentional child exit code such as 127 from being mistaken for an exec failure.
Practical Integration
The new subprocess-status package example invokes a repository-owned helper through
./helper.sh, passes a whitespace-bearing argument without joining, and reports the helper's typed
nonzero exit status. The same source crosses native compilation and execution, formatter checks,
semantic hover, completion, declaration and implementation navigation, and installed-home
qualification.
Compatibility and Non-goals
This release adds API without changing existing std/process argument, environment, current-
directory, exit, or abort behavior. It does not add shell execution, PATH search, environment or
working-directory overrides, standard-stream redirection, pipes, output capture, asynchronous
children, process signals, another native target, or persistent compiler caches.
Candidate Qualification
Release-content commit 35ce75b3cb8b64fe918c5f4066d3bde14d2521b5 passed two independent
locked workspace runs with 1,537 tests passed, zero failed, and one ignored in each run. The
ignored public-HTTPS acquisition test passed separately. Warnings-denied all-target Clippy,
no-default-features checking, deterministic documentation, formatter checks, and repository
validation also passed.
Two independent optimized builds produced the same archive and installed home. The retained local
archive is 8,278,398 bytes and has SHA-256
2a23e254fbfb07f387b6489d947945c7481f7c03be8d659efefe1c3c697412a8. Its isolated installed home
passed version and integrity checks, every public example, package run/build/test/graph operations,
the exact text-banner, stdin-prefix, and subprocess-status process contracts, framed LSP
requests, immutability checking, and compiler and standard-library tamper rejection. Publication
reuses that retained candidate without rebuilding it.