integration is the cross-repository system integration and VM validation repository for EriX.
  • Python 47.3%
  • Rust 28.2%
  • Shell 24.5%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
Erik Inkinen c86c0d89e5
All checks were successful
CI / markdown (push) Successful in 16s
CI / rust (push) Successful in 1m55s
CI / integration (push) Successful in 1h46m14s
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: 880663f28f
Selected feature: fb851108e7

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:43 +03:00
.github build: Seal the immutable component source graph 2026-09-12 08:14:14 +03:00
lib/rootd-integration-orchestration build: Pin orchestration crate dependency closure 2026-09-12 07:38:58 +03:00
scripts build: Seal the immutable component source graph 2026-09-12 08:14:14 +03:00
tests build: Seal the immutable component source graph 2026-09-12 08:14:14 +03:00
.editorconfig Initial commit 2026-02-27 03:26:17 +01:00
.gitignore Retarget post-start bootstrap failure scenario 2026-04-16 00:00:16 +03:00
.markdownlint-cli2.yaml refactor: Own in-guest orchestration in Integration 2026-08-22 06:37:30 +03:00
ARCHITECTURE.md build: Seal the immutable component source graph 2026-09-12 08:14:14 +03:00
cargo-repos.toml build: Seal the immutable component source graph 2026-09-12 08:14:14 +03:00
CODE_OF_CONDUCT.md docs: Synchronize shared contribution and review policies 2026-09-12 06:38:23 +03:00
components.toml build: Seal the immutable component source graph 2026-09-12 08:14:14 +03:00
CONTRIBUTING.md build: Publish immutable dependency resolution helpers 2026-09-12 07:28:50 +03:00
dynlink-acceptance-closure.toml feat: Package the private RTC provider from ext4 2026-08-23 09:47:17 +03:00
dynlink-artifact-abi.toml Add dynlink artifact metadata gate 2026-05-23 16:41:48 +03:00
dynlink-dependency-records.toml build: Refresh generic launcher dependency records 2026-09-07 20:26:14 +03:00
dynlink-executable-migration.toml feat: Package the private RTC provider from ext4 2026-08-23 09:47:17 +03:00
LICENSE Initial commit 2026-02-27 03:26:17 +01:00
README.md build: Seal the immutable component source graph 2026-09-12 08:14:14 +03:00
ROADMAP.md build: Seal the immutable component source graph 2026-09-12 08:14:14 +03:00
runtime.dev.toml feat: Coordinate image policy and interactive console deployment 2026-09-07 22:58:12 +03:00
runtime.release.toml feat: Coordinate image policy and interactive console deployment 2026-09-07 22:58:12 +03:00
runtime.sample.toml feat: Coordinate image policy and interactive console deployment 2026-09-07 22:58:12 +03:00
rustfmt.toml integration: drop unstable rustfmt options for stable toolchains 2026-03-23 10:19:52 +02:00
SECURITY.md docs: Synchronize shared contribution and review policies 2026-09-12 06:38:23 +03:00
SOURCE-PINS.md build: Seal the immutable component source graph 2026-09-12 08:14:14 +03:00

EriX Integration Repository

integration is the cross-repository system integration and VM validation repository for EriX.

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 integration harness. Its purpose in EriX is to prove cross-repository system behavior in deterministic appliance and VM scenarios.

Functionally, it builds component sets, generates test media, runs scenarios, and checks expected markers and artifacts. The repository keeps the implementation, interface contracts, tests, and documentation for that behavior in one reviewable ownership boundary.

The maintained responsibilities are:

  • assemble component revisions into runnable system images
  • generate deterministic test media and VM scenarios
  • provide the no_std, authority-free in-guest scenario policy linked into build-gated rootd integration images
  • verify cross-component behavior, authority failures, and persistence checks
  • publish release artifacts only from push/manual CI runs; pull requests validate without mutation and scheduled CI runs are not defined

Canonical dev and release profiles share the same mount graph: writable ext4 /, read-only FAT /boot, and volatile writable ramfs /tmp. A writable mount does not pregrant write authority to a shell or command. Utilities still request exact operations through the running-job broker and trusted review as needed. Read-only scenario media retain explicit read-only test profiles.

The kernel pin now traverses private read-only mapping chunks directly, with pending updates spanning storage boundaries and no effects from empty chunks. Four independent regressions and the strict 584/608-test kernel matrix pass; live checks, error order and hardware batch behavior remain unchanged. Prior NonNull images complete the commands but miss prompt (1.1091.111 seconds) and four-command (2.8982.938 seconds) acceptance. CI 1548 passes 486/486 scenarios and all post-image probes; CI 1549 validates its successor separately. The new pin still needs its own private images and unchanged-limit observations.

The compact mapping-preparation refinement keeps complete leaf entries and exact PTE keys, with GLOBAL invalidation encoded only in a validated target address bit. Hardware keys use checked non-null conversion on target-span resolution. Independent untagged-oracle regressions and the strict kernel 580/604-test suites pass; live preparation and all authority/flush boundaries remain unchanged. Smaller emitted code, stack and temporary results are not startup acceptance: both origin-image observations still fail the unchanged strict limits. Matching private-image validation remains required, and the main dev/release images are not replaced by this checkpoint.

The selected mapping-lookup refinement retains a table-owned last-full-search index, not a pointer or authorization result. Repeated explicit user-buffer validation and copying still check live bounds, exact page identity, rights, kind and backing under the existing VSpace lock. Mutable exposure, removal and clearing invalidate the hint; the original first-match search remains the fallback. CI 1546 at c306711a passes all 486 scenarios and post-image gates, but both later 21850e67 staging-image observations still miss the one-second READY-to-caret and two-second four-command limits (1.020/1.025 and 2.716/2.634 seconds). Matching new-image acceptance remains required. No main image is replaced, no limit is relaxed and no debugger overhead is subtracted.

CI 1545 at 411bc181 completes all 486 scenarios and post-image gates, closing the earlier CI repair described below. The stricter isolated startup limits remain open: both exact published-image baseline observations and both private c306711a candidate observations fail. The next kernel pin 21850e67 removes redundant mapping-batch empty tags by initializing only the exact used prefix. Every preparation succeeds before reading any staged leaf; errors read no prefix and retain the existing flush. Eight trace-equivalence regressions and the strict 555/579-test matrix pass. Earlier first-preflight index reuse still reacquires the copy lock and authorizes each live page again. Neither emitted work reductions nor host-cost measurements establish candidate image speedup. The main dev and release images are not replaced by this work.

Run 1542 completes all 486 scenarios and its post-image gates. The corrected 7f7e6cfd graph subsequently passes eight private terminal/time/interrupt probes, but run 1543 finishes with 473 passes and thirteen storage watchdog failures after VFS_MOUNT; its post-image gates are skipped. Two unchanged isolated migration-closure runs pass; neither the page-fault tail nor the sampled blocked calls alone establish a deadlock. The baseline storage pipeline previously hid fourteen proof phases behind end-of-pipeline markers. Integration now reports completed proof phases through rootd's existing build-gated logging adapter. These are success-only observations, not heartbeats or early final markers; 120-second total and 45-second silence bounds remain unchanged. Complete replacement CI is still required. The migration-closure VM requires all fourteen new records exactly once and in order between VFS_MOUNT and VFS_IO, retaining every older assertion. The pinned VFSD also removes an independent oversized owned read-reply temporary. Its runtime and smoke PIC selected-frame estimate falls from 267,072 to 169,008 bytes within the unchanged 262,144-byte allocation. The new component CI gate checks emitted frames without claiming whole-program stack safety. This defect is proven separately, not attributed as the cause of all thirteen watchdog failures; matching guest validation remains pending.

CI run 1540 passes all 486 catalog scenarios but fails its later development native-time probe while still selecting the old shell. Integration e7f4fa71 selects exsh b99d6da4; both matching private dev/release native-time probes now pass. Complete replacement CI remains required. Run 1541 separately exposes an accounting-fixture precision assumption: raw shell CPU time increases across exec while both separately truncated centisecond fields remain unchanged. The successor now performs 64 bounded writes with the existing times builtin, scratch file and authority before its sole visible snapshot. The original 32-iteration child and strict accounting assertions remain unchanged; this is deliberate fixture work, not a CPU-speed guarantee or a runtime-accounting fix.

At the same e7f4fa71 image checkpoint, framebuffer-only, serial-only and disabled-terminal probes pass. Independent terminals exhaust the old observer's 160-frame budget. Pacing only ordinary independent command-result captures at 800 ms preserves every fresh-frame predicate, edit, consent and foreign-Enter proof, with unchanged 160-frame and 120/15/10-second bounds. The unchanged image then passes all twenty commands and exact approve/deny/readback checks in 99.816 seconds using 132 captures. This is functional observer evidence, not a startup-performance result. The intermittent post-interrupt launch failure and full remote CI remain open.

The final 776e3407 runtime images pass all eight focused feature probes: dev/release editing and mount/time policy, plus framebuffer-only, serial-only, no-console and independent-console modes. Host oracle cf59e661 completes the independent test's twenty commands in 74.491 seconds using 144 of 160 captures, including both exact consent decisions, processed wrong-seat Enter rejection and approved-only readback. Earlier failed attempts remain retained. The real managed-frame hardware test also passes; stricter startup performance does not.

The subsequent empty-file utility report is a separate regression: those eight probes did not cover named-file cat or copying to an absent destination. tests/native-utility-vm.sh serial|physical image now checks sixteen commands and twenty exact trusted reviews. Source READ, missing-entry CREATE and file WRITE require independent grants; denial is never permission to create. The probe checks empty/nonempty readback, denied creation, denied post-create write, explicit truncation and a usable later shell with unchanged 120/15/10 bounds. Host checks and both matching-image 7f57bb8b utility probes pass: development serial and release physical each complete sixteen commands and twenty exact reviews, including nonempty copy/readback, both denial outcomes, empty-source overwrite truncation and the final shell sentinel. The local artifacts are out/appliance/erix-utility-poll-dev.img and out/appliance/erix-utility-poll-release.img; canonical open images are untouched.

The first fixed-image checkpoint c9a78901 builds separate erix-utility-dev and erix-utility-release images without overwriting an open canonical dev disk. Its new utility probes are 0 PASS / 2 FAIL: dev proves named-file cat and reaches all three separate copy reviews before the command deadline; release reaches the silence watchdog before its banner. Both ran with a separate four-vCPU VM active, but that does not establish the sole cause of failure. Original bounds and failed evidence remain intact. These images are diagnostic builds, not accepted replacements. The complete host matrix passes 300/301 Rust tests and all 472 Python tests across 45 suites.

The release rerun completes its first eight commands, including empty copy and readback, nonempty cat and denied creation. It then times out waiting for the status marker after correctly denying post-create WRITE. That c9 checkpoint's dev/release results remain 0 PASS / 2 FAIL, with three attempts retained. Kernel b54082bd separately removes a repeated nonblocking receive lookup by observing dequeue backpressure and live transfer-waiter state under one lock. Blocking receive, capability validation and generation checks are unchanged; 537/561 host tests and strict checks pass. The matching 7f57bb8b utility probes pass in 102.569s and 98.375s under the original bounds. A separate four-vCPU VM remained active, so these are functional results, not an isolated speedup comparison. The stricter 5/1/1/2-second startup gate remains open.

The explicit [features] switches rtc_cmos, tty_fbcon, tty_serial, and tty_mirror replace the private-provider presence table and describe console deployment. TTY switches do not change logd stamps or provider logging routes. Both paths with mirroring select one session; without mirroring they select two independent shells. One enabled path selects one shell; neither selects none. The generator encodes the three TTY bits in a strict 96-byte TTY1 version-2 startup record. The product orchestration entry starts both independent shell transactions before waiting on either one, with distinct realms and exact lifecycle/status receipts. Temporary cancellation handles exist only during dual-start rollback; all launch and control aliases are retired before normal round-robin status observation. Malformed replies retire all framed receipts and never invoke unvalidated lifecycle/control endpoints. Uncertain cleanup or job disposition fail-stops. Console-mode acceptance remains separate from source/host checks and the accepted mirrored editor probes.

Canonical interactive dev launches now select the same console-count runner as product builds, instead of the authored single-shell fixture path. Zero paths create no TTY session; independent paths start two. Authored scripts and negative fixtures retain their existing protocol. Successful runtime-console completion retires bootstrap and host-report authority, then exits rootd normally without the test-only terminal READY host report that would terminate the VM. Failure reporting is unchanged; surviving services need no retained rootd idle loop.

The focused native-editor-vm.sh probe submits ten separate commands through physical keys or fragmented COM1 sequences. It checks history, saved drafts, insertion, Backspace/Delete, boundaries and wrapped recall, retains raw output and screenshots, and requires fresh results and prompts. The separate native-image-policy-vm.sh probe binds packaged metadata to the chosen image's source epoch and live creation/touch to a deterministic 2030 RTC. It authorizes only named test objects, verifies root writes and /boot denial, and preserves the source image. Both keep the 120-second total, 15-second silence and 10-second command bounds; screenshots alone are not text/caret acceptance.

tests/native-console-mode-vm.sh fbcon|serial|none|independent image checks dedicated feature images with separate serial and exact gray framebuffer evidence. Independent seats must retain distinct cwd, history, input and consent; wrong-seat answers cannot decide a pending review. Disabled paths must show no shell, without suppressing independent service logs. The foreign-seat check requires fresh builtin output and a new prompt while the original review remains pending; merely injecting Enter and waiting is not acceptance of input isolation. Before final READY the observer checks serial order without spending bitmap captures; afterwards it requires fresh exact frames while continuously draining COM1. For this probe only, the unchanged 15-second stall watchdog also accepts finite, ordered verified guest milestones from its private observer log. Screenshots, input injection, file activity, replayed events and malformed records cannot keep a stalled guest alive. Other profiles retain their existing serial progress policy; all command and total deadlines remain unchanged.

tests/native-command-timing-vm.sh [dev-image] records eight separate commands: builtin : and true controls plus six external launch observations. It arms the bounded fresh-log startup observer before VM creation and records every READY interval independently of Enter-to-output/prompt latency. A new exact caret-show is required after each command. Builtins have no first-output measurement; native time must report real nonzero elapsed time in its exact format. These observations are not a waiver of the tighter startup gate.

The ca6f1346 image checkpoint passes dev-serial and release-physical mount/time probes, including source-derived packaged mtimes, live RTC object creation, explicit touch timestamps, dot entries and read-only /boot denial. Earlier failed attempts remain recorded in out/console-editor/ACCEPTANCE.md. The a02f5797 checkpoint additionally passes both 14-command directory probes and exact-pixel editor probes, including wrapped text and the sole insertion caret. Release screenshots confirm that the initial firmware artwork is cleared. Console-mode checks remain separate: they exposed whole-line semicolon history truncation and a framebuffer-only serial-silence watchdog mismatch. Signed exsh 2ad98e0c offers original accepted bytes once before execution-plan segmentation or asynchronous rewriting, staging them in its inactive draft arena until the complete entered line ends. Invalid or oversized aggregates cannot publish a truncated suffix or evict old history. All 928 tests pass in both selections; the 392b6c18 framebuffer-only and serial-only images now pass complete-line recall with a fresh appended execution result. Exact framebuffer consent remains mandatory: mirrored serial text merely wakes the bitmap observer after launch, avoiding redundant screenshots without raising the 128-capture or time bounds.

Block reads reserve only their checked response header plus the current fragment's bytes. Lib-block df03ec77 reduces a 512-byte metadata read to 592 total IPC bytes instead of 32,768 without changing fragmentation, returned length checks or device/request identity. E2fsd 3e564fc3 validates inline xattrs from the same request's checksum-verified inode bytes, removing one duplicate inode read without a cross-request cache or altered external-xattr checks; 249 tests pass in both feature selections. These request-local optimizations and the sparse kernel refinement require end-to-end timing evidence.

The 9dc9cf6b no-console image passes its complete five-second quiet check: disabled physical and serial input produce no shell, service logs remain available, and services survive normal rootd exit. The 392b6c18 checkpoint also passes exact-pixel editor and mount/time probes on canonical dev/release, and the no-console quiet check. Independent-console testing completes fifteen ordinary cwd/history commands but exhausts its unchanged capture bound before the first review; it is not accepted. Single-seat probes now add their own approve/deny decisions and exact object readback within the existing bounds.

Kernel 6d642d95 selects a managed extent's lowest free page with one current mapping-table scan for aligned extents of at most 64 pages. Object identity, holes, aliases, locking and error order remain exact; other geometries keep the original path. The new kernel-managed-frame-occupancy-positive scenario requires real backing readback and private-object cleanup before its success marker. Loaderd 6761638 drops size-only manifest/object queries while retaining live metadata checks, digests and pinned-root authority; verified read lengths split the existing bounded workspace, with full erasure on every result. Both strict component matrices pass. The dd7ed015 managed-frame hardware probe passes real backing readback and complete private-object cleanup. Its isolated date observations are 0.825/0.893 seconds versus an adjacent 392b6c18 control's 1.073 seconds; nested time date is 1.423/1.480 versus 1.985 seconds. These paired command improvements do not close the tighter service-startup gate.

The dd7ed015 framebuffer-only and serial-only probes each pass eleven commands, including their own approve/deny decisions and exact approved-only readback; no-console quiet also passes. Independent mode proves both decisions, rejection of processed foreign-seat Enter, and approved-only readback, but reaches the unchanged 160-capture bound before final completion and remains unaccepted. Its observer now omits eighteen unused command-preamble screenshots while retaining fresh edit/result frames, all consent checks and original bounds.

Exsh 700e41d6 limits borrowed observation reply buffers to 128 bytes for TTY events and 112 for job status, retaining the existing two-receipt audit allowance. Only the borrowed prefix is erased; the unused caller tail is never transmitted or parsed. Cadence, signal ordering, receipt cleanup and authority are unchanged. All 936 tests pass in both feature selections with strict target checks; fresh matching-image and latency acceptance remains separate.

The 547f67b6 checkpoint passes both ten-command editor probes, both twelve-command mount/time probes, both eleven-command single-terminal consent/history probes, and no-console quiet. Independent mode passes nineteen commands and submits the twentieth before its unchanged 160-capture bound: seven feature passes and one failure, not full acceptance. Two isolated timing runs and an adjacent dd7ed015 control show no clear additional whole-command gain from polling buffers alone.

Kernel 48cc425c combines the remaining exact-address and managed-page scans under the same VSpace lock. First-address matches and the original overlap, fallible reservation, page-selection and rights order remain unchanged; device and noncanonical paths keep their original behavior. Nine new tests prove equivalence and one traversal instead of two; 527/551 tests pass with one pre-existing ignored benchmark each. Fresh hardware and timing proof is separate.

On the 776e3407 images, the real managed-frame hardware scenario and all seven non-independent feature probes pass. Independent mode still reaches its capture bound after nineteen commands. Its result observer now carries the same 400-ms interval across Enter instead of taking a closely spaced phase-entry snapshot; every result predicate still requires a fresh frame, and serial isolation, consent paths, deadlines and capture limits are unchanged. Fifty focused host tests and independent review pass. The final .QgXj4d rerun now completes every milestone and preserves source image hashes under the original 120/15/10 bounds.

The corrected strict startup probe completes all guest commands but fails all four thresholds: root readiness 6.195 seconds (limit 5), complete editor caret after readiness 1.805 (limit 1), RTC-to-TTYD alone 2.981 (gap limit 1), and four native commands 4.166 (limit 2). Its observer requires the complete caret and charges execution during Enter acknowledgment without millisecond rounding. Isolated adjacent-image timings do not establish a uniform whole-command gain.

RTC is encoded as a deviced-driver BootConfig node with explicit deviced, loaderd, and timed dependencies; it has no filesystem-launch row. Rootd images receive a build-time version derived from the Integration repository's sorted tag at HEAD, or the full Integration commit when no tag exists. Initial-shell development scenarios require the observable order READY:LAUNCHD, final ERIX_ROOTD:READY, a blank line, the light-gray EriX <tag-or-commit> banner and its blank line, then shell evidence. Release images cross the same internal complete-service barrier but deliberately omit the development-only final READY record before printing the banner. Physical input injection waits for the real dollar-space shell prompt; the former rootd PHYSICAL_INPUT:SESSION_READY coordination stamp is absent. The shell is therefore post-readiness user policy rather than a service-readiness condition. The interactive transcript explicitly exports PATH=/bin:/usr/bin, so command lookup is inherited process state rather than an ambient fallback inside exsh. The tty session carries a bounded native-command operation ceiling. Requests already admitted by the session and executable/script ceilings use routine powerbox authorization; exceptional selectors require trusted prompt mediation. No filesystem or process authority is ambient. Both canonical images execute an external echo through that path in their focused VM gates. The release gate waits for that guest output and then ends only the host QEMU process through its private QMP socket. Rootd observes all selected shells until terminal, retires their exact remaining authority, then exits normally; surviving services do not depend on an idle rootd.

Native command launch is program-agnostic: exsh sends the unchanged executable selector, arguments, cwd, and stdio, with no operand authority records. The running utility requests exact operations through a job-bound broker; provider or consent denial is a utility error, not an executable-admission error. Build-time manifests independently declare CPU accounting, inherited script launch, timed query, session inspection, cwd, and redirection-resolver ABI bits. The three-column exsh/extop catalogs receive explicit inventory declarations 49 and 9 respectively; coreutils flags pass through its own catalog unchanged. tests/launch_manifest_flags_test.py covers all 64 flag combinations, relabelled catalog entries, exact command identity, and rejection of index/sidecar drift. Matching-image broker acceptance is recorded separately from these host checks.

Live-image regression checks also keep the shell's own receiver distinct from its launch sender and require each ABI flag to select only its declared authority. Executable inspection borrows the current cwd through the existing launch sender; inherited script launch must not implicitly install a resolver. Strict startup inventory and fail-closed authority checks remain mandatory.

tests/native-runtime-errors-vm.sh physical|serial [dev-image] uses only a private copy of the dev image. It requires a real dev READY record, root cwd, generic command -v mkdir, utility-owned permission errors and status 1 for touch boot/a/mkdir boot/a, utility argument errors and status 2 for operand-free calls, and a fresh final echo. No prompt is approved or retried. The existing powerbox probe supplies the release-safe counterpart: explicit allow/deny under writable /tmp, a utility-owned denial diagnostic/status 1, and separately authorized readback proving exact creation and absence. Both paths keep the 120-second total, 15-second stall, and 10-second command bounds; host socket fixtures exercise transport and teardown but are not VM evidence.

tests/native-time-vm.sh [source-image] runs six separate COM1 command lines on a private dev or release image. Native time -p must complete an inherited pipeline, preserve redirected child stdout, and write its own portable real/user/sys report after the child's argument-error diagnostic into the same redirected stderr file. Exact redirected-stdin readback proves child EOF did not close the parent's description. The probe uses existing shell redirection authority, never an extra file grant or consent bypass; separate powerbox probes cover runtime requests. It requires exact output/status and later prompts with the unchanged 120/15/10-second limits, retaining logs, per-command timings, and source identity under out/native-time/. Host socket and private-wrapper regressions are CI gates. Integration d8e83d3d passes all ten focused matching-image cases: dev root utility errors on both transports, dev/release directory operations on both transports, and dev/release serial native-time and powerbox consent. Every wrapper exits zero under unchanged 120/15/10-second limits with unchanged canonical images. Exact source hashes, timings, and the earlier 090e7156 two-pass/two-fail attempt are retained in out/runtime-authority/ACCEPTANCE.md. This closes running-program authority acceptance, not the separate tighter startup-performance gate.

COM1 receive is an alternative ordinary input transport for that same focused PTY. drv-serial keeps RX bytes separate from transmitted log history, seriald consumes them only through its private provider route, and ttyd feeds ordinary bytes through its existing line discipline. During an exact focused trusted prompt, ttyd instead captures serial answers after complete private review delivery and an empty post-visibility RX read. No public serial writer gains input-injection authority. Ttyd advances RX one nonblocking step per turn, retaining request identity and bytes without blocking rendering or PTY cleanup. Empty or unavailable reads skip seven focused turns before the next attempt; accepted replies and buffered bytes keep progressing every turn. The focused development-image gate proves both PS/2 and COM1 command input against independent copies of the canonical image.

Interactive reuse is checked separately by tests/interactive-shell-lines-vm.sh physical|serial [source-image]. Each private VM submits ls, waits for directory output and a fresh later prompt, submits another ls, and finally submits an external echo sentinel on its own line. Every command must produce new output and return a new prompt; one semicolon-separated batch is not equivalent evidence. CI covers both transports on both dev and release images. Each command has a ten-second monotonic budget including input injection, inside the 120-second VM deadline. Logs, milestones, image identity, and source checksum are retained under out/interactive-shell-lines, including on failure. This catches terminal focus being redirected to a command's unused lifecycle PTY even though that command inherits the shell's actual stdin. Ttyd changes automatic focus only when provisioning really exports a new stdin sender; lifecycle-only and output-only requests preserve the current focus. The paired tests/interactive-shell-interrupt-vm.sh [source-image] requires both canonical input echo and /bin/cat output before one physical Ctrl+C, then status 130, a new prompt, and a separately entered successful command. Exsh observes the inherited shell PTY through its existing persistent event cursor while forwarding only through its held exact child-control route. CI runs this cancellation check on both image profiles without using repeated interrupts that could spill into the following command.

The additive tests/interactive-interrupt-reuse-vm.sh [source-image] repeats nine independently gated cycles on development and release images. Every cycle requires fresh real-cat output before its single Ctrl+C, then CONTROL130, a new prompt, AFTERINT and another new prompt. The same absolute 120-second deadline, 15-second stall bound and ten-second command budgets apply throughout; there is no retry of a failed interrupt. This is sustained-use coverage, while launchd's host regression proves exact job-row reuse regardless of deployment capacity. A cancelled inherited-stream caller must not terminate the parent TTY. Exsh must consume completion through its already-held status route before dropping the handles; delivery on a control-only signal route cannot consume another holder's separate status observation or bypass authority cleanup.

tests/powerbox-prompt-vm.sh [source-image] [physical|serial] checks automatic trusted attention on each canonical image. No Ctrl+Alt+Delete is injected. The host decodes exact amber ASCII glyphs using the checksum-verified packaged PF2 font, then requires a fresh complete prompt with the exact program, scope-relative object selector, operation, lifetime, and Enter instructions. Physical y alone must leave the prompt pending; one Enter approves the first request. A second request is denied with n followed by Enter. Both selectors, tmp/promptallow and tmp/promptdeny, use writable /tmp on dev and release. A third complete review for /bin/ls tmp explicitly requests directory enumeration for this invocation and needs its own y followed by Enter. Only then does readback verify that the approved object exists and the denied object does not, then a separately entered echo proves prompt input did not spill into exsh. An independent bounded serial audit rejects fresh command-not-found diagnostics or standalone echoed y/n lines, even when a later echo succeeds; its matching context survives read splits and discarded command-evidence buffers. Expected authority-denial diagnostics remain permitted. The optional COM1 probe requires the same fresh complete framebuffer review and its entire byte-identical CRLF-normalized serial mirror, then a bounded 200-ms unchanged-review observation before one serial choice. It sends no physical keys. Separate serial and physical selection state prevents mixed transport confirmation. Accepted serial decisions drain their input batch and queued CRLF before ordinary shell input resumes. The private seriald modal writer excludes ordinary output and bypasses retained public logs; it adds no capabilities. Raw serial still requires a safe operator terminal emulator and does not provide the framebuffer's reserved-color display guarantee. CI checks approval, denial, explicit enumeration, and no answer spill on both transports and image profiles; matching-image evidence remains separate from host fixture results. Every stage is bounded by ten seconds inside the 120-second VM deadline. Source disk and firmware are privately copied and removed after the run; raw serial/QMP diagnostics, hashes, and fresh PPM screenshots remain under out/powerbox-prompt, including on failure. Each run uses only its selected physical or COM1 transport for commands and consent. Cells without trusted amber are background, including untouched firmware artwork; any amber cell must still match an exact black/amber PF2 glyph. Missing field text, mixed colors, and damaged amber glyphs fail closed.

tests/native-directory-vm.sh physical|serial [source-image] covers the reported directory command failures on separate shell lines. It requires nonempty ls bin output, real ls -la metadata, and both enumeration and metadata reviews for ls -la bin; ls tmp is separately denied. Long rows must contain a real file type, permission bits, link count, numeric ownership, size, and UTC timestamp or the explicit provider-unknown marker. Status zero without the required entries is a failure. The same private VM then checks cd bin, /bin from pwd, relative ./ls, a failed change preserving cwd, cd .., / from pwd, and a fresh external sentinel. No directory-navigation authority is manufactured by the host or inferred from a displayed path. Repeated selector reviews must have an exact job/generation/session/realm/ request identity absent from matching pre-command reviews; changed pixels or an old matching review alone cannot satisfy the input gate. Physical and COM1 profiles preserve the existing single-choice, separate-Enter and no-spill gates. CI covers both transports and canonical images with ten-second command and 120-second VM bounds. Private disks/firmware are removed; raw diagnostics, identity hashes, and screenshots remain under out/native-directory.

Loaderd now transfers authenticated executable and dependency bytes in 32-KiB chunks directly into their final caller-provided storage. Its authentication pass reuses one bounded scratch buffer, eliminating the former per-chunk payload copy and reducing VFS round trips without caching mutable authority or changing ELF, manifest, relocation, or launch admission. Relocations travel to procd in bounded batches; procd coalesces adjacent writes and allocates up to 64 pages per frame extent while preserving page permissions and exact cleanup. VFS overlay cursors terminate after the last synthetic mount entry. The native ls VM gate requires directory output, status zero, and at most ten seconds for four external commands after input injection, measured separately from boot. Both input probes retain their shells and stop only their private host QEMU after exact result evidence, avoiding a race with guest teardown. QMP cleanup has a separate one-second bound and preserves the original command failure.

Kernel address-space switching batches up to 64 tracked page mappings, including early-service anonymous shadow aliases. Dependent aliases and duplicate targets split into ordered groups; each group flushes before the next translation, lock release, or interrupt restoration. Global entries retain explicit invalidation. Mapping rights, ownership checks, and the current BSP-only userspace dispatch remain unchanged. IPC range/copy walks use operation-local index hints to avoid repeated full mapping scans. Every use rechecks the live page identity, rights, and ownership; no pointer, backing, or permission is cached between operations. The new kernel-mapping-batch-isolation-positive VM scenario exercises real physical and anonymous translation replacement, ordered alias dependencies, flag preservation, restoration, and scratch cleanup through a feature-gated early kernel probe; normal images omit that probe. The separate kernel-mapping-batch-sparse-positive scenario requires a new sparse-group marker followed by the complete mapping-suite marker. It checks real gapped targets and exact backing dependencies, unselected holes, mixed permissions and complete private scratch restoration. Host policy tests ensure the probe remains early-kernel-only and bounded; matching-kernel VM validation is recorded separately from the model tests.

Generated freestanding memcpy, memset, and memmove use exact-range eight-byte integer operations followed by byte tails. They need no SIMD state or optional CPU extension and never change the direction flag. Backward overlapping moves preserve source bytes; comparison still returns the first unsigned-byte difference. Native assembly tests cover unaligned buffers, overlap, zero length, read-only sources, and inaccessible guard pages. This reduces a measured secondary copy/fill cost; it is not a substitute for the address-space switching improvements or fresh VM timing evidence.

The separate tests/dev-image-startup-vm.sh gate measures the earliest services as well as the disk-resident shell and native tools. Its host-only observer records complete READY lines with monotonic timestamps, rejects stale/replaced/truncated logs, and preserves partial evidence on VM failure. Each event also records its earliest possible arrival from the previous read's start; unread buffered chunks retain that original bound until drained. Observation windows exceeding 100 ms fail, even when accumulated records would otherwise have identical timestamps. Acceptance intervals conservatively use the later event's observed time minus the earlier event's earliest bound; raw point timestamps remain available for analysis. VM completion drains the bounded log to EOF before declaring a missing result. READY gaps include loading, scheduling, service initialization, publication, and display delivery; they are not pure loader times. No guest clock or additional logging capability is introduced. Private-copy runs preserve the canonical image and use run-private firmware variables. JSON, serial, input, observer, and QEMU stderr logs remain under out/startup-performance/check.*. The wrapper accepts at most one optional source-image path; omitting it keeps the canonical development-image default. It requires readable regular image and existing identity-sidecar files before starting any observer or VM, preserves the selected sidecar, and verifies the selected source hash after private-copy execution. No additional identity schema or image-feature policy is inferred. The command injector allows up to ten seconds to retain completed slow-run evidence; the separate performance assertion still rejects any command sequence exceeding two seconds. The VM's 120/15-second hard/silence bounds remain unchanged.

While supervising the initial shell, rootd's shared READ_JOB adapter clears and advertises only 112 bytes: the canonical 72-byte reply plus a bounded 40-byte reserve for auditing unexpected receipts. Delivered capabilities are retired before typed status parsing. The poll/yield cadence and session lifetime are unchanged; this optimization does not introduce a timeout or change the accepted-call completion contract.

New launchd-owned job/script/accounting/stream and ttyd-owned session endpoints record their exact retained receive alias before exporting any sender. One zero-capacity, nonblocking RECV must report empty RETRY; failure follows the existing publication rollback. Delegated foreign receivers are excluded. The kernel preserves this live-validated auxiliary receiver preference when additional callers queue behind an outstanding call, under the same bounded handoff budget. Neither path creates a pending receive buffer or new authority.

This stricter startup target requires all canonical service READY records in order: root launch to final READY within five seconds, each canonical service READY gap within one second, final READY to shell prompt within one second, and the four external commands within two seconds from the start of final Enter emission, including its QMP acknowledgement. Baseline measurements before the new optimization were 14.0, 1.88, 2.38, and 6.60 seconds respectively. The independent 120-second hard and 15-second silence watchdogs still apply. Run the timing gate without concurrent builds or VMs; register-sampling profiles are separate diagnostics, not acceptance timings.

The isolated 186c7c1 comparison records root launch to final READY at 3.324/3.291 seconds, the largest service gap at 0.808/0.806 seconds, the first shell prompt after another 1.390/1.393 seconds, and four commands at 3.861/3.884 seconds. Evidence is retained in out/startup-performance/check.kA39Vl and check.UfhWJj. Both runs still fail the shell and command targets; completed boot barriers are not proof that native-command latency is acceptable. Repeated whole-address-space mapping work during ordinary runnable-service tours remains a measured bottleneck. The mandatory CI performance step remains pending rather than being enabled with a known-failing result or relaxed limits.

The subsequent isolated continuation retains three completed strict-gate failures across two immutable images. Conservative observation bounds, not point timestamps, give the following seconds; every run meets the first two limits and misses the latter two. The recorder's successful evidence status does not imply performance acceptance; all three wrappers exit 1.

Image / evidence Boot (5 s) Gap (1 s) Caret (1 s) Commands (2 s)
776e3407 / check.Ijhmow 3.331945 0.860476 1.236359 2.455439
7f57bb8b / check.dq8Jql 3.186823 0.847521 1.266006 3.118697
7f57bb8b / check.oypESc 3.227462 0.845896 1.213853 3.239898

These are 0 PASS / 3 FAIL measurements, not four failed thresholds per run. RTC-provider READY to ttyd READY is the largest service interval in each. The same full-caret oracle and Enter-before-ACK, unrounded command timing apply to both images. The mixed results do not establish an overall speedup. Exact source hashes and complete evidence remain in each run directory; the strict 5/1/1/2-second gate remains open without changing the 120/15/10-second bounds.

The final loader-bounds checkpoint is ad6da25e2ffb1aad8539cee2330867f4d10c982a, source epoch 1788893085. Loaderd b26f906d includes 75e32c0b's fixed 32-byte dynlink status/commit replies and active-prefix-only peer framing, plus reuse of the same verified immutable root's digest at handoff. Every first full live hash, fresh selected object check, pinned root identity, request/variable-plan capacity, receipt cleanup and terminal erasure remains required. No digest cache crosses a launch. Both 90-test matrices and strict component gates pass. The rejected local-PDE bitmap experiment is absent: fair host benchmarks regressed common restore-heavy cases roughly 3640% for only about 6% shuffled-alias improvement. Kernel b54082bd and the existing hardware scenarios remain unchanged.

The adjacent isolated strict comparison retains these conservative seconds:

Image / evidence Boot (5 s) Gap (1 s) Caret (1 s) Commands (2 s)
7f57bb8b / check.UKNhOl 3.105823 0.817050 1.164035 3.239686
ad6da25e / check.2RwvLL 3.074977 0.793675 1.138679 3.038390
ad6da25e / check.r7CgVn 3.130488 0.820912 1.173104 3.079151

Each wrapper exits 1: first two thresholds pass and the latter two fail. This is 0 PASS / 3 FAIL in the latest comparison, including two failed new-image measurements, or 0 PASS / 6 FAIL across both continuation batches. New command intervals are about 6.2% and 5.0% below the adjacent control, but boot and prompt values straddle it. This limited paired sample neither isolates the two loader changes nor establishes overall startup improvement.

