v0.29.0 Phase 5 Standard Input and Run Invocation Review
Status: complete with no open finding (2026-09-03). The implemented v0.29.0 boundary passes the complete compiler workspace, authored-standard, native execution, semantic editor, formatter, documentation, and static-quality gates. Release identity and archive qualification remain the separate release-preparation boundary.
Reviewed Boundary
The review traced a nocter run invocation from the operating-system argument vector through its single separator partition, generic compiler-option parsing, closed run plan, native compilation, and child-process launch. It separately traced standard input from the Darwin descriptor fact through borrowed File construction, descriptor-read result classification, the common Reader contract, and explicit BufReader state.
The adversarial search covered duplicate separator parsing, lossy OS-string conversion, child arguments entering semantic products, parallel read syscalls, hidden or global buffering, borrowed-descriptor closure, retained compatibility paths, target facts in public APIs, unchecked read counts, and contracts that depend on an external caller preserving an undocumented state.
Run Invocation Authority
run_invocation owns the only structural split of a run command. Its first standalone -- closes compiler input and constructs one RunProgramArguments value from every remaining native OS string. Generic option parsing receives only the compiler vector, so it cannot reinterpret a child option, empty argument, later separator, or non-Unicode value. Other commands retain their ordinary end-of-options rule without sharing the child channel.
The opaque child value moves through ParsedRunCommand and RunCommandPlan beside input and launch policy. It has no production read accessor and its debug representation exposes only a count. The process launcher is the only production consumer that opens it, and passes its values directly to std::process::Command. Discovery, resolution, checking, target construction, MIR, MachineProgram, and native-image requests contain no child-argument field and perform no equivalent partition.
The launcher continues to supply argument zero, inherit all three standard streams, select the already planned working directory, return an executed child's status unchanged, and remove the temporary executable. The new argument channel does not reopen any of those decisions.
Input, Ownership, and Buffering Authority
std/internal/os/darwin is the sole owner of the standard descriptor numbers and read syscall number. std/io/input.nct performs only borrowed File construction. std/io/file.nct owns the single descriptor-read syscall loop, interruption retry, error mapping, and returned-count bound. No input primitive or second syscall loop exists.
FileState distinguishes owned, borrowed, and locally closed wrappers. The common close transition calls the operating system only for owned descriptors and then makes the wrapper terminal. Consequently explicit close, BufReader completion, failure cleanup, and destruction all share one rule and cannot close inherited standard input through a separate path. The private representation prevents user code from forging a descriptor ownership state.
BufReader alone owns unread bytes, cursor position, line assembly, and its terminal flag. Line input reuses its existing refill, CR/LF normalization, UTF-8 validation, allocation failure, and failure-terminal behavior. There is no free line-input function, singleton, static buffer, or stdin-specific decoder. A zero requested capacity is normalized locally before the state machine begins, and every source-reported count is checked before indexing initialized bytes.
Tooling and Observable Behavior
The repository-owned stdin-prefix process contract combines exact child arguments, exact stdin, status, stdout, and stderr. Command tests execute every public package contract; native-session tests additionally force a UTF-8 scalar across three-byte buffer refills and verify repeated EOF; language-server tests open the real implementation source; and the formatter recursively consumes the same authored package.
An adversarial cleanup attempt removed the apparently unreachable tail after while true in the line reader. The semantic editor gate correctly produced E0373 because current Nocter reachability conservatively retains a possible loop exit. Restoring the explicit tail made the complete source valid again. The statement is therefore required source evidence under the current language contract, not dead compatibility code. Native-only success was not accepted as sufficient proof.
Phase 4 already built a fresh archive in a temporary directory, ran the extracted compiler without NOCTER_HOME, piped the shared sample to nocter run, forwarded the prefix after --, compared both streams exactly, and removed the temporary image. Phase 5 did not mutate dist/ or reuse that qualification as a second implementation path.
Residue and Dependency Review
Searches found no decoded child argument, program-argument field outside nocter-command, second run partition, stdin-specific semantic role, duplicate descriptor-read policy, process-global input buffer, public target descriptor, or compatibility alias. The authored-standard dependency graph and compiler architecture tests accept the new edges without widening semantic or backend layers.
Public roots retain declarations and documentation while focused implementation sources own bodies. Cross-responsibility transitions use typed values: the parser closes invocation structure, the run plan closes launch policy, the native session closes executable bytes, the target module provides raw facts, File closes descriptor policy, and BufReader closes buffering. No later responsibility reconstructs an earlier decision from text or an internal representation.
Qualification
Phase 5 passed:
cargo test --locked --manifest-path development/compiler/Cargo.toml --workspace, including 497 checking, 83 language-server, 55 command, and 33 native-session tests, with one public-HTTPS test intentionally ignored;cargo clippy --locked --manifest-path development/compiler/Cargo.toml --workspace --all-targets -- -D warnings;cargo check --locked --manifest-path development/compiler/Cargo.toml --workspace --no-default-features;- focused run partition, exact command-adapter forwarding, standard-input native execution, semantic-editor, and recursive public-example formatter tests;
- deterministic documentation generation and catalog validation;
- packaging shell and JavaScript syntax, Rust formatting, and repository whitespace checks.
No implementation remediation remains from this final review. v0.29.0 is ready for release preparation; this review does not assign the release identity, build the release archive, or publish it.