Native capability-aware command-line utilities for EriX.
  • Rust 99.7%
  • Python 0.2%
  • Linker Script 0.1%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
Erik Inkinen 0711629056
All checks were successful
CI / markdown (push) Successful in 14s
CI / rust (push) Successful in 2m4s
chore: Merge native CLI development into main
Merge the selected feature/native-cli history with an explicit two-parent commit so main retains the development lineage and the validated source snapshot. The resulting tree is identical to the selected feature commit; no dependency pins or runtime behavior are changed by this merge.

Previous main: 05fa4e26eb
Selected feature: 4828b75bf9

Publish this integration point following the requested cross-repository merge. Preserve the feature branch and immutable dependency objects for reproducibility; do not squash, rebase or rewrite existing commits.
2026-09-12 08:28:40 +03:00
.github build: Pin dependency and CI helper source commits 2026-09-12 07:35:32 +03:00
manifests feat: Request exact utility authority after startup 2026-09-07 19:22:26 +03:00
src fix: Read named cat files and explicitly create copy destinations 2026-09-08 05:31:56 +03:00
tests feat: Define POSIX time utility syntax 2026-08-23 13:26:37 +03:00
.editorconfig Initial commit 2026-08-05 19:47:40 +02:00
.gitignore Initial commit 2026-08-05 19:47:40 +02:00
.markdownlint-cli2.yaml Initial commit 2026-08-05 19:47:40 +02:00
ARCHITECTURE.md build: Pin dependency and CI helper source commits 2026-09-12 07:35:32 +03:00
Cargo.toml build: Pin dependency and CI helper source commits 2026-09-12 07:35:32 +03:00
CODE_OF_CONDUCT.md docs: Synchronize shared contribution and review policies 2026-09-12 06:38:07 +03:00
CONTRIBUTING.md build: Pin dependency and CI helper source commits 2026-09-12 07:35:32 +03:00
LICENSE Initial commit 2026-08-05 19:47:40 +02:00
linker.ld feat: Add retained coreutils stream applets 2026-08-17 03:05:46 +03:00
POSIX-TIME-SYNTAX.md feat: Forward inherited time streams through exact loan records 2026-09-07 19:38:34 +03:00
README.md build: Pin dependency and CI helper source commits 2026-09-12 07:35:32 +03:00
ROADMAP.md build: Pin dependency and CI helper source commits 2026-09-12 07:35:32 +03:00
rustfmt.toml Initial commit 2026-08-05 19:47:40 +02:00
SECURITY.md docs: Synchronize shared contribution and review policies 2026-09-12 06:38:07 +03:00

coreutils

coreutils owns the native EriX multicall utility set and the canonical mapping from each authenticated command-directory entry to its maximum launch-manifest authority ceiling.

EriX is a clean-room, capability-based microkernel operating system written entirely in Rust.

See:

  • docs for system architecture and the technical manual
  • lib-ipc for launch-manifest wire records
  • lib-capabi for exact child-local capability inventory policy
  • launchd for authenticated manifest selection and authority intersection

Purpose of This Repository

This repository defines one reviewable owner for native utility behavior and per-applet authority policy. The current foundation is an allocation-free, no_std manifest catalog for the accepted initial applet set.

The maintained responsibilities are:

  • map each exact /bin/<applet> entry to one applet identity
  • expose canonical sorted lib-ipc manifest rows for that entry only
  • keep pure stream applets free of object authority
  • keep read-only applets free of mutation operations
  • limit create, unlink, and rename operations to one-shot lifetime
  • reject relative names, alternate directories, case variants, trailing separators, and a generic multicall entry without fallback
  • execute the authority-free stream/text applets over explicit borrowed input, working-directory data, caller output bytes, and caller sort records
  • authenticate multicall selection from the LCS1 command-entry digest while deliberately ignoring argv[0] as a selector
  • bind every fixed or description-backed stream to the exact installed capability inventory before the runtime can perform I/O
  • execute all 20 implemented applets through receipt-free fixed streams and exact object endpoints with incremental or deployment-sized retained storage and explicit backpressure
  • provide a test-only exact-grant replay probe that invokes the same consumed mkdir sender twice and accepts only kernel NOT_FOUND on the second call
  • parse the exact documented Phase 5 touch, read-only date, and time grammars before any authority is planned
  • admit fixed routes solely from the authenticated manifest and inherited context, never utility names or command arguments in launch services
  • start without object grants, then acquire exact SEND-only operation receipts through the job-bound broker; revoke each lease before reusing its slot
  • diagnose rejected requests inside the running utility with status 1; malformed utility syntax remains its own status-2 error
  • mediate read-only clock observations through that same broker, without retaining a public timed-service capability
  • execute time [-p] utility [args...] through one authenticated inherited script ceiling, one status-only return endpoint, and monotonic samples, with no job-control or public process authority

