pub const OK: i64 = 0;Expand description
Status codes. 0 is success; every other value is an IoErrorKind.
This numbering is one half of a wire contract. The other half is
io_error_kind_of in std/io/lib.nova. The two are independent copies.
MEASURED, not “pinned together by a fixture per kind” for all eight —
that claim was false and this replaces it (final review, I1). The Nova
half (io_error_kind_of’s own arms) is pinned per-code by
fs_io_types.nova. This Rust half, the one that produces a code from a
real std::io::ErrorKind below, is pinned by a fixture that provokes the
real OS condition for only four of the eight: NotFound, AlreadyExists,
InvalidData, and PermissionDenied on Windows only.
Corrected 2026-08-14 (branch file-open-openoptions): naming one
fixture per kind, as this comment used to, went stale for three of those
four the moment file.rs’s open began producing this same numbering
from a second Rust source. Per kind, now:
NotFound:fs_not_found.nova(read_to_stringon a missing path), and independentlyfile_errors.nova(openon a path under a missing parent directory).AlreadyExists:fs_already_exists.nova(create_diron an existing path, twice), and independentlyfile_errors.nova(openwithcreate_newon an existing path).InvalidData:fs_invalid_data.novaonly —File::readhands backBytesand never decodes UTF-8, so nothing aboutFilecan provoke this one.PermissionDenied, Windows only:fs_permission_denied.nova(read_to_stringon a directory,#[cfg(windows)]), and independentlyfile_open_dir.nova(openon a directory,#[cfg(windows)]).
Interrupted, TimedOut and ConnectionRefused are not reachable from
std/fs’s async fns at all, portably or otherwise, so no fixture can pin
them. Reasoned, not measured, for read/write (byte-type branch):
both route through this same fail function exactly as
read_to_string/write_string do, over std::fs::read/std::fs::write
rather than std::fs::read_to_string/std::fs::write — reading or
writing raw bytes instead of UTF-8 text opens no path to a network- or
signal-flavoured ErrorKind that plain-text local I/O did not already
have, so the same unreachability is expected to hold, not separately
provoked. The _ => OTHER fallback is reachable (e.g. read_dir on a
plain file returns it, still unexercised).
Corrected 2026-08-14: it is no longer true that nothing exercises this
fallback. file.rs’s closed/stale/forged-fd case (closed_fd_error)
fabricates a std::io::Error of ErrorKind::Other on every table miss,
unconditionally, which falls to this identical _ arm — and
file_lifetime.nova’s “read after close” check asserts on the exact
message that arm stashes. See docs/adr/0011-io-error-kinds.md, which
states this split correctly as of the same correction.
Corrected 2026-08-16 (branch io-poller-std-net): the “not reachable …
so no fixture can pin them” paragraph above is now stale for two of its
three kinds, and the per-kind breakdown two paragraphs up goes four
fixture-pinned kinds to six. TIMED_OUT and CONNECTION_REFUSED have
carried this numbering with no producer since increment 1, because no
filesystem operation can produce either — crates/nova-runtime/src/net.rs’s
two-phase connect and its read_timeout future are their first. A
connect to a loopback port nothing is listening on is refused either
synchronously (an immediate ECONNREFUSED/WSAECONNREFUSED, routine for
a closed loopback port) or via the second poll’s SO_ERROR check, both
paths through this identical fail (net.rs’s own module doc comment,
“CONNECTION_REFUSED gets its first producer”), pinned end to end by
tests/runtime/net_refused.nova (net_refused_run,
crates/nova-cli/tests/run_tests.rs). read_timeout reports TIMED_OUT
when its deadline passes with a read still would-blocking, pinned by
tests/runtime/net_timeout.nova (net_timeout_run), which also pins the
opposite direction in the same fixture — a deadline comfortably longer
than the peer’s own delay must still succeed with the real data, not fire
merely because a deadline is in play at all. Six of the eight status
codes are therefore fixture-pinned now: the original four two paragraphs
up, plus these two. Only INTERRUPTED remains genuinely unreachable from
either module’s async fns, portably or otherwise — the “reasoned, not
measured” argument above, made for all three together, now supports
INTERRUPTED alone.