rootd is the first user-space policy authority launched by kernel. It receives the kernel -> root handoff and bootstraps critical early services.
Find a file
Erik Inkinen 9381d07410
All checks were successful
CI / markdown (push) Successful in 4s
CI / test (push) Successful in 23s
Document Phase 4.7 loader closure verifier
2026-05-23 01:45:52 +03:00
.github Tighten CI markdown policy 2026-05-22 15:10:39 +03:00
src Add loader cleanup authority verifier 2026-05-23 01:36:55 +03:00
.editorconfig Initial commit 2026-02-26 17:49:22 +01:00
.gitignore Ignore local .ci workspace 2026-04-15 21:53:01 +03:00
.markdownlint-cli2.yaml Tighten CI markdown policy 2026-05-22 15:10:39 +03:00
ARCHITECTURE.md Document Phase 4.7 loader closure verifier 2026-05-23 01:45:52 +03:00
Cargo.toml Add loader cleanup authority verifier 2026-05-23 01:36:55 +03:00
CODE_OF_CONDUCT.md Tighten CI markdown policy 2026-05-22 15:10:39 +03:00
CONTRIBUTING.md Tighten CI markdown policy 2026-05-22 15:10:39 +03:00
LICENSE Initial commit 2026-02-26 17:49:22 +01:00
linker.ld Add initial implementation of rootd with M0 intake and validation features 2026-03-02 14:25:30 +02:00
README.md Document Phase 4.7 loader closure verifier 2026-05-23 01:45:52 +03:00
ROADMAP.md Document Phase 4.7 loader closure verifier 2026-05-23 01:45:52 +03:00
rustfmt.toml rootd: drop unstable rustfmt options for stable toolchains 2026-03-23 10:19:56 +02:00
SECURITY.md Tighten CI markdown policy 2026-05-22 15:10:39 +03:00

EriX Root Task (rootd)

rootd is the first user-space policy authority launched by kernel. It receives the kernel -> root handoff and bootstraps critical early services.

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 design documents, specifications, and development plans.
  • Related architecture repositories for kernel, services, libraries, drivers, and integration tooling.

Purpose of This Repository

This repository implements the EriX root userspace coordinator. Its purpose in EriX is to launch the initial service graph and distribute explicit startup authority.

Functionally, it validates boot metadata, starts services in order, transfers capabilities, and performs runtime verification. The repository keeps the implementation, interface contracts, tests, and documentation for that behavior in one reviewable ownership boundary.

The maintained responsibilities are:

  • launch the initial service graph in deterministic order
  • transfer only the capabilities each service is authorized to receive
  • coordinate boot readiness, service startup, and fail-closed authority validation

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.

This repository follows the project roadmap and the validation rules documented in its own roadmap.

Build Status

Implemented M0 baseline:

  • no_std root task binary with x86_64 SysV entry ABI:
    • rdi = kernel_root_handoff_ptr
    • rsi = kernel_root_handoff_size
    • rdx = root_endpoint_slot
  • strict kernel -> root handoff intake validation (lib-handoff parser + descriptor checks)
  • deterministic rootd status model (READY, HANDOFF_INVALID, CONTRACT_INVALID, INTERNAL_ERROR, SERVICE_BOOTSTRAP_FAILED)
  • required boot-config discovery and v1 parse/validate path (ERIXBCFG)
  • config-driven async dependency startup event loop
  • launch dispatch by launch_kind:
    • rootd direct service startup
    • deviced-managed driver startup (START_DRIVER)
  • feature-gated integration reporting path:
    • runtime bootstrap path uses one binary and consumes boot-config validation_profile (none for runtime image builds, phase profile IDs for smoke/integration scenario builds)
    • packaged release runtime builds select rootd-runtime-release-image; this suppresses rootd stage, service, aggregate, and driver-restamp readiness stamps while preserving the terminal ERIX_ROOTD:READY status
    • packaged runtime builds keep rootd-vfs-verifiers disabled; local integration profiles opt in when they need late VFS verifier probes and trace markers
    • compatibility smoke aliases: rootd-integration-* map to runtime phase features
    • smoke/integration builds return through entry.rs for the final rootd READY report so VM harnesses observe completion before the process parks
    • rootd-integration-force-service-fail now trips inside the real post-START_PROCESS startup handshake so smoke negatives exercise started-child teardown rather than a synthetic final-status rewrite
    • rootd-integration-probed-omit-primary-control and rootd-integration-probed-misroute-primary-control are integration-only fault hooks for the direct rootd -> probed startup contract; runtime builds do not expose them
    • force-fail controls remain integration-only:
    • rootd-integration-smoke
    • rootd-integration-force-fail
    • rootd-integration-force-service-fail
    • rootd-integration-force-spawn-fail

