Programming Language

Nocter

A self-contained systems language built around simplicity, encapsulation, and foolproof design.

/development/reviews/v0.31.0-phase-5.md

v0.31.0 Phase 5 Qualification and Final Review

Status: complete with no open finding (2026-09-03). Phase 5 closes implementation and qualification for captured synchronous subprocess output. It changes the normative chapter from future direction to the current v0.31.0 source-tree contract without claiming that v0.31.0 has already been published.

Complete Path Review

The review traced Command.output through owned command storage, capture-pipe preparation, the shared fork transition, child descriptor installation, staged launch reporting, executable replacement, parent report collection, fair two-stream draining, exact-child observation, public failure selection, and construction of an owning Output. It also reviewed target primitive registration, native selection, editor queries, formatter discovery, the public-example catalog, installed-home execution, release qualification, and generated documentation.

Each decision retains one owner:

  • index.nct owns the public Command, ExitStatus, and transparent Output contract;
  • command.nct owns command input validation, owned path and arguments, argv construction, and the private Command and ExitStatus representation;
  • pipe_darwin.nct owns close-on-exec pipe creation, descriptor normalization, endpoint transfer, and idempotent closure;
  • capture_darwin.nct owns the Darwin readiness-record ABI and one-attempt poll/read classification;
  • capture_session_darwin.nct owns stream liveness, bounded fair draining, capture buffers, and cleanup after capture failure;
  • capture_launch_darwin.nct owns child standard-descriptor installation;
  • launch_report_darwin.nct owns the staged setup/exec report protocol;
  • subprocess_darwin.nct owns fork and exact-child wait classification;
  • command_darwin.nct alone composes those contracts and selects public process failures;
  • internal/os/darwin owns syscall numbers and generic raw syscall result declarations;
  • the compiler transports generic syscall and process-entry facts without knowing Command, Output, stream roles, readiness events, launch stages, or public process failures.

No consumer repeats target ABI decoding, descriptor state, process policy, or an earlier semantic choice. The shared public-example catalog owns the executable fixture and exact process contract; the installed-home qualifier consumes that contract instead of restating expected output bytes.

Resource and Failure Review

Pipe creation failure closes every endpoint acquired earlier in the operation. Fork failure drops the launch report and both capture owners. In the child, descriptor setup closes superseded endpoints, reports a typed setup stage on failure, and terminates without returning to ordinary Nocter code. A rejected executable reports its distinct stage. In the parent, both launch outcomes continue through stream draining and exact-child observation before a public result is selected.

Readiness and bounded reads service both live descriptors fairly. Hangup does not discard unread bytes; only a zero-length read closes a stream. A poll or read failure closes both capture readers before the exact-child wait so an abandoned finite pipe cannot leave the child blocked. Wait failure remains authoritative because no later result may claim a completely observed process. Nonzero exit and signal termination retain bytes as normal Output values.

All allocation required to prepare the child occurs before fork. Capture vectors may grow while the parent drains output and use the language's allocation-abort policy. The child path performs no ordinary allocation or destruction. The public result contains no descriptor or independently owned child, so callers cannot omit closure or reaping.

Repository-wide searches found Darwin syscall constants only in the target OS source, readiness layout and interpretation only in the capture boundary, descriptor ownership only in OwnedPipe, public capture-error selection only in command orchestration, and compiler knowledge of the public process types only in source-facing tests. No obsolete capture API, sequential whole-stream drain, second pipe protocol, magic child exit-code protocol, shell fallback, copied editor declaration, or caller-discipline cleanup contract was found.

The final audit found one release-qualification gap: installed-home qualification compiled every public package but executed only the older status example. Phase 5 now executes subprocess-output, compares its stdout with examples/subprocess-output/sample-output.txt, and requires empty stderr. The public-example test catalog reads the same file, leaving one expected output authority.

Qualification

Phase 5 passes:

  • cargo test --locked --workspace, including complete compiler, native, command, editor, standard-library, example, and documentation-facing suites; one public HTTPS acquisition test remains intentionally ignored;
  • cargo clippy --locked --workspace --all-targets --no-default-features -- -D warnings;
  • cargo check --locked --workspace --no-default-features;
  • cargo fmt --all -- --check;
  • deterministic generation and drift checks for all public HTML;
  • shell and JavaScript syntax checks for release packaging and site generation;
  • native execution of the captured-output public package through source-tree and installed-home contracts;
  • repository whitespace and generated-output checks.

No implementation or documentation remediation remains. v0.31.0 is ready for release preparation; this phase does not assign the release identity, create a distribution archive, tag a commit, or publish an artifact.