The catalog contains cat, cp, date, echo, false, grep, head, ls, mkdir, mv, printf, pwd, rm, rmdir, sort, tail, time, touch, true, and wc. date executes read-only formatting over one trusted source-qualified timed sample. touch consumes only one-shot entry-scoped reference and target endpoints, queries timed only for now or an omitted year, and performs no resolver lookup. time performs bounded PATH search, forwards only authenticated exported environment and current-directory state, transfers its actual inherited streams, reports real/user/system durations, and returns its child's exact status. The generic child transcript contains no object requests or command classification; launchd selects child routes from the child's authenticated manifest. Dynamic streams use generic receipt-backed loans identified by exact authenticated parent descriptions, preserving shared aliases and requesting only the read/write access required by the standard roles. The child proxy closes only its loan; parent report output and eventual cleanup are not delegated. Fixed PTY aliases are transferred unchanged. The three entries are pinned in the coordinated 20-entry Integration catalog and packaged as ext4 hard links with exact version-2 launch flags. Integration complete-catalog run 1468 passes all 483 scenarios, including the native-time positive, unavailable-provider, malformed-sample, denial, persistence, lookup, signal, and monotonic-clock cases. Their allocation-free parser contract is recorded in POSIX-TIME-SYNTAX.md. That historical VM run predates post-start broker acquisition. All ten new focused matching-image VMs pass at Integration d8e83d3d5b5fe7a496e1c7deea27a75910098a9d, with unchanged coreutils a4ff8ea131385bb00ae8330696061c4a51455f47. They prove dev utility-owned denied/usage errors, dev/release time stream inheritance and reports, directory/cwd behavior, and exact serial consent/cleanup. The original 120/15/10-second bounds and canonical image hashes are preserved; detailed evidence is in Integration out/runtime-authority/ACCEPTANCE.md. This documentation-only publication changes no tested runtime input. The separate stricter startup-performance gate remains open. The new consumer has at most two live object leases. ls -l does not acquire metadata for an empty or entirely filtered directory. touch requests reference metadata or wall time only after a target is authorized, and keeps only timestamp data after the exact reference lease is retired.

Native Output Contract

  • Input, arguments, filenames, and stream output are byte strings. No applet decodes Unicode, applies normalization, or consults a locale.
  • sort and ls compare complete records or names lexicographically by unsigned byte value. grep, head, tail, and cat retain selected input order; numeric output uses fixed ASCII decimal syntax.
  • ls prints names by default; -l requests separate no-follow metadata and prints mode, link count, numeric IDs, size, and a UTC timestamp or unknown. -a includes . and .. exactly once, including empty directories. -la requests parent metadata through a separate exact scoped lease after retiring the current-directory metadata lease. It never traverses .. on an enumeration handle, and denied parent scope fails without partial output. It performs no identity lookup, locale collation, terminal quoting, or color.
  • cp copies file bytes only. It does not promise metadata, sparse-layout, or timestamp preservation. Mutation applets emit no success text.
  • cat [-u] [--] [file ...] concatenates named files in operand order. Each pathname requires its own exact READ/file/invocation lease, released before the next operand. No operands or - use inherited stdin without object requests; -u writes each accepted chunk immediately. Empty files emit no bytes and succeed. Ordinary operand failures are diagnosed with status 1 and later operands continue; malformed syntax is rejected before I/O.
  • cp source destination first requests exact source READ, then existing-file destination WRITE. Only a correlated broker NOT_FOUND can select a separate exact-entry CREATE_ENTRY one-shot request; user denial never does. Creation is followed by a separately authorized file WRITE request, not an implicit content grant. No source bytes are read before the destination is authorized. After successful EOF copying, exact endpoint-relative truncation removes any old suffix, including for an empty source. Failed copies are not atomic replacements: creation followed by denied write leaves an empty file, and later I/O failure may leave a written prefix. No cleanup unlink authority is inferred. Equal literal selectors are rejected; distinct same-object aliases preserve bytes through same-offset copying and post-copy truncation, but general hard-link identity detection is not implemented.
  • pwd returns the canonical descriptive path bound to the installed exact cwd endpoint. It performs no resolver lookup or environment expansion.
  • Diagnostics are fixed locale-free bytes, and every failure has a deterministic status. Output-capacity failure rolls back buffered output or reports an exact deployment boundary instead of silently truncating it.
  • echo and printf assemble one invocation's complete result in the bounded deployment workspace before submitting it to the output stream. This keeps a short logical record, including its newline, from being split around another producer's record and fails before output when the workspace is insufficient.
  • printf reuses its format until every operand is consumed. A final partial cycle supplies an empty byte string for an unsatisfied %s; a format with no %s conversion is rendered once and ignores surplus operands.

