Typed Path v1
September 10, 2026 ยท View on GitHub
Status: implemented bounded lexical-path profile; HOSTED GREEN under the v0.4.0 release baseline. The Everyday profile remains incomplete.
Audience: standard-library authors, compiler contributors, and agents working with lexical paths.
This profile adds the std.path.value library over an ordinary source-authored
Path record. A Path contains a Bytes backing value and a usize logical
length. Its backing storage and fields use ordinary source ownership and
constructors; the record is neither opaque nor unforgeable.
Lexical path contract
Admitted paths are NUL-free POSIX lexical byte paths. The profile defines no
UTF-8 interpretation, platform normalization, filesystem lookup, symlink
policy, or filesystem authority. Separators and component boundaries are
handled as bytes under the package's explicit lexical rules. An empty prefix is
valid and relative. Only / separates components; backslashes, colons, dots,
and non-UTF-8 bytes retain their byte meaning. This is lexical composition,
not directory confinement: .. is not resolved or rejected.
path_valid returns false for a forged length beyond capacity without scanning
that length. Other observers and transitions require a valid path. The prefix
validator accepts an explicit in-bounds byte slice extent. Bytes after the
logical length may contain any value and never participate in path queries.
Every constructor and operation validates that the logical length is within
the backing Bytes bounds and that each inspected or written range is valid.
Invalid NUL-containing or out-of-bounds values fail through the ordinary
checked contract path before a result is published.
Consuming operations
The parent and finish operations consume their Path input and return the
checked successor/result according to their source contracts. A consuming
transition settles the prior owner exactly once; it does not copy or revive a
backing buffer. Join uses a caller-supplied output buffer and validates its
capacity and resulting logical length before writing. No operation allocates
an ambient buffer or acquires filesystem authority.
Join keeps both input views inside nested borrowed-match scopes and fills a separate caller-owned output. Those matches return a Copy value; the owning Path is constructed only after both view scopes end. Thus join introduces no borrow escape or owning result from a borrowed match.
The source-authored records lower through the existing checked HIR and retain equivalent behavior on the interpreter, native C11, and Core Wasm lanes. The backends consume checked bounds and ownership facts rather than treating Path layout as authority.
Borrowed queries expose length, capacity, absolute status, nonempty segment count, file-name start, parent end, extension start, and one checked byte. A missing extension is represented by the logical length; the first dot of a file name does not itself begin an extension. Trailing separators make the file-name start equal the logical length.
Join replaces the base when the child is absolute. Otherwise it appends the
child, inserting one / only when both paths are nonempty and the base does
not already end in /. Existing separators are preserved. path_join_length
provides the required output capacity before ownership of a buffer is passed.
The result's logical length is the number of copied bytes; any remaining
output-buffer suffix is unchanged. path_finish returns the entire backing
buffer, so callers must retain the logical length when that prefix matters.
The parent drops the last nonempty component and trailing separators. Relative
single-component paths have an empty parent. An absolute path's parent keeps
its root: / and all-separator paths produce /. path_parent_end reports
the same new logical length used by the consuming transition.
Lexical normalization of these values is the separate additive Path Normalization v1 profile; it changes no shape, signature, or contract defined here.
Package boundary
std.path.value is an additive internal nongeneric library profile. It does
not widen the original public std.path lexical helper package, add a public
generic or nominal ABI, or change the existing std.path declarations and
existing package descriptors or catalog entries. The original package remains the source of its
allocation-free byte inspection helpers; this profile supplies the typed Path
record composition separately.
Path normalization, safe joining beyond the admitted caller-buffer operation, filesystem conversion, and platform-specific path policy remain outside this profile. Its focused source, contract, projection, and cross-engine release corpus is hosted green. Filesystem I/O v1 and v2 are implemented separate profiles with a stricter relative-path grammar and caller-selected provider authority. A lexical Path alone is not filesystem permission or confinement.
Focused verification
The focused selectors are:
cargo test --locked -p semaprax --lib loan_plan::
cargo test --locked -p semaprax --test project standard_library::typed_path
The package backend runner executes the committed main and every authored zero-parameter boolean conformance function in separate authenticated snapshots. It changes only the fixture entry call, then performs ordinary source and HIR verification for each snapshot. This preserves the 16-allocation-site limit per invocation while exercising every case on the interpreter, native C11 O0/O2, and Core Wasm. Each Wasm case repeats four times against a three-entry Bytes arena and requires zero live entries afterward. A source file's presence or successful type checking alone does not count as runtime coverage.
Additional focused cases check constructor and observer contract failures, undersized join output, borrowed-owner escape, conflicting join arguments, canonical graph replay with forged field identity and source drift, bundled dependency composition, and absent public export authority. Catalogs and package metadata are generated from the canonical authored declarations.
Historical local results: all 10 focused loan-plan tests and all 8 typed-path
Project tests passed. The latter included the committed main plus all 11 authored
conformance cases on every listed engine. The 7 existing cursor tests also
passed, and catalog/metadata checks retained every original std.path entry.
These counts describe that local witness; current implementation evidence follows
the hosted-green release baseline, without broadening the lexical-path contract.