Matching utility functionality does pass: development serial .YYG3LA in 53.095723 seconds and release physical .2ftR8b in 59.918327 seconds both exit 0 with all sixteen commands and twenty trusted reviews. Original 120/15/10 bounds, fresh review identities, exact output/status/caret checks, separate source/create/write approvals, denied-effect readbacks, truncation and final shell reuse all pass. No other VM, compiler or manual overlapped the sequential runs. Historical contended utility durations are not isolated comparison baselines. Exact images under out/appliance/ are:

  • erix-startup-bounds-dev.img, SHA-256: 354c6db83572b66874fb2699e736cfe6b334f8bb215f85af9a7529f4232f8703.
  • erix-startup-bounds-release.img, SHA-256: 08d8394079edadaa7f8e6bd6c0ce397fc81407cdd6ff8d31bf23b4408469736e.

The latest utility pair is 2 PASS / 0 FAIL; the strict startup gate stays OPEN. Raw, sidecar and compressed identities, signed boot/closure contents and all 72 component revisions verify. Sources and six protected earlier images are unchanged. Evidence is retained in out/startup-performance/ and the named out/native-utility/ directories. Later documentation publication does not relabel the tested runtime revision or replace retained failures.

The separate rust job in ci.yml runs formatting, strict Clippy, default and all-feature unit tests, a bare-metal build, and warning-denied rustdoc for the in-guest crate without coupling those fast gates to the complete VM job. Direct image PIC and global-assembly compilers, plus the Cargo fallback, explicitly deny warnings: RUSTFLAGS alone does not cover direct rustc. A host regression compiles actual warning and clean-object fixtures to check that this policy rejects diagnostics without rejecting valid artifacts. Build-gated rootd images consume that crate as erix-rootd-integration-orchestration.so. The checked rootd dependency record includes the object explicitly, so the prebuilt registry, early executable manifest, and final image closure all fail before packaging if the library is missing or stale. Integration images select the complete effect adapter; canonical release packaging selects only rootd's product post-readiness hook and the authority-free interactive transaction. The product adapter admits no scenario verifier effect or Integration evidence marker and retires its one launch source after the shell. Late service-readiness evidence is inherent in this authenticated Integration policy boundary. It has no independent Cargo feature or false-valued production selector. The library extends lib-bootstrap's closed product seriald/fbcond marker and disposition contract rather than duplicating either lifecycle rule. Framebuffer probe-square behavior likewise adds no rootd Cargo selector; its authenticated scenario profile and explicit fbcond/kernel fixtures fully define the evidence path. Readiness-only input and multi-provider storage now use separate signed BootConfig profiles instead of crate or rootd features. Their numeric values remain descriptive and grant no input or storage authority. The multiline interrupt fixture likewise uses the existing signed interrupt profile: only the kernel selftest remains build-selected, while rootd runs its normal profile-owned endpoint-authority verifier. COM1 admission additionally requires the exact authenticated deviced-driver/drv-serial BootConfig node; the signed profile name alone cannot select the serial row. The interrupt policy exposes process launch and terminal observation as distinct effects. It passes the exact returned process identity into the wait effect and rejects a substituted terminal identity before emitting readiness; neither descriptive value grants process authority. Dynamic bootstrap-helper and extension policy use the same split. Their authority-free plans supply only request identity, semantic role, launch flags, and expected terminal result; rootd retains the module graph, procd endpoint, staging authority, cleanup, child-endpoint mapping, and exact lifecycle transport. The initial-shell catalog contains 45 focused scenarios. Its cumulative POSIX workloads are partitioned into independently bounded mixed-list rejection, second-command lookup, pipeline state, EXIT action, caught-signal, wait isolation, and exit-teardown transcripts. Each split transcript retains zero session operations and an empty script-authority table. The manifests require both tty and rootd evidence but order markers only within their originating stream, because ttyd may drain accepted output after rootd observes process exit. All scenarios retain the repository-wide 45-second no-progress and 120-second absolute QEMU limits. After MountRoot retires Rootd's final direct kernel process-control source, the five-helper completion proof consumes only those exact lifecycle transcripts. It never requests a global kernel-resource snapshot or causes the retired source to be retained or reacquired. Resource-count comparison remains limited to pre-procd negative tests, where the required source is still owned. The component manifest pins signed rootd revision 1092330 for that runtime effect implementation, its required evidence transport through Rootd's retained send-only logd route, and exact 1,000-lifecycle execution in 250 bounded batches of at most four process/generation selectors. Rootd authenticates the complete signed helper dependency graph once and receives no per-helper capability authority. Procd invokes the kernel's closed map/relocate/seal graph operation before each start. Rootd reports one fixed progress marker after each drained batch and completion only after all exact observations. The manifest also pins signed lib-ipc revision 0dd36b4 and procd revision 1f105a0. Their Integration-only launch/observe contract returns only bounded process identities. Procd deletes the broad staging grant immediately after deriving the exact powerbox grant and deletes that narrow grant before start; it retains only the local process endpoint through successful start and drops that final alias before replying. Queued-event reclamation obligations remain bound to exact process generations. A queued event for an earlier occupant of a reused kernel PID therefore cannot destroy an unstarted helper or exhaust the bounded process arena during those lifecycle batches. Transport failure, malformed or mismatched success, and every standard non-success procd result select distinct fixed retained-logd evidence; the diagnostic carries no process identity or capability authority. Rootd's unconsumed per-role launch debug catalog is deleted rather than moved: the checked inventory now accepts only terminal and production-warning evidence that still has a consumer. The same rule removes direct module, staging, envelope, capability-transfer, and provider-metadata traces; the cleanup-negative logd-start marker remains. Rootd's procd startup-call and foundation-update adapters now receive only the endpoint authority required by their typed IPC transaction. Their 60 unconsumed status, envelope, capability, transfer, and failure markers are deleted instead of being moved into the library; exact result and response validation remains product-owned and fail-closed. Named seeding, sealing, activation, and dynamic staging retain the same exact typed validation and production warnings, but their fifteen unconsumed debug markers and telemetry-only capability queries are deleted rather than moved. Serial verification and seriald writes no longer receive kernel-log authority; their twelve unconsumed debug markers and production-dead value formatter are removed while typed peer, response, retry, and final-ready semantics remain. Kernel-root handoff parsing likewise receives only the immutable handoff bytes; thirteen unconsumed parse-detail markers are removed while all structural validation and phase-level terminal reporting remain product-owned. Runtime PCI discovery likewise receives only its exact probed endpoint. Six unconsumed transport, result, and counter markers and the kernel-log endpoint argument are removed while its fixed request identity, typed retry, yield, and terminal-result validation remain product-owned. Pre-procd graph construction, mapping, relocation, and sealing likewise receive no logging endpoint. Eleven unconsumed detail/failure markers are removed; the library-selected role-completion proof remains a separate best-effort transport after mapping succeeds, and every kernel mutation remains product-owned. Dynamic-extension and kernel-staging adapters also omit twenty-one unconsumed stage/drop/start/wait/result and mapping-detail markers. The shared exact process-completion wait receives only the procd endpoint and expected identities, not a logging endpoint; consumed procd-map and cleanup-fault evidence remains. Framebuffer verification emits each consumed event once through the reviewed debug transport; the obsolete smoke-only forwarding wrapper and its duplicate privileged write are absent without changing marker selection or order. Startup-boundary evidence now crosses the same authority-free boundary as a typed request-ID/marker value. The library owns peer, primary-control, explicit endpoint, and pager-retirement evidence selection; rootd retains capability transfer, mandatory pager source retirement, absence proof, and the explicit best-effort log transport. The library also owns the exact release-image admission policy for Integration-only evidence strings. Rootd passes only the borrowed message to that pure predicate and retains the logd or kernel-log endpoint and the entire transport effect; near-matches and product messages fail closed.

The library also owns the complete dynamic/procd negative-spawn transcript: profile and role selection, exact request fields, unsupported-map acceptance, resource-count equality, cleanup order, and evidence markers. Rootd supplies only explicit slot values and mechanical kernel/procd effects. Cleanup invokes one exact procd abort effect and three independent per-slot exact-retirement effects, retaining the first cleanup error while attempting every revocation. The trait cannot expose DROP separately from same-slot absence proof. Any failure after staged creation is cleaned up before the typed runner returns. The abort adapter already yields after its acknowledged procd reply, so the authority-free policy requests no second scheduler yield after cleanup. Evidence transport is best effort and cannot turn a proven cleanup into a runtime failure; the host marker contract still fails closed if evidence is missing. Signed Integration revision 69d08a5 defines this closed effect surface, and rootd revision 33f299d supplies its exact-disposition implementation. The component manifest now pins descendant rootd revision 249d860, which retains the phase-transition and service-effect closures introduced at 62f8f55, delegates timed's private RTC receive route, reconciles a state-matched exit that wins the procd STOP race, and records the current compiler-qualified source budget exactly. Its production boundary check emits and scans one unique object for the current invocation, so cached compiler objects can neither contaminate nor satisfy that evidence. It also selects the exact dynlinkd self-bootstrap-denial, dynamic-start, and dynamic-ready request/marker tuples for the focused profile. Rootd retains manifest parsing and unconditional rejection and only transports the selected evidence through explicit logging routes. The post-map success marker is selected there too; rootd retains graph mapping, success acceptance, failure diagnostics, and the explicit kernel-log effect. The same authority-free evidence module owns all four cumulative procd-spawn service-group START/READY plans: exact role membership, first-role selection, request identifiers, marker strings, completion order, and the descriptive dynlinkd-versus-runtime logging route choice. Rootd iterates the returned rows and performs only the named logging effect. The follow-on checkpoint module owns the ordered core lookup/time, hardware/console, and storage/VFS/loader success rows and their request IDs. For storage it accepts one descriptive proof that rootd retired its bootstrap-only blockd client plus six downstream service-presence booleans. It refuses residual blockd authority separately from any missing downstream service; no slot number, endpoint, handle, or capability enters the library. The module-requirement policy likewise accepts only closed module-presence and BootConfig-role bitsets. It owns every scenario-specific required-module set, the legacy role-to-profile priority, and exhaustive omission checks. Rootd retains authenticated module descriptors and product boot-artifact validation; the library cannot observe an address, mapping, descriptor, slot, or capability. Scenario-profile selection is now exclusively descriptive input from the authenticated BootConfig validation profile. The orchestration crate has no per-profile Cargo features and exposes no build-selected profile fallback; host-only callers use the explicit runtime profile. Loader filesystem discovery, materialized-launch isolation, and cleanup-authority confinement use distinct signed values 27, 28, and 29; their policy selectors carry no endpoint, process, or loader authority. The same library now maps every profile to a fixed-capacity ordered final execution plan. Each row carries the complete helper or extension contract, bounded stress/concurrency range, or exact dynlink/interrupt verifier profile; profiles whose proof completed earlier receive an empty plan. The plan contains no endpoint or capability, so the rootd adapter can iterate explicit effects without retaining a profile match or reconstructing request ranges. The rootd fixture builder likewise enables one rootd-integration-policy boundary for runtime test images. Initial-shell and physical-input selection are dependency features of the authority-free orchestration library; physical-input implies initial-exsh. Rootd therefore needs no matching scenario Cargo gates and reads only the library's compile-selected booleans inside its Integration-only adapter. Changing ROOTD_TEST_MODE alone cannot change rootd's Cargo feature set.

scripts/check-rootd-integration-surface.py enforces the migration boundary. Its checked inventory classifies every rootd scenario feature, profile/type, verifier or fixture function, marker string, and scenario-gated source site as move, production-validation, or delete. The helper suite proves that a new unclassified verifier fails the check. Inventory changes therefore require an explicit audit instead of silently expanding rootd's integration surface. Pinned rootd 2603439 retains six temporary RTC, storage-layout, and VFS-mount diagnostic selectors and their six rootd probe sites, while admitting their source and calls only for the exact Integration probe features. The refreshed inventory classifies the six call sites, sixteen gated definitions, their shared source gate, the six selectors, and the product adapter's fixture-named false hook as delete; the Integration adapter's private-driver selector and its focused test and the library's explicit full-runtime-transition selector are move. The authority-free scenario-completion stage mapper and its focused mapping test are also move: both consume only library-selected success evidence and are called exclusively by the Integration adapter. The seven feature-gated fully-backed pre-procd stack-policy sites are likewise move: rootd still owns every frame, mapping, pager-registration, and retirement effect, while the gated choices carry no authority. The exact current ledger is therefore 52 items: twelve move, ten production-validation, and thirty delete. These diagnostic branches select only an exit observation and receive no endpoint, object, or capability; classification restores fail-closed CI coverage without accepting them as permanent product surface. The complete runtime-transition selector additionally requires an actual KERNEL_ROOTD_TEST=runtime image, ext4 runtime storage, and the authenticated Runtime validation profile. Every other profile retains its verification-only or loader-pair transition even when compiled into the same image; legacy smoke and profile fixtures cannot acquire the complete runtime suffix from a media name. Host and library tests prove both sides of this boundary. This descendant also consumes the Integration-owned pre-memd negative-spawn schedule, so named and deviced snapshots precede Foundation process-source retirement without adding a new classified rootd surface. The pinned rootd now also owns exact-capacity, move-only lifecycle ledgers for foundation, core, and hardware children. Those product cleanup dispositions, authenticated kernel/procd teardown effects, and source-retirement funnels do not cross into the authority-free orchestration library. The exhaustive check therefore contains exactly 268 items: 255 move, 13 production-validation, and zero delete. The pinned cleanup path uses confirmed STOP terminal evidence directly and validates an exact terminal QUERY only after a lost STOP reply before consuming WAIT. It retries only empty typed transient WAIT replies with the same process/generation selector and independently proves endpoint-slot absence after every DROP attempt. Integration receives neither observation nor authority from that reconciliation; focused rootd unit tests remain its exact proof. A raw pre-acceptance NOT_FOUND on STOP, QUERY, or WAIT permits one additional identical call only after rootd proves that the selected local slot still contains exactly its canonical SEND|GRANT generic procd endpoint. Missing, weaker, substituted, or stronger authority and a repeated absence remain terminal. A later partial startup-transfer failure now aborts the staged child, then drops and proves absence of every local install grant, endpoint source, service endpoint, and published source. A source already retired at its final successful transfer is accepted only after the same proof; an uncertain proof cannot skip the remaining cleanup. The pinned rootd path also reconciles a lost procd START reply through one exact query validator shared by boot-module and ext4 launches. Only authenticated STAGED state selects abort and only authenticated RUNNING state continues startup; substituted or terminal evidence fail-stops. Started ext4 cleanup independently proves its optional published source absent after the drop attempt. Foundation, core, and hardware also follow every fixed phase-boundary source DROP with an exact local-slot absence query; lost replies are accepted only after proof, and one uncertain proof cannot skip later sources. RetireAuthority applies the same proof contract to named-resolution sources, authenticated service sources, ordinary root clients, and the private RTC routes. The attenuated query alias remains live until every queryable client is resolved and is then retired directly through the synchronous local-capability syscall. Rootd passes 308/308 default and all-feature tests with a reviewed 15,849-line, 4,616-byte production baseline. This product lifecycle logic and every authority-bearing route remain outside the Integration library; the exhaustive surface remains 298/286/12/0. MountRoot's namespace and loader-materialization source cleanup now uses the same exact contract through a transition-local injected boundary. Its focused tests prove that exact absence resolves a lost DROP reply and that proof failure cannot skip a later source. Rootd passes 310/310 test matrices with a reviewed 15,859-line, 4,616-byte baseline; the Integration surface remains unchanged. The nested one-shot RTC completion path now retires only the exact role-derived local service endpoint and requires absence proof after DROP. A lost reply is accepted only after that proof, while a substituted slot is rejected before an effect. After semantic kernel-report authority has retired, successful RTC completion is observed through rootd's already retained send-only logd route as ERIX_ROOTD:READY:RTC_PROVIDER; no kernel host-report route is reacquired. That marker is emitted only when the signed ext4 runtime suffix contains the private RTC provider. Boot-image-only authority-retirement profiles omit the entire ext4-only suffix, including the RTC provider, ttyd, powerboxd, and launchd, and therefore prove their declared cleanup sequence without inventing filesystem-runtime completion evidence. Disk-image scenarios retain coverage of the complete suffix. Rootd passes 311/311 test matrices with a reviewed 15,882-line, 4,616-byte baseline; the Integration surface remains unchanged. The StartRuntime failure funnel now has one deterministic exact-order proof over plain cleanup dispositions. Pending leases abort in reverse order, followed by started-service cleanup, authenticated-source retirement, and private-RTC retirement; an earlier failure cannot skip a later family and the first cleanup error remains authoritative. Rootd passes 312/312 test matrices with a reviewed 15,903-line, 4,616-byte baseline. No endpoint, process, source, or cleanup observation enters Integration, so the surface remains 298/286/12/0. RetireAuthority now exposes the full terminal sequence through a rootd-local descriptive injection seam: five pre-report source families, terminal status emission, and final root-client retirement. Cleanup continues after failures and retains the first error. Exit separately proves that report failure cannot skip host-report endpoint retirement. Rootd passes 314/314 test matrices with a reviewed 15,938-line, 4,616-byte baseline. No authority or cleanup observation enters Integration, so the surface remains 298/286/12/0. The pinned terminal follow-up requires each kernel-control reply to agree across syscall status, message-header result, typed response result, and operation. Final host-report responses also require zero value fields. Rootd passes 315/315 test matrices with a reviewed 15,966-line, 4,616-byte baseline. The next pinned test-only proof drives an actually malformed handoff through every terminal retirement family and Exit, and passes a rejected delegated-driver receipt directly into reverse prior-child and phase-source cleanup with first-error precedence. Rootd passes 316/316 test matrices; the production baseline and Integration surface remain 15,966/4,616/8 and 298/286/12/0. The signed selector follow-up removes rootd's last two scenario Cargo features and maps every initial-shell and physical-input fixture directly to the authority-free dependency features. The exact inventory drops those two features and six obsolete cfg sites, then adds six mechanical policy-boundary sites for a reviewed 290/278/12/0 surface. Rootd remains at 316/316 tests with a 15,968-line, 4,616-byte, eight-unsafe-block production baseline. The next dynamic-catalog slice moves all eleven Integration-only executable names, the helper/core/interrupt role family, and pre-procd launch selection; fourteen obsolete cfg surfaces disappear for an exact 276/264/12/0 ledger. Rootd's production measures and 316/316 test matrices remain unchanged. The timed-verifier adapter is then isolated behind one crate-level Integration gate instead of five item gates interleaved with production named publication. The exact inventory falls to 272/260/12/0, while rootd's production surface falls to 15,918 lines and excludes both timed response decoder types. The VFS verifier transport is subsequently isolated behind one crate-level gate. Twelve item gates become one include gate for an exact 261/249/12/0 surface. Rootd production retains only path encoding and signed-mount transport, measures 15,691 lines, and excludes seven verifier-only VFS response types without changing its binary or authority inventory. The pinned deviced final-use follow-up exhaustively retires and proves absent all four child-only public endpoint sources after their final transfers. A lost DROP reply cannot leave an ambiguous source, and one failed proof cannot skip the other independent sources. The checked Integration surface remains 261/249/12/0; rootd measures 15,703 production lines with the same 4,616-byte binary, eight unsafe blocks, and authority inventory. The downstream-consumer follow-up gives all seven retained deviced sources an immediate exact absence proof after final transfer and exhaustively disposes sources for absent optional consumers after registry sealing. The Integration surface remains 261/249/12/0; rootd measures 15,742 production lines with the same binary, unsafe count, and authority inventory. The root device-control follow-up retires the canonical one-slot SLOT_IRQ_CONTROL catalog after deviced startup with DROP plus exact absence proof. Integration remains 261/249/12/0; rootd measures 15,754 production lines with unchanged binary, unsafe count, and authority inventory. The pager fault-delivery follow-up uses the same shared disposition after its final pagerd transfer, so a lost DROP reply cannot skip exact absence proof. This removes a bespoke validator and classifies its injected product-validation seam explicitly, producing a 262/249/13/0 surface without changing rootd production measures. The dynamic staging follow-up centralizes the install-grant, endpoint-source, and service-endpoint scratch disposition across kernel and procd paths before creation and during staged-failure cleanup. Exact proof and continued cleanup remain product-owned; the 262/249/13/0 surface is unchanged while rootd measures 15,784 production lines. The loaderd filesystem-staging follow-up gives the root-local install-grant and staged-process endpoint receipts one exhaustive DROP/query disposition after installation and during preparation cleanup. No receipt authority enters the orchestration library; the surface remains 262/249/13/0 while rootd measures 15,802 production lines. The legacy procd-spawn negative fixture now applies exact DROP/query disposition to its three staging slots both before process creation and after staged abort. The library owns only the fixed order and first-error rule; its effect API names one exact retirement per slot and cannot split DROP from proof. Rootd retains every slot, capability operation, process identity, and absence query. The checked surface remains 262/249/13/0.