Clean-Room Policy

EriX follows a strict clean-room philosophy:

  • No external source code may be copied.
  • No external Rust crates are allowed.
  • No code generation tools that embed third-party code.
  • All code must be authored within the project.

Violations will result in rejection of the contribution.

License

All EriX repositories are licensed under the ISC License.

Development Model

The crate is no_std, forbids unsafe code, denies missing public documentation, and performs no allocation or ambient I/O. Authority-free behavior consumes only explicit borrowed data and caller storage. It depends on lib-capabi, lib-ipc, lib-stdio, lib-time, the lib-ipc syscall shim, and lib-sha2 at full commit pins for exact CSpace policy, canonical launch records, receipt-free stream framing, checked civil-time syntax, syscalls, digest framing, and the clean-room SHA-256 implementation. Integration source revisions and CI caches preserve those Git object identities.

Every nonempty table uses explicit wildcard scope only as a maximum over the separately authenticated session namespace. Its interactive flag permits the trusted approval path but grants nothing by itself. Launchd still requires the invocation, session, optional script envelope, manifest, and resolved object to agree before installing an attenuated capability.

Status

ls [-al] [--] [directory] sorts provider-returned names. -a includes hidden entries, without inventing . or .. rows. -l requests an additional explicit directory metadata grant, separate from enumeration, and prints no-follow type, permissions, numeric link count/UID/GID, byte size, UTC modification time, and name. Unrepresented modification times are printed as unknown; no owner-name lookup or file-content authority is acquired. This is the supported native listing grammar, not a claim of complete POSIX ls conformance.