Implemented Phase0 orchestration baseline:

  • deterministic required module discovery for memd, vspaced, pagerd, procd, and phase0-probe
  • deterministic service launch-order state machine:
    • intake validated
    • module set discovered
    • per-service (memd -> vspaced -> pagerd -> procd) startup-envelope synthesis/validation
    • probe spawn request contract synthesis/validation
  • role-based startup envelope generation using lib-bootstrap + lib-capabi transfer bundle validation
  • integration stage progress reporting (ROOTD_STAGE:*) via feature-gated rootd-report syscall path

Runtime-oriented bring-up path:

  • foundation service launch requests issued through kernel-control IPC (CREATE_STAGED_PROCESS, REGISTER_PAGER, MAP_FRAME, START_PROCESS)
  • later service launch requests issued through procd (CREATE_STAGED_PROCESS, startup-cap install grant materialization, and START_STAGED_PROCESS)
  • pre-bootstrap runtime endpoint inventory validation for the kernel-installed procd driver endpoint plus the dedicated time, IRQ, hotplug, PCI-config, ACPI-read, console, COM1, i8042, memory, vspace, pager, log, process, and child-populate endpoints
  • per-service startup envelope delivery and readiness handshake over endpoint CALL/REPLY
  • probe spawn request via procd plus async probe-completion event wait on the dedicated process endpoint before reporting READY
  • later foundation launches are issued through procd's staged lifecycle surface once procd is ready
  • startup transfer synthesis now injects the dedicated procd driver-lifecycle endpoint into procd and deviced, and extends their caller-visible local slot windows to include slot 2112
  • startup transfer synthesis now materializes those local driver/control slots as real endpoint-cap aliases before the envelope is delivered, so services no longer rely on canonical-slot reachability to make those assignments real
  • startup transfer synthesis now assigns procd the dedicated kernel process-control endpoint as its primary control slot and extends procd's caller-visible local slot window to include slot 2288
  • startup transfer synthesis now assigns deviced the dedicated kernel log/query endpoint as its primary control slot and extends deviced's caller-visible local slot window to include slot 2272
  • startup transfer synthesis now assigns timed the dedicated kernel time-control endpoint as its primary control slot and extends timed's caller-visible local slot window to include slot 2128
  • startup transfer synthesis now assigns irqd the dedicated kernel IRQ-control endpoint as its primary control slot and extends irqd's caller-visible local slot window to include slot 2144
  • startup transfer synthesis now assigns hotplugd the dedicated kernel hotplug-control endpoint as its primary control slot and extends hotplugd's caller-visible local slot window to include slot 2160
  • startup transfer synthesis now assigns probed the PCI-config endpoint and drv-acpi the ACPI-read endpoint as their primary control slots and extends their caller-visible local slot windows to include slots 2176 and 2320
  • startup transfer synthesis now assigns fbcond the dedicated console/framebuffer endpoint as its primary control slot and extends fbcond's caller-visible local slot window to include slot 2192
  • startup transfer synthesis now assigns drv-serial the COM1 endpoint and drv-i8042 the i8042 endpoint as their primary control slots and extends those roles' caller-visible local slot windows to include slots 2208 and 2336
  • startup transfer synthesis now assigns memd, vspaced, and pagerd the dedicated memory, vspace, and pager/fault endpoints as their primary control slot and extends those roles' caller-visible local slot windows to include slots 2224, 2240, and 2256
  • startup transfer synthesis now also copies the boot image frame explicitly into role-local image-frame slots for procd and pagerd so later spawn and pager map requests do not depend on ambient visibility of SLOT_BOOT_MODULE_TABLE