The library now owns time, serial, framebuffer, probe, hotplug, ACPI, driver-lifecycle, normalized-input, input-authority, physical-input, interrupt, crash-reporting, and logging evidence policy. It also owns the complete generic initial-exsh transport: launch transcript submission, TTY lifecycle and multi-PTY independence, staged exec sequencing, reply-authority auditing, bounded status polling, cleanup, outcome classification, and evidence-marker selection. Its hardware/console runner selects and orders hotplug, ACPI, serial, framebuffer, input-authority, and active-input verification, owns their boundary markers and framebuffer mirror requirement, and returns an ordered descriptive readiness result. Rootd supplies only explicit syscall, IPC, logging, and readiness-transport effects. The time verifier owns its deterministic host-only synthetic evidence source and validates exact request and operation correlation. That source is one descriptive counter with no endpoint, clock, timer, or capability; only the freestanding rootd adapter performs timed IPC. The probe verifier also owns its stateless host PCI scan and known-device evidence and rejects mismatched response request, operation, device, and policy identities before accepting it; only the freestanding rootd adapter performs probed or deviced IPC. The driver-lifecycle verifier similarly owns a two-state host model, rejects invalid transitions, and validates every start/read/stop correlation field without owning a process or endpoint. The serial-console verifier likewise owns a two-transition host model and rejects reordered readiness, peer-query, request, or payload evidence. That model performs no endpoint lookup or write; only the freestanding rootd adapter uses seriald authority, and its ordinary host path fails closed. Hardware effect methods require every endpoint, request identifier, bounded event count, and device selector explicitly, including the private ACPI endpoint returned by deviced. Rootd's adapter performs only the requested typed call and emits the library-owned diagnostic event; neither descriptive device identities nor diagnostics confer authority. Signed BootConfig generation keeps selected hardware services in one canonical ordered block: drv-acpi, drv-serial, seriald, fbcond, drv-i8042, drv-ps2-kbd, drv-ps2-mouse, inputd, drv-virtio-block, then blockd. Provider drivers precede their consumers, consumer dependencies name the selected providers explicitly, and Integration-only driver fixtures cannot enter the phase graph. Generation rejects duplicate, reordered, omitted, or interrupted hardware blocks instead of emitting a compatibility topology. Every accepted validation profile consumes an explicit runtime config and emits the same signed native-CLI substrate: an ext root mount whose authority does not exceed the attached medium, the canonical storage sequence, dynlinkd then loaderd, and the ext4 suffix of optional drv-rtc-cmos followed by mandatory ttyd, powerboxd, and launchd. Default and other read-only-media profiles sign every block-backed mount read-only; writable fixture profiles must select qemu_block_readonly=false. The profile changes verifier policy only. Mode-only generation, a FAT root, missing hardware, or omitted suffix policy fails before image construction. Focused configs may select the explicit standard-v1 service policy instead of duplicating its fixed bounded values; unknown or implicit selection fails. Rootd fixture commands enable Integration policy through direct checked rootd_integration_orchestration/<feature> dependency features; scenario-only forwarding aliases are not part of rootd's product feature table. Input effects likewise name each deviced, inputd, seriald, fbcond, ttyd, logd, and returned driver endpoint. The library owns normalized producer-identity and console-projection decisions, diagnostic-route denial, physical counter baselines, and exact trusted-control deltas; the rootd adapter retains no input producer capability and performs only those explicit observations. Interrupt effects receive only the explicit procd and logd endpoints. The library owns the exact client request, role, child-local endpoint slot, accepted terminal status, and profile-specific marker; the rootd adapter can neither discover an endpoint nor retain child authority. Crash effects likewise receive explicit procd, crashd, and optional logd endpoints. The library owns the fault-client contract, child-local endpoint slot, terminal reason, cursor/correlation checks, cooperative retry, and dynamic marker. Launch and exact terminal wait are distinct effects; the returned process identity is passed into wait and checked again before crashd scanning. Rootd returns only descriptive observations after retiring its child endpoint. The same closed catalog selects request identifiers, semantic roles, flags, child-local endpoint slots, and expected results for every bootstrap helper and lookup/time extension. Request-ID override constructors change correlation only; all other launch fields remain immutable orchestration policy. One shared bounded transcript now owns pure graph preparation followed by exact staging-slot retirement, one procd create, dependency-before-executable map steps, one relocation and seal per reported item, map evidence, install-grant retirement, start, optional probe start, and endpoint-source retirement. The effect adapter retains every graph cursor, module byte, endpoint, capability, and process-control route; returned counts and receipts are descriptive only. Its thematic cleanup policy issues one STOP at a time with a 1,024-reply bound, then validates exact QUERY and WAIT receipts before requesting endpoint drop and absence proof. Failed starts are first queried and select only exact staged abort or the same running cleanup; transport, identity, state, or revocation uncertainty invokes an explicit rootd fail-stop effect. Logging effects name separate authenticated submit and query routes, and both the kernel-log and submit routes for the optional dynamic marker. The library owns append content, required roles, response validity, cursor and timestamp monotonicity, stress sequencing, and marker selection; the adapter retains no endpoint. Trusted-terminal policy is one immutable plan covering secondary-session creation, status-route independence, session-control retirement, the exact trusted-delivery delta, and the completion marker. Rootd retains only the typed session-lifecycle adapter. Signed BootConfig driver discovery remains a production rootd validation invariant and is deliberately excluded from the scenario library. Block-storage selector translation remains production logic, while media validation does not. Rootd now admits only typed namespace enumeration, matches the signed ESP and data selectors, rejects malformed, duplicate, or aliased partition identities, and drops plus proves absence of its blockd client before mounting. Raw block reads, MBR and filesystem signatures, journal geometry, sentinel policy, and 28 storage diagnostics are gone. Blockd and the authenticated filesystem providers own those semantics. The library receives only the authority-free multiple-whole-disk observation and validates it against the signed scenario profile; rootd's product selector no longer receives a scenario expectation. The same signed profile selects one total final-verifier timing in the authority-free library. Module-backed proofs run before boot-module retirement, the storage-services proof runs only after runtime startup, and the hardware/console proof is recorded as already complete. Rootd retains all module and runtime authority and performs only the selected execution step. Pinned rootd revision 52dec12 consumes that typed result and removes its unreachable local deferral predicate. The storage-services proof now runs after runtime startup with its complete stage sequence, while the checked rootd surface contracts to 261/248/13/0 without moving authority into this crate. Pinned rootd revision fb2fd48 then deletes the separate constant-false framebuffer-deferral and runtime-serial-only readiness branches, their unused stage buffer, and duplicate assertions. Pre-logd evidence remains uniquely queued and direct framebuffer fallback writes only terminal READY. The reviewed production surface falls to 15,802 lines without changing the 4,616-byte image or any authority measure; the Integration ledger remains 261/248/13/0. Pinned rootd revision 1729fba then routes both sides of MountRoot through the same readiness dispatcher. A descriptive phase bit preserves the former trace and failure-fixture distinctions while the duplicate post-mount context and transport implementation disappear. Production falls to 15,737 active lines, and deleting three superseded cfg adapters reduces the checked ledger to 258/245/13/0 without changing authority. Pinned rootd revision 5cec30f deletes the permanently disabled eager framebuffer-cursor scan and capture path. Deferred verification continues from cursor zero in this crate, while rootd retains only the live framebuffer effect adapter. The reviewed rootd surface falls to 15,724 active lines and removal of four stale cfg surfaces reduces the ledger to 254/241/13/0; image and authority measures remain unchanged. Pinned rootd revision 6ff326c consumes the library-owned readiness disposition through a mechanical adapter and retains only the closed seriald/fbcond product policy plus all stateful transport effects. The reviewed production surface falls to 15,578 lines, and replacing six older cfg surfaces with five exact boundaries reduces the ledger to 253/240/13/0. The 4,616-byte image, eight unsafe blocks, and authority inventory are unchanged. Pinned rootd revision 3f9cfcf also deletes its obsolete test-only driver-readiness catalog. Integration scenario manifests remain the authoritative positive and negative marker contracts. The cleanup removes 296 rootd Rust source lines, including one otherwise empty production include, so the reviewed production baseline is 15,577 lines; the 253/240/13/0 ledger, 4,616-byte image, eight unsafe blocks, runtime behavior, and authority are unchanged. The orchestration library owns the exact observable ERIX_ROOTD:TRACE:VFS:* strings emitted by its VFS verifier plans. Rootd receives those strings as authority-free data and performs only the explicit kernel-log effect; it no longer rewrites an Integration-only debug namespace into the observable trace namespace. Pinned rootd revision 554b471 deletes the unconsumed pre-mount READY_APPEND_CURRENT_* trace branches and that namespace rewrite. The reviewed production baseline falls from 15,577 to 15,500 Rust lines while the release image remains 4,616 bytes and the unsafe count remains eight. Replacing two deleted trace-adapter rows with four exact mechanical cfg boundaries makes the checked ledger 255/242/13/0; authority and runtime behavior are unchanged. The library also classifies its exact TRACE, READYTRACE, and DBG diagnostic namespaces from borrowed text only. Rootd retains the enable flags and every kernel-log/logd effect; no endpoint, capability, or buffer crosses the classification boundary. Pinned rootd revision 3adb9b3 consumes that classification mechanically and removes the broad diagnostic-prefix parsers from production. The reviewed baseline falls from 15,500 to 15,479 Rust lines while the 4,616-byte image, eight unsafe blocks, runtime behavior, and authority remain unchanged. Three exact mechanical cfg boundaries replace two stale marker-prefix rows, yielding the checked 256/243/13/0 ledger. Canonical named-publication names are product capability policy, not scenario policy. Lib-capabi now binds names to its closed pagerd/timed/irqd target set, so this library deletes its wider eight-role duplicate catalog. Signed rootd revision bd57279 consumes that mapping while retaining explicit named seed, response-validation, sealing, and endpoint effects. Its reviewed production baseline falls from 15,479 to 15,441 Rust lines; the image and unsafe count stay unchanged. Removing three obsolete scenario-policy cfg rows yields the checked 253/240/13/0 ledger. Signed rootd revision 7aed97d next removes validation-profile control over named seeding/activation and deviced registry seeding. Those product paths now follow only signed BootConfig publication flags, canonical target scopes, and driver-policy rows. Its reviewed baseline falls from 15,441 to 15,435 lines; three stale cfg rows leave the checked ledger at 250/237/13/0 while image, unsafe, runtime, and authority measures remain unchanged. Probe verification can consume an already product-triggered, exactly correlated discovery response. The library then performs only its explicit read-last-scan and per-device evidence effects; it neither repeats discovery nor receives the probed endpoint used by rootd for the product trigger. The complete IRQD fixture plan is selected here as descriptive admission, request-correlation, timer, and optional serial data. Rootd supplies only the descriptive fact that its authenticated BootConfig contains the exact deviced-driver/drv-serial node; this library combines that fact with the IRQ profile gate. Rootd retains the IRQD endpoint and performs each exact seed, seal, and unmask IPC with fail-closed reply validation. Signed rootd revision 2ad27f2 introduces this binding and keeps the 4,616-byte product image, eight unsafe blocks, and every authority inventory unchanged. Signed rootd revision d930064 now performs that product trigger solely from signed delegated-driver rows in every runtime validation profile and forwards only the correlated descriptive receipt. Exchanging two obsolete profile selectors for two mechanical forwarding sites keeps the checked ledger at 250/237/13/0 and leaves rootd's 15,435-line production baseline, 4,616-byte image, unsafe count, runtime authority, and syscall set unchanged. Signed rootd revision 3c5c0eb consumes the library-owned complete IRQ row slice for both seeding and unmasking, deleting its serial-profile selector and duplicate optional-row branches. The checked ledger falls to 249/236/13/0 and the reviewed source surface to 15,413 lines; the 4,616-byte image, eight unsafe blocks, authority, and syscall inventories remain unchanged. Signed Integration revisions 04f4219 and c972697 complete that plan with fixture admission and checked per-row request correlations. Signed rootd revision a7d0eb7 removes all three local IRQ fixture request constants and consumes only the typed plan. The exact ledger falls to 246/233/13/0 and the reviewed surface to 15,412 lines; rootd passes 316 default and 315 all-feature tests while the orchestration crate remains at 248 and 249. Signed Integration revision 2f9c639 next owns the exact descriptive full and legacy StartFoundation retirement slices. Signed rootd revision aec42c2 consumes the selected slice mechanically while retaining every capability DROP, absence proof, and failure disposition. Exchanging two obsolete local policy sites for three mechanical cfg sites yields an exact 247/234/13/0 ledger; rootd's reviewed surface is 15,411 lines, its image remains 4,616 bytes, and the orchestration crate passes 249 default and 250 all-feature tests. Signed Integration revision 64b8ecf then constructs every exact loader discover/launch request and intentionally malformed discovery body. Signed rootd revision b00d3e3 consumes those values mechanically and deletes its three request builders plus duplicate tests. Rootd's loader adapter files total 249 lines, down by 110 source lines; it passes 313 default and 312 all-feature tests, while the orchestration crate passes 250 and 251. The exact ledger stays 247/234/13/0 and all production measures remain unchanged. Signed rootd revision 211247b next deletes the unconsumed target-only hardware debug, numeric, and lifecycle-marker mirrors. Probe, hotplug, ACPI, and driver adapters no longer receive a kernel-log endpoint; every authenticated service effect and evidence check remains intact. Rootd removes 102 Rust lines and passes 313 default and 312 all-feature tests. Replacing four obsolete transport cfg rows with two mechanical enable-state rows reconciles the ledger to 245/232/13/0; every production measure remains unchanged. Signed Integration revision a5508d9 then owns the total final-execution action plan for every profile, including complete helper/extension contracts, bounded stress and lookup ranges, dynamic-bootstrap helper order, and exact dynlink/crash/interrupt profiles. Signed rootd revision 8ada277 replaces its complete per-profile match with a mechanical explicit-effect dispatcher and admits only the planned storage action after module retirement. Rootd removes 41 Rust lines and passes 313 default and 312 all-feature tests; the orchestration crate passes 253 and 254. The exact ledger is 246/233/13/0 and the 15,411-line, 4,616-byte, eight-unsafe production baseline is unchanged. Host-only service launch ordering is likewise authority-free policy. The orchestration crate owns a total profile-to-order mapping whose rows contain only signed service roles and rootd report-stage codes. Its bounded 4--23-row plans preserve foundation order, console adjacency, and storage/dynlink tails; rootd must still validate and execute every row through its own BootConfig and service authority. Signed Integration revision 558aba1 and signed rootd revision de54855 complete that split. Rootd deletes 811 net Rust lines, passes 313 default and 312 all-feature tests, and leaves its 15,411-line, 4,616-byte, eight-unsafe production baseline unchanged. The orchestration crate passes 256 and 257 tests, and the reconciled surface ledger remains 246/233/13/0. Signed Integration revision e850a65 then makes the legacy DynlinkPreProcd exception explicit in the authority-free Foundation plan as one optional process-source number beside the immediately retired slots. Signed rootd revision e9e1d1a accepts only the canonical process-control slot, carries it through move-only Core, Hardware, and MountRoot authority states, and drops and proves it absent immediately after the final direct storage launch and before named resolution or runtime staging. Every earlier phase failure independently attempts the same retirement; a lost DROP reply is accepted only after exact absence proof, while failed proof preserves the state for retry and prevents the success transition. Rootd passes 318 default and 317 all-feature tests at a reviewed 15,402 production lines, 4,616 bytes, and eight unsafe blocks. Classifying the 22 newly explicit adapters produces the exact 268/255/13/0 ledger; the orchestration crate remains at 256 and 257 tests. Signed lib-capabi revision d41f0c9 next completes the shared final-use catalog at 30 source-to-final-consumer entries, including the four deviced-final and seven later deviced-consumer sources, without granting transfer authority. Signed rootd revision e95326b consumes the catalog only after exact route validation and installation, retains its local DROP and absence-proof effects, and uses the same rows for absent optional consumers, including blockd. Rootd passes 317/316 tests and its production baseline falls to 15,280 lines while the 4,616-byte image, eight unsafe blocks, and all other measured inventories remain unchanged. No cfg site changes, so the audited Integration ledger remains exactly 268/255/13/0. Signed rootd revision c93b402 then admits all 21 wholly Integration-only effect-adapter files through one guarded integration_adapters.rs include. This replaces 20 scattered crate-level cfg sites and excludes scenario_policy.rs from release compiler inputs without moving any endpoint or capability effect out of rootd. The checked surface contracts to 248/235/13/0, and the release baseline falls one non-effectful include line to 15,279. Rootd retains 317/316 tests, a 4,616-byte image, eight unsafe blocks, and unchanged dependency, syscall, decoder, stage, and authority inventories. Signed rootd follow-up f6785f3 folds eight nested hardware, console, dynamic-launch, monitoring, negative-spawn, and VFS-marker adapter includes into that same boundary. All 29 wholly Integration-only adapter files now have one admission point, the exact checked surface contracts again to 240/227/13/0, and the reviewed release baseline falls to 15,269 lines. Rootd retains the same 317/316 tests, image size, unsafe count, and authority measures. Signed rootd follow-up 2d26e5c moves integration_policy.rs behind the same gate as the thirtieth wholly Integration-only adapter file. Only its compile-time initial-shell source-retention result remains in the common mode adapter; production fixes it to false and retires the launchd source immediately. The exact surface contracts to 238/225/13/0 and the reviewed release baseline falls to 15,268 lines without changing any authority measure. Signed rootd follow-up b19b348 adds the thirty-first wholly Integration-only adapter by consolidating the legacy retained process-control exception's Foundation, Core, Hardware, failed-phase, and MountRoot effect implementations. The adapter is absent from production compiler inputs, and production retains no exception state or authority. Eight superseded cfg rows leave the exact surface at 230/217/13/0 while the 15,268-line baseline and every authority measure remain unchanged. Signed lib-bootstrap revision b1dbeaf then becomes the sole product owner of the exact 29-role signed boot-store executable-name mapping. Signed rootd revision a6e531c consumes it after the Integration-only extension overlay and rejects post-mount and unassigned extension roles. This changes no cfg surface, so the exact ledger remains 230/217/13/0; removing rootd's duplicate table lowers its reviewed baseline to 15,237 lines while its 4,616-byte image and all authority measures remain unchanged. Signed lib-bootstrap revision 5da8002 next becomes the sole owner of six disjoint ordered Phase 5 service catalogs covering exactly 33 bootstrap roles. Signed rootd revision d92d41b aliases its Foundation, Core, Hardware, MountRoot storage, and StartRuntime ext4 arrays to that shared contract while retaining every sequencing and authority effect. The exact surface remains 230/217/13/0; rootd's reviewed baseline falls to 15,203 lines without changing its image or authority inventories. Signed rootd revision f6fb701 next centralizes every rootd-owned asynchronous DROP-plus-local-absence disposition in one generic primitive. Exhaustive unit coverage binds all 30 shared final-use rows to their declared consumer, admits a lost DROP reply only after exact proof, rejects uncertain proof, and confirms non-final consumers do not select retirement. The private RTC path removes one redundant query; the 230/217/13/0 surface, production baseline, image, and authority inventories remain unchanged. Signed lib-bootstrap revision c5256a2 next binds all 22 Foundation, Core, and Hardware roles to their canonical readiness report and rootd-versus-deviced launch kind. Signed rootd revision c158bb7 consumes those rows while retaining every signed dependency/subsequence check and authenticated effect. The exact surface is 228/215/13/0; rootd's reviewed baseline falls to 15,170 lines while its 4,616-byte image, eight unsafe blocks, and authority inventories stay unchanged. Signed lib-bootstrap revision 81917f9 completes that contract with the five MountRoot and six StartRuntime rows and one exact row matcher. Signed rootd revision 59558ea consumes all 33 role/readiness/launch-owner rows, proving the direct storage sequence, adjacent direct dynlinkd/loaderd pair, and selected filesystem suffix before effects. The exact surface remains 228/215/13/0; rootd passes 321/320 tests at a reviewed 15,176 lines and unchanged 4,616-byte, eight-unsafe-block, and authority measures. Signed lib-bootstrap revisions 2b4824a and a1011d6 then own exact product seriald/fbcond marker selection, borrowed-text membership, and readiness disposition. This library reuses that type, deletes its lifecycle duplication, and proves every product mode and endpoint combination remains exact; signed rootd revisions bf722de and 43ada27 delete the local record, field-copy adapter, product matrix, marker match, release-filter literals, and four cfg sites while retaining every effect. The surface falls to 222/211/11/0 and rootd's reviewed baseline to 15,147 lines; image, unsafe, and authority measures remain unchanged. Signed rootd revision 3c22778 then centralizes Integration-smoke selection in one mode helper. Product builds receive a compile-time false result, while Integration builds read the authenticated scenario fact. Entry, logging, and readiness modules remove three positive/complement cfg pairs. The surface falls to 218/207/11/0 and rootd's reviewed baseline to 15,141 lines; all other measures remain fixed. Signed rootd revision b51c0d4 next moves the hardware-console runtime-mode and framebuffer-cursor state, readiness observation, and verifier invocation into one typed context inside the existing Integration-only adapter boundary. Release-active bootstrap and hardware-phase code retain only one opaque guarded crossing, and product compilation admits no context type or Integration effect. The exact surface contracts to 215/204/11/0 while rootd's 15,141-line, 4,616-byte, eight-unsafe-block, and authority baselines remain fixed. Signed rootd revision a9fbd8f next consolidates build-specific bootstrap policy behind two complementary compile boundaries. Integration mode facts, module/profile projection, endpoint requirements, and terminal override live in the existing Integration adapter; product Foundation, Core, and Hardware retirement implementations live in one product adapter. Semantic phases call uniform methods without scattered positive/complement branches. The exact surface contracts to 197/186/11/0 and rootd's reviewed baseline to 15,139 lines; its 4,616-byte image, eight unsafe blocks, and authority measures remain fixed. Signed rootd revision 8aa37ab next removes Integration-only module-name parsing from the common handoff path. Its build-gated adapter owns the ten exact fixture names, two aliases, type/required-flag checks, duplicate rejection, and descriptor-free presence projection. Product rootd recognizes none of that catalog and stores no fixture state; the release-object gate rejects seven distinctive literals. The exhaustive surface contracts to 196/185/11/0 and the reviewed rootd baseline falls to 15,097 lines with binary and authority measures fixed. Signed rootd revision 00c8d04 then places the remaining product mode identity, constants, module and endpoint validation, and host launch selection inside the product adapter, while the complementary aliases and launch order remain inside the Integration adapter. Common handoff, required-module, and type modules contain no Integration feature branch, the obsolete mode.rs is deleted, and the product presence value is zero-sized. The source regression gate rejects restoration. Thirteen stale cfg rows disappear, contracting the exhaustive surface to 183/172/11/0 and the reviewed rootd baseline to 15,095 lines without changing runtime effects or authority. Signed rootd revision c903739 next moves validation-profile decoding, host profile encoding, target terminal override selection, and the last Integration-only pre-module failure code behind the same adapters. Product accepts only the signed runtime profile and its terminal hook is a no-op; Integration owns its closed profile and override mappings. The four newly cleaned common modules are source-gated, and six stale cfg rows disappear, contracting the exhaustive surface to 177/166/11/0 and the reviewed rootd baseline to 15,082 lines without changing runtime effects or authority. Signed rootd revision 9e628bf then moves release-message admission, boot-log suppression, stage-marker lookup, ready-stamp disposition, and final-route choice behind the same complementary adapters. Endpoint-bearing logging and ready-stamp transports remain explicit in rootd but choose no product-versus- scenario policy. The source gate preserves that boundary. Eight stale cfg rows disappear, contracting the exhaustive surface to 169/158/11/0 and the reviewed rootd baseline to 15,061 lines without changing runtime effects or authority. Signed rootd revision a80ac51 next moves the remaining Integration live-marker, routed-evidence, marker-flag, and debug/trace logging effects into a dedicated 103-line adapter. Every endpoint and request identifier remains explicit; the shared request-ID hash used by product terminal status carries no build branch. Common logging is now Integration feature-free and source-gated. Eight stale cfg rows disappear, contracting the exhaustive surface to 161/150/11/0 and the compiler-qualified rootd baseline to 15,006 lines without changing runtime effects or authority. Signed rootd revision db4fef8 then moves console reads, discovery-history reads, ACPI/hotplug discovery, and driver lifecycle effects into the existing explicit Integration adapters. Product console writes, canonical probe discovery, and device reads remain with their semantic owners. Four common transport files are Integration feature-free and source-gated, and every moved effect retains explicit endpoint and request identity. Ten stale cfg rows disappear, contracting the exhaustive surface to 151/140/11/0, the compiler-qualified rootd baseline to 14,736 lines, and accepted external typed messages from 39 to 29 without changing runtime effects or authority. Signed rootd revision f54da1a removes the redundant nested Integration feature gates from initial-shell, physical-input, and loader-verification adapters that are already admitted only by integration_adapters.rs. Target/host selection, explicit endpoint inputs, and fail-closed host behavior remain unchanged. Eight stale cfg rows disappear, contracting the exhaustive surface to 143/132/11/0; the 14,736-line product baseline, 29 accepted typed messages, image size, and all authority and runtime-effect measures remain fixed. Signed rootd revision fab1395 next moves IRQ fixture seed, seal, and mask effects into a dedicated 203-line Integration adapter behind the same boundary. The 183-line common hardware-seed module retains only product named/deviced registry behavior and is feature-free and source-gated. Explicit IRQD endpoints, request correlations, reply checks, and seed/seal/unmask order stay fixed. Nine stale cfg rows disappear, yielding 134/123/11/0, a 14,577-line product baseline, and 26 rather than 29 accepted typed messages; image, runtime-effect, and authority measures remain fixed. Signed rootd revision ead5b85 then isolates Integration-specific process-completion retry, terminal-state, and host-fixture policy in a 70-line adapter. The 156-line common procd host module remains feature-free and retains the shared WAIT transport required by product cleanup and explicit dynamic effects. Endpoint/request correlation, yielding, and failure behavior remain unchanged. Two stale cfg rows disappear, yielding 132/121/11/0 and a 14,517-line product baseline while accepted messages and all other measures stay fixed. Signed rootd revision b26e576 then moves the target-only hexadecimal formatter and kernel boot-log effect used by VFS evidence into the 148-line Integration logging adapter. Product capability operations remain in the 737-line feature-free common kernel-control IPC module. The explicit endpoint, prefix checks, rendering, and best-effort disposition stay fixed. One stale cfg row disappears, yielding 131/120/11/0 and a 14,478-line product baseline while accepted messages and all other measures remain fixed. Signed rootd revision cb78a72 next moves forced service-start failure selection into the Integration adapter's authority-free postcheck. The common procd transport remains responsible for its explicit endpoint, authenticated request, correlated reply, role/status validation, and host fixture behavior, and is now feature-free and source-gated. One stale cfg row disappears, yielding 130/119/11/0; the explicit product postcheck raises the reviewed baseline to 14,481 lines while the 4,616-byte image, 26 accepted messages, eight unsafe blocks, runtime effects, and authority remain fixed. Signed rootd revision 2d27e87 then moves post-start cleanup evidence into the 155-line Integration logging adapter. The 986-line feature-free, source-gated common cleanup module retains process kill, terminal wait, destruction, endpoint retirement, and fail-stop cleanup. Product builds compile a capability-free no-op disposition; Integration builds preserve the explicit kernel-log endpoint, marker, and best-effort behavior. One stale cfg row disappears, yielding 129/118/11/0 and a 14,480-line product baseline while the image, accepted messages, unsafe blocks, runtime effects, and authority remain fixed. Signed rootd revision 398987b next replaces three common conditional retained process-source fields with a build-selected phase state. Product state is zero-sized; only rootd's Integration adapter owns and disposes the retained pre-procd process source, and no endpoint or capability enters this library. Foundation and core token definitions are feature-free and source-gated; the hardware token loses this authority branch while retaining unrelated scenario validation. Three stale cfg rows disappear, yielding 126/115/11/0 and a 14,481-line product source baseline while the 4,616-byte image, 26 accepted messages, eight unsafe blocks, ten dependencies, five syscalls, runtime effects, and authority inventory remain fixed. Signed rootd revision 7c07380 then routes the retained process source's final MountRoot use, failure cleanup, and success proof through rootd-local build-selected adapters. Its launchd-source disposition moves into the Integration-only StartRuntime adapter; product state is zero-sized, and no capability, source token, retirement effect, or authority enters this library. The common MountRoot phase is feature-free and source-gated. Five audited cfg rows disappear, yielding 121/110/11/0 and a 14,500-line product source baseline while the 4,616-byte image and every other runtime and authority measure remain fixed. Pinned rootd revision 673564e carries that source with the prepared dynlinkd/loaderd pair only for the signed DynlinkPreProcd fixture. Its verification transition aborts the pair before exact retirement, while runtime-starting transitions reject and clean up unexpected retention. Runtime authority cannot contain the source, and no capability enters this library. Signed rootd revision 221b80a then replaces ValidateHandoff's conditional CPU count and intake-marker branch with build-selected rootd policy state. Product state is zero-sized and capability-free; only rootd's Integration adapter retains the descriptive count required by its multicore scenario and emits the conditional marker through the explicit kernel-log route. The common validation phase remains structurally authoritative but is feature-free and source-gated; no state, endpoint, or effect enters this library. Four audited cfg rows disappear, yielding 117/106/11/0 and a 14,515-line product source baseline while the 4,616-byte image and every other runtime and authority measure remain fixed. Signed rootd revision b9dd2bd then replaces StartHardware's conditional context, construction, readiness observation, and verifier call with one build-selected policy state. Product state is zero-sized and capability-free; only rootd's Integration adapter retains the framebuffer evidence cursor, performs hardware-console verification through explicit service routes, and borrows the live pre-retirement hardware authority token. The common hardware phase is feature-free and source-gated; no state, endpoint, token, or effect enters this library. Six audited cfg rows disappear, yielding 111/100/11/0 and a 14,550-line product source baseline while the 4,616-byte image and every other runtime and authority measure remain fixed. Signed rootd revision d6616fd then replaces MountRoot block-storage completion's conditional mode parameter and provider-evidence branches with one build-selected policy state. Product state is zero-sized and capability-free; only rootd's Integration adapter retains the signed scenario profile and validates the descriptive multiple-whole-disk observation. Device endpoints, namespace selection, blockd-source retirement, filesystem mounting, and all authority effects remain in rootd; no endpoint, device identity, or authority enters this library. The common storage module is feature-free and source-gated. Four audited cfg rows disappear, yielding 107/96/11/0 and a 14,566-line product source baseline while the 4,616-byte image and every other runtime and authority measure remain fixed. Signed rootd revisions b4fac9f and cbd2ec2 then replace BootConfig post-node finalization's conditional scenario state and IRQ fixture branch with one build-selected policy state. Product state is zero-sized and capability-free; only rootd's Integration adapter retains the signed scenario profile and selects this library's authority-free IRQ fixture plan. The IRQD endpoint, ordered seed/seal/unmask effects, request correlation, reply validation, and failure mapping remain in rootd; no endpoint or authority enters this library. The common finalizer is feature-free and source-gated. Two audited cfg rows disappear, yielding 105/94/11/0 and a 14,581-line product source baseline while the 4,616-byte image and every other runtime and authority measure remain fixed. The pinned rootd now routes startup-cap installation and direct-launch observations through one build-selected policy state. Product state is zero-sized and endpoint-free; only the Integration adapter retains explicit kernel-log and logd slots, consumes this library's authority-free route and evidence selections, rejects substituted routes before delegation, and emits startup-peer, logd-begin, pager-drop, and control-route evidence. Capability installation, retirement, exact absence proof, and cleanup remain in rootd. Seventeen audited cfg rows disappear, yielding 88/77/11/0 and a 14,579-line product source baseline while the 4,616-byte image and every other runtime and authority measure remain fixed. Signed rootd revision 6c96849 next replaces signed-BootConfig VFS smoke execution's two conditional common branches with a build-selected compile adapter. Product expansion evaluates and retains no endpoint arguments. Only rootd's Integration adapter selects this library's authority-free storage or memory plan and invokes explicit rootd-local VFS and logging effects; filesystem mounting, the live VFS endpoint, and readiness emission remain in rootd. Common vfs_bootcfg.rs is Integration feature-free and source-gated. The two stale cfg rows disappear, yielding 86/75/11/0 and a reviewed 14,581-line product source baseline. The 4,616-byte image and every other runtime and authority measure remain fixed. Signed rootd revision 738afec next moves pre-procd target naming, legacy kernel-launch selection, readiness and role evidence, deliberate cleanup-fault hooks, and probe-start transport behind the build-selected adapter boundary. Product expansion admits only signed product executable names and the procd kernel path; its evidence and fault macros do not evaluate or retain endpoint arguments. Only rootd's Integration adapter consumes this library's authority-free selections, while dynamic mapping, cleanup, endpoint effects, and capability retirement remain rootd-local. Common dynlink_pre_procd.rs and launch_runtime.rs are Integration feature-free and source-gated. Eleven stale cfg rows disappear, yielding 75/64/11/0 and a reviewed 14,524-line product source baseline. The 4,616-byte image and every other runtime and authority measure remain fixed. Signed rootd revision ab91a71 then moves dynlinkd denial, negative-spawn, map, START, READY, log-routing, and singleton-marker evidence behind a dedicated build-selected adapter. Product macros do not evaluate endpoint arguments; only the Integration adapter consumes this library's descriptive evidence and invokes explicit rootd log effects. Common dynlink_support.rs is Integration feature-free, and common dynlink_procd_spawn.rs has no orchestration-library reference or evidence transport. Its four remaining classified sites are granular probe and relocation effects. Nineteen stale cfg rows disappear, yielding 56/45/11/0 and a reviewed 14,476-line product baseline. The 4,616-byte image and every other runtime and authority measure remain fixed. Signed rootd revision 36dc133 next moves the last four per-step fixture helpers into its 769-line Integration-only dynamic-launch effect adapter: lazy probe-page derivation, relocation counting, one exact relocation call, and one exact object-seal call. Authority-bearing effects still require the explicit procd endpoint and correlated request/process/generation identity; this library receives only descriptive observations. Common dynlink_procd_spawn.rs is Integration feature-free and source-gated while retaining the product whole-graph path. Four stale cfg rows disappear, yielding 52/41/11/0 and a reviewed 14,358-line product baseline. The 4,616-byte image and every other runtime and authority measure remain fixed. Dynamic cleanup now carries that same exact process/generation identity into its terminal-wait effect. This prevents a root-visible event for another process from being consumed during reconciliation without giving the authority-free policy library an endpoint or capability. Signed rootd revision d3500f6 then moves startup peer-fault selection and undeclared-peer injection into its Integration-only startup-capability adapter. Common startup-transfer and authenticated route-plan code retains explicit transfer-table effects behind build-selected macros; product expansion neither evaluates fixture inputs nor constructs undeclared transfers. Both common files are feature-free and source-gated. Twenty stale cfg rows disappear, yielding 32/21/11/0 and a reviewed 14,352-line product baseline. The 4,616-byte image and every other runtime and authority measure remain fixed. Signed rootd revision 7785d28 next moves whole-bootstrap readiness routing, pre/post-runtime verification, scenario timing, initial-shell/loader verification, and final debug-authority retirement into a 320-line Integration-only adapter. The 506-line common bootstrap.rs is feature-free, library-free, and source-gated; its build-selected product state is zero-sized and performs no scenario effects. Explicit endpoint and capability effects remain invocation-scoped in rootd. Seventeen stale cfg rows disappear, yielding 15/4/11/0. The explicit product compile interfaces add 98 reviewed active lines for a 14,450-line baseline; the 4,616-byte image and every other runtime and authority measure remain fixed. Signed Integration revision 1d1895a now owns the exhaustive final-execution action dispatcher and the deferred storage-only admission rule. Signed rootd revision fbf3514 implements the library effect trait with a 585-line, invocation-scoped adapter carrying only the explicit module view, service endpoints, kernel-log route, and concrete launch, wait, checkpoint, and verifier effects. No capability enters the library. Removing the stale dispatcher row yields 14/3/11/0; because rootd's execution.rs was already Integration-only, the 14,450-line product baseline, 4,616-byte image, and every authority measure remain fixed. The final audit confirms that the only remaining feature and two cfg sites are the intentional product-exclusion boundary: rootd-integration-policy links this library and selects rootd's Integration effect adapters only in explicit Integration builds, while product rootd selects its complementary authority adapter and has no orchestration dependency. Signed rootd revision 64d6912 records that invariant. Reclassification yields an exact 14/0/14/0 ledger with no remaining migration row and changes no product measure. Pinned rootd revision 117b6d6 closes its product kernel-control operation selector. Five unreferenced operations are rejected and resource snapshots are admitted only through the build-selected Integration adapter. The semantic baseline now checks exactly 42 release-active protocol operation identifiers; the rootd Integration surface remains 14/0/14/0. Pinned rootd revision bc85135 binds that compiler-derived inventory to 14 closed semantic groups. Every release operation has exactly one authenticated transport owner, semantic owner, bounded rootd sequencing role, and retirement postcondition. Assigned service routes remain distinct from scoped kernel capability plumbing and dedicated root-only effects; direct kernel process operations are temporary foundation transport for procd, not permanent rootd authority. The checker rejects additions, omissions, duplicates, owner or family drift, rootd ownership, and promotion of the temporary route while the Integration surface remains 14/0/14/0. Pinned rootd revision 66cb1c7 additionally records all 72 operation-to-source-file bindings from sanitized release compiler inputs. Moving an operation into another product module, deleting its last source site, or adding a new site is reviewed semantic drift even if the 42-operation inventory remains unchanged. Tests, comments, literals, and Integration-only adapters cannot satisfy a product source binding; the rootd Integration surface remains 14/0/14/0. Pinned rootd revision 62f8f55 upgrades that ownership contract to schema 3. Seven release-family evidence rows bind process, image, publication, driver, time, namespace, and terminal policy to their exact targeted groups. Time and terminal policy remain capability-transfer-only; image work admits only loaderd preparation plus graph-declared dynlinkd route transfer. Missing, reassigned, or widened family evidence fails rootd's product audit. Combined with Integration's exact 14/0/14/0 ledger, rootd retains no functional verifier or provider-policy row awaiting migration or deletion. Pinned rootd revision 4d90264 carries the selected process-control transport from staging through start and rollback and hides its route tag behind an opaque module boundary. Product chooses temporary kernel control only for procd; Integration may still select its declared pre-procd fixture roles behind the build-selected policy. Consumers cannot construct temporary-kernel transport, inject an unchecked delegated endpoint, re-evaluate mode/role after staging, or replace the selected procd endpoint during cleanup. Both generic kernel-control routes reject all ten temporary process operations; only the private process-transport entry point accepts them, and then only with the carried temporary route and fixed kernel endpoint. The opaque value is now move-only: effect boundaries borrow it, while lifecycle states transfer its sole ownership. Rootd's reviewed source count falls to 14,609 lines; its 42 operations, 72 source bindings, 4,616-byte image, eight unsafe blocks, and the 14/0/14/0 Integration surface remain fixed. Filesystem launch failure handling follows the same narrow boundary. The pinned rootd deletes 15 unconsumed launchd phase and loader-rejection warnings, their stable request-ID hash, and the logging inputs used only for those messages. Exact loader transport, receipt, response, process, authority-retirement, and reverse-cleanup validation remain product-owned. The reviewed production baseline is 16,230 active Rust lines, a 4,616-byte image, ten normal dependencies, eight unsafe blocks, and five direct syscall operations. The final eight specific bootstrap warning families are unconsumed as well. The pinned rootd removes their formatter, stable request IDs, and warning-only transport while preserving typed failures, terminal status, mandatory cleanup, and authority disposition. Its current baseline is 16,051 active lines with every other recorded measure unchanged. Forced-terminal fixture selection and precedence now reside in the authority-free orchestration crate as one closed enum. Signed rootd commit d3a608b retains a single mechanical success-only status mapping and removes the two per-feature branches, reducing the reviewed production baseline to 16,045 lines without changing the 4,616-byte image or any authority measure. The crate also owns the exact logd-start and post-start-cleanup evidence strings; they contain no endpoint or process identity and grant no authority. Signed rootd commit e69e330 uses them only from tests or explicit Integration builds and converges kernel- and procd-managed cleanup on one post-success effect. The production baseline is 16,039 lines; the image and authority measures are unchanged. The authority-free logging policy also owns the dynlink-procd direct-kernel suppression family used by non-smoke fixture builds; rootd supplies only the borrowed message after its own runtime/smoke decision. Signed rootd commit bfea4d3 removes the product prefix table and lowers the reviewed baseline to 16,030 lines without changing the image or authority measures. The library readiness catalog maps descriptive rootd report-stage codes to the exact 29 Integration evidence strings. It receives no bootstrap token or log route; seriald/fbcond lifecycle-control ownership remains in rootd. Signed rootd commit 1412a01 removes the other 27 product strings and lowers the reviewed baseline to 16,007 lines without changing the image or authority measures. The catalog now also returns the complete authority-free Integration readiness disposition: whether to emit, retain internally, route through logd, echo on the early kernel sink before or after append, and treat append failure as fatal. Its inputs contain only a report-stage code, runtime/release facts, and endpoint-presence booleans. Rootd remains the sole owner of endpoint slots, request identifiers, buffers, retries, ordering state, and capability effects. The same authority-free logging module selects the two post-shell verification strings from only a build-feature fact and the presence of an authenticated physical-input baseline. Rootd retains the baseline object, launch-source retirement, logging endpoint, failure handling, and marker transport. Signed library commit 2f4fd5d and rootd commit 8d52aad remove both literals from product source. The exact ledger is now 392 items: 380 move, 12 production-validation, and zero delete; the 16,007-line production baseline is unchanged because the adapter was already excluded from release builds. Signed rootd commit f133c47 then converts ten validated fixture descriptors to the same closed eight-byte presence value before handoff discovery returns. No scenario mapping address, size, or hash remains in retained rootd state. The inventory is now 390 items: 378 move, 12 production-validation, and zero delete; production measurements remain unchanged. Signed library commits 3e30ba6 and 47ff31d next replace the former multiple-provider requirement boolean with a closed descriptive evidence type and authority-free validator. Signed rootd commit 3a8345c performs identical signed-topology selection for every profile and supplies the observation only after namespace and partition selection. The ledger remains 390/378/12/0; the reviewed production baseline falls to 16,002 active lines while the 4,616-byte image and every authority measure remain unchanged. Signed orchestration commit db5cdff then moves the deterministic host-only time evidence source into the library and requires exact request/operation correlation. Signed rootd commit 1c0268c removes its duplicate synthetic clock state while retaining the real timed IPC adapter. Three stale cfg rows leave an exact 387/375/12/0 ledger; rootd falls to 15,976 active lines, while the 4,616-byte image and all authority measures remain unchanged. Signed orchestration commit 0dcae00 next owns the deterministic host hotplug insert/remove model and exact correlation checks. Signed rootd commit 5c30072 removes the atomic host state and duplicate test while preserving the real freestanding hotplug IPC adapter. Four stale cfg rows leave an exact 383/371/12/0 ledger; rootd falls to 15,873 active lines, while the image and authority inventory remain unchanged. Signed orchestration commit e810f16 then owns the fixed host ACPI scan and device evidence and checks exact request, operation, device, and policy-identity correlation. Signed rootd commit 06d9e94 removes the duplicate host replies while preserving the freestanding drv-acpi and deviced IPC adapter. Two stale cfg rows leave an exact 381/369/12/0 ledger; rootd falls to 15,835 active lines, while the image and authority inventory remain unchanged. Signed orchestration commit 6e1d223 next owns the stateless host PCI scan and known-device evidence plus exact response correlation. Signed rootd commit a85905f removes successful host probed replies, preserves target typed IPC, and makes the non-target product stub fail closed. One stale cfg row leaves an exact 380/368/12/0 ledger; rootd falls to 15,809 active lines, while the image and authority inventory remain unchanged. Signed orchestration commit 3a784bf then owns the two-state host driver lifecycle, invalid-transition rules, and exact start/read/stop correlation. Signed rootd commit 0eff7b0 removes fabricated host start/stop replies and makes the deviced lifecycle adapter, hardware observer, and debug transport target-only. Two stale cfg rows leave an exact 378/366/12/0 ledger; rootd falls to 15,779 active lines. Signed orchestration commit b2cba27 then owns the two-transition host serial-console model, and signed rootd commit a20e035 removes its fabricated successful write. The ledger remains 378/366/12/0 and rootd falls to 15,772 active lines, while the image and authority inventory remain unchanged. Signed orchestration commit 078e4fd next owns deterministic host framebuffer and normalized-input evidence as authority-free descriptive state with exact request, operation, role, payload, cursor, and marker correlation. Signed rootd commit ff65920 removes the fabricated framebuffer, serial-mirror, and input replies while retaining real target IPC and a fail-closed host framebuffer product path. Exchanging three stale transport rows for two mechanical adapters leaves an exact 377/365/12/0 ledger; rootd falls to 15,696 active lines, while the image and authority inventory remain unchanged. The library passes 209 default and 210 all-feature tests; rootd passes 281 tests in each matrix. Signed orchestration commit 9ac7403 then lowers the top-level hotplug step to the existing exact discovery and last-event verifier effects. Signed rootd commit 2e2ab6c removes the coarse verify_hotplug callback and duplicate runner while retaining one typed IPC per target effect and authority-free host delegation. Removing that final stale function row produces the exact 376/364/12/0 ledger; the production baseline remains 15,696 lines and 4,616 bytes because the adapter is Integration-only. Signed orchestration commit d90f65e next lowers the ACPI step to exact deviced lookup, driver-capability query, discovery, last-scan, and device-read effects. Signed rootd commit 368562d removes the coarse verify_acpi callback and duplicate runner; the target performs one typed operation per effect, the host delegates to the authority-free model, and unconsumed per-operation ACPI debug observations are absent. Removing the stale function row produces the exact 375/363/12/0 ledger. Production remains 15,696 lines and 4,616 bytes. Signed orchestration commit 62f2593 then lowers serial verification to exact driver-lookup, capability-query, and typed-write effects with explicit deviced and seriald routes. Signed rootd commit 7267d79 removes the coarse callback, duplicate runner, and unused IRQ-route guard; it rejects route substitution and performs one operation per effect. Removing the stale row produces the exact 374/362/12/0 ledger, with production measures unchanged. Integration passes 210 default and 211 all-feature tests; rootd passes 281 in both matrices. Signed orchestration commit c1d4345 then lowers framebuffer verification to exact peer-query, status-read, fixed-route write, optional mirror, retained-stream read, and progress-yield effects with explicit fbcond and logd routes. Signed rootd commit 27bcc1a removes the coarse callback and duplicate runner, rejects route substitution, and retains only one existing transport operation per effect. Removing the stale row produces the exact 373/361/12/0 ledger, with production measures unchanged. Integration passes 211 default and 212 all-feature tests; rootd passes 282 in both matrices. Signed orchestration commit c65279e then lowers input-authority verification to exact inputd status, three deviced lookup, denied i8042 diagnostic, and logd marker effects through a dedicated narrow trait. Signed rootd commit 7e0f9cb removes the coarse callback and duplicate partition runner, validates fixed routes, and binds the diagnostic route to the exact lookup result. Removing the stale row produces the exact 372/360/12/0 ledger, with production measures unchanged. Integration passes 212 default and 213 all-feature tests; rootd passes 283 in both matrices. Signed orchestration commit 69e4f52 then lowers active-input verification to exact deviced lookup, i8042 injection, progress, inputd status/event, and serial/fbcond projection effects through another narrow trait. Signed rootd commit ebd949e removes the coarse callback and duplicate input runner, validates every fixed route, and reuses only the i8042 route proven by the authority partition. Removing the stale row produces the exact 371/359/12/0 ledger, with production measures unchanged. Integration passes 213 default and 214 all-feature tests; rootd passes 283 in both matrices. Signed orchestration commit 1a9b0ce then makes every monotonic and wall effect receive the descriptive timed route explicitly and rejects an absent route before any effect. Signed rootd commit 9793c87 replaces the coarse time wrapper with a stateless exact-effect adapter and removes unrelated kernel-log and procd preconditions. Exchanging the stale wrapper row for the mechanical adapter row preserves the exact 371/359/12/0 ledger. The reviewed production baseline falls to 15,674 active lines while the 4,616-byte image and authority inventory remain unchanged. Integration passes 214 default and 215 all-feature tests; rootd passes 284 in both matrices. Signed orchestration commit 827f3d4 next splits interrupt-client launch from its exact terminal wait and rejects a substituted returned process identity before success evidence. Signed rootd commit 561c5e5 implements the two effects while retaining the existing dynamic launch and wait transports. The surface ledger remains 371/359/12/0 and production remains 15,674 active lines and 4,616 bytes. Integration passes 215 default and 216 all-feature tests; rootd remains at 284 tests in both matrices. The checked ledger classifies seriald/fbcond readiness, framebuffer context handoff, and the four terminal failure strings as retained product validation. They drive product lifecycle or terminal reporting and are not movable fixture policy merely because scenarios also observe them. The dynamic catalog additionally owns the eleven Integration-only executable names, the closed helper/core/interrupt launch family, and the pre-procd kernel-launch selector. These APIs consume only role numbers, the signed validation profile, and a product-supplied manifest-recognition boolean; they receive no module bytes, endpoint, process, or capability authority. The pinned production rootd also carries its own semantic-bootstrap baseline: release-active source, unsafe blocks, accepted external typed messages, direct syscalls, normal dependencies, binary size, and one reviewed authority row for each bootstrap stage. Integration does not own or weaken that product gate; its component pin makes image and VM evidence resolve the reviewed rootd surface. The same pin now carries rootd's checked bootstrap threat model. Its closed catalog covers malicious boot bytes, malformed replies, forged descriptive identities, transferred-capability confusion, partial launches, and accidental Integration inclusion; all release decoders and authority families must remain classified. Integration may supply build-gated policy to a fixture image, but it cannot add an exception to the production boundary or its failure rules. Rootd's target semantic phase contract is pinned with the same rule. Only its eight reviewed phases may exist; each authority-lineage output is a strict subset of the preceding input, and all 33 bootstrap service roles have one start phase. Integration orchestration remains outside that service catalog, so a fixture cannot insert exsh, coreutils, extop, or another ordinary program into production rootd's phase graph. The pinned schema-2 contract binds every phase to a real repository-local Rust unit test through twelve checked anchors. Its evidence classes are exactly malformed handoff, rejected delegate, lost reply, partial capability transfer, child-start failure, and cleanup failure; missing coverage, invented classes, path escape, and stale test names fail the product audit. Integration supplies no exception to the strict authority contraction or empty Exit result. The pinned StartFoundation implementation now consumes a non-copy authority token while starting exactly procd, memd, vspaced, and pagerd. Once pagerd is ready, rootd attempts every inherited RAM-allocation and root-object authority drop plus the consumed memd, vspaced, and pagerd primary-control endpoint source drop and the production process-control source drop before entering the residual bootstrap. Post-start managed cleanup retains the exact staged generation and uses only rootd's authenticated procd route; numeric process identities remain descriptive. Query effects receive both identity scalars and never a PID alone, preventing a recycled process number from redirecting test cleanup or loader visibility checks. The authority-free orchestration library owns the one descriptive legacy exception as an exact seven-slot retirement slice plus the sole retained process-source number. Rootd receives no capability object and must represent that retention in its consuming phase state, perform its final DROP, and prove exact absence itself. A lost STOP reply is accepted only after an exact role/process/generation/terminal QUERY, which must validate before the matching event is consumed. A lost endpoint DROP reply still requires an exact absence proof. Partial startup-transfer cleanup applies that same proof to every local staged-launch slot after abort, without passing those slots or outcomes to Integration. The legacy Integration-only DynlinkPreProcd fixture is the only plan that retains direct process control, while the runtime profile is test-locked against that exception. The next typed transition requires the exact selected core prefix named -> logd -> crashd -> timed -> irqd -> deviced -> probed -> hotplugd; Integration profiles may select only a leading prefix, and driver fixtures follow the complete selected core set. Rootd derives a send-only query client, then exhaustively retires its inherited time, IRQ, hotplug, platform-discovery, and transferable query sources after StartCore. StartHardware then consumes only the ten canonical hardware roles and retires their inherited discovery and device sources. MountRoot executes the signed mount, pre-stages owned dynlinkd and loaderd leases, and invokes the root-only one-shot operation that unmaps every recorded boot blob. StartRuntime starts those leases and the exact ext4 suffix while retiring each final-use endpoint source before START. The terminal transition runs exhaustive root-client cleanup, attempts one final typed status report, retires the report endpoint, and invokes process_exit instead of entering a receive loop. Kernel process exit then retires rootd's recorded receiver and clears its complete CSpace. Reverse procd cleanup and terminal fail-stop rules remain product invariants; Integration supplies no bypass or alternate mount path. If startup-envelope construction fails after a process is staged, rootd aborts that exact staged generation and independently retires its install grant, endpoint source, and service endpoint. An abort failure cannot skip another capability drop; rootd unit tests preserve this fail-closed property without making those capabilities observable to Integration. The focused subsystem-rootd-foundation-authority-retirement-positive scenario requires pagerd readiness followed in order by residual service readiness, probe completion, and final readiness. It also forbids both the retired deviced-timed and discarded best-effort foundation debug names. This proves that moving the drop point does not strand the later bootstrap without treating a diagnostic marker as proof of the individual capability removals, which remain covered by rootd's exhaustive unit tests. The focused subsystem-rootd-procd-managed-cleanup-negative scenario reaches named after the foundation boundary, starts logd, makes that service reject its startup request, and requires the correlated post-start cleanup marker before the service-failure exit. It therefore covers the live procd-managed stop path without granting the fixture a process-control endpoint or treating the PID/generation pair as authority. The focused subsystem-rootd-core-authority-retirement-positive scenario requires the canonical core readiness order, then requires device discovery, hotplug, and final readiness after the consuming transition. It composes that live post-retirement continuation proof with rootd's unit-level assertions for the exact five-slot retirement set and exhaustive cleanup; it does not expose a capability-probing route to the fixture. The phase5-semantic-bootstrap scenario group fixes those three authority transition scenarios together with the inserted-foundation contract negative as the complete focused semantic-bootstrap VM set. CI locks its exact four-file membership and dry-runs every entry. Run it with scripts/run-scenario-group.sh phase5-semantic-bootstrap; the separate complete catalog remains mandatory before Phase 5 closure. Because orchestration is an independently linked shared library, the image builder resolves the selected rootd feature closure before constructing the shared-object registry, propagates only the named dependency features into erix-rootd-integration-orchestration.so, and includes that exact set in the registry cache identity. Unknown rootd or library features fail the build instead of silently producing a default-policy fixture. The fixture builder publishes the selected registry path and manifest digest as a checked build receipt; scenario and appliance packaging reload that exact receipt only after feature selection, so an earlier default registry cannot be reused as ambient build state. Rootd smoke/runtime fixtures load the receipt even when their scenario-level prebuilt option began as disabled, because fixture construction promotes those images to required dynamic consumption internally. Loader policy owns the ABI self-check and the complete filesystem-discovery, ELF rejection, materialized-child isolation, and five-boundary cleanup sequences. Every effect names its loaderd, procd, kernel-log, and logd route, request identifier, and path explicitly. Rootd only encodes or submits that request and returns a typed response; the library alone chooses the final continue or expected fail-stop disposition. Core VFS I/O policy owns five disjoint plans for the memory root, ESP, data root, indexed-directory proof, and volatile /tmp proof. Each plan fixes its paths, request range, payload, operation order, response expectations, cleanup order, and trace evidence. Effects name the exact vfsd namespace session and kernel-log route on every call; the library cannot discover or retain either capability. For signed BootConfig storage mounts, the library also inspects the validated descriptive mount table and selects the volatile /tmp plan only when that exact path is backed by the memory provider; rootd supplies the table and executes the selected plan without retaining scenario expectations. The complete memory pipeline is instantiated from matching core-I/O and extended-API plans, including a /tmp/api namespace, so signed read-only / plus writable memory-backed /tmp topology cannot accidentally issue mutating smoke operations against the root filesystem. FAT and ext truncate verification uses a shared 22-operation policy with two immutable plans. The library fixes each file path, disjoint request range, fill byte, shrink and growth sizes, zero-filled read evidence, and trace behavior; rootd supplies only explicit open, write, truncate, stat, read, close, and kernel-log effects. The ext sparse policy reuses that bounded effect surface while owning both paths, the write-past-end offset and tail, zero-hole and tail reads, sparse truncation evidence, its disjoint request range, and its trace. FAT, exFAT, and ext metadata verification adds only explicitly addressed set-metadata and path-status effects to the same file boundary. The library owns host and created-file expectations, timestamp normalization, mode and ownership changes, filesystem flags, immutable denial, exact request order, and traces; rootd selects one immutable plan and retains no route for the library. FAT namespace verification owns the optional lowercase host fixture, bounded directory enumeration, persistent payloads, file and directory replacement, and nonempty-directory, type-mismatch, and descendant-cycle denials. Its effects name the VFS route explicitly for every raw stat, directory read, path-status, and two-path operation. The extended VFS policy owns its fourteen-operation cross-API transcript, including root and signed /tmp path plans, payload, request identifiers, truncate size, link denial, metadata/stat values, cleanup order, and traces. Effects receive the VFS and kernel-log routes explicitly and retain neither. The ext rename policy owns overwrite and cross-directory moves, symlink and device identity, tree and HTree moves, cycle and nonempty-directory denials, prefix evidence, and the complete request sequence. Its effects receive the VFS route explicitly and return only typed observations. The encrypted ext casefold policy owns its optional fixture, lowercase lookup, payload, case-preserving directory entry, end-of-stream evidence, and exact request sequence behind explicitly supplied raw-stat and directory-read effects. The ext link policy owns fast/slow symlink evidence, hard-link counts, special inode modes, denial cases, created-link and persistent-file sequencing, cleanup, and diagnostics. Every typed effect receives the VFS or kernel-log route explicitly. Persistent-media plans own FAT/ext host markers, read-only and ext-only profiles, created markers, indexed-directory evidence, large-file samples and sizes, payloads, diagnostics, and request sequencing. The typed dispatcher invokes those immutable plans over the shared explicit file effects; rootd has no dedicated persistent-plan adapter. VFS completion-marker policy is library-owned as one ordered transcript: a focused profile emits only its selected evidence, while the baseline emits FAT truncate, ext-link, and ext-rename evidence followed by encrypted-casefold evidence only when that optional proof ran. Rootd's adapter iterates the plan over the explicit logd route and chooses no marker or ordering. The encompassing memory, read-only, FAT/ext, and verity pipeline order is library-owned as typed VfsPipelineStep slices too. The baseline fixes all fifteen nested plans and completion placement; each focused profile fixes one proof followed by its completion transcript. These steps contain descriptive plans and markers only, so rootd remains the sole holder of the explicitly supplied VFS, kernel-log, and logd routes. Its 253-line dispatcher makes no scenario-selection or expected-value decision and centralizes verifier-error mapping. Ten redundant high-level verifier/plan wrapper families and the dedicated persistent adapter are gone. Together with the nine prior selector files and four duplicated entries, the VFS split removes 387 rootd source lines. Dynamic-link fixture constants are library-owned too: the exact dynamically materialized rootd-intake marker, six named-service negative-selftest diagnostics, and the zero optional-spawn-flags policy. Rootd still performs every kernel-log and procd effect explicitly. Its two dedicated policy files are deleted and the mixed marker adapter contains production diagnostics only, removing another 31 rootd Rust lines.

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.

