Programming Language

Nocter

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

/development/milestones/v0.27.0.md

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

  • Utf8Path exposes allocation-free parent, file_name, file_stem, and extension views with exact behavior for empty, rooted, trailing-separator, repeated-separator, dot, and UTF-8 paths;
  • is_absolute and path validation publish their existing allocation-free behavior as noalloc;
  • fs.create_dir creates one directory and distinguishes an existing entry;
  • fs.create_dir_all creates missing authored prefixes, accepts existing directories, and rejects empty input or an existing non-directory prefix;
  • fs.remove_dir removes 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.