Implemented:

  • exact-path catalog and maximum ceilings for all 20 accepted applets
  • domain-separated digest lookup for all catalog entries and a borrowed LCS1 startup parser that rejects zero, unknown, and malformed identities
  • distinct empty, read-only, list, copy, create, rename, and unlink ceilings
  • canonical wire-valid row ordering and one-shot mutation lifetimes
  • focused replay validation that proves a consumed mutation endpoint cannot be reused; the fixture adds no production route or authority
  • a checked erix-coreutils-applet-catalog-v2 packaging projection whose 20 entries, inherited-launch flags, and authority rows are tested byte-for-byte against the runtime policy, allowing image construction to consume policy without duplicating it
  • regressions proving there is no /bin/coreutils fallback or union manifest
  • authenticated-applet invocation that omits argument zero as a selector, plus deterministic caller-sized behavior for every catalog applet
  • heap-ordered sort records and strong output rollback without allocation, locale lookup, filesystem lookup, or authority
  • an opaque FilesystemRuntime boundary for resumable partial cp, caller- sized deterministic ls collection/rendering, and move-only create, unlink, and rename grants that are returned only under retryable backpressure
  • applet-owned operand validation and lazy post-start requests for exact operation leases; same-parent mv only, no prelaunch operand plan, and no authority request for malformed syntax
  • an opaque runtime-startup proof that scans the complete CSpace, admits only exact process context, selected standard streams, canonical send-only dynamic descriptions at the original delegated base, and manifest-selected fixed cwd, launch, and broker routes. It requires the generic resolver and every unselected auxiliary slot to be absent and rejects malformed, surplus, or over-righted authority before I/O
  • a freestanding position-independent multicall entry with deterministic argument-only/status execution, incremental cat, head, and wc, plus deployment-sized retained execution for grep, sort, and tail; protocol-sized scratch and the complete retained workspace are erased, and dynamic descriptions are closed during teardown
  • target pwd execution through the fixed job-lifetime cwd endpoint: the receipt-free request contains no handle or selector, validates correlated authority-free framing, and prints only the canonical descriptive path
  • target read-only date execution through the exact job broker: exported TZ and format syntax are preflighted by the running utility before any clock request; exactly one correlated v2 sample is accepted only from hardware-RTC or degraded evidence, and one newline-terminated record is written without clock-adjust or object authority
  • target touch execution through one one-shot READ_ENTRY_METADATA endpoint for -r and one one-shot TOUCH_ENTRY endpoint per target: current time is source-qualified and rounded to its declared precision, explicit timestamps need no clock query, terminal target failures do not suppress later independent targets, and no generic resolver or provider endpoint is installed
  • target time execution through one invocation-bound inherited launch route, one manifest-admitted job broker, and one fresh read-only child-status receipt: exact NOT_FOUND alone advances PATH search, clean non-not-found rejection is status 126, all-absent search is status 127, terminal child status is propagated, status authority is retired on success and failure, and launchd selects child routes from the child's authenticated manifest without any caller-side program-name classification
  • target exact-object execution for cp, ls, mkdir, mv, rm, and rmdir: file and directory calls force handle zero, mutations carry no source path, rename carries only its validated destination basename, retry preserves the same grant, and terminal mutation results consume it
  • deployment-sized ls collection grows name bytes and compact record ranges toward each other before deterministic heap ordering, with no fixed entry or name-count ceiling
  • exact file transport borrows initialized payloads directly from caller-owned storage, keeping maximum-size VFS copies off the shared applet dispatch stack and preserving the separate retained-workspace and 64 KiB stack lifetimes
  • linear-time literal grep matching across arbitrary transport fragments, a wrapping last-record tail arena, deterministic heap-sorted records, and pre-effect printf format validation
  • bounded single-submission echo and printf output with regressions proving each complete result reaches the stream adapter in one logical write
  • strict Rust, Rustdoc, freestanding, source-size, dependency, and Markdown CI
  • exact-ID parser coverage for every row of the documented POSIX time utility syntax matrix

Integration now capacity-patches the retained workspace, installs one multicall object and 20 authenticated command entries plus sidecars on ext4, and launches them through the normal post-mount loaderd/dynlinkd/procd path. No generic coreutils entry, applet sidecar, or executable is present in boot.img. Runtime reads the authenticated post-link capacity words through volatile accesses so optimization cannot substitute the build-time placeholder. Focused VM coverage is committed; its final coordinated validation remains tracked by the Phase 5 integration plan.

Governance Principles

coreutils owns applet behavior and its maximum policy, not runtime authority.

  • A command entry selects exactly one ceiling; argument zero and basename text never select policy.
  • No applet receives the union of all utility operations.
  • Selector bytes remain non-authoritative until resolved through launchd's authenticated peer routes.
  • Every installed grant is bounded by the intersection of manifest, session, script, and invocation policy.
  • Git dependencies use full 40-character commit rev pins. Integration source revisions and CI caches preserve those identities, with no branch-head or synthetic-commit substitution.

Component Boundaries

  • This crate performs no ambient filesystem lookup, service discovery, generic process control, logging, clock adjustment, or device access. Target filesystem behavior consumes only opaque resolved handles and move-only exact operation leases requested after startup. date may query only the job broker admitted by its authenticated startup proof. time may launch only through the exact inherited script route and receives status observation without cancellation or job-control authority.
  • launchd authenticates the entry, retains manifest-bounded job context, and brokers post-start requests without parsing utility operands.
  • powerboxd owns exceptional approval and exact object-bound grant lifetime.
  • exsh supplies invocation data through its bounded launch route.
  • The freestanding entry, receipt-free standard-stream adapter, deployment- sized retained-record workspace, exact cwd query, and resolved-object filesystem transport are implemented.

Contact

Development occurs in the EriX organization. Decisions and rationale are recorded in issues and design documents.

Maintainers can be reached at admin@erikinkinen.fi.