v0.19.0 Phase 1 Streaming Text Input Review
Result: passed (2026-08-28). This review covers the public BufReader line contracts, reusable destination behavior, UTF-8 validation authority, terminal-state convergence, bounded storage, native behavior, standard-library dependency boundaries, and editor behavior introduced by v0.19.0 Phase 1.
Review Criteria
The review traced:
- every byte from an underlying partial read through delimiter classification, UTF-8 validation,
publication into
String, and later destruction; - every transition caused by EOF, explicit close, I/O failure, invalid UTF-8, and recoverable growth failure;
- ownership of unread bytes, the incomplete line, the caller destination, UTF-8 policy, and the
stable
std.string.invalid_utf8failure; - all new standard-library module dependencies and every public API added to
StringandBufReader; - public contract and implementation-source hover, member completion, and navigation;
- duplicate validators, raw-pointer-derived string views, compatibility wrappers, new compiler primitives, and editor-only declaration reconstruction.
Findings and Remediation
A borrowed internal UTF-8 adapter would have bypassed result provenance
The first implementation attempted to turn a validated byte slice into &str inside std/internal/utf8 and pass that borrow into existing string mutation. The checker correctly rejected the result: a package-internal helper cannot manufacture a returned borrow whose origin is not expressed by its contract. Weakening provenance or adding a privileged primitive would have made the compiler understand an implementation shortcut.
The accepted design keeps validation independent of representation. std/internal/utf8 owns the validator and stable error construction; String.try_push_utf8 validates first and then copies bytes into storage owned by String. std/io/buffer sees only that safe public operation and never constructs a string view from a raw pointer.
Byte copying initially introduced an unnecessary public pointer dependency
The first String.try_push_utf8 body computed an offset address through std/ptr.addr. The standard dependency guard rejected the new string -> ptr edge. The operation now uses the package-internal byte-store contract, whose offset parameter already expresses the required copy. No user-facing pointer API or new compiler primitive is needed.
A buffered reader needs one raw incomplete-line owner
Publishing bytes directly into the caller's String would temporarily violate the invariant that every String contains valid UTF-8. Validating each refill independently would reject a scalar split across reads. BufReader therefore owns one reusable Vec<u8> for the current line, validates the complete delimiter-free byte sequence, and only then publishes it. This is not a second text representation: the buffer is raw bytes, while String remains the sole owner of validated text storage.
Final Boundary Assessment
spec/21-practical-standard-library.mdexclusively owns observable line, delimiter, EOF, terminal, failure, and allocation-bound behavior.std/io.Fileretains interruption retry and target I/O policy.BufReaderconsumes only theReaderresult and does not reinterpret errno or syscall facts.std/io/bufferexclusively owns unread-byte position, incomplete-line bytes, and its terminal state. One refill implementation serves byte reads and line reads.std/internal/utf8exclusively owns the UTF-8 state machine and thestd.string.invalid_utf8constructor. The publicstd/string.is_valid_utf8function is a thin API projection onto that authority, not a second validator.Stringexclusively owns mutation of its representation.try_push_utf8validates before reserving or publishing bytes, so invalid input leaves an existing value unchanged.- EOF preserves a pending final line long enough to publish it once, while every subsequent byte and line operation observes the same terminal state. Failure and explicit close additionally discard the incomplete line.
- storage is bounded by the configured read buffer, the largest current line, and caller-retained destination capacity. No completed line or complete file is retained.
- the reviewed dependency set records only
io/buffer -> stringandstring -> internal/utf8as new ownership edges. - LSP tests consume the same checked standard-library declarations and bodies as compilation; no editor-only declaration or method reconstruction was added.
No unresolved correctness or responsibility-boundary finding remains in Phase 1 scope.
Verification
The completed tree passed with /private/tmp/nocter-v019-phase1 as the external Cargo target:
cargo test --locked --manifest-path development/compiler/Cargo.toml --workspace
cargo clippy --locked --manifest-path development/compiler/Cargo.toml \
--workspace --all-targets -- -D warnings
cargo fmt --manifest-path development/compiler/Cargo.toml --all -- --check
node docs/build-docs.js
git diff --check
Native acceptance covers refill boundaries, a UTF-8 scalar split across refills, short final reads, lines larger than the buffer, empty lines, CRLF, lone CR, a final unterminated line, invalid UTF-8, repeated EOF, explicit close, zero requested capacity, destination reuse, and terminal failure. Editor acceptance covers member completion, imported navigation, and source-backed hover in both the public contract and implementation source.