Current runtime-mode policy:

  • runtime builds are bootstrap-only (no synthetic probe/client/stress execution)
  • smoke/integration builds retain synthetic checks for CI verification
  • runtime filesystem policy is BootConfig-driven: selected provider entries supply only the private authority needed by vfsd, while MNT1 mount rows choose the actual root and secondary mounts
  • phase4-loader-contract smoke mode reuses the memory-VFS stack and verifies the first typed loaderd ABI locally: path-only launch naming, bounded argv/env blocks, deterministic response states, no inherited capability or peer/service endpoint authority, and explicit bootstrap-only static bridge policy
  • phase4-loader-fs-discovery smoke mode starts loaderd after the real block-backed filesystem stack, transfers only explicit vfsd and procd peers, and verifies public-namespace discovery of executable source paths plus fail-closed missing, directory, malformed, denied, oversized, and changed-while-loading cases. It also exercises LAUNCH_PATH static bootstrap-bridge ELF planning and process handoff, proving a valid disk fixture starts and exits with the expected code while malformed ELF, invalid load-plan, and REQUIRE_DYNAMIC requests fail with typed loader errors.
  • phase4-loader-materialized-launch smoke mode narrows the mounted-storage verifier to concrete disk-backed executable handoff. It waits for loaderd, requires explicit vfsd/procd peers, asks loaderd to materialize and launch /data/bin/loader-ok and /data/bin/loader-alt through procd, and waits for distinct process-completion exit codes before emitting per-file disk-execution proof markers. The same focused verifier launches the changed-source fixture and requires typed stale-source failure with no returned process id before emitting the process-handoff proof marker.
  • phase4-loader-cleanup-authority smoke mode reuses the focused block-backed loader stack, injects materialization cleanup faults through integration-only request IDs, and emits per-failure and authority-denial markers after proving disk-launched processes do not inherit provider, block, key, journal, peer-service, loader scratch, or caller authority.
  • phase4-loader-closure is the focused Phase 4.7 final gate. It runs the filesystem-discovery, ELF-plan, materialized-launch, and cleanup-authority scenarios to prove AC11 through AC13 without enabling older broad VM suites.
  • runtime BootConfig storage-mount proof uses provider-neutral directory/file create, write, read, readdir, unlink, and rmdir operations, so FAT roots are not required to expose POSIX-only extended API semantics
  • packaged runtime images keep the service-level readiness surface visible on fbcond/serial for fbcond, blockd, ramfsd, keyd, e2fsd, fatd, vfsd, optional loaderd, and the configured ERIX_DEVICED:READY:* driver set, plus aggregate STORAGE readiness when block storage is configured; operation-level VFS_MOUNT and VFS_IO proof stamps remain late-verifier or focused integration coverage
  • strict runtime storage bring-up waits for the drv-virtio-block endpoint and validates the blockd namespace plus GPT partitions; the runtime driver readiness tail is restamped through logd's fbcond-only internal path after the configured driver endpoints are present
  • media-backed filesystem smoke reads fixed representative chunks from the large ext host file, then checks the total size, so targeted filesystem media tests do not spend their budget repeating the same sequential read path
  • media-backed ext link-special smoke reads host-created fast/block symlinks, verifies regular-file hard-link counts through create/unlink, and proves FIFO/device metadata cannot be opened as device authority
  • media-backed ext rename smoke performs file, symlink, special-metadata, directory, overwrite, cycle-rejection, and HTree rename checks through public vfsd calls
  • media-backed ext truncate smoke creates /data/EXTTRUNC.BIN, verifies shrink across block mappings, shrink within the retained tail, zero-filled growth, zero-length shrink, and zero-filled growth from empty through public vfsd calls
    • the integration-only rootd-integration-phase4-ext-truncate feature narrows targeted VM runs to this verifier after the real blockd -> vfsd -> e2fsd mount path is established
  • media-backed ext sparse smoke creates /data/EXTSPARSE.BIN, writes past EOF, verifies zero-filled hole reads and tail data through public vfsd calls, then creates /data/EXTSPTRUNC.BIN to verify sparse truncate leaves the retained hole zero-filled
    • the integration-only rootd-integration-phase4-ext-sparse feature narrows targeted VM runs to this verifier after the real blockd -> vfsd -> e2fsd mount path is established
  • media-backed ext metadata smoke creates /data/EXTMETA.TXT, applies explicit mode, owner, atime, mtime, and user filesystem flag updates through public vfsd, verifies the returned stat fields, sets immutable state, and checks that a later metadata mutation is denied
    • the integration-only rootd-integration-phase4-ext-metadata feature narrows targeted VM runs to this verifier after the real block-backed ext mount path is established
  • media-backed FAT truncate smoke creates /esp/FATTRUNC.BIN, verifies shrink-across-cluster, shrink-within-cluster, zero-filled growth, zero-length shrink, and zero-filled growth from empty through public vfsd calls
  • media-backed FAT short-name smoke, when the fixture is present, opens and lists a host-created lowercase 8.3 entry, creates a lowercase 8.3 file through vfsd, and leaves both for host NT-flag verification
    • the integration-only rootd-integration-phase4-fat-short-name feature narrows targeted VM runs to this FAT short-name verifier after the real blockd -> vfsd -> fatd mount path is established
  • media-backed FAT rename smoke replaces a file and an empty directory through public vfsd, checks incompatible replacement denials, and leaves the mutated ESP for host fsck.fat and mtools verification
    • the integration-only rootd-integration-phase4-fat-rename feature narrows targeted VM runs to this verifier after the real block-backed FAT mount path is established
  • media-backed FAT metadata smoke stats host-created FAT timestamps, creates /esp/FATMETA.TXT, applies explicit atime/mtime/fs_flags updates through public vfsd, verifies date-only atime, two-second mtime, stat-only creation time, and read-only unlink denial, and leaves the ESP for host checks
    • the integration-only rootd-integration-phase4-fat-metadata feature narrows targeted VM runs to this verifier after the real block-backed FAT mount path is established
  • media-backed exFAT metadata smoke stats host-created primary-entry timestamps, attributes, 10 ms increments, and UTC offsets, creates /esp/EXMETA.TXT, applies explicit atime/mtime/fs_flags updates through public vfsd, verifies read-only unlink denial, and leaves the ESP for fsck.exfat, dump.exfat, and direct metadata checks
    • the integration-only rootd-integration-phase4-exfat-metadata feature narrows targeted VM runs to this verifier after the real block-backed exFAT mount path is established
  • media-backed encrypted casefold ext smoke verifies fscrypt v2 lookup and readdir through public vfsd calls when /data/secure is present, while keeping all key material private to the keyd/e2fsd provider path
  • volatile VFS smoke now extends the basic file/directory pipeline with rename, truncate, symlink/readlink, hard-link rejection, and metadata-update checks through the public vfsd endpoint
  • fsverity media uses a dedicated boot-config validation profile that mounts the same private keyd/e2fsd/fatd/vfsd stack and verifies only the verity-protected ext marker through public VFS reads
  • read-only-only ext4 feature media uses a dedicated boot-config validation profile that mounts /data with the VFS read-only flag and verifies host marker plus HTree traversal without creating mutation handles
  • runtime-only builds keep the non-returning ready-terminal handoff after bootstrap completes; smoke/integration builds do not divert there and rely on entry.rs to publish the terminal READY status
  • phase3-framebuffer bootstrap fails closed if console-font is not present
  • phase3-framebuffer verification now budgets enough fbcond read chunks to scan the full retained continuity window instead of assuming the whole stream fits inside the old 256-read limit
  • rootd now treats the first ERIX_ROOTD:READY:FBCOND cursor capture as best-effort: if fbcond is still re-entering its service loop, later framebuffer verification falls back to retained-stream cursor 0 instead of failing bootstrap immediately on that handoff race, and each timed retry rescans from fbcond's current oldest retained byte instead of advancing from a non-absolute offset derived from cursor 0
  • phase3-input bootstrap requires drv-i8042, drv-ps2-kbd, drv-ps2-mouse, and inputd