Deterministic VM Test Contract (Current)

Scenario-driven VM tests are grouped as:

  • full-system normal run
  • subsystem positive run
  • subsystem negative run
  • targeted scenario groups under tests/scenario-groups, including exact-entry-grants for one-shot receiver-retirement replay and retained- parent selector-race proofs, multi-block-provider for two independently discovered virtio-block PCI functions, location-derived physical identities, cursor-driven provider traversal, and successful GPT-backed storage through the second provider, ram-allocator-domain for one exact manage-only capability spanning every authenticated usable extent, atomic RAM-frame backing, non-power-of-two page alignment, alias lifetime, exact final-cap reclamation, and range reuse, host-report-authority for the root-only endpoint and rejected ambient syscall proof, fs-compliance-matrix for the cross-filesystem compliance matrix smoke gate, fs-cross-api for the expanded VFS rename/truncate/symlink/readlink, hard-link denial, and metadata-update verifier and fat-metadata for focused FAT32 timestamp/attribute stat and mutation checks and exfat-metadata for focused exFAT primary-entry timestamp/attribute stat and mutation checks and exfat-entry-types for focused exFAT Volume Label/GUID, benign vendor, TexFAT padding, and malformed entry-type checks and exfat-rename for focused exFAT file and empty-directory replacement checks with host fsck.exfat and fat-truncate for FAT12/FAT16/FAT32 truncate shrink/grow media checks and ext-links for ext2/ext3/ext4 symlink, hard-link, and special-inode metadata verification and ext-rename for ext2/ext3/ext4 rename, overwrite, directory-move, and HTree rename verification and ext-truncate for ext2/ext3/ext4 regular-file truncate shrink/grow media checks and ext-sparse for ext4 write-past-EOF sparse-hole and truncate-hole media checks and ext-metadata for ext2/ext3/ext4 inode metadata stat and mutation media checks and ext-geometry-boundaries for inconsistent ext2/ext3 block geometry plus format-valid 1,024-byte ext4 inode coverage and ext-advanced-corpus-maintenance for advanced ext corpus maintenance across fast-commit indexed directories, sparse/unwritten extents, metadata mutation checks, legacy fscrypt v1, fsverity built-in signature policy, and large-inode metadata preservation and ext-xattr-policy for ext2/ext4 xattr and POSIX ACL preservation plus malformed xattr fail-closed checks with mandatory host debugfs/e2fsck -fn and optional getfattr/getfacl projection when FUSE is available. The FUSE projection retries a normal unmount and then lazy-detaches so a transient busy mount cannot poison scenario cleanup. vfs-memory-provider-rename covers the memory-provider ABI and startup-peer rename path.

Runtime and appliance scenarios also forbid the direct ERIX_DRV_SERIAL:PROVIDER_REGISTERED driver debug marker; the public serial readiness surface in dev/runtime fixture boots is ERIX_DEVICED:READY:DRV_SERIAL, and dev runtime framebuffer output receives the configured ERIX_DEVICED:READY:* driver startup set through logd's fbcond-only mirror path. Release runtime images suppress every ready stamp, including the development-only final ERIX_ROOTD:READY. Committed dev/release runtime TOML mounts /boot from the ESP as read-only FAT, and the dynlink image closure check rejects every non-bootloader executable that is not a dynamic artifact. The fixture policy keeps that production authority boundary intact: only positive FAT-mutation scenarios select a signed writable test policy, with distinct runtime.dev.storage-writable-fat.toml and runtime.dev.storage-writable-exfat.toml provider kinds. Host validation rejects an omitted or mismatched selection and an unrelated scenario that retains either writable mount. Verity, read-only, and ext-only scenarios therefore receive no FAT-family mutation authority. It also rechecks every staged VM service fixture as a PIE ET_DYN artifact after it is copied into the bootloader fixture directory. The pinned rootd requires serial and direct framebuffer READY writes to report a byte count exactly equal to the requested length; partial and over-reported completion cannot satisfy the visibility barrier. The authority-free Integration verifier applies the same exact-count rule, so host-side scenario evidence cannot bless a response that the product runtime rejects. Pinned logd applies the same exact nonempty count rule to its seriald and fbcond mirror transports, preserving replay work on short or over-reported success evidence. The encrypted/casefold VFS proof likewise rejects a read length larger than its exact bounded request, binds EOF and next offset, and closes the opened file or directory handle after completed or failed reads. Cleanup failure takes precedence over the earlier evidence or transport disposition. The ext-rename proof applies exact length and next-offset framing to its fixed prefix reads and closes the opened handle after either a completed read or a transport error; cleanup failure takes precedence. The fixture builder compiles the kernel, rootd, services, drivers, and test helpers directly as dynamic artifacts; it does not create fixed-address or static precursor executables. Bootloader remains the sole static exception. Host-side filesystem evidence checks capture debugfs/dumpe2fs output before marker matching so pipefail/SIGPIPE behavior cannot hide or invent runtime-image evidence. scripts/run-ci-vm-scenarios.sh executes a committed scenario list and shards it across private worker workspaces. Blank lines and lines whose first non-whitespace character is # are list metadata and are never scheduled as scenario paths. Each worker is extracted from the exact HEAD^{commit} archive and verifies every tracked blob against that commit's Git tree before any scenario can run. Before copying prepared components, the runner also verifies every manifest-pinned checkout against its exact commit; stale prepared state fails with a clone-components.sh recovery instruction instead of silently testing an older runtime. Each private worker also exposes its verified archived repository as the sibling Integration component selected by nested rootd dependency and dynamic-closure resolution. A stale prepared Integration self-checkout therefore cannot shadow the exact worker commit. A source mismatch reports the commit, path, and expected and observed blob identities. The worker root is normalized against the Integration checkout before sharding, so a relative override remains stable after workers enter their private checkout. The current native-shell checkpoint selects the complete committed scenario catalog, including forty-one focused initial-exsh scenarios, both focused extop scenarios, the physical-input disk scenario, two trusted powerbox decision scenarios, and every historical native-CLI scenario. The script accepts ERIX_CI_VM_WORKERS as either a positive integer or auto, and auto is the default. auto resolves to the host's online CPU thread count. The aggregate workflow selects auto; run 706 proved that one serialized worker reaches Forgejo's 24-hour job limit after only 207 completed scenarios and therefore cannot supply a complete-catalog gate. Each worker defaults CARGO_BUILD_JOBS to 1 through ERIX_CI_VM_WORKER_CARGO_JOBS, so worker-level parallelism does not multiply into nested Cargo/rustc process fan-out. Disk-image residency and launch intent are independent. A scenario may package the ext4-resident exsh program without starting it; only the explicit initial_exsh_launch = true field selects the Integration launch transaction. Schema validation requires that field for every scripted-shell or physical-input case and couples it to a runtime-rootd disk image. The runner defaults it to false, and rootd fixture selection treats auto as false, so an unrelated runtime program inventory cannot retain the Integration-only initial-shell state machine or silently acquire one shell launch transaction. ERIX_CI_VM_BOOTIMG_TIMEOUT_SECS controls each worker's boot image packaging timeout and defaults to 600 seconds; ERIX_CI_VM_QEMU_DEFAULT_TIMEOUT_SECS supplies the ordinary VM deadline and defaults to 120 seconds, including bootloader negative-case VM probes. ERIX_CI_VM_QEMU_TIMEOUT_SECS retains its role as the global cap and defaults to the same 120-second absolute ceiling. A legacy caller that tightens only this cap also clamps the implicit default to the same value. ERIX_CI_VM_QEMU_STALL_TIMEOUT_SECS defaults to 45 seconds and terminates a QEMU process group when its serial log does not change for that interval, even when the hard deadline has not elapsed. The two closed quiet-release contracts, appliance-full-system-release and subsystem-runtime-release-positive, intentionally disable both early consoles and permit no product serial record before terminal readiness. Their watchdog therefore ignores OVMF chatter and arms the same 45-second deadline only after the first ERIX_ product record. A release warning followed by silence still stalls in 45 seconds; a boot with no observable product record remains bounded by the unchanged 120-second absolute deadline. The selector rejects either named contract if its release profile, console flags, launch/input policy, sole final-READY requirement, or forbidden early-marker set drifts. Scenario definitions also reject deadlines above the repository-wide 120-second maximum, so local and CI runs bound both total execution and an observably stalled guest. Every committed scenario now fits the common ceiling; CI may tighten either bound without weakening any exit, marker, warning, or authority assertion. The ceilings are calibrated against a healthy main-branch result of 422 scenarios in 40 minutes on 12 workers: 68.2 occupied worker-seconds per scenario on average makes the absolute limit about 1.76 times that mean, while the independent progress limit releases a worker after 45 seconds of observable product silence; bootloader marker-mode probes also enforce that window in the harness so a QEMU process terminated on timeout cannot be reported as a clean exit; the runner logs QEMU KVM availability near startup, sends a sole active worker's native output directly to CI, streams each parallel worker through an unbuffered shell prefixer, and emits an aggregate progress heartbeat every 60 seconds while workers remain. ERIX_CI_VM_HEARTBEAT_SECS accepts a positive integer override for diagnostics. Each heartbeat reports pending workers and completed, passed, and failed scenario counts from the worker result files, so an 80-minute failed-scenario timeout cannot make an advancing job appear silent. Parallel pipelines remain pipefail protected, and the runner prints a final passed/failed/total scenario summary with failed scenario names; scripts/run-scenarios.sh remains the serialized single-workspace runner for local focused runs and prints the same per-run summary. In monorepo mode it defaults Cargo and independent dynamic-artifact work to every online hardware thread; CARGO_BUILD_JOBS or ERIX_DYNAMIC_BUILD_JOBS can set an explicit diagnostic limit.

Complete-catalog run 1316 at Integration e3cbf4f finished all 461 scenarios in 55 minutes 23 seconds of worker execution: 365 passed and 96 failed. Exact serial classification separated 86 legacy profiles that inherited a Runtime-only full transition, one vm-appliance runtime-media mismatch, and nine independent regressions. The authenticated profile now selects the transition, not the compiled feature alone. A vm-appliance scenario requiring runtime-fs or loader-fs derives its attached disk from the packaged self-contained image and replaces only the boot partition with an empty valid FAT filesystem; the ext4 runtime graph and executables remain byte-identical. The strengthened appliance-full-system-dev scenario locally reaches loaderd, ttyd, powerboxd, launchd, and final READY through that separate-ESP topology. The independent failures are covered by bounded deadline selections, canonical powerbox marker order, exact procd retry authority, retained asynchronous here-document bodies, and a times workload that exceeds the POSIX centisecond display quantum without adding authority. Signed complete-catalog run 1468 at Integration 1838b7b closes that acceptance gate with all 483 scenarios passing in 40 minutes 11 seconds.

Complete-catalog run 1318 at Integration dcfb181 finished all 461 scenarios in about 52 minutes of worker execution: 369 passed and 92 failed. This restores bounded full-catalog throughput to 8.9 scenarios per minute and proves the then-current 120/180-second hard ceilings plus 45-second progress watchdog no longer hide a multi-hour stall. Its exact failure classes are 16 status-37 protection exits, 47 status-41 service exits, 13 forbidden-marker reports, 12 missing-marker reports, three no-progress stalls, and one accounting assertion. Pinned kernel 8a8b8ab separates executing VSpace lifetime from userspace map/manage authority: dropping rootd's final VSpace capability no longer destroys the still-running dynamic address space. The focused dynamic-bootstrap replay therefore removes its protection fault and reaches the separate service-failure terminal report. Pinned rootd 8571227 also gives terminal log submission one exact SEND-only receiver-rebind retry. Focused dynamic-bootstrap diagnosis then found that the positive memd graph retained rootd's singleton deployment arena while the Integration-only policy attempted to construct the named and deviced negative graphs. Pinned rootd 4211ac1 constructs and releases every negative graph before acquiring the positive graph; the replay passes all three negative roles and advances through positive memd, vspaced, pagerd, and the core service sequence. Its later storage-path status-41 exit was a separate regression, not evidence that the graph-lifetime repair failed. Signed complete-catalog run 1468 supersedes that failing checkpoint and passes all 483 scenarios. VM runners default QEMU_ACCEL/scenario qemu_accel to auto: they select KVM when /dev/kvm is usable and the selected QEMU binary advertises KVM support, and otherwise fall back to TCG. Set qemu_accel = "tcg" or QEMU_ACCEL=tcg only for tests that must force emulation.

Monorepo scenario builds reuse immutable local git-source mirrors under out/git-source-overrides-monorepo and content-addressed dynamic build caches under out/dynlink-build-cache. Cache identity includes source trees, feature sets, linker inputs, the selected target dependency record, the authenticated identity of every shared object in that target's transitive closure, and the toolchain. Unrelated registry rows and cache-local paths therefore do not force identical services to rebuild in separate scenario workers. Relevant artifact, compiler-metadata, dependency, or target-record changes still produce a new cache key. Fixture construction hashes its immutable builder/toolchain input set once and resolves every target-scoped dynamic-link closure in one validated registry pass. Each executable key still combines that prepared context with its own component tree, feature set, linker inputs, deployment policy, and authenticated closure; factoring the common context changes neither cache equivalence nor invalidation behavior. When a worker's exact commit archive has no Git metadata, source-tree identity traversal prunes .git, .ci, out, target, and __pycache__ directories before descent. Generated component trees and caches therefore cannot inflate provenance hashing or influence its result; every remaining source path and byte remains part of the deterministic digest. Shared-object compilation also remaps worker-local source and scratch roots to package-scoped canonical paths. Equivalent registries therefore retain byte-identical object and compiler-metadata hashes across isolated workers, while a real source, feature, dependency, or toolchain change still invalidates consumers. The registry builder caches each shared object and its complete compiler-metadata closure under that exact authenticated build identity and expected artifact- metadata digest. Artifact metadata names each manifest by its stable component- relative coordinate, never by a host or worker checkout prefix. A scenario- specific orchestration feature therefore rebuilds only its changed object; unchanged objects are restored under a per-toolchain/source namespace after every cached file passes its recorded SHA-256 check. Whole-registry cache keys still include the complete selected feature set, so composing a new registry cannot reuse a stale orchestration row. The capacity and runtime-policy sources for both exsh and extop are explicit inputs, so changing a packaged workspace or authority ceiling cannot reuse a stale dynamic artifact. CI workers preserve those caches and component Cargo targets across runner invocations, and each private worker begins with a reflinked copy of the main workspace's immutable dynamic cache. ERIX_MONOREPO_GIT_SOURCE_OVERRIDES_ROOT, ERIX_DYNLINK_ARTIFACT_CACHE_ROOT, ERIX_DYNLINK_REGISTRY_CACHE_ROOT, and ERIX_DYNLINK_OBJECT_CACHE_ROOT can move the caches; ERIX_DYNLINK_DISABLE_BUILD_CACHE=1 forces a clean diagnostic build. Reuse never changes canonical Cargo URLs or grants fallback authority.

The aggregate workflow clones the configured component snapshot before running host helper tests. Catalog-bound coreutils and extop tests resolve their exact inputs from out/components/<repo> in component-checkout CI and retain the existing sibling-repository fallback for monorepo development. Explicit COREUTILS_CATALOG and EXTOP_CATALOG inputs remain available for isolated fixtures; resolution does not infer an executable path or grant runtime authority. tests/ci-component-source-layout.sh locks the clone-before-helper ordering and both workspace-first and explicit monorepo resolution modes.

The loader contract scenario is subsystem-loader-contract-positive. It runs only the new memory-VFS based contract proof, requires ERIX_ROOTD:READY:LOADER_CONTRACT, and does not replace older storage and loader filesystem scenarios.

The loader ELF-plan scenario is subsystem-loader-elf-plan-positive. It runs only the focused block-backed loader path, requires ERIX_ROOTD:READY:LOADER_ELF_PLAN, and keeps older VM scenario groups out of the local validation path.

The loader filesystem-preflight scenario is subsystem-loader-filesystem-preflight-positive. It runs only the focused block-backed loader path and proves authenticated discovery plus malformed ELF and overlapping load-plan rejection. It forbids successful materialization so pre-mount validation cannot claim launch-child lifecycle authority. The authority-free loader verifier constructs every exact typed discover and launch request plus the intentionally malformed discovery bytes before calling an effect adapter. Endpoint slots remain separate explicit effect inputs, so a planned request body cannot carry or select loader authority.

The loader root-lifecycle-isolation scenario is subsystem-loader-root-lifecycle-isolation-negative. It permits rootd to ask loaderd to materialize one authenticated fixture, then requires procd to deny root's query with no managed state disclosed. Rootd records ERIX_ROOTD:LOADER_LIFECYCLE:LAUNCHD_ONLY and fails closed instead of waiting on launchd's private event route.

The procd endpoint-partition scenario is subsystem-procd-root-launch-child-visibility-negative. It focuses the same negative transaction on procd's endpoint policy: loader materialization, root orchestration, and launchd lifecycle remain distinct, and only launchd may query or consume the resulting child's lifecycle.

The loader cleanup-authority scenario is subsystem-loader-cleanup-authority-positive. It runs only the focused pre-start cleanup and authority regression path, requires cleanup-failure markers for each procd-owned partial state, authority-denial markers for unwanted provider/block/key/journal/peer/scratch/caller authority, and ERIX_ROOTD:READY:LOADER_CLEANUP_AUTHORITY. Fault injection begins only after procd creates materialization state; no loader request identifier is reserved for a synthetic pre-procd failure.

The loader closure group is loader-closure. It runs only the focused filesystem-discovery, ELF-plan, root-lifecycle-isolation, and cleanup-authority scenarios needed to prove loader AC11 through AC13 without running older broad VM groups.

The loader boot/image integration group is loader-boot-image-integration. It covers the runtime features.program_loader toggle, optional omission with the same VFS/storage stack, and the appliance disk-image path that installs a disk-loadable native loader fixture under /bin.

The dynamic-linking complete-graph group is dynlink-complete-graph. It runs the current storage-services profile, authenticates the packaged runtime graph, starts dynlinkd before loaderd, streams two selected executables and their full dependency closures, and requires distinct child exit codes plus stale-source authority rejection. Partial model, library-only, linker-only, and loader-only profiles are intentionally absent: the integration contract is the complete product path.

The dynamic-linking final migration closure scenario group is dynlink-final-migration-closure. It runs only the focused positive VM path after dynlink_final_migration_mode=required regenerates executable inventory and requires check-dynlink-acceptance-closure.py with --require-final-migration, proving that all kernel and service executables in runtime/appliance images are migrated dynamic artifacts before the boot starts. The ext4-only drv-rtc-cmos, exsh, and coreutils rows are included because their inspected dynamic artifacts, runtime graphs, and post-mount launch paths are complete. The RTC executable is a private one-shot provider rather than a named service or general client route. The multicall coreutils artifact expands into twenty exact /bin/<applet> graph roots rather than one generic executable selector, while its bytes remain stored once; host-tool and not-yet-created rows remain tracked outside the native runtime image closure.

