- Rust 100%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
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: |
||
| .github | ||
| src | ||
| tests | ||
| .editorconfig | ||
| .gitignore | ||
| .markdownlint-cli2.yaml | ||
| ARCHITECTURE.md | ||
| Cargo.toml | ||
| CODE_OF_CONDUCT.md | ||
| CONTRIBUTING.md | ||
| LICENSE | ||
| README.md | ||
| ROADMAP.md | ||
| rustfmt.toml | ||
| SECURITY.md | ||
lib-capabi
lib-capabi is the allocation-free Rust owner of EriX's capability type,
rights, role, bootstrap-slot, and root-to-service capability-intake registries.
EriX is a clean-room, capability-based microkernel operating system written entirely in Rust.
Technical requirements are tracked in the EriX requirements, conventions, and project documentation.
See:
- docs for the normative capability and startup specifications
- lib-bootstrap for the root-to-service envelope and transfer-table representation
- lib-ipc for message framing and semantic endpoint-kind identifiers
Purpose of This Repository
Terminal framebuffer/input and serial routes are structurally optional, with unchanged exact sources, destinations, and rights. Authenticated console policy in consumers requires enabled routes and rejects disabled ones; logging routes remain independent and mandatory. Two bootstrap lifecycle receipts also select distinct framebuffer/serial seats in independent dual-console mode. Three existing-window slots hold the second shell status and short-lived cancellation senders; successful dual startup retires cancellation authority immediately.
Generic native startup inventories distinguish optional manifest-declared cwd,
resolver, inherited launcher, and exact-job broker routes. The broker reuses
slot service_endpoint_base + 7 with exactly SEND rights; delegated description
slots remain at +8. No program name or argument-derived mutation pregrant is
part of this inventory contract.
The crate centralizes the numeric and validation contracts that otherwise would be duplicated across the kernel, root process, and services. It exposes:
- capability type and rights-mask registries
- service-role identifiers and role-local slot assignments
- the canonical kernel-to-root slot requirements
- a dedicated root-only host-report endpoint slot
- a required, disjoint root-only boot-module-retirement endpoint slot whose one-shot capability is never part of a service intake bundle
- exact 16-byte little-endian capability-transfer descriptors containing only source slot, destination slot, capability type, and rights
- fixed little-endian intake descriptors
- per-role coarse intake classes
- exact endpoint source, destination, rights, and endpoint-kind policy
- a
ttydrole whose ordinary input, secure attention, framebuffer session output, framebuffer trusted chrome, and serial session output routes are distinct endpoint objects - an authenticated procd-to-ttyd session-provisioning route, fixed temporary endpoint source/receipt slots, and a complete-record retained session interval for lifecycle, PTY input, and PTY output receivers
- two disjoint rootd-local temporary receipts for ttyd's root-authenticated bootstrap-session lifecycle senders, including independent dual-console startup, and no rootd PTY stream receipt is reserved
- one rootd-local send-only query client, disjoint from every transferable
kernel source and temporary receipt, so later bootstrap inspection cannot
retain the inherited query source delegated to
deviced - one disjoint rootd-local staging source for a bounded sequence of explicitly authorized initial-shell launches; each attenuated alias is consumed before the slot can be reused and the slot is empty outside that sequence
launchdandpowerboxdroles whose request, loader, process, session-policy, trusted-prompt, object-resolution, and grant-installation routes are distinct endpoint objects with exact transfer rights; launchd alone additionally has the endpoint-only factory needed to publish caller-scoped job routes and one send-only timed route used solely for syntax-selected native children; a separate pairwise decision-ready endpoint gives powerboxd onlySENDand launchd onlyRECV- fixed vfsd/procd scope, object, and reply staging slots for powerbox peer receipt provenance, plus a unique manage-only revocation-grant type that is distinct from staged-child install grants
- disjoint vfsd-local redirection scratch addresses for one temporary cwd receipt and simultaneous operation/cleanup endpoint sources; these addresses are absent from startup intake and convey no authority while empty
- a shared five-slice procd managed-process scratch multiplier covering child endpoint, working-directory cleanup, install-grant, powerbox-revocation, and child-VSpace aliases; addressability alone conveys no authority
- disjoint pagerd destination pools for procd-managed children and rootd's bounded pre-procd services, plus role-derived root-local VSpace receipts and one fixed transient frame receipt; the shared 256-KiB dynamic-stack reserve bounds nested transport frames and anonymous writable fault authority independently of image layout
- a separate launchd-to-vfsd resolver object with fixed scope staging,
disjoint exact-executable and
.lmfmanifest receipts, and a loaderd temporary-read slot; a third fixed launchd receipt and a fixed procd staging destination carry one provider-pinned working directory without public namespace authority; further disjoint procd-local slots stage only the optional script-launch sender and one mutually exclusive fixed observation sender carrying either job-bound CPU accounting or public wall time during the same atomic child installation; another fixed procd-local slot can stage one authenticated launch-description endpoint, and a further disjoint slot stages only a job-bound redirection-resolver sender; the latter pair occupies the two reserved slots immediately before procd's managed-process scratch arena, inside its authenticated CSpace window but outside its role-local control routes, and every staging alias is cleared after its install attempt - an exact fixed
exshchild inventory: provider-pinned current directory, TTY lifecycle, stdin, stdout, stderr, bounded launchd, job-bound redirection-resolver, and job-bound CPU-accounting endpoints are the only external authority. A route-bound shell receivesSEND|GRANTonly on its bounded launchd endpoint so a SUBMIT call can carry explicitly declared child capabilities; an execution-only shell must have that slot absent. The other seven endpoints remain exactSEND; the accounting endpoint accepts only receipt-free time reads. Full-CSpace validation also requires exact intrinsic self capabilities and the kernel-supplied bound receiver, and rejects every other slot or excess right - numeric-only reservations for descriptor operation or cleanup senders; canonical allocation skips the kernel-supplied bound receiver, while a separate allocation-free inventory validator admits only the complete, ordered declaration of exact send-only descriptor endpoints and rejects missing, surplus, malformed, or over-righted authority. Its fixed-stream-aware form also accepts an explicit authenticated stdin/stdout/stderr presence mask: a cleared bit requires that fixed slot to be absent while the declared dynamic description remains the only stream authority
- a complete coreutils child-inventory validator admitting only intrinsic
process authority, exact process context and selected streams, an optional
invocation-bound resolver, separately selected fixed launch and public-time
routes, and a strictly ordered set of send-only delegated endpoints. The
launch route is exact
SEND|GRANT, the timed route is exactSEND, and an absent selection requires the corresponding slot to be empty. The shared index mapper derives every delegated description slot while skipping only the kernel-supplied bound receiver - a complete extop child-inventory validator admitting only its TTY lifecycle, standard streams, session-scoped inspection sender, and an ordered optional set of exact send-only job-control handles. It rejects cwd, launch, resolver, discovery, global VFS, procd, memd, and kernel-control authority; numeric job or process identities cannot select a handle. Exsh, coreutils, and extop all remain unavailable as root startup-transfer bundles because they are ext4 launch children rather than boot services
- an explicit per-device
devicedprovider-alias interval and one transaction-local provider destination inblockd - one explicit 30-entry final-use catalog naming the exact root-held startup source and final consumer role for every source retired during a service install, including the four deviced-final and seven later deviced-consumer sources; the catalog describes retirement timing but grants no transfer authority
- allocation-free parsers, iterators, a caller-storage-backed transfer-table writer, and slice- or encoded-table startup-bundle validation
The process-service registry assigns distinct routes for root orchestration,
loader materialization, dynamic-link planning, VFS sessions, and driver
lifecycle. The canonical vfsd endpoint is root-only mount control. Root and
loader namespace traffic uses different endpoint objects; root receives a
read-write namespace client, while loaderd receives a read-only namespace
client alongside its dedicated procd materialization and dynlinkd peers.
Only the materialization peer carries GRANT, solely so procd can return one
process-bound install grant and, for an explicitly declared staged service, its
exact process endpoint into separate fixed loaderd receipt slots. There is no
broad VFS or static-loader fallback. Rootd's reusable filesystem-service
staging destinations are likewise fixed at distinct install-grant and
process-endpoint receipt slots, so a loader reply cannot redirect either
authority.
Vfsd also receives exactly one mandatory send-only query route from timed's
authenticated public service endpoint. That route cannot receive, grant, or
submit private RTC samples. E2fsd, fatd/exFAT, and the volatile memory provider
receive no timed endpoint; vfsd passes only checked descriptive timestamps over
their existing provider routes.
Launchd and powerboxd request endpoints are created as part of their staged
processes at the canonical child-local slots. Their startup transfer tables
therefore contain only peer routes: seven for launchd and five for powerboxd.
Launchd's seventh peer route is timed's public SEND endpoint; powerboxd never
receives it. The dedicated one-way decision notification's singleton
root creator lives beyond the full creator and root-client regions and every
v1 role transfer-source window.
The root creator and root-local steady client are separate authorities and are
never represented as a self-endpoint startup transfer. Launchd's primary
control slot is a separately installed endpoint factory that can only create
and attenuate generic endpoints; it cannot populate or control a process.
Rootd's first ext4 shell transaction uses two additional disjoint temporary
client slots: one send-only alias of launchd's public route and one destination
for launchd's read-only job-status reply. They are adjacent to, but distinct
from, the temporary ttyd bootstrap lifecycle receipt. No root TTY stream slot
exists, and all three temporary authorities have explicit teardown ownership.
The shared final-use catalog replaces root-local bit masks: after the listed
consumer installation succeeds, root drops that exact source and proves its
absence. Sources absent from the closed catalog are never selected for this
retirement path.
Bundle validation rejects malformed descriptors, unknown roles or capability
types, invalid rights, missing or excessive intake classes, duplicate exact
endpoint transfers, and endpoint transfers that do not match the role's
declared policy. Validation uses checked repeated passes over caller-provided
slices or encoded tables and has no validator-specific transfer, class, or
endpoint-policy ceiling.
CapTransferTableWriterV1 likewise derives its capacity solely from the byte
slice supplied by its caller and exposes only the complete encoded prefix.
The crate carries no capability and performs no syscall, I/O, allocation, service discovery, transfer, or revocation. Numeric slots and handles are metadata; only the receiving runtime can prove that an installed capability has the declared identity and provenance.
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
EriX development is modular, deterministic, reproducible, authority-explicit, security-first, and self-hosting oriented.
Repository validation requires:
cargo fmt --all -- --check
cargo clippy --all-targets --all-features -- -D warnings
RUSTFLAGS="-D warnings" cargo test --all-targets --all-features
RUSTDOCFLAGS="-D warnings" cargo doc --no-deps --all-features
RUSTFLAGS="-D warnings" cargo check --target x86_64-unknown-none
The crate is no_std, denies unsafe code and missing public documentation, and
depends only on lib-ipc for the canonical semantic endpoint-kind registry.
Capability policy refers to those named constants directly; it does not copy
their numeric values into a second registry.
Named publication names are part of the same closed target-scoped contract:
only pagerd, timed, and irqd receive canonical fixed-width names, and roles
without a resolution endpoint receive neither a publication slot nor a name.
Governance Principles
lib-capabi governance is limited to shared capability representation and
startup-intake validation:
- Authority classes and endpoint routes are explicit, narrow, and fail closed.
- Install grants authorize staged-child population; revocation grants instead bind one already-installed child slot and carry only the authority to revoke that exact installation. Neither capability class substitutes for the other.
- A transfer descriptor is a declaration, never proof of authority.
- Structural and role-policy validation remains allocation-free.
- Exact endpoint policies bind non-repeatable endpoint authority to declared source and destination slots and exact rights.
- Per-device block-provider aliases are bounded by the destination CSpace range that can represent them. The shared deviced process-window length covers that complete range; empty slots convey no authority. Consumers reuse one transaction-local destination instead of retaining a provider table. The shared blockd process-window length ends immediately after that destination.
- Vspaced uses named transient imported-frame and imported-VSpace slots; the slot names do not imply caller-selected physical binding authority.
- Vfsd receives the endpoint-factory kernel route at its dedicated local slot. This route is distinct from child population and is the only kernel-control authority used to mint and attenuate exact filesystem-object endpoints.
- Vfsd's process-visible CSpace reaches the architectural slot boundary. Its retained-endpoint interval begins at slot 3072 and is shared by exact-object operation receivers, cleanup receivers, and job-bound resolver receivers. Empty addressable slots confer no authority, each occupied slot has one typed owner record, and live occupancy remains bounded by deployment storage.
- Ttyd receives the same narrow endpoint-factory kind at a distinct local primary-control slot. It can create generic endpoints and attenuate local aliases, but it receives no staged-child population authority. Three full-rights transaction sources are retired after ttyd retains receive-only lifecycle/input/output aliases and replies to procd with send-only clients.
- Procd alone holds the send side of ttyd's session-provisioning route. Four fixed empty destinations receive the lifecycle, stdin, stdout, and stderr aliases temporarily; the stdout and stderr capabilities may name the same output endpoint object while their numeric receipt slots remain distinct.
- Rootd's bootstrap owner uses one separate fixed empty lifecycle destination inside its reserved authenticated-client interval. The address is not a stream slot and conveys no authority while empty.
- Named resolution is partitioned by target endpoint object. A caller scope is
optional when the launch graph omits discovery, but any supplied scope must
use that target's exact source, destination, and transfer-bearing rights.
Named's three server scopes remain required by the registry role. Resolved
publications are send-only except IRQD's LAPIC-timer handler object, whose
registration API explicitly requires
GRANTto transfer the caller's handler endpoint. IRQD's administrative endpoint is never published. - IRQD receives two distinct receive-and-grant handler objects, one for the
LAPIC timer and one for COM1. Deviced receives only the COM1 send-and-grant
object for delegation to
drv-serial; no consumer receives IRQD registry or mask-control authority. - The serial driver's private event object is distinct from its provider endpoint. Deviced uses one transaction-local creator alias to install a receive-only runtime slot and a send-only registration source; deviced drops its creator immediately, and the driver drops the registration source once IRQD accepts the attenuated send alias.
- Routine operations use authenticated fixed endpoints: producer identity is
selected by endpoint object, and pass-through launchers such as
devicedreceive a distinct source slot for each child producer. In particular, drv-serial cannot inherit deviced's log policy, and each PS/2 driver receives only its event-kind-specific input route. Root has no input-event producer route, so verification cannot synthesize driver identity. The i8042 byte streams are partitioned separately:drv-i8042receives one keyboard and one mouse receiver, while each translator receives only its matching send client. - The trusted terminal graph removes
inputd's direct console-write authority.inputdreceives only ordinary-event and secure-attention send routes tottyd;ttydreceives those on separate slots and holds separate send-only routes for ordinary framebuffer text, framebuffer trusted chrome, and ordinary serial output. Neither ordinary PTY text nor the serial mirror can address the trusted-chrome receiver. - Launchd receives no primary kernel-control endpoint. It holds only its receive-and-grant request route, send-and-grant loader/procd/powerbox routes, and send-only ttyd session-policy route. Powerboxd likewise holds only its request route, object-bound VFS resolver, ttyd policy/prompt routes, and scoped procd grant installer. TTY policy and prompt endpoints never carry transfer authority.
- Driver-lifecycle verifier aliases occupy dedicated slots after all deployed role windows. Their start, stop, and restart cleanup cannot alias or revoke deviced's ACPI, i8042, or other production authority sources.
- Foundation memory services accept no named-resolution scope or other peer endpoint: their availability precedes the registry and logging stack.
devicedreceives the optionalRTC_CMOS_IOsender, the private timed sample sender, and a dedicated RTC-only loader sender. It transfers only the first two intodrv-rtc-cmos's private role window after exact materialization. The hardware kind permits only fixed NMI-preserving wall-clock/status selectors on index port0x70and data reads from0x71; timed holds the sole receiver. The RTC role is absent from every named catalog.vfsdalone receives the mandatory send-only public wall-clock query route. Filesystem providers receive timestamp values, never timed or RTC authority.- Host-visible integration reporting occupies a distinct required root slot; service intake policy never delegates that endpoint.
- Non-endpoint provenance must be enforced by the producer and receiver until an explicit shared provenance contract is added.
- Pre-release changes update all producers and consumers together; unused aliases, padding, and compatibility-only representations are removed.
Library Boundaries
The crate describes which authority a role may receive but cannot inspect a live CSpace. Callers must compare the declared transfer with the capability actually installed in the destination slot, including semantic endpoint kind where the registry requires one.
Contact
Development occurs in the EriX organization. Decisions require documented rationale in issues or design documents.
Maintainers can be reached at admin@erikinkinen.fi.