Authority cleanup status:

  • runtime launch now always sheds legacy untyped plus kernel/device-management caps after successful deviced handoff
  • deviced receives the log/query endpoint plus the narrow CHILD_POPULATE endpoint, not the broad process endpoint
  • rootd rejects any populated legacy slot 4 during runtime endpoint inventory validation instead of tolerating bootstrap compatibility aliases
  • CAP_COPY (8) is treated as reserved/denied in transport routing; only CAP_COPY_ATTENUATED remains available on the narrow child-populate path
  • post-start bootstrap failures now fail closed: once START_PROCESS succeeds, any later startup or immediate finalize failure kills the child with managed-stop, waits for its terminal event, destroys the process, and drops the retained local service endpoint slot before reporting SERVICE_BOOTSTRAP_FAILED
  • startup-wired peers are expected to validate their delegated local slots directly; unused named startup caps are being removed

Governance Principles

rootd governance is scoped to deterministic service launch and explicit capability transfer.

The scoped governance rules are:

  • It launches services only from validated boot configuration and known startup contracts.
  • It transfers no capability unless the target role is authorized to receive that exact authority.
  • It keeps startup ordering explicit so dependent services cannot race authority setup.
  • It treats residual, ambient, or duplicate authority as a startup validation failure.

Authority Boundaries

  • rootd owns initial distribution of service capabilities but does not make later service policy decisions.
  • New services must be represented through bounded boot-config metadata and documented transfer rules.

Contact

Development occurs in EriX organization and discussions happen in issues and design documents.

No decisions are considered valid without documented rationale.

Maintainers can be reached via email: admin@erikinkinen.fi.