The dynamic-linking focused boot-image dynamic scenario group is bootimg-dynamic-focused. It covers kernel entry, bootstrap helpers, core services, device/console/input services, storage/loader services, the complete runtime graph, final closure, and negative failure classes. scripts/list-ci-scenarios.py emits the full committed VM scenario set by default and accepts --group-file for an explicit focused set. The aggregate workflow validates and boots the complete scenario catalog, including the initial-exsh start/exit, missing-program, PATH-search, exact-not-found, provider-backed redirection-script, local here-document, exact nested/outer exit-status, POSIX for snapshot/one-time-expansion, parenthesized-subshell state-isolation, function-scope, eval, dot, successor-exec, external-pipeline, CPU-times, and persistent-trap scenarios, plus the historical powerboxd, ttyd, and launchd ext4 lifecycle scenarios in tests/scenario-groups/native-cli-runtime.txt. The six-entry native-cli-time group adds three bounded fixed-RTC positives, an authority-free utility positive, an otherwise identical runtime whose authenticated private RTC provider is absent, and a provider build that submits one semantically malformed private sample. The clock positive alone enables an RTC startup classifier that substitutes distinct process-exit values for receive, framing, inventory, and reply failures. It selects signed rootd revision ba9cc5c, which retains the generation-bound cleanup repair from b414de6, uses only ordinary procd/kernel scheduling, and isolates complete Integration runtime-transition policy in the authority-free orchestration library. Kernel revision 9e27303 removes the completed call-first scheduling fixture, extends the retained narrow RTC trace across reply-copy, wake, and exit-switch boundaries, and retains the prior production scheduler quantum after a controlled one-tick experiment showed no measurable change. A separate tenfold-shorter BSP LAPIC experiment also left the approximately 74-second RTC and 217-second TTYD milestones unchanged, so the exact revert retains the established bounded interval. Authoritative retained serial evidence records queued CALL admission (RTC_CALL_RC=6, the kernel's internal blocked CALL result), a clean provider exit, and subsequent rootd TTYD and POWERBOXD readiness. The positive scenario keeps the narrow kernel RTC startup trace to classify ordinary direct-versus-queued delivery; it cannot select a receiver or change scheduling and does not enable broader IPC-block trace families. The current ordinary-scheduling replay also exposed a separate storage throughput regression after the clean RTC exit: each partition block request rescanned the complete GPT entry array twice, amplifying one loaderd VFS read into thousands of provider calls. The cache introduced by signed blockd revision 0b33df0, with warning-denied bare-metal build correction ff9b461, retains only the last partition geometry inside the current provider namespace, clears it with provider state, and still performs an unbounded complete scan on a cache miss. The focused native-time group is the regression gate for both the RTC handoff and this post-RTC ext4 executable-loading path. With blockd ff9b461, the exact focused guest reached storage, dynlinkd, loaderd, the clean RTC reply, and TTYD readiness before the global 300-second watchdog expired. A controlled one-tick scheduler rerun reached TTYD at the same time and returned the same timeout, disproving that hypothesis. An exact experiment then restored a bounded 256-observation local used-ring window in the physical provider. It reached TTYD at the same approximately 216-second point and exhausted the same watchdog, proving local guest polling cannot advance QEMU device emulation without a VM exit. Signed drv-virtio-block revision 0022a09 therefore restores the validated one-observation cooperative design, including exact completion checks, periodic idempotent notification, and indefinite outstanding DMA ownership. The timer experiment likewise timed out at 300 seconds with identical milestones. Artifact inspection then identified the remaining deterministic amplifier: loaderd authenticates every byte while filesystem executables still carry build-only debug and static-symbol sections. Image finalization now strips that metadata from every packaged executable and shared-object copy only after deployment-capacity patching and before final hashes and manifests are generated. It preserves .erix_dynlink, dynamic symbols, relocations, load segments, and all authority-bearing metadata. Early canonical executables are finalized before their identical signed-store mirrors are refreshed; shared-object source registry artifacts remain unchanged while their zone-assigned image copies are finalized. The focused rerun therefore measures the corrected authenticated byte path without changing the watchdog, scheduling policy, or endpoint authority. The obsolete rootd RTC phase selectors are removed. RTC lifecycle failures are now observed at deviced's exact loader, child-start, sample-acknowledgement, and clean-exit boundaries instead of injecting control flow into rootd.

The same pinned rootd revision closes runtime terminal-report ordering. Rootd first resolves reverse cleanup, exact source retirement, and every ordinary authenticated client disposition without an output effect. Exit then sends the sole typed status through rootd's dedicated kernel host-report endpoint, retires that endpoint, and exits. Runtime images deliberately suppress the kernel smoke-marker text, so Integration observes the kernel-owned QEMU exit 0x14 rather than requiring a second rootd logd/seriald publication. The missing-program and exact command-not-found scenarios bind that exit to their unique reconciled shell marker and complete before either watchdog. Removing the four obsolete rootd terminal marker rows reduces the audited product-validation surface without changing the operation, source-binding, capability, or authority-family inventories. Its pre-acceptance cleanup retry now proves the retained procd route has exactly its canonical SEND|GRANT rights before yielding once; missing, weaker, stronger, substituted, or repeatedly absent authority remains terminal. The initial-shell runner now separates a fully reconciled expected negative from an unexpected service or transport failure. Rootd retires its retained launchd source in both cases, but only unexpected failures invoke broad runtime teardown; expected command-not-found and clean rejection outcomes preserve the already-procd-owned service graph until the one-shot kernel host report ends the focused VM. That provider serializes a canonical private request before changing only the encoded nanosecond field, so timed observes the invalid semantic value and can return the exact typed, correlated rejection without accepting time state. The QEMU runner validates the civil timestamp before emitting -rtc base=...,clock=vm; scenario data cannot inject additional options. Setting SCENARIO_BUILD_ONLY=1 on a disk-image scenario builds its exact scenario-selected appliance and raw GPT image, reports the image path, and stops before disk-case mutation, QEMU startup, marker assertions, or post-VM media inspection. The selector is rejected for every other run mode and for values other than 0 or 1; dry-run output records the effective value. The native-time component snapshot pins lib-ipc 0dd36b4, launchd 0b22de9, loaderd caf5aa7, procd 1f105a0, rootd eef3c3a, and ttyd c09775a together. The packaged tty session admits the same exact-entry metadata-read and touch operation set exercised by the exact-source host tests, while successful loader launches and all procd queries preserve the exact process generation. The focused scenario policy test rejects any of these pins drifting back to an earlier contract. The pinned ttyd submits an accepted framebuffer or serial renderer call once, retains its original private request buffer, and polls exact correlated completion between bounded service-loop turns. It therefore continues authenticated lifecycle intake without resubmission, timeout, discovery, or additional authority while rendering is pending. The closed native-cli-ttyd-renderer-liveness group names exactly the nine native-CLI scenarios that stalled behind the old synchronous wait. Complete-catalog run 1468 passes all nine together with the other 474 catalog members. At signed Integration revision 7fe1979, SCENARIO_BUILD_ONLY=1 produces all three focused images without entering QEMU. Each is 156,237,824 bytes; the positive, unavailable, and malformed SHA-256 values are respectively c26f9fa62708db210628529373fcf584328f77f04e181d6f3b17b3e0a741127f, 520e9ddd052c7828158be176724c332eebf0335b0cbf26af99d78722ae889e77, and e03268dacd0ee445d75d68d4d178b441f6b2af5a063f404876cdc7f39b6c7280. All checksum sidecars, identity sidecars, GPT verification, read-only FAT checks, and read-only ext checks pass. The positive and malformed graphs carry 38 executables and four filesystem launches; the unavailable graph carries 37 and three because drv-rtc-cmos is absent. These are construction results only, not VM or post-mutation timestamp evidence. At signed Integration revision a5f6570, the unavailable-provider and malformed-sample VMs pass and the positive VM reaches final readiness after proving the trusted date, persisted writes, utility-denial status 1, timed statuses 0 and 1, missing-command status 127, and self-signal status 143. Its marker assertion then exposes a Coreutils defect: one printf '%s\\n' invocation with four proof operands emits only the first. Coreutils c808279 repairs both buffered and target execution by reusing the format until all operands are consumed without changing authority; pinned successor bbd8a14 retains that repair and records its completed VM acceptance. The current fixture separates RTC/filesystem persistence from time process semantics. Both scripts emit distinct bounded shell-builtin milestones after their ext4, FAT, denial, status, lookup, and signal phases. Each record advances the 45-second progress watchdog only after real work completes, cannot be divided by an unrelated kernel diagnostic, and adds no launch or object authority. The utility script has an empty filesystem authority table. Both positive VMs now pass end to end at Integration 2d784a7: the filesystem path also passes its read-only media verifier, and the utility path proves all four timing triplets and statuses 0, 1, 127, and 143. Only the complete catalog requires a fresh rerun with that bounded contract. The two exact bounded trap-script VMs jointly prove every trap state, EXIT-status, direct self-TERM, timed self-TERM, shell-exit, and root-readiness boundary, while their contiguous-marker assertion exposes token-by-token trap -p output interleaved with kernel child-exit diagnostics. Exsh descendant aaf2d11 retains the bounded listing repair and additionally keeps asynchronous here-document bodies with their isolated child when a same-line parent command captures $!. It also stages bounded listings for one logical selected-stdout write, preserves the complete oversized-output fallback, clears its already-owned scratch, and adds no authority. This snapshot pins that repair; the exact trap VM and complete catalog require a fresh rerun. The focused physical-input group contains the baseline pointer/SAS/exit proof plus approval and denial profiles. The latter type an authority-bearing coreutils command into interactive ext4 exsh, require its complete fresh trusted framebuffer review, select physical y or n, and commit once with Enter. Distinct shell status markers establish approval and denial results. Rootd requests prompt-default policy only for this fixture and separately marks that exsh startup admitted no direct loaderd or procd endpoint. The signal-contract checkpoint pins exsh, lib-ipc, and lib-tty as one coherent catalog set. Its ttyd successor also pins the exact compiler-described OrdinaryEventSlot layout that shares authenticated TTY1 ordinary capacity between input and descriptive per-session PTY events. The capacity patcher derives the changed arena size from the packaged target ELF; it does not add a bootstrap field, boot-store executable, endpoint, or authority. The trusted-grant successor pins lib-ipc, lib-bootstrap, ttyd, and powerboxd as one coherent contract. TTY1 uses its previously reserved word for a caller-sized grant-view table, and runtime configuration requires that table to cover the entire powerboxd grant table. Ttyd receives exact receipt-free ACTIVE and REMOVE reconciliation over its existing private powerbox endpoint; the mirror carries descriptions only and grants no lookup, revocation, or process-control route. The current coordinated successor pins exsh 296f5364, launchd 6166eed7, lib-ipc 6959c644, and procd 2209b088. It carries only validated ignored dispositions across ordinary, pipeline-child, utility-bearing exec, and ENOEXEC process boundaries. The existing endpoint-selected job-control route derives one exact process generation before launchd forwards a receipt-free delivery request on its private procd endpoint. Explicit and default ignore are mutation-free, terminate-class defaults use a tagged reason distinct from managed cancellation, and unsupported stop/continue requests fail without mutation. This pin adds no executable to boot.img and does not claim a new end-to-end VM until exsh consumes authenticated terminal events. Same-branch pushes retain an active complete-catalog run and queue the newer revision in the same concurrency group. This preserves partial and terminal regression evidence from every started sweep while still preventing two branch sweeps from intentionally running together. Local iteration may select tests/scenario-groups/authority-capacity-provenance.txt, which contains the newly added named-receipt, log-state, RAM allocator-domain, kernel hardware-deadline, semantic VFS path-body, and IRQD endpoint-authority regressions. Positive cases set dynlink_filesystem_mirror_check=required, which runs scripts/check-dynlink-filesystem-mirrors.py against closure-report.json before boot. It requires identity for every declared filesystem mirror and for the boot-store half of each early/boot-image row, while rejecting residual boot-store paths on filesystem-only rows. The complete-graph and final-closure cases emit dynamic artifacts for every executable in the selected boot graph before strict executable metadata checks run. The filesystem mirror mismatch negative uses dynlink_filesystem_mirror_check=expected-failure plus an injected rootd mirror hash divergence so host validation rejects a stale mirror before boot. Negatives keep serial markers separate for bootloader kernel-link failure, kernel service-link failure, and normal service failure.

dynamic-linking operator evidence reuses that focused group and documents the manual inspection path. boot-tool inspect must show dynlink-img, dynlink-early, dynlink-objs, and dynlink-store in boot.img; extracted manifests plus closure-report.json compare the signed boot-image dynamic object store with the /lib/erix/dynlink filesystem mirror. The report keeps bootloader as the only static executable exception and leaves host-tool inventory rows outside the native runtime image closure.

The subsystem-stress-1k-positive scenario is part of the dynamic-only runtime validation surface. It runs the procd-mediated 1k spawn/exit stress loop in policy-selected batches of at most four simultaneously live helpers with exact generation-bound terminal draining. The stress fixture alone adds procd-integration-stress-batch: Rootd authenticates the complete signed exit(42) dependency graph once, while each launch response returns only distinct process/generation identities and transfers no child endpoint or installation grant. Procd uses the kernel's full-graph map/relocate/seal operation, holds its local process endpoint through successful start, but retires broad grant authority before graph mapping and narrow grant authority before start. It drops the endpoint before returning that identity-only response. Exact prefix observation reclaims each terminal generation before the next batch. The four-helper ceiling is the focused VM-proven bound: eight and 32 simultaneous signed helper graphs exhausted the fragmented kernel heap, while four completed all 1,000 lifecycles under the unchanged 120-second absolute and 45-second no-progress watchdogs. Production procd builds deny both operation IDs. Signed lib-ipc 0dd36b4, procd 1f105a0, and rootd eef3c3a define and consume this closed test contract; signed kernel b3ebbd4 suppresses only repetitive successful Integration traces. The scenario retains the exact 1,000-lifecycle requirement under the repository-wide 120-second deadline, requires batch progress, exact completion, and final ERIX_ROOTD:READY, and still passes the strict dynamic image closure gate that rejects non-bootloader static executables before boot. Scenario validation now rejects an earlier exit_on_serial_marker whenever final READY is also required. The five affected dynamic-bootstrap scenarios therefore terminate on final READY, after every earlier lifecycle marker can be observed, instead of stopping QEMU before satisfying their own contracts.

Dynamic-link host fixture builders assemble their small metadata, import, and runtime support objects through scripts/dynlink_assembler.py and link dynamic artifacts through scripts/dynlink_linker.py. The helpers prefer standalone LLVM tools when present, then fall back to Rust-bundled global_asm and rust-lld, so isolated runners still build the same ET_DYN artifacts and run the same metadata and closure checks. CI installs the Debian llvm and lld packages so the standalone tool path is available in the canonical container.

Runtime packaging derives loaderd and dynlinkd private storage from the explicit filesystem-loadable graph rather than a product cap or the larger boot closure. It derives rootd's reusable early-link graph arena from the largest packaged executable dependency closure and patches both the exact graph-record count and its page-rounded backing extent. It also derives vfsd mount-record storage from the selected mount rows and handle-record storage from explicit deployment policy. One [service_state.procd].managed_process_records value, bounded by procd's canonical 128-slot pagerd partition, sizes procd lifecycle and event slices, procd's capability scratch ranges, and its pagerd binding-record contribution. Pagerd's binding arena adds rootd's disjoint 64-slot temporary-launch contribution, so the canonical deployment patches 192 binding records. The pagerd CSpace window remains fixed at canonical slots 320..512; deployment count does not resize it. Packaging validates the record contributions and fixed partition bounds against embedded target layouts and the shared capability-space ABI before patching exact page-rounded arenas; callers do not apply parallel limits. vspaced keeps no deployment-sized mapping state: operation-scoped capability receipts identify each VSpace and the kernel remains the authoritative mapping state owner. [kernel_state].reserved_heap_bytes selects positive page-aligned kernel-private storage for runtime images. The build discards any inherited ERIX_KERNEL_RESERVED_HEAP_BYTES, exports only the validated configuration value, includes it in kernel artifact cache identity, and records it inside the signed kernel image. The native-CLI profiles select 80 MiB so persistent frame and VSpace metadata for the complete ext4 executable graph does not inherit the retired 64-MiB compatibility extent; this setting conveys no usable-RAM or service authority. For ramfsd, packaging derives the mount-record count from only the selected provider = "ramfs" rows and requires explicit nodes-per-mount, file-bytes-per-node, and provider-handle policy. No service or caller supplies a hidden compile-time ceiling. For e2fsd, the mount-record count likewise equals only selected provider = "ext" rows and the provider-handle count is explicit deployment policy. For fatd, the mount-record count equals only selected provider = "fat" rows and the provider-handle count is explicit deployment policy. For logd, runtime configuration supplies canonical retained-record, pending-submission, and retained-byte counts. Packaging maps only their exact typed, page-rounded storage, including one exceptional terminal-delivery record; logd retains no allocator or duplicate sink-payload queues. For crashd, runtime configuration supplies one positive retained-report record count. Packaging patches an exact typed arena, so overwrite policy is deployment-selected rather than fixed at the retired 256-record crate table; the daemon receives neither allocator authority nor access to page padding. For seriald, runtime configuration supplies one positive retained-stream byte count. Packaging patches an exact byte arena, so readback retention is selected by deployment rather than fixed at the retired 4-KiB crate ring; seriald receives neither allocator authority nor access to page padding. For fbcond, runtime configuration independently supplies one positive retained-stream byte count. Packaging patches the exact prefix of a dedicated page-rounded arena, replacing the retired 128-KiB source ring without granting allocator authority or access to page padding. For deviced, runtime configuration supplies binding and HAL-registration record counts. Packaging includes the five per-binding state vectors in one exact typed arena, so valid deployments are not constrained by the retired 16-record crate tables and the service receives no allocator authority. For irqd, runtime configuration supplies the handler-record count. Packaging patches one exact typed registry arena, so neither the service nor its callers retain the retired 16-handler ceiling or allocator access to page padding. The focused subsystem-irqd-endpoint-authority-positive VM resolves only the LAPIC-timer handler object, requires a mask-control request on that object to be denied, then proves registration, timer delivery, and acknowledgement still complete. This distinguishes handler authority from root-held IRQD administration at runtime. The focused subsystem-irqd-multiline-delivery-positive VM enables the integration-only kernel_interrupt_multiline_test fixture. It starts the ordinary LAPIC client after a serial-capable stack registers the COM1 driver and requires exactly one kernel observation with both lines delivered and still outstanding, followed by exactly one observation that both captured deliveries were acknowledged by their independent handlers. The fixture adds no runtime interrupt-injection operation or caller authority. scripts/service_deployment_capacity.py reads each component ELF's embedded target Rust layout, mirrors the real allocation sequence, patches its deployment arena and containing load segment, and updates authenticated runtime-read capacity words. When the service has an in-image stack, the arena must precede the terminal .stack_reserve; patching moves that reserve and its section-bound symbols with arena growth. An exact symbol at the old capacity- section end moves to the new end as well, so a runtime linker-extent proof cannot authenticate stale bounds. Generated dynamic-service import cells use a .data.* input section so ordinary service linker scripts place them before deployment arenas and the terminal stack instead of creating a later allocated orphan section. Packaging then rediscovers the changed artifacts before emitting the final runtime graph. The image manifest binds the exact lowercase SHA-256 and canonical VFS path of that final graph as runtime_graph_hash and runtime_graph_path; strict metadata validation rejects missing, stale, noncanonical, or post-hash-mutated inputs. Images without delegated runtime programs receive an authenticated empty deny-all graph.

The dynamic-linking executable inventory gate is scripts/check-dynlink-executable-inventory.py. It generates the authoritative executable target list from configured component Cargo manifests, including src/main.rs and [[bin]] targets, then joins that generated list with dynlink-executable-migration.toml. CI fails if a discovered target lacks a status, if kernel is treated as a static exception, or if any target other than bootloader is approved for static execution. The generated JSON inventory is written to out/dynlink-executable-inventory.json during CI.

The discovered exsh target is admitted only as an ext4-resident runtime program. Rootd's selected initial-shell feature now supplies the explicit post-mount ttyd and launchd transaction; complete POSIX shell usability remains blocked on the later CLI work. Its exact dynamic dependency closure, including lib-sha2 and lib-stdio, is recorded. Canonical dev and release runtime inventories explicitly select the real exsh-runtime PIE as an ext4-only runtime-graph root; it has no early-manifest or boot-store entry, and packaging grants no launch, terminal, namespace, or process authority. scripts/build-launch-manifests.py cross-checks the dependency records, final image manifest, executable bytes, parsed runtime-graph root, and exsh-owned catalog before writing the exact 624-byte exsh.elf.lmf. The sidecar binds the stable executable dependency-manifest digest, executable content, complete graph, canonical /lib/erix/dynlink/executables/exsh.elf command entry, and all nine declared filesystem/session authority ceilings. Its authenticated header declares CPU accounting, held cwd, and the job-bound redirection resolver. The ceilings grant nothing without matching session, script, and invocation policy, and the manifest never serializes invocation-local VFS capability identity. components.toml includes both repositories with empty build commands so coordinated CI can discover and validate their manifests without treating either one as a statically built image component.

The discovered coreutils target is likewise an ext4-only runtime program. Its repository-owned erix-coreutils-applet-catalog-v2 projection is the single packaging input for all twenty command names, exact /bin paths, signed launch flags, and maximum authority rows. Image generation aliases one inspected multicall PIE into twenty independently hashed runtime-graph roots; disk installation stores those bytes once and creates exact hard links only for the catalogued entries. Every entry receives a separately indexed launch sidecar whose command digest, launch flags, and authority-table digest bind that applet alone. The current catalog declares timed query for date and touch, held cwd for pwd, and timed query, cwd, and inherited script launch for time. All six generic bits are independent, not constrained by utility names. Launchd does not parse POSIX utility syntax or install a direct timed sender: a running consumer uses the broker only when its operation needs clock data. There is no /bin/coreutils, early-manifest entry, BootConfig node, or boot-store copy.

The discovered extop target is a separate ext4-only runtime program. Its repository-owned EXTOP1 catalog admits only /bin/extop, the exact job-lifetime INSPECT_PROCESS ceiling for the SHA-256 scope of session, and an interactive job-control maximum that must be refined to a delegated exact job. Image generation emits one runtime-graph root and one indexed sidecar, stores the PIE once, and hard-links that inode at /bin/extop. Its authenticated header requests the accounting route that authorizes its session snapshots. Neither the executable nor its sidecar enters boot.img or BootConfig.

The discovered drv-rtc-cmos target is a private ext4-only provider. Signed runtime policy either omits it or places one exact role-36 launch immediately after loaderd with dependencies on loaderd and timed. Rootd installs only sampling-only CMOS authority—fixed selector writes to port 0x70 and data-port reads from 0x71—plus one authenticated send-only timed provider route. The driver has no named publication, general client, restart, CMOS data-write, index-read, NMI-masking, unrelated-selector, or implicit clock-setting path. After one bounded sample attempt it reports ready, exits cleanly, and procd reconciles the exact process generation before rootd reports provider completion; process teardown retires the final installed authority.

The dynamic-linking manifest dependency closure gate is scripts/check-dynlink-dependency-closure.py. It maps every normal Cargo manifest dependency for each non-bootloader executable target to an erix-<package>.so dynamic object name, compares those generated edges and a canonical manifest digest against dynlink-dependency-records.toml, and writes out/dynlink-dependency-closure.json. Dev-dependencies, build-dependencies, and proc-macro/build tooling are excluded from executable dynamic edges; renamed dependencies use the package name for the object and retain the alias in the generated JSON. scripts/verify-dynlink-image-closure.py is the image-time companion that rejects non-bootloader static executable entries, missing/stale image dependency records, duplicate image dependency records, and explicit statically bundled dependency records.

Image conversion first copies post-mount build outputs into private staging, patches their selected deployment-capacity symbols there, and then removes non-runtime debug sections and the static symbol table. Early bootstrap capacities are patched on the canonical module and mirrored into the signed boot store, so the catalog and boot-module bytes remain identical. The finalizer explicitly retains .erix_dynlink, allocated program segments, dynamic symbols, relocations, and dependency records. All executable hashes, runtime graphs, lookup rows, and launch manifests are derived from those final bytes, so no authenticated identity is mutated after publication.

The dynamic-linking image-conversion gate is scripts/build-dynlink-image-manifest.py plus scripts/verify-dynlink-image-closure.py. Fixture, runtime, and appliance builds now emit a dynamic image manifest, an early boot-image dependency manifest, an early object bundle, a binary erix-dynlink-runtime-graph-v1 source graph, and deterministic erix-*.so object-store artifacts from dynlink-dependency-records.toml. The runtime graph binds each exact package/digest identity to one authorized absolute VFS path and uses direct object indexes for dependency traversal. Boot executables remain in the signed boot closure but do not automatically become loader authority. Packaging fails before boot if a required object is missing, has a stale hash, lacks relocation/dynamic section metadata, is placed in the wrong early-versus-filesystem zone, or if bootloader gains dynamic dependency requirements. Runtime features.program_loader=true now includes dynlinkd before loaderd with explicit vfsd authority.

The dynamic-linking object-store contract adds a full boot.img dynamic store and a filesystem mirror. The generated manifest records erix-dynlink-boot-store-v1, erix-dynlink-filesystem-store-v1, boot-store paths, filesystem paths, hashes, executable identities, shared-object identities, and explicit no-ambient authority flags. Disk-image installation places manifests, dynamic executable mirrors, and shared objects under /lib/erix/dynlink; tests/dynlink-object-store-contract.sh covers the host contract, and bootimg-filesystem-object-store is the focused VM group. The generated erix-launch-manifest-index-v1 records every admitted sidecar hash, authenticated header flags, and five policy digests. Installation rejects a missing, unindexed, stale, executable-mode, malformed, or catalog-divergent authority sidecar; indexed .lmf files are installed as non-executable data with mode 0644 beside their 0755 executable. Exsh retains native-command filesystem delegation maxima plus its exact session-inspection maximum, extop retains that exact session scope plus an explicitly interactive control maximum. Exsh declares CPU/cwd/resolver ABI support and extop declares CPU/session inspection; neither declaration selects rights by argv. Each coreutils entry binds its exact catalogued launch flags and maximum rows with an all-zero object selector that must be refined to an exact object by an authorized running-program request. The boot store contains only executables explicitly marked for early startup and shared objects assigned to the boot-image zone. Post-mount executables and filesystem-zone objects still receive authenticated ext4 paths, but packaging omits their boot-store paths and the closure verifier rejects any residual boot-store copy. The fixture builder keeps those inputs in a separate FILESYSTEM_EXECUTABLE_FIXTURES set. Runtime profiles with complete TTY1 and PBX1 policies build ttyd and powerboxd with their runtime features, while the explicit [programs] exsh = true inventory builds exsh with exsh-runtime, [programs] coreutils = true builds the multicall runtime artifact, and [programs] extop = true builds the native monitor. Each selected artifact is marked for the filesystem zone and never enters the boot-service set. Selecting either program requires the program loader and launchd policy. Exsh additionally requires complete [program_state.exsh] caller-resource policy; coreutils requires one positive, page-aligned [program_state.coreutils].workspace_bytes ceiling. Extop requires all four [program_state.extop] workspace, processor-row, process-row, and control-handle capacities; the control count cannot exceed the process count. Inventory booleans and workspace sizes remain authority-free. tests/exsh-filesystem-packaging.sh proves the exact five-object dependency closure, runtime-graph membership, and absence from the early manifest and boot store. It also parses every LMF1 field, verifies the exsh-owned exact session-inspection authority digest, installs the exact sidecar on ext4, and rejects changed graph bytes, dependency identity, executable content, or indexed sidecar bytes. Dynamic service packages may expose a package-local library target: the artifact builder compiles that library and its binary as separate package-owned PIC objects, then links both against the declared prebuilt shared-object closure. Every direct rustc PIC compile uses the owning package's declared Rust edition, including Rust 2024 services loaded from the filesystem partition. It does not turn the package-local crate into a static cross-repository dependency.

scripts/powerboxd_state_capacity.py parses the executable's PBX1 target layout, derives the exact page-rounded arena for every configured request, grant, selector-byte, retained-record, cleanup-record, and transient capability-slot pool, and patches the authenticated arena word. Its focused host test proves exact growth and rejection of missing, partial, or zero capacity. The canonical runtime profiles supply every PBX1 storage value plus the transient capability-slot base and count. Configuration rejects a range outside the native-broker CSpace window, and image packaging rejects a powerboxd artifact unless the complete storage projection is present. tests/dynlink-service-local-library.sh covers the package-local library link path, and tests/powerboxd-filesystem-packaging.sh proves that capacity patching rebuilds the final artifact identity, includes powerboxd in the runtime graph, and leaves it out of the early manifest and boot store. scripts/ttyd_state_capacity.py likewise parses ttyd's target record layouts, including the PTY stream, opaque shared ordinary input/control, and trusted grant-view slots, derives and patches its page-rounded session, PTY, event, cleanup, ordinary output, trusted chrome, PTY input, canonical-line, PTY output, output-record, and grant-view arena in runtime allocation order, and rejects partial or absent TTY1 policy whenever ttyd is packaged. Runtime parsing also rejects a grant-view capacity that differs from powerboxd's grant capacity. tests/ttyd-filesystem-packaging.sh proves the real binary and package-local library remain ext4-only. scripts/launchd_state_capacity.py derives and patches launchd's exact page-rounded transaction, job, intent, manifest, authority, script, pending, cleanup, status, reply, launch-stream endpoint, retained logical-stream, selected-body, and transient-slot arena from the version-5 target layout and authenticated version-2 LCH1 policy. The target descriptor carries distinct script-envelope, launch-stream endpoint, and logical-stream record sizes. The logical-stream count derives from the authenticated endpoint count, while its disjoint byte arena derives from authenticated intent-byte capacity. Validation reserves twelve non-aliased slots per job for control, status, script, and resolver pairs, a job-broker creator/source/receiver triple, and an exact retained filesystem-scope sender when required, then two slots per configured stream pair, and requires a disjoint, nonempty tail for launch-intake receipts. The standard 128-job/64-stream policy reserves 1,920 slots: 1,664 for job and stream routes and 256 for intake receipts. Boundary tests reject the prior eleven-slot geometry and require a nonempty disjoint intake tail without enlarging the CSpace budget. scripts/exsh_workspace_capacity.py parses the pristine version-20 target layout, expands the thirteen explicit command/syntax/variable/descriptor/local- body/expansion/launch/search/subshell/function/background-job resource classes into all 94 authenticated capacity words, reproduces exsh's complete typed carve order, and patches the page-rounded .exsh_workspace. Stable for item/byte arenas derive from the explicit expansion policy. Subshell frame depth is backed by complete variable-slot/byte, positional-slot/byte, and function-slot/byte/event/here- document/boundary snapshot arenas for every admitted nested level; checked products cannot overflow or advertise unbacked state. The same depth also backs complete trap-slot/action-byte snapshots, so caught dispositions can reset on entry while ignored dispositions survive and the exact parent table can be restored and erased on leave. The syntax-record policy additionally backs one typed pending/completed pipeline-job slot per admitted command record. A caller-sized background-job ledger retains only exact status/control routes and descriptive process identities. Function depth separately backs persistent definitions, immutable active-call snapshots, iterative execution frames, parameter checkpoints, and validation frames. Its retained descriptor layers have a caller-sized local journal, and a second complete evaluation workspace expands definition-site redirections after call parameters have been installed without aliasing the invocation candidate. Authenticated eval source, event, here-document, substitution- boundary, execution-frame, and parser arenas derive from the same deployment classes and are carved before both evaluation workspaces. Four additional capacity words provide the fixed 28-condition live/candidate trap slot sets and derive both action-byte arenas from the explicit command-byte class, without a separate private action ceiling. The 96 capacity words and 70 type-layout words form the exact 166-word EXS21 descriptor. Two new explicit byte classes back the interactive editor, its saved draft, and volatile command history. The editor/draft slices share one capacity; history has its own byte budget. Neither adds filesystem storage or authority. The distinct command-search byte arena is deployment-sized and cannot become an implicit pathname limit. Packaging rejects a missing policy, a stale version or type layout, any non-pristine default word, and an undersized or overlapping NOBITS range. tests/exsh-workspace-capacity.sh covers the exact word projection, growth, patch, and stale-layout rejection; the filesystem packaging test proves that the final patched ELF is rehashed before its image and launch manifests are emitted. Initial-exsh VM scenarios select explicit test deployment policies rather than the product dev profile. The preceding EXS20 layout derived a 4,194,304-byte workspace, down from 106,061,824 bytes. Current canonical EXS21 builds derive 4,235,264 bytes, including the editor/draft/history slices, while retaining 64 KiB command/search bodies, 128 syntax records, 16 descriptors, four nested subshell/function levels, and 16 background jobs. The canonical dev, release, sample, writable-FAT, and writable-exFAT profiles, plus the non-product smoke fallback, use that same bounded tuple. The former 106,061,824-byte product allocation exceeded both the 64 MiB sample heap and the 80 MiB dev/release heap before any other service allocation; the bounded allocation fits the smallest canonical heap and prevents unrelated filesystem launches from failing while merely packaging exsh. This changes retained storage only and grants no launch, filesystem, endpoint, or namespace authority. The subsequent read-only-root regression is repaired at signed vfsd revision 18d1dfa. Vfsd now retains the validated mount flags and omits access-time evidence for READ_AT, READDIR, and READLINK on read-only mounts, including provider-pinned exact objects and ordered redirection streams. Loaderd discovery and POSIX sourced-script input therefore remain non-mutating provider reads even after timed becomes available; writable mounts still receive trusted atime updates, and filesystem providers independently retain their read-only enforcement. The RTC reconciliation contract now belongs to deviced: it accepts success only after exact clean process exit and retirement of the materialization receipts and child aliases, so rootd receives no RTC process-lifecycle authority. At the pinned rootd and vfsd revisions, the canonical default-profile appliance-disk-image-dynlink-kernel-artifact-positive VM crosses RTC cleanup, read-only loader discovery, and final marker validation. The writable native-time filesystem VM also passes every in-guest and post-VM payload, timestamp, ctime-order, and read-only-denial check, proving writable atime propagation remains intact. Both use the unchanged 120/45-second watchdogs. The scenario contract test rejects an implicit product-profile fallback or a divergent canonical profile or special RTC policy. It also requires eight TTY session and PTY records: rootd owns one authenticated bootstrap session before launchd provisions exsh, and unused records confer no endpoint or session authority. scripts/coreutils_workspace_capacity.py parses the pristine ERIXCORCAPLAY001 target layout and patches the exact page-aligned .coreutils_workspace byte ceiling before the multicall ELF is hashed. tests/coreutils-catalog.sh enforces the repository-owned command/authority projection, tests/coreutils-workspace-capacity.sh covers pristine layout and exact capacity failures, and tests/coreutils-filesystem-packaging.sh proves all twenty ext4 entries share the one stored inode while retaining distinct, tamper-evident sidecars, exact date/time/touch flags, and no generic or boot-image executable path. tests/launchd-filesystem-packaging.sh proves the rehashed real binary and package-local library remain ext4-only and absent from the boot store. scripts/extop_workspace_capacity.py parses the pristine ERIXTOPCAPLAY001 target layout and patches the caller-owned workspace plus processor, process, and control record capacities before final hashing. tests/extop-catalog-capacity.sh covers exact catalog scopes, capacity validation, and stale-layout rejection; tests/extop-filesystem-packaging.sh proves the one ext4 entry, exact two-row sidecar, absence from the boot store, and tamper rejection. The same validated runtime policies are encoded once into BootConfig's canonical FSL1 tail. The first filesystem launch node binds private role 36 to /lib/erix/dynlink/executables/drv-rtc-cmos.elf and the fixed 24-byte RTC1 authority description. The next node binds role 30 to /lib/erix/dynlink/executables/ttyd.elf and the complete 96-byte TTY1 record. The next binds role 32 to the exact powerboxd selector and complete 64-byte PBX1 record; the final row binds role 31 to /lib/erix/dynlink/executables/launchd.elf and the complete 68-byte version-2 LCH1 record. This is authenticated configuration only: BootConfig contains no ELF bytes, boot-store path, namespace capability, or process-control authority. The RTC, ttyd, powerboxd, and launchd BootConfig tests check complete gap-free node/row/policy bindings and reject reordering or substitution. The RTC image test additionally proves that the executable and its five-object closure are present in the ext4 runtime graph and absent from the early manifest and boot store. Production disk construction installs runtime-graph executables with mode 0755, indexed launch-manifest sidecars with mode 0644, and shared objects as non-executable data. It never overlays the authenticated graph with the retired loader filesystem fixture. The focused appliance-disk-image-powerboxd-filesystem-positive scenario boots the real ext4 executable through loaderd, dynlinkd, and procd, then requires ordered loader, VFS I/O, powerboxd, and final root readiness while rejecting trace and service-failure markers. The corresponding ttyd scenario requires the ordered loader, root-mount, VFS-I/O, typed ttyd, and final readiness sequence. The launchd scenario requires that same mount and I/O prefix, then ttyd and powerboxd readiness before unique typed launchd and final readiness. It runs the real ext4 object through loaderd, dynlinkd, and procd and rejects service failure or diagnostic trace markers. Reaching both broker readiness markers also proves that powerboxd's final decision-notification sender and launchd's paired receiver fit their exact child CSpace windows and survive the complete rootd-to-procd startup handoff.

Three focused coreutils scenarios start the ext4-only multicall artifact exclusively through its catalogued /bin/<applet> entries. Bounded POSIX shell scripts separately cover text pipelines, exact-object copy/rename/unlink lifetime, and directory mutation plus status/current-directory primitives. Each uses the repository-wide 120-second absolute deadline and 45-second silence watchdog. The separate native time-utility scenarios are now split into bounded filesystem-persistence and process-semantics positives with independent completion and post-VM contracts. Rootd selects only each variant's filesystem operation families and puts one or two exact selector/lifetime/class rows in its script envelope. Expected cross-applet operations fail, so sequential launches cannot accumulate the catalog's authority ceilings. The fixture selector is mutually exclusive with every other initial-exsh command mode and requires the complete post-mount runtime graph.

The focused appliance-disk-image-initial-exsh-regular-builtins-script-positive scenario keeps the same ext4-only exsh launch and empty authority envelope. It requires fresh, clustered, explicit-operand, silent, and resettable getopts behavior; octal and symbolic umask state; command -v/-V, function bypass, and default-path execution; and operand-tolerant true/false. One expected exact /bin/grep reads the mode-0600 file only through exsh's explicit inherited stream, proving that mask attenuation does not widen namespace authority. External probes remain exact catalogued /bin launches, and the warning-free focused VM completes its serial marker and final readiness contract.

The native-cli-initial-exsh group identifies forty-one focused entry scenarios within the full CI catalog. The baseline positive case requires the ext4-loaded shell's typed zero-status exit before final rootd readiness. The missing-program fixture keeps the complete service and mount graph but excludes exsh from the runtime program inventory; its clean-rejection marker follows launchd's correlated abort and temporary-authority cleanup before rootd reports service failure. The PATH case launches a second ext4 exsh through the first shell's unchanged bounded route and requires a distinct zero-status marker. The exact- absence case searches one missing candidate, requires status 127 after clean abort, and rejects final readiness without adding authority to either launch. The redirection-script case creates a POSIX script through the job-bound /tmp provider, reopens it as a nested ext4 exsh child's fd zero, and proves that the dynamic description replaces rather than supplements inherited fixed stdin. The here-document case supplies a quoted literal body from exsh's authenticated local producer as nested ext4 exsh fd zero, then requires terminal cleanup and final readiness without adding rootd or filesystem authority.

Its fifteen native-time entries run ext4-resident date, touch, and time through exsh. The clock positive performs exactly two external launches and has an empty script-authority table: trusted date must succeed and an ungranted touch must execute and return utility status 1 without creating an entry. The ext and FAT persistence proofs are nine separate scenarios with exactly one filesystem-mutating external command apiece. Create and truncate each receive only invocation-lifetime write plus one-shot create-entry authority for their exact target. Current-time and explicit-time touch each receive one one-shot touch row. The cross-mount reference case receives only one metadata-read row for its seeded ext4 source and one touch row for its FAT target. This preserves create, truncation, current-time, explicit-time, and reference-copy semantics without allowing one expensive provider operation to consume another's VM budget or authority. The utility-positive path checks child success and failure status, while a separate auxiliary positive checks not-found and signal status. Both require POSIX timing output with zero filesystem session operations and empty script-authority tables. The signal child installs a TERM action, targets only its authenticated $$ identity with the regular kill built-in, and exits 143 from the caught action; an unmatched or undelivered signal instead reaches a distinct failure exit. The unavailable path retains only write, create, and touch rows, omits the authenticated private RTC provider despite fixed virtual hardware, and requires date and current-time touch to report unavailable while an explicit timestamp still succeeds. A separate clockless negative uses the same provider omission to prove monotonic time remains independent with zero filesystem authority. Rootd emits the terminal success marker only after hanging up the session and retiring every temporary launch, lifecycle, and status capability. The malformed peer selects the same three-row script authority while compiling only the private provider with its adversarial sample feature; timed must return the exact rejection and remain unavailable. Each mutation positive has a closed post-VM verifier mode: denied checks absence on ext; ext create, truncate, current-touch, and explicit-touch modes verify their exact payload and timestamp contract; and the five FAT modes verify create, truncate, current-touch, explicit-touch, or reference-copy state. The reference mode also verifies its immutable ext4 source. All fifteen native-time paths use the common 120-second absolute deadline and retain the 45-second no-serial-progress deadline. A healthy main-branch run completed 422 scenarios in 40 minutes with 12 workers, or 68.2 occupied worker-seconds per scenario; multi-hour execution is therefore a stall failure, not a valid slow path. Timeout selection changes no guest authority or accepted marker. The replacement fixed-RTC and clockless workflows are independent disk scenarios. Host gates lock their exact selectors, launch counts, authority rows, markers, catalog membership, and persistence modes before focused VM validation.

The native-cli-physical-input group contains three focused post-mount hardware paths. After rootd validates ttyd's interactive parent-session receipt, commits the exsh launch, and validates its status route, the disk VM exposes a private Unix QMP socket to a bounded host helper. The runner allocates that socket under a short system temporary path instead of inheriting a potentially deep build TMPDIR, and removes the private directory on every exit path. The baseline sends relative mouse motion, Ctrl+Alt+Delete, and exit; two peers type an exact-object operation one acknowledged key stroke at a time and answer its trusted prompt with physical y or n followed by Enter. Bounded inter-group and inter-key settling intervals prevent the emulated PS/2 queue from dropping a line delimiter or truncating a longer command while the scenario retains one overall timeout. Since line echo is earlier than prompt registration, a PF2 glyph matcher requires the complete fresh amber review, including its exact executable, scope-relative selector, operation, lifetime, and Enter instructions. Consent is never retried into a subsequent prompt or resumed shell. Only the approval, denial, replay, and selector-race profiles select rootd's powerbox fixture feature, which admits one-shot CREATE_ENTRY and a prompt default for the primary session; ordinary physical-input and secondary sessions remain deny-all. Rootd observes inputd's public keyboard, pointer, and exact trusted-acknowledgement counters in the post-commit callback while the process session remains live. Rootd then publishes an evidence-ready marker, and the host sends input that may terminate the shell only after observing that second barrier. Terminal-status observation and exact hangup follow. Rootd publishes success only after exsh reports the expected status and the ext4-loaded shell exits normally. Scenario data cannot name the QMP socket, fabricate a target event, or grant target-side input authority.

The native-cli-trusted-tty group adds three ext4-backed interactive proofs. The multi-PTY member creates one independently receipted empty session beside the running exsh session and proves ordinary PTY echo. The host waits for both the echoed true MULTIPTY builtin and exsh's second prompt before sending trusted control. Keeping the probe inside exsh prevents an unrelated completed child-session cleanup from becoming the anchor for focus traversal. It then paces secure attention, selects the authored secondary with the previous-session control, and returns to exsh with the next-session control as separate bounded input groups before exit. The final Return is retried only until the guest publishes the unique initial-exsh exit marker, so QMP controller acceptance cannot be mistaken for delivery through the emulated PS/2 queue. The spoof-negative member prints CTRLALTDELETE through ordinary PTY output before sending the one real secure-attention chord; rootd accepts only an exact trusted-delivery delta of one. The session-control member enters secure attention, focuses the secondary session, kills that focus with target-free Ctrl+Alt+K, and can type exit only after ttyd restores primary focus. Its expected delta is exactly three. All three use QEMU's private input socket and return no input producer, PTY stream, session selector, or job-control authority to rootd. Their terminating input is also held behind rootd's evidence-ready marker. The one-shot local group invocation stopped before image construction because BOOTIMG_SIGNING_KEY was unset (passed=0 failed=3 total=3). No target build or runtime result is claimed, and the failure was neither investigated nor rerun.

The native-cli-launch-handles group contains one focused ext4 client proof. Rootd launches interactive exsh with only its mandatory status sender. Exsh then observes /bin/false as status one, launches foreground /bin/cat, and forwards a physical Ctrl+C only through cat's independent control sender before observing status 130. The QMP profile retries that selector-free chord until a new CONTROL130 marker appears, so a slow foreground handoff cannot turn the test into a timing lottery. The profile names neither a process nor a job; serial status text plus the target completion marker proves the two route roles were used without returning either child sender to rootd. The warning-free focused run passes 1/1, including ordered authority-boundary and final-ready assertions.

The exact-entry-grants group contains two focused negative disk scenarios. The replay member builds coreutils with a test-only mode, performs one approved mkdir, then calls the same child send alias again and succeeds only when the kernel reports NOT_FOUND after vfsd retires its receiver. The selector-race member opens an exact ramfs entry and then asks a test-only provider hook to rename the retained parent through the ordinary API; only BUSY is accepted before the exact mutation proceeds. Scenario coupling prevents either QMP profile from selecting a production feature combination, and neither fixture adds a mount, namespace, parent, path, or control capability. The required one-shot local group invocation stopped before image construction because BOOTIMG_KEY_ID was not selected (passed=0 failed=2 total=2). It was recorded without diagnosis or rerun, so target-build and runtime evidence remain open.

The native-cli-extop group identifies the two process-monitor scenarios in that same complete catalog. The positive case boots two processors, launches the ext4-only /bin/extop through exsh, loaderd, dynlinkd, and procd, and requires two bounded dashboard samples containing both processor rows, memory accounting, and the session-scoped process table. Its bootstrap session carries only INSPECT_PROCESS; no process-control operation is delegated. The negative case leaves the session deny-all, supplies only a forged numeric job identity, and requires launch denial before any dashboard row can reveal or mutate an out-of-session process. The current positive run rejects the initial exsh commit with an authority-class invalid argument before extop executes. The negative run reaches the expected command-denied status 126, then exits rootd status 220 without its completion marker. Both failures are recorded without debugging. The exit-status case makes that nested shell return seven, expands the outer shell's $?, and requires the outer POSIX exit built-in to propagate the exact status before rootd resumes final readiness. It changes no launch or authority record. The for case mutates positionals and an expansion variable inside loop bodies to prove that omitted in snapshots "$@" and explicit words expand once. It uses the same ext4 executable, launch transcript, and authority-free command bytes as the other focused variants. The parenthesized-subshell case mutates variables, positionals, option flags, and status inside (...), then proves their restoration and successful ! (exit 9) completion in the outer source. It adds no authority or launch record and executes the same ext4-only exsh artifact through loaderd, dynlinkd, and procd. The function case defines and invokes POSIX functions, proves call-local arguments, shift, return 7, and caller-parameter restoration, then enters a parenthesized environment. That environment inherits an outer binding but confines replacement, definition, and unset -f; leave restores the outer binding and omits the inner one with ordinary status 127. Final removal also falls through to status 127. The same fixture applies an invocation-site output redirection before a definition-site pathname expanded from a call-local argument, executes the written body through nested ext4 exsh, then retains a function-body here-document until another nested child exits seven. It accepts that status only after descriptor/provider cleanup and scope restoration. The fixture also calls break 3 and continue 3 from functions inside caller loops, requires both caller bodies to resume, and sends exit 7 through two nested child-function scopes. The case changes only authority-free -c bytes and uses the same ext4 executable and fixed launch transcript. Its large authenticated workspace also crosses the kernel's historical 32,768-frame registry boundary and switches its large user range after ext4 materialization. It forbids kernel-heap exhaustion, proving both bounded frame-registry growth and allocation-free range-permission activation. The eval case runs nested POSIX eval in the current environment, suspends and resumes a function around an eval-originated return, transfers continue and break from eval to the selected caller loop, replays a retained here-document, and checks exact status and leading negation. It changes only authority-free command bytes; exsh remains ext4-only and rootd receives no evaluator, descriptor, stream, namespace, process, or additional launch authority. The dot case installs two non-executable shell files on the ext4 data partition only for its focused image. The outer ext4 exsh selects one file through PATH; that source opens the other by direct path. The pair proves current-environment mutation, retained here-document parsing, redirection cleanup, function-local and eval-to-dot return, exact nested statuses, and noninteractive missing-source termination inside a subshell. Neither file is placed in boot.img or admitted as a launchable program, and the rootd launch and authority transcript is unchanged. The exec case installs two executable-mode POSIX shell files only in ext4, with no native launch manifests. It first proves exact status 127, then status 126 when an execution-only shell cannot authorize the required successor handoff. The selected script is read only after exact native-manifest absence, and its interpreter is the fixed ext4 exsh.elf selector rather than a PATH fallback. A direct successor returns status 23, a separately authenticated shell then launches and reaps one nested ext4 shell, and the final PATH-selected script successor returns zero. Both scripts compare stable $$, the selected pathname in $0, remaining arguments, prefix export, and an inherited descriptor persisted by redirection-only exec. Sequential child completion, isolated nested-shell reuse, and current-environment replay of the provider-backed output prove predecessor route/provider cleanup. The successor boundary releases predecessor-local state only after it atomically reparents remaining inherited descriptions to the exact same-realm candidate resolver through launchd's receipt-free private vfsd call and migrates the matching cleanup-ledger rows. A pre-boundary format refusal discards only duplicated candidate aliases, so the running predecessor can read the selected script through its still-live stream. The predecessor receiver is retired before the next shell is admitted. This adds no executable to boot.img and grants rootd no new authority. The times case invokes the no-operand special built-in four times: before and after one failed lookup, after one terminal-observed ext4 child, and from an ext4 successor that replaced the original stable shell job. A host validator accepts only eight canonical C-locale rows, requires exact child-counter equality across the failed lookup, strict child growth after the waited child, unchanged child counters across replacement, strict successor self-time growth, and non-regressing shell totals. Operand, prefix/redirection, closed-stdout, and status behavior are checked inside the target first. The serial transcript transfers no authority. Every snapshot uses the stable job's dedicated send-only CPU-accounting endpoint, including after exec; neither shell executable is added to boot.img. The final snapshot also proves that fixed terminal descriptions use fresh successor-session endpoints rather than senders owned by the predecessor TTY lifecycle that commit hangs up. Because that snapshot is immediately followed by orderly exit, it also proves that ttyd makes the successor routes non-callable while draining accepted bytes through framebuffer and serial before exact receiver-capability cleanup. The trap case checks persistent prefix and disposition replacement, canonical default/ignore/executable listings, invalid-condition continuation, status-two direct-special-builtin syntax termination in nested ext4 shells, and closed-stdout status. Nested ext4 invocations prove EXIT action file effects, pre-action status restoration, explicit and operand-less exit selection, syntax-error status, caught self-TERM safe-point dispatch with exact status 143 both directly and through time, primary EOF dispatch, and consume-before-execute recursion prevention. The serial transcript and terminal status are the only observations; neither rootd nor exsh receives signal, event, process, or job authority. Exact-revision KVM validation applies the same 120-second hard and 45-second no-progress ceilings to the nested-child trap matrix and trap dispatch. These bounds do not relax ordered, unique, terminal, failure-marker, or authority assertions. Disk-scenario ordering follows the signed semantic topology: VFS mount and I/O readiness precede loaderd, then ttyd and launchd. The schema rejects a return to the obsolete loader-before-mount host assertion. The trap-dispatch case enables a ttyd integration fixture that commits and consumes one canonical INT on the bootstrap session's first authenticated event read through its existing bounded queue. The outer ext4 exsh forwards it only over the bounded, syscall-yielding foreground child's returned exact job route, observes status 130 before running the caught action, and then executes the following external list member exactly once. Ordered unique markers prove action-before-resume and no replay; rootd still owns only its status route, and ordinary ttyd images do not enable the seeded event. The asynchronous-wait case selects a distinct build-gated one-shot mode and the unchanged outer rootd launch transcript. Ttyd preserves the first exact empty post-asynchronous read and injects only on the same session's next read inside wait. Launchd now returns a stable POSIX-visible process identity from a namespace disjoint from recyclable kernel TCB IDs; procd retains that identity through terminal state and successors while exact routes remain the only lifecycle authority. The ext4 shell proves immediate asynchronous status zero, distinct nonzero descriptive $! values, caught INT interruption of wait at status 130, later status-seven observation, status-127 retirement, all-job waiting, parent-state isolation, asynchronous here-document status nine, and teardown cleanup of an unobserved final child. Rootd emits the success evidence through shell built-ins, avoiding a utility lookup outside its deliberately restricted PATH. Ordered unique markers and final readiness are observed over serial; neither the scenario nor rootd gains a child job, process, event, stream, or control selector. The one-entry native-cli-asynchronous-wait group permits running only this new VM locally. The focused VM passes its complete required, forbidden, unique, and ordered marker contract at signed Integration 48c12c3 with rootd 5de3dee, procd 1f105a0, launchd 0b22de9, ttyd dbe2be2, and exsh f0f44af. It reaches final readiness under the unchanged 120-second absolute and 45-second serial-progress watchdogs. The regular-builtins case uses the unchanged outer launch transcript and an empty script-authority table. Distinct target-side statuses classify failures in getopts, umask, command, or default-path execution before rootd emits a single success marker. Its mask-077 file is read only through the exact stream opened by exsh, so creation-mode privacy is preserved without granting the child namespace authority. The one-entry native-cli-regular-builtins group permits focused local execution while the pushed CI workflow continues to select the complete scenario catalog. The extop out-of-session case now completes its full negative contract. The forged scalar control claim is denied with status 126, launchd publishes the following authority-free coreutils job without inventing an accounting route, and coreutils submits the complete completion marker and newline as one logical write. Exact denial, shell success, rootd script success, and final readiness markers all pass in the warning-free focused disk VM. Component selection pins exsh, lib-ipc, and lib-tty as one coherent signal- vocabulary set. This prevents a newly resolved PTY adapter from compiling against an older pinned IPC catalog while keeping the catalog descriptive and adding no event route to the VM. The first complete replay exposed one kernel scheduler regression after all 438 scenarios reached launchd readiness: sustained pending IPC wake traffic could starve the already-runnable cooperative block driver while the device had completed its request. The focused replay pins the round-robin voluntary-yield repair and passes without a driver reset or widened authority. The pipeline case first rejects a mixed AND-OR list containing a singleton compound pipeline with status 126 before any stream allocation and proves that neither compound mutates parent state. It next commits a finite ext4 exsh child before the missing second command returns status 127; partial-submission reconciliation must observe that finite child and retire both job routes and the provisional stream. The following valid work proves immediate reuse. The fixture then transports nondefault IFS, a readonly set variable, and a readonly declared-unset variable into isolated ext4 children as exact descriptive LCS1 v1.5 state. It requires zero from the IFS split/shift proof and one from both forbidden assignments, then confirms the parent state did not change. It next commits one three-stage ext4 pipeline: a function-definition child, a brace-group child containing built-in export, and an exsh.elf -s reader for its reinput-safe declaration stream. The parent retains its original variable and no function binding, proven by exact status 127 on parent invocation. It then launches ext4 exsh as both writer and reader around one launchd-provisioned stream. An outer built-in first prepares valid shell input in ext4. The outer shell is required to commit each pair before waiting; the writer overrides stdout to a second ext4 file and the reader overrides stdin from the prepared file. Explicit descriptor-three aliases retain both logical pipe halves through child exit. The gate requires successful child statuses to prove the output commit and redirected-input evaluation, retirement of both exact status/control route pairs, and outer status zero before final rootd readiness. No executable is added to boot.img, and neither exsh nor rootd receives stream endpoint authority. Its first focused run reached launchd readiness but exposed an exact 8-KiB managed-frame metadata allocation with only 5,280 fragmented heap bytes free while the second 83-MiB exsh was being staged. The authenticated native-CLI heap policy was raised from 72 MiB to 80 MiB, and both large-shell scenarios now reject the kernel's exact allocation-failure marker. The focused replay pins launchd 8ca9977, builds the complete image without warnings. A superseded multi-pair fixture then timed out after its first two children exited successfully, before reaching any redirection, so it did not isolate the new behavior. The bounded single-pair fixture exposed a pre-child status-126 failure: exsh semantically released a pathname provider immediately after launchd had accepted cleanup ownership. Exsh d4805f9 instead drops only its duplicate local aliases after COMMIT and leaves launchd as the sole provider-lifecycle owner. A generated-checkout-only binary search proved stream setup, process start, job publication, the capability-bearing COMMIT reply, and temporary source retirement all complete. The apparent first-COMMIT stall was an early local stop during the fixture's normal long-running window, not a launchd/procd or authority regression. After removing every diagnostic change, the warning-free focused replay passed both role-preserving precedence cases and exact route retirement. The workload now runs as separate state, function-isolation, and descriptor-redirection scripts, each with an empty script-authority table and the common 120-second ceiling. The later three-stage compound fixture exposed a distinct middle-child COMMIT rejection. Launchd found an endpoint ordinal only among prepared rows; after the reader transfer became live, the writer moved from filtered ordinal one to zero and the requested ordinal became invalid. A diagnostic-only replay encoded the exact COMMIT / INVALID_ARGUMENT / INTENT result as status 141, then all instrumentation was removed. Launchd 8d96bc5 now counts every live transaction row while resolving the stable ordinal and still requires the selected row to be prepared, without granting exsh or rootd endpoint authority. The next pristine replay passed all three new children, but exposed an independent script-route rendezvous error before the final launch. A behavior-preserving diagnostic encoded 0xE2100006: after non-blocking receive reported a transfer waiter, the armed blocking receive resumed with retryable status 6. Launchd 6c1f58e returns that outcome to bounded polling while retaining fail-stop handling for terminal receive errors. It also reserves transaction receipt ranges only across inventory-proven empty local slots, so handed-off cleanup authority cannot become an implicit reusable destination. The negative prefix then passes before the diagnostic-free positive pipelines, proving both pre-BEGIN denial and finite-predecessor observation on the same ext4-only path. With diagnostics removed, the focused VM passes the three-stage isolation proof, the prior redirection-precedence pair, exact cleanup, and final readiness. The exact-state replay pins lib-ipc 96cffcf, launchd 2949549, exsh 6dd0a0a, and rootd e4a1270; with a conservative 1,800-second single-vCPU host budget, it passes nondefault IFS plus readonly-set and readonly-declared-unset child-state assertions while keeping exsh on the ext4 runtime partition rather than adding it to the boot image. Scenario builds request the initial shell only for disk-image modes. The historical standalone-appliance regression keeps that launch disabled, but its secondary disk is now derived from the self-contained image so the production ext4 program store remains available after mount. The derivation replaces the copied ESP with a valid empty FAT32 filesystem: the packaged ESP tree is the sole firmware boot source, /boot remains mountable, and loaderd, dynlinkd, and procd load post-mount services from unchanged ext4 bytes. Boot-image-only VMs still do not convert textual program configuration into unavailable filesystem authority. Direct release packaging retains its configured auto selection for the disk artifact pipeline.

The dynamic-linking shared-object pipeline is scripts/build-dynlink-shared-objects.py. It scans library package manifests, compiles each owning library crate to a target-none PIC object plus compiler metadata sidecar, links one real ELF64 ET_DYN erix-<package>.so per package/version/target/feature/ABI identity with ld.lld, records normal, target-specific, optional, build, dev, and proc-macro dependency policy in erix-dynlink-shared-object-registry-v2, and lets image packaging copy those prebuilt objects instead of synthesizing per-executable dependency bytes. Each zone-assigned shared-object image copy is stripped of non-runtime debug and static-symbol metadata before its image hash is recorded; required dynamic-linking sections and .erix_dynlink remain intact. Registry source artifacts remain byte-identical and are never used as mutable packaging scratch. Each object identity commits to the exact owning source revision and the ordered build identities of its dependency closure, so a source or transitive dependency revision cannot reuse a stale logical object identity. tests/dynlink-shared-object-pipeline.sh covers deduplication, DT_NEEDED transitive object inclusion, real library symbols, compiler metadata sidecars, compiler metadata dependency closures for downstream rustc-only executable links, stale-hash rejection, and missing-transitive failure; dynlink-real-shared-objects is the focused VM group.

The dynamic-linking prebuilt-consumption gate is scripts/check-dynlink-prebuilt-consumption.py. It reads the shared-object registry before each kernel or service build in DYNLINK_PREBUILT_MODE=required, rejects missing, stale, wrong-target, wrong-feature, wrong-ABI, manifest-digest-mismatched, source-fallback, or static-bundle inputs, and writes erix-dynlink-prebuilt-link-plan-v2 metadata for every Cargo manifest dependency consumed as a shared object. Plans carry the source revision and dependency build identities committed by the registry. tests/dynlink-prebuilt-consumption.sh covers source-checkout-free link planning, repeated dependency reuse, source-revision invalidation, transitive identity invalidation, and negative registry mutations; dynlink-prebuilt-consumption is the focused VM group.

The dynamic-linking kernel dynamic artifact gate is scripts/build-dynlink-kernel-artifact.py plus the kernel-specific artifact inspection path in scripts/check-dynlink-artifact-metadata.py. Dynamic image packaging consumes kernel-dyn.elf as the kernel executable; VM, appliance, and disk-image runners fail if that dynamic kernel fixture is absent. No static kernel comparison fixture is built or staged. With a shared-object registry, the generated artifact is linked from kernel-owned PIC objects, the target-none Rust runtime shim, Rust core/alloc/compiler-builtins archives, and DT_NEEDED edges to the prebuilt shared objects. The direct rustc PIC path expands the kernel crate's Cargo feature implications before compiling dynamic objects, so dynamic-kernel cfg gates match the crate manifest. The shim supplies the current Rust allocator ABI functions plus one exported copy of the C memory helpers used by early shared-object relocations. It is an ELF64 ET_DYN PIE with erix_dynlink_entry, entry ABI erix-kernel-relocated-entry-v2, handoff pointer register rdi, exact handoff-size register rsi, entry-only exports, undefined dependency implementation/import symbols, relocation records, and dependency metadata matching dynlink-dependency-records.toml. tests/dynlink-kernel-artifact.sh covers missing dependency metadata, static-artifact rejection, import relocation checks, and accidental dependency-export definitions inside the executable; dynlink-kernel-artifact is the focused VM group.

Bootloader negative VM scenarios use the same dynamic kernel fixture before mutating boot.img. When they exit early on a rejection marker, the VM harness runs QEMU under its own process group and tears down that group before returning; it also sweeps any remaining process with the exact scenario serial-log argument before returning. tests/bootloader-vm-early-marker-cleanup.sh covers the no-stale-QEMU regression. Serial marker success is token-boundary aware: a terminal marker such as ERIX_ROOTD:READY does not match staged readiness markers such as ERIX_ROOTD:READY:PROCD, so final-ready VM exits wait for the real terminal stamp.

The dynamic-linking dynamic-kernel relocation path is covered by dynlink-kernel-relocation. The group runs a positive VM that boots through kernel-dyn.elf from the signed dynlink-store, resolves kernel dependency imports from validated shared-object exports, and now includes missing-object, stale-object, missing-export, duplicate-export, unsupported-relocation, and W^X negatives that exit on bootloader markers before ERIX_KERNEL:ENTER. The VM harness prepares bootloader exact-revision sources for its UEFI build while isolating the helper boot-tool build so local override patches do not create Cargo warning noise. In a monorepo checkout those dependency checkouts may fetch the selected commit objects from sibling local repositories, while Cargo resolves canonical URLs through generated mirrors that preserve the original commit IDs.

The dynamic-linking dynamic boot catalog handoff path is covered by dynlink-boot-catalog. The group runs only the new positive catalog handoff scenario and the duplicate logical-name negative. It requires ERIX_BOOTLOADER:DYNLINK_CATALOG_READY, ERIX_KERNEL:DYNLINK_CATALOG_OK, and ERIX_ROOTD:READY on the positive path, while the negative exits on ERIX_BOOTLOADER:DYNLINK_CATALOG_DUPLICATE_NAME before kernel entry.

The kernel entry length contract is covered independently by kernel-handoff-length. This new focused group boots only the positive pointer-and-length path and requires ERIX_KERNEL:HANDOFF_SIZE_OK before dynamic catalog parsing and root readiness. It forbids both the exact-length failure marker and the general handoff failure marker.

The normalized service-resolution receipt contract is covered independently by named-resolution-receipt. Its sole new scenario launches the dynamic lookup and time helpers, requires their successful completion markers, and therefore proves that callers reserve the full receipt-bearing reply and authenticate the transferred endpoint before use.

The dynamic-linking dynamic rootd bootstrap path is covered by dynlink-rootd-bootstrap. The group runs only the new positive scenario plus focused negatives for missing dependency, relocation failure, W^X permission rejection, and stale shared-object hash. It selects rootd_test_mode=dynlink-rootd-bootstrap, requires dynamic boot catalog markers, kernel ROOTD_DYNBOOT markers, and ERIX_ROOTD:DYNLINK_ROOTD:INTAKE_OK on success. The relocation negative retargets a counted R_X86_64_RELATIVE entry to text and requires kernel cleanup plus ROOT_SLOT_POLICY_VIOLATION, and the group keeps older VM groups out of the focused run.

The dynamic-linking pre-procd dynamic launch path is covered by dynlink-pre-procd. The group runs only the new positive scenario plus focused negatives for missing dependency, unresolved symbol, dependency cycle, W^X permission rejection, and cleanup after partial launch. It selects rootd_test_mode=dynlink-pre-procd, requires dynamic boot catalog and dynamic rootd intake markers, and on success requires ERIX_ROOTD:DYNLINK_PRE_PROCD:MEMD_OK, ERIX_ROOTD:DYNLINK_PRE_PROCD:VSPACED_OK, ERIX_ROOTD:DYNLINK_PRE_PROCD:PAGERD_OK, ERIX_ROOTD:DYNLINK_PRE_PROCD:PROCD_OK, and ERIX_ROOTD:DYNLINK_PRE_PROCD:READY without starting dynlinkd.

The dynamic-linking procd early dynamic spawn path is covered by dynlink-procd-spawn. The group runs only the new positive scenario, selects rootd_test_mode=dynlink-procd-spawn, requires dynamic boot-catalog and dynamic rootd intake markers, reuses the dynamic procd from the pre-procd path, then requires procd-mediated denied-object, abort, cleanup, map, start, and ready markers for dynamic memd, vspaced, and pagerd before dynlinkd is available.

The dynamic-linking bootstrap helper port is covered by dynlink-bootstrap-helpers. The group runs only the new positive scenario, selects rootd_test_mode=dynlink-bootstrap-helpers, packages probe, exit, isolation-a, isolation-b, and fault-kill as dynamic boot artifacts, then launches them through the rootd/procd early dynamic path. The verifier requires the existing lazy-fault, isolation, expected-kill, and exit semantics plus the ERIX_ROOTD:DYNLINK_BOOTSTRAP_HELPERS:CLEANUP_OK resource cleanup marker.

The dynamic-linking core-service coordination port is covered by dynlink-core-services. The group runs only the new positive and missing-dependency scenarios, selects rootd_test_mode=dynlink-core-services, packages named, logd, crashd, timed, lookup-client, and time-client as dynamic boot artifacts, and launches them through the rootd/procd early dynamic path. The verifier requires denied-object cleanup plus lookup, logging, crash, and time markers while forbidding dynlinkd startup.

The dynamic-linking hardware, console, and input port is covered by dynlink-hardware-console-services. The group runs only the new positive and missing-dependency scenarios, selects rootd_test_mode=dynlink-hardware-console-services, packages irqd, deviced, probed, hotplugd, drv-acpi, driver-capcheck, driver-hold, irq-client, drv-serial, seriald, fbcond, drv-i8042, drv-ps2-keyboard, drv-ps2-mouse, and inputd as dynamic boot artifacts, and launches the rootd-managed services through the rootd/procd early dynamic path. The verifier requires interrupt delivery, driver registration, serial and framebuffer console continuity, and the i8042 authority-partition marker while active input delivery remains post-mount behind ext4-only ttyd. Missing dynamic dependencies fail before device or IRQ authority is retained. The positive scenario enables deviced's integration-only background-reconcile deferral so discovery reports do not start drivers until rootd exercises the explicit admin verification path. Dynamic service artifact builds expand the service crate's Cargo feature graph before the direct rustc PIC compile, keeping integration feature aliases aligned with their runtime cfg gates.

The dynamic-linking storage/filesystem/loader port is covered by dynlink-storage-services. The group runs only the new positive and missing-dependency scenarios, selects rootd_test_mode=dynlink-storage-services, uses the loader-fs media, packages drv-virtio-block, blockd, ramfsd, keyd, e2fsd, fatd, vfsd, dynlinkd, and loaderd as dynamic artifacts, starts dynlinkd before loaderd, and keeps loader process handoff explicit. The fixture mode selection treats this stack as both a loader stack and a dynlinkd stack, so the generated dynlinkd boot-config node always has a matching packaged dynamic service artifact before loaderd can start. The verifier requires storage, VFS, loader, disk-execution, process-handoff, and fail-closed missing-object markers while preserving the existing explicit block, filesystem, key, VFS, loader, and procd authority bundles.

The dynamic-linking dynamic materialization fixture extends loader-fs with /lib/erix/dynlink/objects/filesystem/libdep.so. The disk-backed /bin/dyn-loader-ok executable relocates a dependency pointer and exits with the byte loaded from that object. The complete-graph scenario proves those dependency bytes execute through the same filesystem launch path instead of boot-image module bytes or a summary-only handoff.

The dynamic-linking artifact metadata gate is scripts/check-dynlink-artifact-metadata.py plus dynlink-artifact-abi.toml. The ABI record fixes the supported Rust/no-std dynamic artifact shape as ELF64 x86_64 ET_DYN, .erix_dynlink metadata, PIE executable or shared-object kind, erix_dynlink_entry for executables, panic-abort/no-unwind, and unsupported TLS, init/fini, lazy binding, IFUNC, text relocations, and unwind features. Generated dynamic dependency objects are inspectable ELF fixtures with .dynamic, .dynsym, .rela.dyn, SysV hash, and .erix_dynlink sections. The checker runs before packaging and fails if metadata is missing, hashes are stale, unsupported features are declared, or bootloader stops being the only static executable exception. Image manifests pass --strict-executables before every boot image, runtime appliance, and disk-image packaging path. Non-bootloader executable artifact bytes are inspected with the same ET_DYN and metadata rules before any VM boot can use them, so kernel, rootd, services, and drivers cannot silently fall back to static artifacts. After coordinated CI artifact builds, CI also runs scripts/check-dynlink-porting-wave-gates.py over the generated executable inventory, searching the consolidated component tree and any focused VM worker component trees that exist. Every artifact actually built must be dynamic and have dependency metadata matching dynlink-dependency-records.toml; migrated targets not selected by that scenario set are reported as unbuilt rather than treated as failed builds. Ordinary sibling-repository Cargo outputs are not packaging artifacts and are excluded unless a caller explicitly names them with --artifact-root. Callers that intentionally build the complete migrated inventory can add --require-all-artifacts. Service-state packaging also patches deviced with the configured binding and HAL-registration record counts. The corresponding exact typed arena replaces the daemon's former crate-wide 16-record tables without granting allocator authority or exposing page-rounding padding. It patches irqd from the configured handler-record count in the same pass; the focused capacity image carries 256 records in a two-page arena. It patches crashd from the configured report-record count as well; the new focused capacity VM packages 512 records, accepts a procd crash report, and proves typed readback through the authority-partitioned public endpoint. The final staged VM boot service fixtures are independently checked by scripts/lib/dynamic-boot-fixtures.sh, which invokes the same metadata checker on each copied service path before fonts, boot config generation, or boot image publication.

The dynamic-linking lookup-manifest gate is part of scripts/build-dynlink-image-manifest.py and scripts/verify-dynlink-image-closure.py. Generated image manifests now carry erix-dynlink-lookup-manifest-v1 dependency rows that map every executable dependency to an object path, object hash, metadata hash, version, object ABI, object identity, allowed lookup root, and stable load order. The only native lookup roots are the boot-image early bundle and the runtime filesystem object store; current-directory lookup, global search paths, service-discovery bypass, and direct block-device lookup are forbidden. tests/dynlink-lookup-manifests.sh and dynlink-lookup-manifests cover the focused host and VM gates.

The dynamic-linking acceptance-closure gate is scripts/check-dynlink-acceptance-closure.py plus dynlink-acceptance-closure.toml. It maps the six executable porting waves and every dynamic-linking acceptance criterion to runnable scenario groups or host CI gates, validates that each non-bootloader migration row is assigned to a wave, and keeps bootloader as the only approved static executable exception. CI runs the map with final runtime migration enabled for the closure scenario: kernel and service rows must be migrated, kernel has no static boot-artifact exception, and category = "tool" host-tool rows remain tracked without becoming runtime image exceptions. The focused dynlink-final-migration-closure group runs --require-final-migration before image build and boot. The focused bootimg-dynamic-focused group is also mapped as the dynamic boot-image VM coverage criterion. The migration inventory classifies ext4-only exsh as migrated; full POSIX shell-language completion is a product milestone, not a reason to misclassify the executable's already completed dynamic packaging and launch path. dynamic-linking documentation additionally requires the generated closure-report.json and filesystem mirror rows to be usable as operator evidence for boot.img inspection, mirror comparison, and dynamic failure-class triage.

All scenario classes execute as VM boots. The default full-system scenario validates core multi-service bootstrap smoke (bootloader -> kernel -> rootd -> {memd,vspaced,pagerd,procd} contract checks), and runtime appliance/disk-image scenarios boot their packaged images to the terminal ERIX_ROOTD:READY stamp unless they are explicit negative media tests. The current packaging workflow does not boot them. The complete catalog and focused groups remain available for local or separately requested validation without running older VM scenarios in the current pushed gate.

Filesystem Compliance and Strict Gate

scripts/fs_compliance_matrix.py is the checked cross-filesystem status matrix. It records FAT12, FAT16, FAT32, VFAT, exFAT, ext2, ext3, and ext4 rows as read-write, read-only, rejected, obsolete-rejected, or planned, and links accepted states to unit tests, deterministic media, host producer tools, host verification tools, and VM scenarios. Negative media is grouped by malformed feature bits, metadata checksums, geometry, allocation accounting, directory entries, journal state, and bitmap state. Operation probes are checked alongside the status matrix. They record the current provider result for mount, open/create, read/write, directory, rename, truncate, symlink/readlink, hard-link, metadata-update, unlink/rmdir, and xattr surfaces for each FAT/exFAT/ext format. The matrix checker rejects rows that advertise a mutable operation while the current provider path is explicitly denied, and it documents preservation-only or permanent non-goal surfaces without adding new provider authority.

tests/fs-compliance-matrix.sh remains available as a local matrix-drift diagnostic without running a VM. In an integration-only checkout, cross-repo evidence is resolved from out/components/<repo> after scripts/clone-components.sh; in a monorepo checkout, sibling repos such as ../fatd and ../e2fsd are used directly. CI relies on the focused fs-compliance-matrix VM scenario group instead of running the standalone matrix checker as a separate gate. scripts/fs-strict-validation.sh is the local strict filesystem slice gate: it runs the ext feature-registry and ext interoperability checkers, then runs cargo fmt --all -- --check, cargo clippy --all-targets -- -D warnings, and cargo test --all-targets for the filesystem Rust repos, and finally runs the focused fs-compliance-matrix VM scenario group unless ERIX_FS_STRICT_SKIP_VM=1 is set.

Every scenario is parsed once as strict schema-version-1 TOML before fixture construction. scripts/parse-scenario.py rejects duplicate or unknown keys, wrong scalar types, unsupported product-independent enum values, invalid cross-field combinations, non-positive CPU counts, negative timeouts, filename / scenario-name mismatches, and duplicate names across the committed scenario set. Boolean fields such as qemu_block_readonly use native TOML booleans; qemu_smp_cpus and qemu_timeout_secs use native TOML integers. The shell runner receives only shell-quoted assignments whose field names come from that closed schema.

Scenario schema includes rootd bring-up controls:

  • kernel_rootd_test (none|smoke|runtime)
  • rootd_test_mode (none|smoke|force-fail|bootstrap-*|core-service-*|hardware-*|console-and-input-*|storage-*|input-readiness|multi-block-provider|dynlink-rootd-bootstrap|dynlink-pre-procd|dynlink-procd-spawn|dynlink-bootstrap-helpers|dynlink-core-services|dynlink-hardware-console-services|dynlink-storage-services)
    • in current implementation this is translated into a generated BootConfig payload (out/fixtures/boot-config.bin) instead of selecting rootd launch arrays at compile-time
    • publication flags are emitted only for the target-scoped pagerd, timed, and irqd services and only when named is present; bootstrap-only graphs carry no discovery declaration
    • loader-contract selects validation profile 26 and the same memory-provider/vfsd service stack as vfs-memory
    • loader-fs-discovery, loader-materialized-launch, and loader-cleanup-authority select distinct validation profiles 27, 28, and 29 over the same canonical topology; Cargo features cannot select or override the loader verifier policy
    • multi-block-provider selects validation profile 21, the ordinary storage launch graph, and an additional rootd proof that the namespace contains at least two distinct physical whole-disk providers
    • input-readiness selects the pre-mount input graph and proves the partitioned i8042 diagnostics and translator endpoints without injecting an event that would require ext4-only ttyd
    • dynlink-rootd-bootstrap selects validation profile 34, the bootstrap foundation service stack only, and the dynamic rootd bootstrap verifier
    • dynlink-pre-procd selects validation profile 35, the bootstrap foundation service stack only, and the dynamic pre-procd service launch verifier
    • dynlink-procd-spawn selects validation profile 36, the bootstrap foundation service stack only, and the procd-mediated early dynamic service spawn verifier
    • dynlink-bootstrap-helpers selects validation profile 37, the bootstrap helper dynamic launch verifier
    • dynlink-core-services selects validation profile 38, the core-service coordination dynamic launch verifier
    • dynlink-hardware-console-services selects validation profile 39, the hardware, console, and input dynamic launch verifier
    • dynlink-storage-services selects validation profile 40, the storage, filesystem, VFS, and loader dynamic launch verifier
  • dynlinkd_test_mode (none|smoke|force-fail)
    • controls the dynlinkd service binary features for complete loader profiles, including rootd_test_mode=dynlink-storage-services
  • dynlink_final_migration_mode (disabled|required)
    • when required, regenerates executable inventory, requires acceptance closure before build, and forces every executable in the selected boot graph through dynamic artifact generation
  • runtime_config_profile (dev|release)
    • selects runtime.<profile>.toml at integration repo root
  • runtime_config_path (optional, relative to integration root or absolute)
    • explicit runtime TOML override for scenario/appliance builds
    • if omitted, runtime.<profile>.toml is used
    • local overrides must be selected explicitly, for example RUNTIME_CONFIG_PATH=runtime.local.toml
    • features.program_loader=true adds loaderd behind the loader runtime toggle, requires VFS plus ext-backed storage, and selects loader-fs for automatic block-storage fixture media
  • require_markers and forbid_markers accept comma-separated exact markers; a trailing * selects an entire marker prefix for family-wide assertions
  • unique_markers accepts the same syntax and requires each selected marker to occur exactly once in the serial log
  • ordered_markers accepts the same syntax and requires the selected markers to occur in the listed serial-log order
  • block_storage_image (auto|none|gpt|malformed-gpt|fs|loader-fs|fs-ext2|fs-ext2-indirect|fs-ext2-compat|fs-ext2-xattr|fs-ext2-geometry-512|fs-ext2-links|fs-ext2-rename|fs-ext2-corpus-1k|fs-ext2-corpus-2k|fs-ext2-corpus-4k|fs-ext3|fs-ext3-replay|fs-ext3-external-journal|fs-ext3-jbd2-legacy|fs-ext3-jbd2-csum-v2|fs-ext3-jbd2-csum-v3|fs-ext3-many-journal|fs-ext3-fast-commit|fs-ext3-htree|fs-ext3-htree-depth0|fs-ext3-htree-depth1|fs-ext3-geometry-512|fs-ext3-links|fs-ext3-rename|fs-ext4-metadata|fs-ext4-extent-tree|fs-ext4-bigalloc|fs-ext4-meta-bg|fs-ext4-stable-resize|fs-ext4-xattr|fs-ext4-quota|fs-ext4-orphan-list|fs-ext4-orphan-file|fs-ext4-mmp|fs-ext4-large-dir|fs-ext4-encrypted|fs-ext4-encrypted-casefold|fs-ext4-casefold|fs-ext4-inline|fs-ext4-verity|fs-ext4-verity-salted|fs-ext4-verity-large|fs-ext4-shared-blocks|fs-ext4-geometry-512|fs-ext4-links|fs-ext4-rename|fs-fat12|fs-fat12-metadata|fs-fat16|fs-fat16-metadata|fs-fat32-primary-only|fs-fat32-mirrored|fs-fat32-active-fat|fs-fat32-metadata-clean|fs-fat32-directory-metadata|fs-fat32-metadata-set|fs-fat32-short-name|fs-fat32-rename|fs-fat32-vfat-unicode|fs-fat32-stress|fs-fat32-deep-directory|fs-exfat|fs-exfat-boot-region|fs-exfat-stale-backup|fs-exfat-one-fat|fs-exfat-active-fat|fs-exfat-unicode|fs-exfat-contiguous|fs-exfat-stream-metadata|fs-exfat-metadata|fs-exfat-entry-types|fs-exfat-rename|fs-exfat-corpus|malformed-fat|malformed-exfat|exfat-bad-upcase-table|exfat-bad-name-hash|exfat-duplicate-upcase-name|exfat-malformed-utf16-name|exfat-bad-main-boot|exfat-bad-backup-boot|exfat-bad-extended-boot|exfat-boot-region-mismatch|exfat-dirty-volume|exfat-media-failure|exfat-invalid-active-fat|exfat-reserved-volume-flags|exfat-duplicate-bitmap-entry|exfat-duplicate-upcase-entry|exfat-bad-bitmap-entry|exfat-bad-bitmap-length|exfat-corrupt-directory-set|exfat-bad-entry-type|exfat-bitmap-fat-mismatch|exfat-duplicate-cluster|exfat-no-fat-missing-bitmap|exfat-leaked-cluster|exfat-chain-loop|exfat-out-of-range-chain|exfat-invalid-valid-data|malformed-ext|ext2-inconsistent-block-geometry|ext3-inconsistent-block-geometry|ext4-large-inode|ext2-bad-block-map|ext2-bad-dirent|ext2-bad-inode-size|ext2-bad-bitmap|ext2-reserved-inode-corruption|ext-needs-recovery|fat-mirror-mismatch|fat-cluster-loop|fat-bad-lfn|fat-bad-lfn-ordinal|fat-orphan-lfn|fat-duplicate-alias|fat-short-leading-e5|fat-oem-short-name|fat-invalid-nt-flags|fat-ambiguous-lfn-alias|fat-bad-cluster-chain|fat-file-chain-loop|fat-cross-linked-files|fat-out-of-range-chain|fat32-bad-fsinfo-count|fat32-bad-backup-boot|fat32-dirty-metadata|fat32-hard-error-metadata|fat32-bad-reserved-entry|ext-checksum-failure|ext-unsupported-feature|ext-obsolete-feature-corpus|ext-unknown-feature-corpus|ext-unknown-feature-gap-corpus|ext-readonly-feature|ext-shared-blocks-feature|ext-journal-device-volume|ext-bigalloc-bad-bitmap|ext4-meta-bg-bad-descriptor|ext4-encrypted-missing-key|ext4-encrypted-wrong-key|ext4-encrypted-casefold-missing-key|ext4-encrypted-casefold-wrong-key|ext4-bad-fscrypt-policy|ext4-bad-encrypted-casefold-policy|ext4-bad-encrypted-casefold-name|ext4-bad-casefold-encoding|ext4-bad-casefold-name|ext4-bad-xattr|ext4-bad-quota|ext4-bad-orphan-list|ext4-bad-orphan-file|ext4-bad-mmp-active|ext4-bad-mmp-checksum|ext4-bad-inline-data|ext4-bad-verity-data|ext4-bad-verity-algorithm|ext4-bad-verity-signature|ext4-verity-signature|ext4-verity-encrypted|ext4-bad-verity-merkle|ext-external-journal|ext-jbd2-unknown-feature|ext-jbd2-csum-failure|ext-fast-commit-mutating|ext-fast-commit-htree|ext-fast-commit-linear|ext-fast-commit-bad-tail|ext-external-journal-uuid-mismatch|ext-external-journal-misroute|ext-malformed-extent|ext-malformed-htree|ext-malformed-htree-index|ext-malformed-htree-deep)
    • auto attaches the deterministic GPT disk only when features.user_storage=true and features.storage_virtio=true
    • non-none variants attach a secondary raw modern-only virtio-blk disk to QEMU (virtio-blk-pci,disable-legacy=on) in read-only mode so the deterministic fixture cannot be rewritten during negative-path boots
    • fs builds a GPT disk with erix-esp FAT32 and erix-data ext4 partitions; loader-fs uses a clean ext2 erix-data partition and adds executable /bin ELFs with distinct byte fingerprints and exit markers, a dynamic dependency object at /lib/erix/dynlink/objects/filesystem/libdep.so, plus a changed-source ELF used to prove stale materialization fails before process start; host-side scenario verification checks those fingerprints are present only in the filesystem executable/object fixtures and absent from boot image service modules; fs-ext2 and fs-ext3 use clean ext2/ext3 data partitions for legacy provider coverage; fs-ext2-indirect adds a host-generated ext2 large-file corpus that crosses the direct-block boundary and verifies a VFS-created block-stride probe file after shutdown; fs-ext2-compat carries dir_prealloc, imagic_inodes, ext_attr, and resize_inode for ext2 compatibility safety coverage; fs-ext2-xattr adds user xattr and POSIX ACL payloads and verifies host debugfs plus e2fsck -fn xattr/ACL preservation after VM mutation, with getfattr/getfacl projection when FUSE is available; fs-ext2-geometry-512 keeps ext2 at the supported 4 KiB block limit while validating 512-byte inode tables and inline xattr preservation; fs-ext2-corpus-1k, fs-ext2-corpus-2k, and fs-ext2-corpus-4k broaden ext2 coverage with varied block/inode geometry, sparse superblocks, non-default blocks-per-group, grown directories, and sparse triple-indirect host files; ext2-inconsistent-block-geometry advertises a different block size without changing the encoded layout and therefore fails closed; ext2-bad-block-map, ext2-bad-dirent, ext2-bad-inode-size, ext2-bad-bitmap, and ext2-reserved-inode-corruption provide fail-closed malformed ext2 media; fs-ext3-replay, fs-ext3-external-journal, fs-ext3-jbd2-legacy, fs-ext3-jbd2-csum-v2, fs-ext3-jbd2-csum-v3, fs-ext3-many-journal, fs-ext3-fast-commit, ext-fast-commit-mutating, ext-fast-commit-htree, ext-fast-commit-linear, ext-fast-commit-bad-tail, fs-ext3-htree, fs-ext3-htree-depth0, fs-ext3-htree-depth1, and fs-ext3-geometry-512 exercise recovery-required replay, explicit same-disk external-journal partition selection, legacy and CRC32C checksum-v2/v3 JBD2 dialect validation, device-absolute external JBD2 log addressing independent of the journal-superblock offset, journal-ring replay without a fixed transaction-count cap, split provider-originated journaled writeback, ordered-data large writes, fast-commit no-delta validation, supported multi-segment mutating-delta replay, indexed-directory and multi-block linear dentry replay, and bad-tail fast-commit fail-closed media; ext3-inconsistent-block-geometry applies the same malformed-layout check to journaled media; indexed-directory ext3 mutation coverage; ext-malformed-htree-index and ext-malformed-htree-deep keep malformed index layouts and non-large_dir depth-2 HTree metadata fail-closed; these malformed fixtures keep scenario-local QEMU timeouts because they must prove public mount exposure before the focused malformed-directory operation fails; ext-external-journal, ext-journal-device-volume, ext-external-journal-uuid-mismatch, and ext-external-journal-misroute cover fail-closed missing mapping, standalone journal-device, UUID, and BootConfig mapping failures; fs-ext4-metadata adds metadata checksums and a host-built indexed HTree directory; fs-ext4-extent-tree fragments free space so VFS-created large files spill into indexed extent leaf blocks and are checked after shutdown; the focused ext sparse scenario reuses that media to prove write-past-EOF gaps stay unmapped with host debugfs bmap and clean e2fsck -fn; fs-ext4-bigalloc uses e2fsprogs bigalloc media to prove cluster bitmap and free-count accounting, while ext-bigalloc-bad-bitmap flips a free cluster bit without fixing counters so mount validation fails closed; fs-ext4-meta-bg uses e2fsprogs meta_bg descriptor placement with non-default blocks-per-group, and ext4-meta-bg-bad-descriptor corrupts s_first_meta_bg so e2fsd rejects impossible descriptor layout; fs-ext4-stable-resize carries stable_inodes plus resize_inode media so VM mutation, host e2fsck -fn, and generator checks cover stable inode mutation safety and resize-reserved metadata preservation; fs-ext4-xattr carries metadata-checksummed external xattr blocks, inline inode-body xattr metadata, a large user xattr, and a POSIX ACL, verifies preservation with host debugfs plus e2fsck -fn, projects getfattr/getfacl checks when FUSE is available, while ext4-bad-xattr corrupts the external xattr checksum for fail-closed validation; fs-ext4-quota carries user/group/project quota metadata and a PROJINHERIT directory, while ext4-bad-quota corrupts quota metadata for fail-closed validation; fs-ext4-orphan-list and fs-ext4-orphan-file carry recoverable legacy and orphan-file orphan state, while ext4-bad-orphan-list and ext4-bad-orphan-file cover fail-closed corrupt orphan metadata; fs-ext4-mmp carries clean metadata-checksummed MMP media, while ext4-bad-mmp-active and ext4-bad-mmp-checksum prove active and malformed MMP state fail closed; fs-ext4-large-dir carries ext4 large_dir media with a depth-2 HTree for VFS marker insertion and host debugfs/e2fsck -fn checks; fs-ext4-encrypted carries an fscrypt v2 encrypted host marker unlocked only through keyd startup material, while ext4-encrypted-missing-key, ext4-encrypted-wrong-key, and ext4-bad-fscrypt-policy prove missing material, mismatched material, and malformed policy modes fail closed; ext4-fscrypt-v1-policy, ext4-fscrypt-hctr2-policy, ext4-fscrypt-direct-key-policy, and ext4-fscrypt-data-unit-policy prove explicit non-goal fscrypt policies fail closed before key lookup; fs-ext4-encrypted-casefold carries an encrypted case-insensitive directory that is unlocked through keyd and verified by lookup plus readdir, while ext4-encrypted-casefold-missing-key, ext4-encrypted-casefold-wrong-key, ext4-bad-encrypted-casefold-policy, and ext4-bad-encrypted-casefold-name prove missing material, mismatched material, malformed policy metadata, and malformed encrypted names fail closed; fs-ext4-casefold carries host-created UTF-8 casefold directories with root-level folded lookup and indexed /htree mutation, while ext4-bad-casefold-encoding and ext4-bad-casefold-name prove unsupported encodings and malformed normalized names fail closed; fs-ext4-inline carries ext4 inline-data files and directories, verifies inline host and VFS markers with debugfs plus e2fsck -fn, and ext4-bad-inline-data proves malformed inline payloads fail closed; fs-ext4-verity carries a read-only Linux-layout fsverity host marker unlocked through a private keyd trust root, fs-ext4-verity-salted adds descriptor salt coverage, and ext4-bad-verity-data, ext4-bad-verity-algorithm, ext4-bad-verity-signature, ext4-verity-signature, ext4-verity-encrypted, and ext4-bad-verity-merkle prove fail-closed data, algorithm, malformed PKCS#7, unsupported signature-policy, encrypted verity, and Merkle-tree tamper rejection; fs-ext4-shared-blocks carries shared-block ext4 media with a depth-2 HTree and uses rootd's read-only profile for host-marker traversal, while ext-shared-blocks-feature proves read-write mount denial; fs-ext4-geometry-512 carries 4 KiB blocks and 512-byte inodes with metadata checksums, extents, an internal journal, indexed directories, inode-body xattrs, and inline-data payloads; ext4-large-inode proves 1,024-byte inode records mount and preserve their unknown tails during metadata mutation; fs-ext2-links, fs-ext3-links, and fs-ext4-links carry host-created fast and block-backed symlinks, regular-file hard links, and FIFO/character/block special inode metadata; the ext-links group verifies readlink/stat/link-count behavior and proves special-file metadata does not imply openable device authority; fs-ext2-rename, fs-ext3-rename, and fs-ext4-rename carry host-created rename fixtures for same-directory moves, cross-directory moves, compatible overwrite, directory .. repair, special metadata entries, and indexed HTree entries; the ext-rename group verifies the public VFS-visible results and leaves the media clean for host e2fsck -fn; fs-fat12, fs-fat12-metadata, fs-fat16, fs-fat16-metadata, fs-fat32-primary-only, fs-fat32-mirrored, fs-fat32-active-fat, fs-fat32-metadata-clean, fs-fat32-directory-metadata, fs-fat32-metadata-set, fs-fat32-short-name, fs-fat32-rename, fs-fat32-vfat-unicode, fs-fat32-stress, fs-fat32-deep-directory, fs-exfat, fs-exfat-boot-region, fs-exfat-stale-backup, fs-exfat-one-fat, fs-exfat-active-fat, fs-exfat-unicode, fs-exfat-contiguous, fs-exfat-stream-metadata, fs-exfat-metadata, fs-exfat-entry-types, fs-exfat-rename, and fs-exfat-corpus vary ESP media geometry, FAT32 extended-BPB policy, FAT32 reserved-entry state, FAT directory-entry metadata, VFAT Unicode/dense-alias entries, fragmented FAT allocation, grown directories, sparse-looking payloads, free-slot reuse, exFAT main/backup boot-region checksum policy, exFAT active-FAT/volume-state policy, exFAT upcase-table Unicode NameHash policy, exFAT no-FAT-chain allocation policy, exFAT ValidDataLength zero-fill behavior, and fragmented exFAT streams, plus 1 KiB exFAT clusters, two FATs, dual allocation bitmaps, a grown root chain, fragmented host data, deep Unicode-heavy paths, and spare allocation clusters for public VFS mutations while keeping the same clean ext4 data partition and storage marker flow; active-FAT media uses a direct FAT divergence check because dosfstools repairs the intentionally inactive FAT copy even when ExtFlags selects FAT 1; ext-obsolete-feature-corpus sets all obsolete ext feature bits rejected by e2fsd, ext-unknown-feature-corpus sets high future compat, incompat, and ro-compat bits, and ext-unknown-feature-gap-corpus sets currently undefined feature-bit gaps so negative VM scenarios prove fail-closed mount behavior before VFS state is exposed; e2fs-fat positives set qemu_block_readonly=false to exercise writable mount requests; e2fs-fat-readonly positives attach writable QEMU media but pass the VFS read-only mount flag for /
    • malformed-gpt corrupts the primary GPT header CRC and entry array after CRCs are written so storage fail-closed negatives stay deterministic
    • malformed FAT/ext variants derive from the filesystem disk and corrupt provider-specific media, including FAT mirror mismatch, FAT cluster loops, bad VFAT LFN entries, duplicate short aliases, bad referenced FAT chains, cross-linked files, out-of-range FAT links, inconsistent FSInfo counts, malformed exFAT upcase metadata, bad exFAT NameHash entries, duplicate exFAT upcase-equivalent names, malformed exFAT UTF-16 names, bitmap/FAT mismatches, duplicate exFAT cluster ownership, missing no-FAT-chain bitmap coverage, leaked clusters, exFAT chain loops, out-of-range exFAT starts, ext checksum- required media, unsupported/obsolete/unknown ext features, external journal metadata, standalone journal-device volumes, external-journal UUID/mapping failures, unknown JBD2 feature bits, JBD2 checksum failures, bad fast-commit tails and mixed/indexed/linear fast-commit replay after full commits, malformed extents, malformed HTree metadata, malformed ext4 casefold metadata, and malformed inline-data metadata
  • qemu_block_readonly (TOML Boolean)
    • defaults to true for existing block-storage scenarios
    • set to false only when a scenario intentionally validates writable media
  • disk_image_case (no-virtio-sata|single-virtio-junk-sata|single-virtio-esp-raw-sata|single-virtio-gpt|two-virtio-disks)
    • used with run_mode=vm-disk-image to boot the packaged .img through QEMU and validate SATA/virtio storage topology behavior
    • extra virtio disks are read-only unless the scenario adds the :rw suffix; the two-virtio case keeps junk media read-only while making the copied GPT storage disk writable for the runtime / mount
  • missing_service (none|memd|vspaced|pagerd|procd|probe|named|timed|logd|crashd|irqd|deviced|probed|hotplugd|drv-acpi|drv-serial|drv-virtio-block|seriald|blockd|fbcond|console-font|drv-i8042|drv-ps2-keyboard|drv-ps2-mouse|inputd|ramfsd|keyd|e2fsd|fatd|vfsd|lookup|time|irq|driver-hold|driver-capcheck)
    • in e2fs-fat, missing-provider negatives prove the specific absent provider blocks VFS exposure; the missing-FAT-provider case still expects E2FSD readiness because rootd starts the ext provider first
  • service_primary_control_fault (none|probed-omit-primary-control|probed-misroute-primary-control|drv-acpi-omit-primary-control|drv-acpi-misroute-primary-control|drv-serial-omit-primary-control|drv-serial-misroute-primary-control|drv-i8042-omit-primary-control|drv-i8042-misroute-primary-control)
    • integration-only authority-shape override for staged service startup
    • used to prove fail-closed behavior when a narrow primary-control endpoint is omitted or replaced with the wrong endpoint family
    • constructor-rejected variants must not require receiver retirement: the child never starts or binds a receiver after route validation fails
  • service_explicit_endpoint_fault (none|deviced-misroute-pci-config-endpoint|deviced-misroute-pci-device-endpoint)
    • integration-only wrong-kind auxiliary endpoint override for staged service startup
    • used to prove fail-closed validation of explicit endpoint source-slot and endpoint-kind contracts outside the primary control slot
  • service_startup_peer_fault (none|logd-inject-timed-resolution-scope|probed-omit-deviced-peer|probed-misroute-deviced-peer|probed-inject-undeclared-peer|inputd-omit-deviced-peer|inputd-misroute-deviced-peer|drv-serial-omit-deviced-peer|drv-serial-misroute-deviced-peer|drv-serial-misroute-logd-peer|vfsd-omit-memory-provider-peer|vfsd-misroute-memory-provider-peer|e2fsd-omit-blockd-peer|e2fsd-misroute-blockd-peer|e2fsd-omit-keyd-peer|e2fsd-misroute-keyd-peer|fatd-omit-blockd-peer|fatd-misroute-blockd-peer|vfsd-omit-e2fsd-peer|vfsd-misroute-e2fsd-peer|vfsd-omit-fatd-peer|vfsd-misroute-fatd-peer)
    • integration-only startup-peer override for split delegated peers
    • used to prove fail-closed rejection of omitted, misrouted, or undeclared startup peers for both root-launched and deviced-launched consumers
    • source/destination selection is an authority-free library result; rootd supplies both candidate pairs and remains the only component that validates and transfers the selected capability
    • project requirements: logd-inject-timed-resolution-scope -> rootd_test_mode=logging, probed-* -> rootd_test_mode=probe, inputd-* -> rootd_test_mode=input, drv-serial-* -> rootd_test_mode=serial, vfsd-omit-memory-provider-peer|vfsd-misroute-memory-provider-peer -> rootd_test_mode=vfs-memory, and e2fsd-*|fatd-*|vfsd-*-e2fsd-peer|vfsd-*-fatd-peer -> rootd_test_mode=e2fs-fat
    • the omitted memory-provider peer case may still require VFSD readiness as precursor evidence, but it must forbid VFS_MOUNT and VFS_IO
  • per-service build modes:
    • memd_test_mode, vspaced_test_mode, pagerd_test_mode, procd_test_mode, named_test_mode, timed_test_mode, logd_test_mode, crashd_test_mode, irqd_test_mode, deviced_test_mode, probed_test_mode, hotplugd_test_mode, drv_acpi_test_mode, drv_serial_test_mode, drv_virtio_block_test_mode, seriald_test_mode, blockd_test_mode, fbcond_test_mode, drv_i8042_test_mode, drv_ps2_keyboard_test_mode, drv_ps2_mouse_test_mode, inputd_test_mode
    • values: none|runtime|smoke|serial-probe|force-fail (serial-probe currently applies to drv_serial_test_mode)

Runtime policy:

  • kernel_rootd_test=runtime is bootstrap-only bring-up driven by generated BootConfig from runtime TOML, with validation_profile=none.
  • BootConfig v1.5 encodes compact timeout-free entries and dependency-role records in separate count-derived tables. Dependencies must name earlier entries, so the payload itself carries a canonical topological launch order without fixed graph or per-entry dependency ceilings. Every generated graph begins with the exact required direct-launch chain procd -> memd -> vspaced -> pagerd; the generator rejects attempts to omit any member, and the rootd ingress rejects insertion, reordering, stage reuse, cycles, undeclared edges, or duplicate roles. Private KYD1, EJRN, and MNT1 tail tables are likewise sized by their encoded row and path counts. A final optional FSL1 table binds each filesystem-launch entry in order to one exact role, canonical path, and role-private startup policy without embedding the executable.
  • Kernel-to-root module records carry the exact verified file size in addition to the page-rounded mapping extent, so rootd parses precisely the generated BootConfig bytes rather than mapping padding.
  • runtime VM scenarios opt into RUNTIME_IMAGE_TEST_HARNESS=1 so QEMU exits classed success/failure without enabling smoke-only service feature gates.
  • runtime/appliance kernel builds enable kernel-runtime-image; packaged dev and release artifacts leave RUNTIME_IMAGE_TEST_HARNESS=0 so kernel-rootd-smoke-test and integration debug-exit code are not included.
  • runtime/appliance rootd builds keep diagnostic chatter quiet as well: ERIX_ROOTD:TRACE:*, late VFS verifier probes, and focused test-marker mutation paths are reserved for integration smoke runs and must stay out of ordinary runtime/appliance serial output.
  • High-volume focused runtime fixtures, including the pipeline, wait, and native-time workflows, select the kernel's kernel-integration-runtime-quiet refinement. It removes only repetitive successful demand-fault, process-exit, lifecycle, and rootd/logd-reply debug projection while preserving exact RTC evidence, failure diagnostics, marker contracts, guest behavior, and the explicit host-report terminal.
  • runtime mode must not rely on synthetic probe/client workflows.
  • when features.user_storage=true and features.storage_virtio=true, the harness generates a deterministic GPT disk image locally and attaches it as a secondary raw modern-only virtio-blk disk for both subsystem and appliance runs. The disk stays read-only by default; full-system appliance profiles that request writable runtime mounts set qemu_block_readonly=false so the guest can create the configured namespace without weakening read-only media tests. Host policy validation rejects any block-backed writable mount in a full-system scenario whose QEMU medium remains read-only.
  • disk-image VM scenarios boot the built GPT appliance image directly and cover no virtio disk, junk virtio media, raw ESP-only virtio media, a single virtio GPT boot image, and a two-virtio-disk topology. Extra disks stay read-only by default, with an explicit writable suffix only for the storage disk that must satisfy a writable runtime mount.
  • storage-capable VM runners default to QEMU_MEMORY=1G, keeping the current DMA window rooted at 0x2000_0000 inside guest RAM for virtio queue/data buffers; callers can still override QEMU_MEMORY explicitly when needed.
  • smoke/negative matrices remain unchanged and continue to use integration smoke features.
  • smoke/negative matrices keep mode knobs as fixture-generation inputs and feed rootd through BootConfig payloads.
  • rootd_test_mode=stress-1k stays on the normal narrowed runtime endpoint inventory. Its leak-bound assertions use SNAPSHOT_RESOURCE_COUNTS over the dedicated process endpoint and do not inject kernel-rootd-test-root-endpoint. Only this profile enables procd's receipt-free integration stress batches; ordinary smoke and production builds cannot execute those batch operations.
  • runtime TOML also controls filesystem composition: user_vfs=true|false adds or removes the public vfsd service, while fs_ramfs, fs_e2fs, and fs_fat select the private filesystem providers that may be delegated to it. fs_e2fs also includes private keyd, which is required for ext fscrypt authority.
    • [[mounts]] rows are encoded into the generated BootConfig mount table and decide the runtime namespace layout independently of provider selection
    • runtime/appliance validation proves configured filesystem bring-up through ERIX_ROOTD:READY:VFSD, ERIX_ROOTD:READY:VFS_MOUNT, and ERIX_ROOTD:READY:VFS_IO; provider-ready markers appear only for selected providers
    • persistent runtime mount scenarios intentionally require storage/VFS and DRV_VIRTIO_BLOCK provider readiness, leaving serial, framebuffer, and input-provider readiness to the focused console-and-input scenarios
    • runtime BootConfig mount scenarios use provider-neutral basic VFS I/O, so FAT-root coverage does not require symlink/readlink or POSIX metadata semantics that FAT providers intentionally deny

Current integration checks consume these marker families:

  • ERIX_BOOTLOADER:* (bootloader startup and failure markers)
  • ERIX_KERNEL:* and ERIX_KERNEL_STUB:* (kernel bring-up/test markers)
  • ERIX_KRN:* (kernel library/runtime diagnostics)

Rootd smoke negatives now assert the specific reported failure class when available:

  • ERIX_KERNEL:ROOTD_SMOKE:CONTRACT_INVALID
  • ERIX_KERNEL:ROOTD_SMOKE:INTERNAL_ERROR
  • ERIX_KERNEL:ROOTD_SMOKE:SERVICE_FAIL

The generic ERIX_KERNEL:ROOTD_SMOKE:FAIL marker is reserved for unknown or legacy rootd failure reports.

The force-service-fail negative path now forces failure from rootd's real post-START_PROCESS startup handshake and requires ERIX_ROOTD:DBG:POST_START_CLEANUP_OK so the VM suite proves that the started child was torn down before exit class 0x14 is reported.

Bootstrap scenarios now assert staged rootd progress markers in order:

  • ERIX_KERNEL:ROOTD_STAGE:INTAKE_VALIDATED
  • ERIX_KERNEL:ROOTD_STAGE:MODULES_DISCOVERED
  • ERIX_KERNEL:ROOTD_STAGE:MEMD_READY
  • ERIX_KERNEL:ROOTD_STAGE:VSPACED_READY
  • ERIX_KERNEL:ROOTD_STAGE:PAGERD_READY
  • ERIX_KERNEL:ROOTD_STAGE:PROCD_READY
  • ERIX_KERNEL:ROOTD_STAGE:SERVICES_READY
  • ERIX_KERNEL:ROOTD_STAGE:PROBE_SPAWN_REQUESTED
  • ERIX_KERNEL:ROOTD_STAGE:PROBE_SPAWNED
  • ERIX_KERNEL:ROOTD_STAGE:PROBE_EVENT_RECEIVED
  • ERIX_KERNEL:ROOTD_STAGE:PROBE_COMPLETED

Resolved demand faults are normal runtime behavior and emit no ERIX_KERNEL:BOOTSTRAP:FAULT_* markers. Positive paging and isolation scenarios forbid that marker family; the expected-fault-kill scenario requires FAULT_RESOLVE_FAIL and FAULT_KILLED instead.

The focused subsystem-pager-write-protect-policy-positive scenario registers the write-protect helper with pagerd, then writes a present read-only page. It requires the kernel-policy and killed markers while forbidding every pager notification marker, proving pager registration does not delegate protection fault policy. The helper name is the complete product name and stays within the boot image's 15-byte service-name field; no compatibility alias is packaged.

Time scenarios additionally assert:

  • ERIX_KERNEL:ROOTD_STAGE:TIMED_READY
  • ERIX_KERNEL:ROOTD_STAGE:TIME_READY

Framebuffer scenarios additionally assert framebuffer continuity contracts and enforce fail-closed behavior when the console-font blob is missing.

Pre-mount input-readiness scenarios assert deterministic input stack staging and authority partitioning:

  • ERIX_DEVICED:READY:DRV_I8042
  • ERIX_DEVICED:READY:DRV_PS2_KEYBOARD
  • ERIX_DEVICED:READY:DRV_PS2_MOUSE
  • ERIX_KERNEL:ROOTD_STAGE:INPUTD_READY
  • ERIX_ROOTD:READY:I8042_AUTHORITY_PARTITION

The focused pre-mount active-input negative additionally requires ERIX_ROOTD:INPUT_ROUTING:TTYD_REQUIRED and forbids the input-routing and console-input stage markers. A future post-mount positive must include the ext4-loaded ttyd graph before it may claim those end-to-end markers.

Service deployment-capacity VMs use service-specific runtime configurations, but retain the complete signed native-CLI service and mount topology. Every such configuration reserves at least 80 MiB of kernel heap; the parser rejects the former 64-MiB fixtures before image construction. Service-private arena sizes remain the only values varied by each capacity scenario. The host authority test enumerates every scenario-selected runtime-config path and runs the same parser over each unique file, so a focused configuration cannot drift below the floor without failing before CI enters QEMU.

The current dev-runtime positive VMs use the production disk-image path. They must load ttyd, powerboxd, launchd, and exsh from ext4 through the ordinary loaderd/dynlinkd/procd graph. The loader boot-image scenario instead uses a loader-only runtime configuration to isolate its pre-mount contract.

The cumulative dynamic-spawn fixture executes the memd, named, and deviced negative transcripts immediately before memd. This is the last boundary where the explicit Foundation process-control source needed for exact resource snapshots still exists; the ordinary Foundation retirement remains unchanged, and later named/deviced staging receives no residual kernel process authority.

Current unwanted-explicit-authority negatives additionally cover:

  • an undeclared timed resolution scope injected into logd
  • wrong-kind auxiliary explicit endpoint transfer into deviced
  • wrong-kind PCI-device/MMIO explicit endpoint transfer into deviced
  • root-launched split startup-peer misroutes such as inputd -> deviced
  • deviced-launched split startup-peer misroutes such as drv-serial -> deviced
  • drv-serial's authenticated log client misrouted into the generic log slot
  • subsystem-scoped startup-peer harness validation so hardware, console, and input delegated-peer negatives run under the matching rootd bring-up mode instead of being misclassified as probe-only

The deviced-evidence-authority-regressions group binds the eight ACPI, i8042, and pre-serial driver negatives whose fail-closed result must remain observable without granting deviced authority to select a log sink.

The matching subsystem-logd-scoped-resolution-positive scenario proves that the declared seriald and fbcond scopes materialize and reach terminal readiness; subsystem-logd-cross-scope-negative proves the extra timed scope is rejected before logd readiness.

The authenticated-producer-endpoints group proves the deviced-launched producer boundary: its positive scenario reaches drv-serial and both PS/2 drivers through fixed clients, while its negative scenario requires drv-serial to reject a log client installed in the generic service slot. The independent producer-ready markers are checked for presence and uniqueness rather than a scheduler-dependent total order; only the logd, inputd, i8042-authority-partition, and terminal root barriers form an ordered chain.

EXT-CROSS validation is tracked by a repository-local manifest:

  • scripts/check-ext-cross-corpus.py compares the e2fsd feature registry against scripts/ext_cross_corpus.py, verifies that every accepted feature has focused positive VM coverage, checks malformed-media negatives for fail-closed VFS exposure, recomputes every scenario's fsverity trust material from the fixture payload and salt, pins authority-negative scenarios, and enforces the 1k LoC boundary on near-limit ext media modules.
  • scripts/check-fs-compliance-matrix.py also validates the advanced ext corpus rows in scripts/ext_cross_corpus.py, requiring implemented, planned, rejected, obsolete-rejected, and permanent non-goal classes to carry VM scenarios, unit evidence, and documentation links before the matrix can pass.
  • scripts/check-ext-interoperability-corpus.py validates the Linux/e2fsprogs ext interoperability matrix in scripts/ext_interop_corpus.py. The matrix links each ext2/ext3/ext4 corpus image to the feature bits it proves, required host tools, malformed companions, and provider-mutation VM scenarios.
  • tests/ext-cross-corpus.sh is the unit-style entrypoint for the manifest check and runs in CI after the selected component commits have been cloned.
  • tests/ext-interoperability-corpus.sh is the unit-style entrypoint for the interoperability matrix check.
  • tests/scenario-groups/ext-cross-*.txt groups the focused VM subsets for feature positives, feature-registry negatives, malformed ext media, and authority regressions; tests/scenario-groups/ext-interoperability-corpus.txt groups the focused ext2/ext3/ext4 Linux/e2fsprogs corpus VM subset; tests/scenario-groups/host-report-authority.txt contains only the new root-only reporting-authority VM proof; tests/scenario-groups/vfs-memory-provider-rename.txt groups the renamed volatile-memory provider VFS scenarios; tests/scenario-groups/fat-01.txt groups the targeted FAT32 extended-BPB media scenarios, and tests/scenario-groups/fat-02.txt groups FAT32 reserved-entry, dirty-state, and hard-error-state scenarios. tests/scenario-groups/fat-03.txt groups FAT12/FAT16/FAT32 directory metadata scenarios. tests/scenario-groups/fat-04.txt groups the VFAT Unicode/dense-alias positive scenario plus malformed ordinal, orphan-chain, and duplicate-alias fail-closed scenarios. tests/scenario-groups/fat-short-name.txt groups lowercase short-entry NT-flag positive media plus short-byte, OEM-byte, NT-flag, ambiguous-LFN, and duplicate-alias fail-closed scenarios. Its positive scenario uses rootd_test_mode=e2fs-fat-short-name to keep the VM path focused on the new verifier while preserving the real block-backed VFS stack. tests/scenario-groups/fat-rename.txt groups the focused FAT32 rename replacement scenario. It uses rootd_test_mode=e2fs-fat-rename, then verifies file-over-file replacement, empty directory replacement, rejected incompatible replacements, and clean host fsck.fat media. tests/scenario-groups/fat-metadata.txt groups the focused FAT32 metadata scenario. It uses rootd_test_mode=e2fs-fat-metadata, then verifies host-created timestamp stat fields, explicit VFS atime/mtime/fs_flags mutation, read-only denial, and clean host fsck.fat media. tests/scenario-groups/exfat-metadata.txt groups the focused exFAT metadata scenario. It uses rootd_test_mode=e2fs-fat-exfat-metadata, then verifies host-created primary-entry timestamps, UTC offsets, attribute stat fields, explicit VFS atime/mtime/fs_flags mutation, read-only denial, and clean host fsck.exfat/dump.exfat media. tests/scenario-groups/ext-truncate.txt groups the focused ext2/ext3/ext4 regular-file truncate scenarios. It uses rootd_test_mode=e2fs-fat-ext-truncate, then verifies public VFS shrink/grow behavior and clean host debugfs/e2fsck -fn media. tests/scenario-groups/ext-sparse.txt groups the focused ext4 sparse-hole scenario. It uses rootd_test_mode=e2fs-fat-ext-sparse, then verifies write-past-EOF holes, sparse truncate tail trimming, host debugfs bmap allocation state, and clean e2fsck -fn media. tests/scenario-groups/ext-fscrypt-policy.txt groups focused ext4 fscrypt policy negatives for v1 descriptor access, AES-256-HCTR2, direct-key, and non-default data-unit-size media. tests/scenario-groups/ext-metadata.txt groups the focused ext2/ext3/ext4 inode metadata scenarios. It uses rootd_test_mode=e2fs-fat-ext-metadata, then verifies public VFS mode, owner, atime, mtime, and filesystem flag updates, immutable denial, and clean host debugfs/stat/e2fsck -fn media. tests/scenario-groups/exfat-entry-types.txt groups the exFAT Volume Label/GUID, TexFAT padding, and benign vendor-entry positive media plus an unsupported vendor-allocation entry-set negative. tests/scenario-groups/exfat-rename.txt groups the focused exFAT rename replacement scenario. It uses rootd_test_mode=e2fs-fat-rename, then verifies file-over-file replacement, empty directory replacement, rejected incompatible replacements, clean host fsck.exfat media, and direct parser checks for removed source names. tests/scenario-groups/exfat-percent.txt groups primary percent-in-use refresh media and a patched partial-update dirty-volume negative. tests/scenario-groups/fat-05.txt groups allocation-stress media, and tests/scenario-groups/fat-depth.txt contains the focused 24-level stackless FAT mount proof. tests/scenario-groups/exfat-03.txt groups exFAT upcase-table Unicode lookup plus bad-NameHash, duplicate-upcase-name, and malformed-UTF16 fail-closed media, and tests/scenario-groups/exfat-04.txt groups exFAT allocation reconciliation positive and fail-closed media. tests/scenario-groups/exfat-05.txt groups sparse-valid-data/fragmented-stream exFAT media and invalid valid-data fail-closed media. tests/scenario-groups/exfat-06.txt groups the broadened exFAT interoperability corpus and root-metadata fail-closed media. tests/scenario-groups/ext-geometry.txt groups the targeted ext2/ext3/ext4 512-byte-inode VM media, tests/scenario-groups/ext-geometry-boundaries.txt groups inconsistent ext2/ext3 block layouts and the format-valid ext4 large-inode positive media, tests/scenario-groups/ext-links.txt groups the ext2/ext3/ext4 symlink, hard-link, and special-inode metadata VM media, and tests/scenario-groups/ext-rename.txt groups the ext2/ext3/ext4 rename and directory-move VM media. tests/scenario-groups/ext-truncate.txt groups focused ext2/ext3/ext4 regular-file truncate VM media, and tests/scenario-groups/ext-sparse.txt groups focused ext4 sparse-hole VM media. tests/scenario-groups/ext-fscrypt-policy.txt groups focused ext4 fscrypt policy fail-closed VM media, and tests/scenario-groups/ext-verity-signature-policy.txt groups focused ext4 fsverity built-in signature, missing/wrong-root, and encrypted-verity fail-closed VM media. tests/scenario-groups/loader-fs-discovery.txt groups the focused loader filesystem-discovery scenario using rootd_test_mode=loader-fs-discovery and loader-fs media. tests/scenario-groups/vfs-namespace-session-authority.txt selects the focused proof that loaderd's dedicated VFS session rejects mount control, directory enumeration, and write-open authority before normal read-only discovery succeeds. tests/scenario-groups/loader-elf-plan.txt groups the focused loader ELF-plan scenario using the same rootd mode and media, but asserts the dedicated ERIX_ROOTD:READY:LOADER_ELF_PLAN proof marker. tests/scenario-groups/loader-process-handoff.txt retains its historical group name but now selects the filesystem-preflight scenario. It asserts discovery and malformed-plan rejection while forbidding successful child creation. tests/scenario-groups/loader-materialized-launch.txt groups the root-lifecycle-isolation negative scenario using the same rootd mode and media. It treats an identity-only DENIED response as evidence that rootd cannot observe launchd-owned children. tests/scenario-groups/procd-loader-endpoint-partition.txt groups the focused negative proof for disjoint root, materialization, and launchd lifecycle endpoints. tests/scenario-groups/loader-cleanup-authority.txt groups the focused cleanup-authority scenario using the same media while asserting only the new cleanup and authority-denial marker family. tests/scenario-groups/loader-closure.txt groups the final loader closure evidence set: VFS policy, malformed ELF/load-plan rejection, launchd-only lifecycle visibility, stale-source rejection, cleanup, and authority denial. tests/scenario-groups/loader-boot-image-integration.txt groups the loader boot/image scenarios for runtime loader enablement, optional omission, and appliance disk-image fixture packaging. tests/scenario-groups/dynlink-complete-graph.txt groups the focused current product path. It uses rootd_test_mode=dynlink-storage-services, requires both dynlinkd and loaderd, and proves the authenticated dynamic service graph, VFS I/O, loader discovery, and malformed-plan rejection. Post-mount executable lifecycle is exercised through launchd scenarios instead. tests/scenario-groups/dynlink-artifact-metadata.txt groups the focused dynamic-linking artifact metadata scenario. It boots only the appliance disk-image path after host-side dynamic artifact ABI, ELF section, metadata, relocation-record, symbol-table, static executable rejection, and static-exception inspection passes. tests/scenario-groups/dynlink-real-shared-objects.txt groups the focused dynamic-linking real shared-object closure scenario. It boots only the appliance disk-image path after library-owned PIC objects, compiler metadata sidecars, DT_NEEDED edges, and registry deduplication pass host-side inspection. tests/scenario-groups/dynlink-kernel-artifact.txt groups the focused dynamic-linking kernel artifact scenario. It boots only the appliance disk-image path after the generated kernel-dyn.elf artifact, kernel shared objects, boot-image store, and filesystem mirror pass host-side inspection. tests/scenario-groups/dynlink-kernel-relocation.txt groups the focused dynamic-linking bootloader relocation scenarios. It boots the dynamic kernel from boot.img, proves missing-object, stale-hash, missing-export, duplicate-export, unsupported-relocation, and W^X failures before kernel entry, and skips older VM groups. tests/scenario-groups/kernel-handoff-length.txt contains only the new SysV64 pointer-and-exact-length ingress scenario. It requires the kernel's pre-parse length-validation marker and skips older VM groups. tests/scenario-groups/dynlink-rootd-bootstrap.txt groups the focused dynamic-linking dynamic rootd bootstrap scenarios. It uses rootd_test_mode=dynlink-rootd-bootstrap, boots the dynamic rootd executable from the signed boot dynamic store, and covers the new missing-dependency, relocation-failure, W^X, and stale-hash negatives without running older VM groups. tests/scenario-groups/dynlink-pre-procd.txt groups the focused dynamic-linking dynamic pre-procd service launch scenarios. It uses rootd_test_mode=dynlink-pre-procd, boots the dynamic rootd executable, launches memd, vspaced, pagerd, and procd from signed boot-catalog dynamic artifacts, and covers missing-dependency, unresolved-symbol, dependency-cycle, W^X, and cleanup negatives without running older VM groups. tests/scenario-groups/dynlink-procd-spawn.txt groups the focused dynamic-linking procd early dynamic spawn scenario. It uses rootd_test_mode=dynlink-procd-spawn, reuses the dynamic rootd and procd catalog bootstrap, then validates procd-mediated denied-object, abort, cleanup, map, start, and ready markers for dynamic memd, vspaced, and pagerd without running older VM groups. tests/scenario-groups/dynlink-bootstrap-helpers.txt groups the focused dynamic-linking dynamic bootstrap helper scenario. It uses rootd_test_mode=dynlink-bootstrap-helpers, launches all five helper executables from signed dynamic boot artifacts through procd, and checks lazy-paging, isolation, expected-fault-kill, exit-code, and cleanup markers without running older VM groups. tests/scenario-groups/dynlink-core-services.txt groups the focused dynamic-linking dynamic core-service coordination scenarios. It uses rootd_test_mode=dynlink-core-services, launches named, logd, crashd, timed, lookup-client, and time-client from signed dynamic boot artifacts through procd, and checks denied-object, lookup, logging, crash, and time markers without running older VM groups. tests/scenario-groups/dynlink-hardware-console-services.txt groups the focused dynamic-linking hardware, console, serial, and input scenarios. It uses rootd_test_mode=dynlink-hardware-console-services and packages the services, drivers, and helper clients as signed dynamic boot artifacts, checks interrupt, driver, serial, framebuffer, and pre-mount input-authority markers, enables explicit rootd-driven deviced activation in the positive case, and includes a missing-dependency fail-closed case without running older VM groups. Active input routing remains a post-mount ttyd contract. The service artifact builder expands Cargo feature implications before invoking rustc directly so dynamic artifacts use the same cfg surface as the static fixture build. tests/scenario-groups/dynlink-storage-services.txt groups the focused dynamic-linking dynamic storage, filesystem, VFS, and loader scenarios. It uses rootd_test_mode=dynlink-storage-services, packages the storage/filesystem/loader targets as signed dynamic boot artifacts, exercises the loader-fs disk media, checks storage, VFS, loader, disk-execution, and process-handoff markers, and includes a missing shared-object fail-closed case without running older VM groups.
  • tests/scenario-groups/multi-block-provider.txt contains only the new two-provider VM. Its disk-image case attaches a junk virtio disk followed by a GPT virtio disk, requires two location-derived physical whole-disk identities, and reaches normal storage and terminal readiness through blockd's full-width provider-and-namespace cursor pair without running older VM groups.
  • scripts/run-scenario-group.sh <group> runs only a named scenario group, so cross-cutting work can validate new VM coverage without invoking the older full scenario matrix locally.
  • tests/scenario-groups/irqd-multiline-delivery.txt contains only the focused simultaneous LAPIC/COM1 delivery scenario.
  • tests/scenario-groups/ipc-transport-framing.txt contains the focused canonical IPC transport scenario. It boots the integrated runtime with strict contiguous request framing, independently sized writable call buffers, and the shared transport ceiling, then requires startup, device, console, pre-mount input-authority, and VFS readiness without running older VM scenarios.
  • tests/scenario-groups/process-memory-streaming.txt contains the focused child-population scenario. It loads the dedicated 5,000-byte filesystem fixture through loaderd, dynlinkd, and procd, requires semantic load and launch success across bounded materialization fragments, and then requires root's lifecycle query to fail with the launchd-only identity-denial contract.
  • tests/scenario-groups/phase5-catalog-regressions.txt contains the eight scenarios classified by the full 483-scenario Phase 5 catalog run. It covers malformed ext casefold mount rejection, signed volatile-memory I/O, post-retirement RTC readiness, and bounded process-memory materialization.

Storage scenarios now additionally cover:

  • positive block bring-up through blockd
  • positive GPT partition publication through blockd
  • missing drv-virtio-block
  • missing blockd
  • malformed GPT media
  • wrong-kind deviced PCI-device/MMIO authority
  • runtime disk-image topology coverage for SATA boot without virtio storage, junk virtio media, ESP-only virtio media, a single GPT virtio boot disk, and two virtio disks; the two-disk case leaves junk media read-only and grants write access only to the copied GPT storage disk needed by the runtime root mount

Current exit-code class mapping:

  • 0x10: success
  • 0x11: bootloader failure
  • 0x12: kernel failure
  • 0x13: rootd failure
  • 0x14: service bootstrap failure

Repository Layout (Current)

integration/
├── components.toml
├── cargo-repos.toml
├── dynlink-executable-migration.toml
├── dynlink-dependency-records.toml
├── dynlink-artifact-abi.toml
├── scripts/
│   ├── clone-components.sh
│   ├── build-all.sh
│   ├── build-kernel-fixture.sh
│   ├── build-kernel-fixture-main.sh
│   ├── build-dynlink-kernel-artifact.py
│   ├── dynlink_kernel_metadata.py
│   ├── dynlink_closure_policy.py
│   ├── generate-monorepo-cargo-config.py
│   ├── generate-block-test-disk.py
│   ├── disk_image_gpt.py
│   ├── setup-component-ci-overrides.sh
│   ├── setup-component-ci-overrides.py
│   ├── boot_config_codec.py
│   ├── boot_config_hardware.py
│   ├── generate-boot-config.py
│   ├── parse-runtime-config.py
│   ├── build-dynlink-artifact-fixture.py
│   ├── check-dynlink-dependency-closure.py
│   ├── check-dynlink-executable-inventory.py
│   ├── check-dynlink-artifact-metadata.py
│   ├── verify-dynlink-image-closure.py
│   ├── check-dynlink-filesystem-mirrors.py
│   ├── check-ext-cross-corpus.py
│   ├── ext_cross_corpus.py
│   ├── run-scenario.sh
│   ├── prepare-appliance-runtime-disk.sh
│   ├── run-scenario-group.sh
│   ├── run-scenarios.sh
│   ├── run-vm.sh
│   ├── run-bootloader-vm.sh
│   ├── run-bootloader-negative-case.sh
│   ├── run-disk-image-vm.sh
│   ├── run-kernel-exception-negative-tests.sh
│   ├── package-dev-appliance.sh
│   ├── package-appliance.sh
│   ├── build-disk-image.sh
│   ├── publish-release-artifacts.sh
│   ├── assert-markers.sh
│   ├── lib/bootloader-cargo.sh
│   ├── lib/rootd-fixture-features.sh
│   ├── lib/scenario.sh
│   ├── lib/scenario-storage.sh
│   └── lib/components.sh
├── tests/
│   ├── dynlink-dependency-closure.sh
│   ├── dynlink-executable-inventory.sh
│   ├── dynlink-artifact-metadata.sh
│   ├── dynlink-filesystem-mirrors.sh
│   ├── bootloader-vm-marker-timeout-status.sh
│   ├── generate-monorepo-cargo-config.sh
│   ├── ext-cross-corpus.sh
│   ├── scenario-groups/*.txt
│   └── scenarios/*.toml
├── runtime.sample.toml
├── runtime.dev.toml
├── runtime.release.toml
├── .github/workflows/ci.yml
├── README.md
├── ARCHITECTURE.md
└── ROADMAP.md

Large integration helpers are split at thematic boundaries. Kernel artifact metadata, dynamic closure policy, signed hardware-phase validation, GPT image construction, rootd fixture feature selection, and scenario storage preparation live in dedicated modules so every tracked script remains at or below 1,000 lines.

Quick Start

From integration/:

./scripts/clone-components.sh
./scripts/build-all.sh
./scripts/run-scenarios.sh
./scripts/run-scenario.sh tests/scenarios/full-system-normal.toml
./tests/ext-cross-corpus.sh
./scripts/run-scenario-group.sh ext-cross-feature-registry
./scripts/run-scenario-group.sh fat-truncate
./tests/generate-monorepo-cargo-config.sh
export BOOTIMG_SIGNING_KEY=tests/keys/bootimg-test-ed25519.pem
export BOOTIMG_PUBLIC_KEY_HEX_FILE=tests/keys/bootimg-test-ed25519.pub.hex
export BOOTIMG_KEY_ID=0
export BOOTIMG_SIGNING_PROVENANCE="repository test key; not for production trust"
./scripts/package-dev-appliance.sh
./scripts/build-disk-image.sh
APPLIANCE_NAME=erix-release RUNTIME_CONFIG_PROFILE=release ./scripts/package-appliance.sh
RUNTIME_CONFIG_PROFILE=release ./scripts/build-disk-image.sh erix-release
PUBLISH_DRY_RUN=1 ./scripts/publish-release-artifacts.sh
./scripts/setup-component-ci-overrides.sh /path/to/component

Those relative paths are intentionally relative to the checked-out bootloader repository because its fixture builder owns path resolution. They select repository fixtures suitable only for tests. The integration caller must not prefix them with the component checkout path. Production packaging must inject its own private key, matching public-key file, and key ID. Publication additionally requires BOOTIMG_SIGNING_PROVENANCE; that caller-supplied statement is embedded in the pre-release body so test-signed artifacts cannot be presented without their trust classification.

Appliance archives and raw disk images are byte-reproducible under the same recorded inputs and host-tool versions. Archive entry order, ownership, and timestamps are normalized. GPT disk/partition GUIDs, the FAT volume ID, the ext4 UUID, and the ext4 directory-hash seed are derived from a fingerprint of the appliance tree, runtime configuration, image parameters, normalized epoch, and media-tool versions. FAT and ext4 creation/mutation use that epoch in UTC. The default epoch is the Integration source revision's Git commit timestamp, not a fixed 1980 date or the current build clock. Explicit SOURCE_DATE_EPOCH is supported within the unsigned 32-bit seconds range. Packaging records its decision in source-date-epoch.json; disk construction requires that record and rejects a conflicting override, so a later checkout cannot retimestamp an already packaged appliance. Guest mutations use the independently queried runtime clock, not this build-time value.

Each raw image has a sibling <name>.img.identity.json that records the fingerprint, derivation contexts, effective identifiers, and epoch. A caller that intentionally needs distinct media identity may set any of IMAGE_DISK_GUID, IMAGE_ESP_PARTITION_GUID, IMAGE_DATA_PARTITION_GUID, IMAGE_DATA_FS_UUID, IMAGE_DATA_HASH_SEED, or IMAGE_FAT_VOLUME_ID. Overrides are validated and recorded instead of bypassing the identity manifest. The identity manifest has its own .sha256 file and is published alongside the image checksum.

setup-component-ci-overrides.sh resolves the exact commits selected by the standalone crate's manifests, using the catalog as a repository allowlist. Sibling repositories may supply those commit objects, but cannot override the selected revisions. Generated Cargo transport mirrors preserve original Git commit identities and disable registry sources. Manifest discovery prunes .git, .ci, out, and target before descent. See immutable source selection for closure validation, explicit monorepo mode, and the separate Integration tool/runtime source roles.

To bootstrap the multi-repository checkout into the current directory without first cloning integration, select a reviewed full commit containing the immutable bootstrap helper and fetch the script from that exact commit:

revision=YOUR_REVIEWED_40_LOWERCASE_HEX_COMMIT
base="https://git.erikinkinen.fi/erix/integration/raw/commit/$revision"
curl -fsSL "$base/scripts/bootstrap-repos.sh" |
  sh -s -- --integration-revision "$revision"

The script verifies that exact Integration tool commit and uses the catalogs and helper code from it. Component repositories are detached at their selected commits; dirty targets fail without reset or cleanup. The tool lives at integration, while its separately pinned runtime-library source lives at integration/out/components/integration. To use SSH transport, add --ssh:

curl -fsSL "$base/scripts/bootstrap-repos.sh" |
  sh -s -- --integration-revision "$revision" --ssh

build-kernel-fixture.sh now generates and injects a required boot-config section payload for rootd orchestration.

Runtime appliance defaults:

  • KERNEL_ROOTD_TEST=runtime
  • RUNTIME_IMAGE_TEST_HARNESS=0
  • RUNTIME_CONFIG_PROFILE=dev
  • ROOTD_TEST_MODE=none (runtime image composition is config-driven)

Runtime config files:

  • runtime.dev.toml (default dev profile)
  • runtime.release.toml (default release profile)
  • runtime.sample.toml (schema + documented behavior)
  • runtime.local.toml (gitignored local override selected only through RUNTIME_CONFIG_PATH)
  • committed dev/release defaults mount / from ext on erix-data, /boot from FAT on erix-esp, and /tmp from ramfs
  • [service_state.logd] explicitly selects canonical retained-record, pending-submission, and retained-byte capacities. These values patch one exact typed arena before the logd artifact is signed; they are deployment policy rather than service ceilings. Retained-byte storage must accommodate at least one complete 192-byte early-kernel-log transfer record.
  • [service_state.procd].managed_process_records explicitly selects one nonzero process-record count no greater than procd's canonical 128-slot pagerd partition. It sizes procd lifecycle/event storage, procd's capability scratch ranges, and its pagerd binding-record contribution. Pagerd adds the disjoint 64-slot rootd temporary-launch contribution to its binding arena; the default 128-record policy therefore patches 192 binding records. Pagerd's CSpace import window remains the fixed canonical slots 320..512; deployment count does not resize that partition. Rootd and procd consume lib-capabi's same versioned per-process multiplier; addressable empty slots convey no authority. Vspaced retains no service-local mapping state or deployment-sized capacity.
  • [service_state.powerboxd] supplies the complete authenticated PBX1 policy: request, grant, selector-byte, trusted-prompt, session-policy, decision, consumption-receipt, cleanup, expiration, resolution, reply, and transient capability-slot storage. Every value is positive, the slot range must remain within the native-broker CSpace window, and the page-rounded arena grants no allocator or namespace authority. Runtime BootConfig generation reuses this exact validated policy for the post-mount powerboxd launch row; it never reconstructs capacities from patched ELF size or local defaults.
  • [service_state.seriald].retained_bytes explicitly selects the positive serial readback byte count. Packaging authenticates the exact prefix in a dedicated page-rounded arena; the value is deployment policy, not a daemon source ceiling.
  • [service_state.fbcond].retained_bytes explicitly selects framebuffer-console readback retention. Packaging authenticates only that prefix of a dedicated page-rounded arena; no daemon or caller retains a parallel byte ceiling.
  • [service_state.drv_serial].retained_bytes explicitly selects the positive serial-driver readback byte count. Packaging authenticates the exact prefix in .drv_serial_state_arena; the page-rounded remainder is not allocator authority and the former 4 KiB source limit no longer exists.
  • [service_state.drv_i8042] independently selects positive keyboard_retained_bytes and mouse_retained_bytes. Packaging authenticates both exact contiguous slices in .drv_i8042_state_arena; neither stream can consume the other's retention policy, and page-rounded padding is unusable.
  • service_state.vspaced is intentionally absent and rejected. Vspaced keeps no redundant mapping records or service-local capacity; exact per-call capability receipts authorize operations and kernel results report real mapping limits.
  • [service_state.irqd].handler_records explicitly selects the nonzero interrupt-handler registry count. It is authenticated deployment policy, not a crate-wide ceiling, and packaging exposes no allocator over rounded pages.
  • [service_state.inputd].event_records explicitly selects the input-event retention count. Configurations with input enabled require a positive count; configurations without input require zero. Packaging authenticates the exact typed slice in .inputd_state_arena, so inputd has neither a source-coded ring ceiling nor allocator authority over page padding.
  • [service_state.vfsd].handle_records explicitly selects the deployment's VFS handle-record count. The mount-record count is the exact number of [[mounts]] rows; neither value is a compile-time service ceiling. The shared VM profile provisions 128 records so the Phase 5 shell scenarios can retain digest-only lost-reply tombstones across their bounded repeated redirections until each launch resolver is retired.
  • [service_state.ramfsd] explicitly selects nodes per ramfs mount, file bytes per node, and provider-private handle records. Its mount-record count is the exact number of [[mounts]] rows whose provider is ramfs; a configuration without ramfs mounts must set all three values to zero.
  • [service_state.e2fsd].handle_records explicitly selects provider-private ext handle records. The mount-record count is the exact number of [[mounts]] rows whose provider is ext; a configuration without ext mounts must set the handle count to zero.
  • [service_state.fatd].handle_records explicitly selects provider-private FAT handle records. The mount-record count is the exact number of [[mounts]] rows whose provider is fat; a configuration without FAT mounts must set the handle count to zero.
  • features.program_loader is the loader toggle. The dev profile enables it and packages loaderd plus the loader executable fixture path. The current release profile enables the same authenticated loader path.

Storage helpers:

  • scripts/generate-block-test-disk.py builds deterministic gpt, malformed-gpt, fs, FAT12/FAT16/FAT32/exFAT ESP variants, exFAT boot-region, active-state, percent-in-use, and upcase-name positive/negative variants, malformed FAT/exFAT/ext, ext recovery-required, encrypted ext4, casefold ext4, inline-data ext4, and Linux-layout fsverity ext4 raw disks locally. CI installs the host fsverity package alongside e2fsprogs/exfatprogs so fsverity media coverage has the expected host tooling available. tests/generate-block-test-disk.sh checks GPT CRC corruption, FAT12/FAT16 marker readability, deterministic exFAT marker readability via scripts/verify-exfat-image.py, malformed-media variant generation, and host fsck.fat -n / fsck.exfat -n / e2fsck -fn on the filesystem fixture. FAT32 active-FAT VM verification uses scripts/verify-fat32-active-fat.py after mutation so valid inactive-FAT divergence is not normalized away. exFAT active-FAT VM verification uses scripts/verify-exfat-image.py to check the FAT count, the primary VolumeFlags active selector, and the VFS-created marker after mutation because the installed fsck.exfat rejects two-FAT TexFAT-style images even though the fixture is intentionally exercising the provider's active-selector policy. That scenario carries a local 600-second VM budget so the dynamic-only image can finish the full VFS mount and I/O readiness path before post-VM exFAT validation runs. EXFAT-03 Unicode-name VM verification also uses scripts/verify-exfat-image.py so upcase-table lookup and stream NameHash semantics are checked with the same deterministic parser. EXFAT-04 VM verification uses the same parser to reconcile all reachable exFAT stream ownership against the allocation bitmap and uses host fsck.exfat -n on the accepted contiguous no-FAT-chain image. EXFAT-05 VM verification checks sparse valid data, DataLength, ValidDataLength, zero-filled ranges, and fragmented stream chains. Focused exFAT metadata VM verification checks host-created primary-entry attributes, create/modify/access timestamps, 10 ms increments, UTC offsets, VFS-updated metadata, and read-only denial, then verifies the ESP with fsck.exfat, dump.exfat, and direct exFAT entry-set checks. Focused ext metadata VM verification checks VFS-updated mode, owner, atime, mtime, nodump/noatime/immutable flags, immutable mutation denial, and the resulting data partition with debugfs, host stat, and e2fsck -fn. Focused ext sparse VM verification checks that a write past EOF reads a zero-filled hole without allocating logical block zero, that the tail block is allocated, that truncating a sparse file keeps the leading hole unmapped, and that the resulting data partition passes e2fsck -fn. exFAT entry-type VM verification checks Volume Label/GUID root metadata, TexFAT padding, preserved vendor-extension secondaries, and fail-closed vendor-allocation media with the direct parser and host exFAT tools. exFAT rename VM verification reuses the public rootd rename flow and checks the resulting ESP with fsck.exfat plus direct payload and absence checks. exFAT percent-in-use VM verification starts from unknown primary/backup percent values, requires the accepted image's primary value to match the allocation bitmap after public VFS mutations, keeps backup stale, and rejects patched dirty partial-update media on read-write mount. EXFAT-06 VM verification uses the same parser to assert 1 KiB clusters, two FATs, a grown root chain, fragmented deep Unicode-path payloads, and spare allocation clusters for public VFS mutations; its negative media rejects bad upcase tables, malformed bitmap entries, duplicate critical metadata entries, and corrupt directory-entry sets before VFS readiness. FAT32 dirty and hard-error metadata variants are negative read-write mount tests; malformed reserved-entry variants keep mirrors consistent so fatd fails specifically on FAT[0]/FAT[1] metadata validation. FAT-04 verifies host mtools listing/lookup for accepted VFAT Unicode and dense-alias fixtures after VM execution and patches malformed LFN/alias fixtures for targeted negative mount failures. FAT short-name verification checks host-created lowercase short entries and VFS-created lowercase short entries with direct NT-flag parsing after VM execution. FAT-05 verifies fragmented cluster chains, multi-cluster directories, slot reuse, sparse-looking payloads, and fail-closed malformed referenced-chain media. The focused FAT depth scenario mounts a host-created 24-level directory tree through fatd, reaches ordinary VFS readiness, and verifies the deepest marker with mtools after the VM. EXFAT-03 verifies upcase-table Unicode lookup and bad-NameHash, duplicate-upcase-name, and malformed-UTF16 fail-closed media. EXFAT-04 verifies no-FAT-chain contiguous streams plus bitmap/FAT mismatch, duplicate ownership, missing bitmap allocation, leaked allocation, loop, and out-of-range fail-closed media. FAT12/FAT16/FAT32 directory-metadata variants use scripts/verify-fat-directory-metadata.py plus mtools to verify timestamps, attributes, volume labels, lowercase short-name flags, and VFS-created archive/timestamp metadata after the VM. FAT metadata mutation uses scripts/verify-fat-metadata.py plus mtools and direct directory-entry parsing to verify host-created timestamps, date-only access time, two-second modification time, stat-only creation time, and read-only attributes after the VM. FAT rename replacement uses scripts/verify-fat-rename.py plus mtools and fsck.fat -n to verify the destination file payload, renamed directory child, rejected non-empty destination, and removed source names after the VM. exFAT rename replacement uses scripts/verify-exfat-image.py plus fsck.exfat -n to verify the same public VFS mutations on exFAT media. exFAT percent-in-use media uses the direct parser to verify the final primary percent against the active allocation bitmap while preserving stale backup PercentInUse=0xff. FAT truncate variants use scripts/verify-fat-truncate.py, host mtools, and fsck.fat -n to verify shrink, zero-length shrink, zero-filled growth, released-chain cleanup, and FAT32 FSInfo accounting after the VM. Ext truncate variants use debugfs and e2fsck -fn to verify the focused /EXTTRUNC.BIN shrink/grow result after the VM. Ext metadata variants use scripts/verify-ext-metadata.py, host stat, and e2fsck -fn to verify /EXTMETA.TXT mode, owner, explicit atime/mtime, preserved legacy ctime, flags, payload, and clean media.
  • BLOCK_STORAGE_IMAGE=auto|none|gpt|malformed-gpt|fs|loader-fs|fs-ext2|fs-ext2-indirect|fs-ext2-compat|fs-ext2-xattr|fs-ext2-geometry-512|fs-ext2-links|fs-ext2-rename|fs-ext2-corpus-1k|fs-ext2-corpus-2k|fs-ext2-corpus-4k|fs-ext3|fs-ext3-replay|fs-ext3-external-journal|fs-ext3-jbd2-legacy|fs-ext3-jbd2-csum-v2|fs-ext3-jbd2-csum-v3|fs-ext3-many-journal|fs-ext3-fast-commit|fs-ext3-htree|fs-ext3-htree-depth0|fs-ext3-htree-depth1|fs-ext3-geometry-512|fs-ext3-links|fs-ext3-rename|fs-ext4-metadata|fs-ext4-extent-tree|fs-ext4-bigalloc|fs-ext4-meta-bg|fs-ext4-stable-resize|fs-ext4-xattr|fs-ext4-quota|fs-ext4-orphan-list|fs-ext4-orphan-file|fs-ext4-mmp|fs-ext4-large-dir|fs-ext4-encrypted|fs-ext4-encrypted-casefold|fs-ext4-casefold|fs-ext4-inline|fs-ext4-verity|fs-ext4-verity-salted|fs-ext4-verity-large|fs-ext4-shared-blocks|fs-ext4-geometry-512|fs-ext4-links|fs-ext4-rename|fs-fat12|fs-fat12-metadata|fs-fat16|fs-fat16-metadata|fs-fat32-primary-only|fs-fat32-mirrored|fs-fat32-active-fat|fs-fat32-metadata-clean|fs-fat32-directory-metadata|fs-fat32-metadata-set|fs-fat32-rename|fs-fat32-vfat-unicode|fs-fat32-stress|fs-fat32-deep-directory|fs-exfat|fs-exfat-boot-region|fs-exfat-stale-backup|fs-exfat-one-fat|fs-exfat-active-fat|fs-exfat-unicode|fs-exfat-contiguous|fs-exfat-stream-metadata|fs-exfat-metadata|fs-exfat-entry-types|fs-exfat-rename|fs-exfat-percent|fs-exfat-corpus|malformed-fat|malformed-exfat|exfat-bad-upcase-table|exfat-bad-name-hash|exfat-duplicate-upcase-name|exfat-malformed-utf16-name|exfat-bad-main-boot|exfat-bad-backup-boot|exfat-bad-extended-boot|exfat-boot-region-mismatch|exfat-dirty-volume|exfat-partial-update-dirty|exfat-media-failure|exfat-invalid-active-fat|exfat-reserved-volume-flags|exfat-duplicate-bitmap-entry|exfat-duplicate-upcase-entry|exfat-bad-bitmap-entry|exfat-bad-bitmap-length|exfat-corrupt-directory-set|exfat-bad-entry-type|exfat-bitmap-fat-mismatch|exfat-duplicate-cluster|exfat-no-fat-missing-bitmap|exfat-leaked-cluster|exfat-chain-loop|exfat-out-of-range-chain|exfat-invalid-valid-data|malformed-ext|ext2-inconsistent-block-geometry|ext3-inconsistent-block-geometry|ext4-large-inode|ext2-bad-block-map|ext2-bad-dirent|ext2-bad-inode-size|ext2-bad-bitmap|ext2-reserved-inode-corruption|ext-needs-recovery|fat-mirror-mismatch|fat-cluster-loop|fat-bad-lfn|fat-bad-lfn-ordinal|fat-orphan-lfn|fat-duplicate-alias|fat-bad-cluster-chain|fat-file-chain-loop|fat-cross-linked-files|fat-out-of-range-chain|fat32-bad-fsinfo-count|fat32-bad-backup-boot|fat32-dirty-metadata|fat32-hard-error-metadata|fat32-bad-reserved-entry|ext-checksum-failure|ext-unsupported-feature|ext-obsolete-feature-corpus|ext-unknown-feature-corpus|ext-unknown-feature-gap-corpus|ext-readonly-feature|ext-shared-blocks-feature|ext-journal-device-volume|ext-bigalloc-bad-bitmap|ext4-meta-bg-bad-descriptor|ext4-encrypted-missing-key|ext4-encrypted-wrong-key|ext4-encrypted-casefold-missing-key|ext4-encrypted-casefold-wrong-key|ext4-bad-fscrypt-policy|ext4-bad-encrypted-casefold-policy|ext4-bad-encrypted-casefold-name|ext4-bad-casefold-encoding|ext4-bad-casefold-name|ext4-bad-xattr|ext4-bad-quota|ext4-bad-orphan-list|ext4-bad-orphan-file|ext4-bad-mmp-active|ext4-bad-mmp-checksum|ext4-bad-inline-data|ext4-bad-verity-data|ext4-bad-verity-algorithm|ext4-bad-verity-signature|ext4-verity-signature|ext4-verity-encrypted|ext4-bad-verity-merkle|ext-external-journal|ext-jbd2-unknown-feature|ext-jbd2-csum-failure|ext-fast-commit-mutating|ext-fast-commit-htree|ext-fast-commit-linear|ext-fast-commit-bad-tail|ext-external-journal-uuid-mismatch|ext-external-journal-misroute|ext-malformed-extent|ext-malformed-htree|ext-malformed-htree-index|ext-malformed-htree-deep controls whether a secondary read-only virtio-blk disk is attached during fixture, subsystem, and appliance runs.
  • fscrypt scenarios may set keyd_fscrypt_material_id_hex and keyd_fscrypt_material_hex; the harness encodes those bytes in rootd's private keyd startup material tail, not in named or provider metadata. The encoded row carries no caller role or compatibility padding.
  • fsverity scenarios may set keyd_fsverity_root_id_hex and keyd_fsverity_root_hex; the harness encodes those bytes in the same private keyd startup material tail as trust-root material for e2fsd and selects rootd's targeted fsverity validation profile for positive/tamper media. Linux-layout fsverity coverage is grouped under tests/scenario-groups/ext-verity-linux.txt, while explicit signature and authority-policy negatives are grouped under tests/scenario-groups/ext-verity-signature-policy.txt.
  • scripts/build-disk-image.sh builds erix-dev.img and erix-release.img as GPT-partitioned raw disks. Partition 1 is a FAT32 ESP named erix-esp; partition 2 is an ext4 filesystem named erix-data containing the selected dynamic executable/object mirror and any enabled loader fixtures.
  • scripts/package-dev-appliance.sh is the canonical development packaging entry point. It selects the isolated Integration policy, the full ext4 runtime transition, and the product interactive exsh console plan. Its explicit INITIAL_EXSH_INTERACTIVE_ESCALATION=1 selector retains the same session capability ceiling and trusted powerbox policy without enabling an authored physical-input test transcript. The closed Boolean selector rejects combinations with authored command or physical-fixture selections. The resulting dev image exposes the complete readiness stream and starts exsh from ext4. Release packaging continues through package-appliance.sh with product rootd and its bounded post-completion shell hook; it does not compile the Integration effect adapters.
  • CI builds, boots, and publishes runtime appliance images as part of the committed VM scenario set. Positive development images must reach terminal ERIX_ROOTD:READY; release images instead prove the later version banner and shell output while forbidding that record. Staged ERIX_ROOTD:READY:* markers are evidence only for their owning services. After constructing the publication artifacts, CI boots both exact canonical images and drives each interactive shell through emulated PS/2 input. The dev gate also requires every semantic readiness marker and final READY. Both gates require the independently expected exact version banner and a fresh, complete shell caret. Two separate physical command epochs prove exact typed input, distinct PATH/absolute external-command output, status zero and a new caret; typed echo alone cannot pass. Each gate retains hashed boot and final framebuffer screendumps and retires only QEMU after acknowledged host quit: both product shells intentionally remain live. The focused visual gate requires default fbcond foreground across multiple rows and light-gray terminal pixels, so a prompt-only framebuffer cannot pass merely because serial output is complete. tests/canonical-image-vm.sh dev|release [source-image] copies the source disk and both firmware files privately, retains diagnostics, checks source hashes even after VM failure, and uses unchanged 120/15/10-second total/stall/whole- command bounds. An older supplied image requires an independently known EXPECTED_INTEGRATION_VERSION; accepting its observed banner is not proof. The nine authored physical-input, powerbox and trusted-TTY scenarios still select the Integration fixture runner and require their original guest evidence-ready, exit and authority-cleanup assertions. Product observations do not substitute for those scenario contracts.
  • EXT-CROSS groups live under tests/scenario-groups/; use scripts/run-scenario-group.sh ext-cross-feature-registry for the fail-closed feature-bit subset, ext-cross-feature-positives for accepted feature media, ext-cross-malformed-media for malformed ext fixtures, and ext-cross-authority for authority-shape negatives.
  • Use scripts/run-scenario-group.sh ext-advanced-corpus-maintenance for the targeted advanced ext corpus maintenance subset without rerunning older broad VM groups.
  • Use scripts/run-scenario-group.sh ext-interoperability-corpus for the targeted Linux/e2fsprogs ext2/ext3/ext4 interoperability subset without running older VM scenarios.

Set RUNTIME_CONFIG_PROFILE=release (or RUNTIME_CONFIG_PATH=...) to select runtime image behavior, and APPLIANCE_NAME to select output artifact prefix. Release builds keep memd, vspaced, and pagerd free of discovery and logging dependencies; procd receives its release-image feature so its implied runtime logging chain stays quiet too. Runtime probed also receives its release-image feature so packaged release images preserve ERIX_PROBED:WARN:* records while suppressing informational discovery telemetry. Runtime logd receives its release-image feature as well, retaining submitted records while suppressing external sink output for non-warning records and non-final readiness markers.

Source selection requires explicit full lowercase commit IDs in component catalogs and Cargo manifests. scripts/clone-components.sh fetches and verifies those exact objects, checks them out detached, and records revision, sha, and pinned = true in out/resolved-revisions.json. Missing commits and dirty component worktrees fail closed without resetting or cleaning local changes. Branch names and ambient CI branch variables never replace a selected revision.

Explicit ERIX_COMPONENT_SOURCE=monorepo validation requires clean sibling checkouts at the selected catalog and manifest pins. Per-build Cargo patches include only the active dependency graph; transport mirrors retain the original commit IDs. The Integration runtime-library row always uses its separately pinned out/components/integration checkout, not the executing orchestration tool's HEAD. See immutable source selection.

Acceptance of a declared pin set still requires its source build and applicable runtime checks. Host resolver tests do not establish appliance or VM acceptance; retain resolved source inventories with images and validate the committed set.

Main outputs:

  • out/resolved-revisions.json
  • VM serial logs generated by the active harness
  • out/appliance/erix-dev.tar.gz
  • out/appliance/erix-dev.img
  • out/appliance/erix-dev.img.sha256
  • out/appliance/erix-dev.img.identity.json
  • out/appliance/erix-dev.img.identity.json.sha256
  • out/appliance/erix-dev.img.zst and out/appliance/erix-dev.img.zst.sha256 (when compression is enabled)
  • out/appliance/erix-release.tar.gz
  • out/appliance/erix-release.img
  • out/appliance/erix-release.img.sha256
  • out/appliance/erix-release.img.identity.json
  • out/appliance/erix-release.img.identity.json.sha256
  • out/appliance/erix-release.img.zst and out/appliance/erix-release.img.zst.sha256 (when compression is enabled)

Governance Principles

integration governance is scoped to assembling, building, and validating cross-repository EriX systems.

The scoped governance rules are:

  • Scenarios must be deterministic and make component revision selection explicit.
  • Generated media and VM tests must fail closed on missing tools, warnings, or authority regressions.
  • Dependencies use immutable commit IDs; generated local transport configuration must not change those selected revisions.
  • New system behavior requires targeted positive and negative scenarios before it is considered validated.
  • Cross-cutting ext work must update the EXT-CROSS and ext interoperability corpus manifests plus grouped scenario lists in the same branch as feature-registry, authority, or media boundary changes.

Validation Boundaries

  • Host VM-runner fixtures must work without a preexisting out/appliance and keep firmware sources, writable variables and every log in private temporary paths. Both runners create the selected OVMF variables destination's parent independently of the serial-log path. tests/vm_firmware_fixture_test.py checks cold-checkout defaults, nested destinations, source preservation, failure before QEMU launch and serial-fixture isolation using fake QEMU. Sibling firmware/input fixtures also preserve guarded ambient output paths. Invalid editor-profile and console-mode cases use private dummy disks rather than assuming an already-built canonical image exists.
  • Marker-only failures print bounded final serial context (80 lines within 16 KiB) alongside the unchanged failing assertion, so a correct guest exit cannot conceal missing or reordered final output in the CI job log.
  • integration may coordinate component builds but does not own component source policy.
  • Driver daemons remain managed through deviced and procd; tests should assert that ownership boundary.
  • Hardware verification accepts the exact authenticated RTC seed's zero PCI metadata only with matching typed identity, presence and live generation. It still reads that seed, rejects malformed seed fields, and checks ordinary PCI devices and report counts independently. Seeded RTC presence must not be confused with a PCI discovery report or permission to start a driver.

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.