v0.27.0: Filesystem and Path Completion
Status: complete, published, and externally audited (2026-09-02). v0.27.0 closes one practical application boundary: allocation-free lexical inspection of owned UTF-8 paths and explicit creation or removal of directories. It does not add recursive deletion, canonicalization, descriptor-relative traversal, non-UTF-8 paths, or another target.
Completion Boundary
Utf8Pathexposes allocation-freeparent,file_name,file_stem, andextensionviews with exact behavior for empty, rooted, trailing-separator, repeated-separator, dot, and UTF-8 paths;is_absoluteand path validation publish their existing allocation-free behavior asnoalloc;fs.create_dircreates one directory and distinguishes an existing entry;fs.create_dir_allcreates missing authored prefixes, accepts existing directories, and rejects empty input or an existing non-directory prefix;fs.remove_dirremoves one empty directory, never recursively removes content, and never treats a final symbolic link as a directory;- stable public failures distinguish an existing entry, a non-directory component, and a nonempty directory;
- formatter, hover, completion, navigation, authored-standard checks, native tests, and an installed-home path see the same contracts;
- complete workspace, documentation, and adversarial authority-review gates pass.
Architecture Boundary
std/path owns NUL validation, owned UTF-8 spelling, joining, and byte-lexical query algorithms. A lexical query cannot call std/fs, inspect target state, allocate storage, or normalize . and ... All returned views borrow the one owned spelling.
std/internal/os/darwin owns raw syscall numbers, errno classification, and mode constants. std/internal/path owns native path-argument preparation shared by filesystem clients. std/fs/darwin owns target observation or mutation attempts. std/fs owns public failure policy and the left-to-right create_dir_all state machine. No additional target-neutral module is introduced while only one target implementation exists; such a layer would be a forwarding wrapper rather than an authority.
Directory mutation is attempted once. Unlike an observational read, a mutating call is not retried after an interruption because the target may already have changed state. Recursive removal remains deferred until Nocter has a descriptor-relative traversal contract that can state its symlink and concurrent-mutation safety precisely.
Phase 0: Contract and Feasibility
Status: complete. The practical-standard-library specification fixes the public surface, borrowed-view rules, lexical edge cases, directory creation behavior, non-recursive deletion, stable errors, noalloc guarantees, and the existing three-owner implementation boundary.
Darwin ARM64 supplies direct mkdir and rmdir syscalls through the existing syscall primitive surface. The current UTF-8 target-path argument and OS-error classification contracts are reusable; no compiler syntax, semantic identity, ABI model, or new primitive role is required.
Phase 1: Lexical Path Queries
Status: complete. One private lexical scan authority in std/path owns separator trimming, component boundaries, and extension selection. Bodyless root contracts publish allocation-free borrowed views; two source tests cover rooted, relative, repeated-separator, trailing-separator, dot, multi-extension, and UTF-8 spellings through native execution. The authored-standard semantic graph and complete workspace pass with the same declarations.
Phase 2: Directory Lifecycle
Status: complete. Raw Darwin mkdir and rmdir constants and one-attempt adapters feed a typed create outcome into the standard-owned policy. One shared I/O classification mapper owns all stable std.io.* construction, including nonempty directories. create_dir_all validates the complete spelling before mutation, walks borrowed UTF-8 prefixes, accepts existing directories, and leaves completed prefixes visible after a later failure. Four native filesystem tests cover malformed directory records, invalid entry encoding, lifecycle success, existing entries, empty input, non-directory prefixes, nonempty removal, and explicit cleanup.
Phase 3: Tooling and Practical Integration
Status: complete. One canonical formatter fixture exercises the public path and directory surface. One language-server scenario reaches the same declarations through completion, hover, contract navigation, and implementation navigation without a feature-local source model. One temporary-directory application compiles against the physical toolchain standard, executes lexical queries and a complete create/write/remove lifecycle, and therefore covers the same installed-home-compatible compilation boundary used by a distributed toolchain. The authored standard dependency graph accepts the new source-test dependencies.
Phase 4: Qualification and Review
Status: complete. Complete workspace, Clippy, formatter, documentation, native, architecture, and repository gates pass. The final review corrected dangling-link classification without public-error re-interpretation and corrected rightmost-dot selection for trailing-dot names. It found no remaining duplicate authority, target leakage, retry after mutation, recursive-delete residue, hidden allocation, obsolete wrapper, or caller-discipline contract in this boundary.