Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Run Targets, Init Mandate, And Default-Run Integration

This backlog captures three intertwined make-target and manifest-policy requirements raised against the current Makefile and system-*.cue set. They share manifests, harness scripts, and review surface, so they should land as one mainline track rather than scattered fixes.

Policy Statements

  1. make run and make run-display are the only operator run targets. Every focused proof and every alternate manifest, firmware, device, or measurement QEMU variant uses test-*, even when its recipe only starts QEMU. Scripted input driving, transcript assertions, timeout-based pass/fail, log greps, and harness script wrapping must never live in the run or run-display recipes.
  2. init usage is MANDATORY in every boot manifest. The boot init binary must be init (the capos-init ELF). Service or demo binaries such as capos-shell, credential-store, terminal-session, network-client, revocable-read, memoryobject-shared-parent, and per-demo entrypoints must be declared as services and launched by init, never as the top-level init binary.
  3. make run stays the default user-facing target demonstrating a sane, safe, full-featured (as of the current state) capOS instance. Milestone closeout follows the authoritative CLAUDE.md integration checklist.

Current State

Representative run-* recipes that contain test logic

This non-exhaustive snapshot identifies early migration families. Every listed target embeds input drivers, asserts, or harness invocations and therefore violates policy 1, but Gate C closure requires auditing all current run-* recipes in Makefile rather than treating this list as a complete inventory:

  • run-smoke, run-net
  • run-spawn
  • run-chat, run-adventure, run-terminal
  • run-credential
  • run-measure

Migrated Gate C families are recorded in the Gate C changelog section.

The three registered driver targets remain unchanged and gate-resolvable: run-cloud-prod-remote-session-web-ui-l4, run-cloud-tls-webui-terminated, and run-remote-session-capset-interop. Renaming registered run-* validation gate values remains outside this migration. The deferred artifact-prefix follow-up for migrated test-* recipe bodies is closed in Gate C below. The inventory derived by tools/run_target_inventory.py reports 17 remaining non-compliant run-* targets after this migration. Gate C remains open for run-smoke, general run-net, IPv6 TCP L4 proofs; the remaining service proofs; the remaining resource-profile proof (run-resource-profile); remaining language/runtime proofs; other storage families; the two retained POSIX validation-gate targets (run-posix-file and run-posix-system); the scheduler lifecycle proof (run-scheduling-context); the registered remote-session Web UI L4 driver proof (run-cloud-prod-remote-session-web-ui-l4); remaining hardware, device, and cloud-provider proof families; and other focused proofs still named run-* in Makefile.

(test-network-client, test-telnet(-vm), and test-ssh-gateway-terminal-host(-vm) were on this list but are now exit-2 retirement stubs with no test logic, retired with the kernel socket owner.)

Compliant run-* recipes (QEMU-only):

  • run – interactive, manifest-driven, terminal on stdio.
  • run-display – interactive variant with QEMU display.

Init-mandate manifest status

The enumerated shell-led and service-led migration waves below are complete, but Gate B is not complete across the repository. Many self-contained focused proof manifests still select their proof binary directly through initConfig.init.binary. The init-mandate-loader-validation-rule task owns the decision whether that class is an explicit exception or must migrate behind init, followed by the matching loader rule and confirming manifest and documentation re-greps.

Migrated to init-owned service graphs (Gate B 4/4, 2026-07-27 04:14 UTC): system-shell-uptime.cue, system-shell-uptime-ungranted.cue, system-shell-fs.cue, system-shell-fs-ungranted.cue, and system-manual-smoke.cue now boot init and launch capos-shell as a single init-spawned service named shell under exitWhenServiceExits. The shell service keeps the exact caps it held as init. The uptime and filesystem granted/ungranted pairs preserve their timer and root asymmetry; those sources and stdio are minted per child and do not broaden init. The manual proof forwards its read-only manual grant through init. Their proofs (make test-shell-uptime, make test-shell-fs, and make test-system-manual-smoke) preserve their existing behavior assertions and add the parameterized assert_init_owned_shell_service topology pin.

Migrated to init-owned service graphs (Gate B 1/3, 2026-07-17 20:02 UTC): system-smoke.cue, system-shell.cue, system-login.cue, and system-login-setup.cue now boot init and launch capos-shell as a single init-spawned service named shell under exitWhenServiceExits. init holds only the bootstrap authority (console/boot/spawner) plus the scoped grants it forwards; the shell service receives exactly the caps it held as init (terminal moved, the rest shared – system-shell.cue adds console/wall_clock grants, with stdio (kernel:endpoint) per-child minted so init never holds it; system-login-setup.cue adds setup). Their proofs (make run-smoke, make test-shell, make test-login, make test-login-setup) pin the init-owned topology via the parameterized assert_init_owned_shell_service in tools/qemu-shell-smoke.sh (init as PID 2 with its cap count, capos-shell spawned as the shell service with its scoped cap count). No init/src/main.rs change was required: the generic manifest spawn loop already supports this shape. The init-mandate loader rule (rejecting a non-init top-level binary) is the separate successor task init-mandate-loader-validation-rule.

Migrated to init-owned service graphs (Gate B, 2026-07-17): system-local-users.cue, system-credential.cue, and system-terminal.cue now boot init and launch the former top-level binary (capos-shell, credential-store, terminal-session) as a single init-spawned service under exitWhenServiceExits. init holds only the bootstrap authority (console/boot/spawner) plus the scoped grants it forwards; each service receives exactly the caps it held as init. Their proofs (make test-local-users, make run-credential, make test-terminal) assert the same boundary properties, with the local-users boundary check relocated to assert_init_owned_shell_service in tools/qemu-shell-smoke.sh.

Migrated to init-owned service graphs (Gate B 3/3, 2026-07-17 19:44 UTC): system-revocable-read.cue and system-memoryobject-shared.cue now boot init and launch their former top-level binary (revocable-read, memoryobject-shared-parent) as a single init-spawned service under exitWhenServiceExits. Each service keeps exactly the caps it validated as init (revocable-read: console/boot/spawner, since it reads the forwarded BootPackage and spawns revocation-observer; memoryobject-shared-parent: console/frames/spawner) – init holds only console/boot/spawner, with frames a per-child-minted source the spawner grants the parent fresh. Their proofs (make test-revocable-read, make test-memoryobject-shared) were strengthened to pin the init-owned topology: the created process 2 for service 'init' / spawned process 3/spawned process 4 lines plus per-process cap counts assert init (PID 2) owns the graph and no bootstrap authority leaks into the demo processes (PID 3/4).

Manifests already compliant: system.cue, system-adventure.cue, system-chat.cue, system-spawn.cue, system-measure.cue, system-restricted-shell-launcher.cue, all remaining system-ssh-*.cue (system-telnet.cue, system-network-client.cue, and system-ssh-gateway-terminal-host.cue are removed with the kernel socket owner).

Default-run feature integration gap

make run boots system.cue, which already wires the anonymous shell, the login flow with the seeded password verifier in MOTD, the chat/adventure demos, chat/adventure spawn instructions, the host-local remote-session CapSet gateway, and (as of 2026-05-14 09:07 UTC) the self-served remote-session-web-ui service. The Telnet research demo is retired (the focused proof using system-telnet.cue and its gateway demo are removed with the kernel socket owner). The retired SSH gateway terminal host is absent by design. Its future SSH Shell Gateway successor remains absent from the default path and its MOTD.

The default make run recipe now attaches virtio-net with host-local remote CapSet forwarding to guest port 2327 and host-local web UI forwarding to guest port 8080. Both use the same ?=-overridable host port with fallback-to-free-port behavior implemented in tools/qemu-run-hostfwd.py. Future network-backed milestones, including the SSH Shell Gateway, remain subject to the authoritative integration checklist above.

Open Gates

Gate A: Naming and contract

  • Strict split selected (2026-07-18 01:04 UTC). run and run-display are the only operator entrypoints. Every other current run-* recipe, including run-uefi, run-net, and run-measure, moves to test-* in Gate C even if the resulting recipe only starts QEMU. This accepts a larger one-time rename so the prefix remains stable when a recipe gains or loses automation. The permissive split was rejected because deciding what counts as the default manifest or a documented variation would reintroduce case-by-case review and naming drift.
  • The CLAUDE.md “Build and Test” section and REVIEW.md define the strict prefix and behavior contract. They identify the current extra run-* names as Gate C migration debt rather than precedent.

Gate B: Init mandate enforcement

  • For every non-compliant manifest, restructure so the init binary is init and the previous top-level binary becomes a service. Preserve the focused-proof intent: the service receives the same scoped caps it had as init, init holds only the bootstrap authority needed to spawn and supervise it, and the smoke/proof transcript continues to assert the same boundary properties. (2026-07-17: the primary shell-family manifests – system-smoke.cue, system-shell.cue, system-login.cue, system-login-setup.cue – are migrated. 2026-07-27: the deferred shell-led focused proofs (system-shell-uptime*, system-shell-fs*, and system-manual-smoke.cue) are also migrated. Other self-contained focused proofs still select their proof binary directly; no exception class has been accepted for them.)
  • After settling that direct-proof scope, add a manifest-loader validation rule (or mkmanifest check) that enforces the resulting policy. Under Policy Statement 2 as written, it rejects any manifest whose initConfig.init.binary is not init and also rejects the field being missing. Update host tests to cover the negative case.
  • Update every doc that currently describes a shell-led, service-led, or per-demo manifest as having the service or proof binary as init. A 2026-04-28 12:48 UTC docs pass reconciled the current default system.cue path as standalone-init-owned. As of 2026-07-17 the primary focused shell-led manifests (system-smoke.cue, system-shell.cue, system-login.cue, system-login-setup.cue) are themselves migrated to init-owned graphs. As of 2026-07-27 the deferred shell-led proofs (system-shell-uptime*, system-shell-fs*, system-manual-smoke.cue) are migrated too. The final docs audit on 2026-08-02 12:35 UTC reviewed every match from rg -n -i '(shell-led|service-led|demo-led|as (the )?(boot )?init|init binary|top-level binary|pid 2|initConfig\.init\.binary)' docs README.md CLAUDE.md AGENTS.md REVIEW*.md --glob '*.md' and found no remaining sentence that assigns a migrated manifest’s boot init role to its service binary. That migrated-family result does not close the repository-wide criterion: current docs accurately record self-contained direct-boot proof manifests whose exception or migration remains undecided. Repeat the audit after init-mandate-loader-validation-rule settles and implements that scope.

Gate C: Test split

  • Five SSH focused proofs migrated to test-ssh-* (2026-07-27 08:49 UTC); evidence.

  • Six memory and IPC capability proofs migrated to test-* (2026-07-27 11:13 UTC); evidence.

  • Six RAM-backed storage capability service proofs migrated to test-* (2026-07-27 14:58 UTC); evidence.

  • Sixteen WASI and wasm-host language/runtime proofs migrated to test-* (2026-07-27 17:34 UTC); evidence.

  • Six CPU-isolation, SQPOLL, and AutoNoHz scheduler proofs migrated to test-scheduler-* (2026-07-27 20:14 UTC); evidence.

  • Six libcapos and libcapos-posix C-substrate proofs migrated to test-c-* (2026-07-27 23:09 UTC); evidence.

  • Three crypto key-custody proofs migrated to test-crypto-* (2026-07-28 03:13 UTC); evidence.

  • Seven disk-backed storage and filesystem proofs migrated to test-* (2026-07-28 09:51 UTC); evidence.

  • Eight installable-system proofs migrated to test-installable-* (2026-07-28 10:35 UTC); evidence.

  • Seven block-device, record-store, and durable-coordinator proofs migrated to test-* (2026-07-28 14:49 UTC); evidence.

  • Six boot-source proofs migrated to test-* (2026-07-28 20:38 UTC); evidence.

  • Six hardware-audit and hardware-grant-cycle proofs migrated to test-* (2026-07-29 00:15 UTC); evidence.

  • Eleven endpoint, crash-disconnect, and untrusted-exhaustion proofs migrated to test-* (2026-07-29 01:52 UTC); evidence.

  • Three resource-limit proofs migrated to test-* (2026-07-29 03:21 UTC); evidence.

  • Nine shell, login, and local-user proofs migrated to test-* (2026-07-29 10:07 UTC); evidence.

  • Eight scheduler fairness, scale, and baseline proofs migrated to test-* (2026-07-29 11:44 UTC); evidence.

  • Fourteen POSIX process, exec, descriptor, and stdio proofs migrated to test-* (2026-07-29 12:47 UTC); evidence.

  • Twelve POSIX libc, networking, and shell targets migrated to test-* (2026-07-29 13:39 UTC); evidence.

  • Twelve NVMe controller and queue bring-up targets migrated to test-* (2026-07-29 16:00 UTC); evidence.

  • Sixteen NVMe block-device, sync-to-flush, and filesystem proofs migrated to test-* (2026-07-29 17:54 UTC); evidence.

  • Ten virtio-net bring-up, authority, and queue-materialization proofs migrated to test-* (2026-07-29 18:59 UTC); evidence.

  • Eight userspace NIC-driver ownership, queue, and interrupt proofs migrated to test-* (2026-07-29 22:12 UTC); evidence.

  • Eleven virtio-net datapath, interrupt-delivery, and teardown proofs migrated to test-* (2026-07-29 23:35 UTC); evidence.

  • Ten userspace smoltcp network-stack proofs migrated to test-* (2026-07-30 00:13 UTC); evidence.

  • Nine ICMP and IPv6 datapath proofs migrated to test-* (2026-07-30 01:12 UTC); evidence.

  • Nine network usability and diagnostics proofs migrated to test-* (2026-07-30 02:28 UTC); evidence.

  • Twelve DDF hardware-grant, interrupt, and audit-service proofs migrated to test-* (2026-07-30 07:09 UTC); evidence.

  • test-dmapool-grant returned to green with typed userspace exception evidence (2026-07-30); evidence.

  • Seven cloud DDF, provider-waiter, IOMMU, and NVMe synchronous-I/O proofs migrated to test-* (2026-07-30 09:31 UTC); evidence.

  • Nine session, identity, authority-broker, service-routing, monitoring, and debug proofs migrated to test-* (2026-07-30 12:29 UTC); evidence.

  • Five capability-lifecycle, cap-retargeting, spawn-grant, and user-fault proofs migrated to test-* (2026-07-30 15:23 UTC); evidence.

  • The shared-service demo and Lua runtime family migrated to test-* (2026-07-30 18:38 UTC); evidence.

  • The UEFI and raw-disk boot family migrated to test-* (2026-07-31 04:35 UTC); evidence.

  • Platform discovery and diagnostics proofs migrated to test-* (2026-07-31 07:27 UTC); evidence.

  • WebUI sustained-connection and GCE legacy-virtio serving proofs migrated to test-* (2026-07-31 09:36 UTC); evidence.

  • Task-coordinator API and TLS client-handshake serving proofs migrated to test-* (2026-07-31 12:22 UTC); evidence.

  • TerminalSession and virtio-net reset-before-free proofs migrated to test-* (2026-07-31 16:05 UTC); evidence.

  • Twenty-one classifier-owned retirement stubs migrated to matching test-* names (2026-07-31 18:22 UTC); evidence.

  • Measurement and default-manifest boot proofs migrated to test-* (2026-07-31 23:00 UTC); evidence.

  • Three remote-session and TLS WebUI QEMU-only siblings migrated to test-* (2026-08-01 21:08 UTC); evidence.

  • Artifact-log prefix residual (closed 2026-08-02 02:21 UTC): immediately before the coordinated rename, the Makefile inventory had 40 migrated test-* recipes that wrote 80 distinct UART artifacts under target/run-*-{kernel,terminal}.log. The complete pre-rename inventory by migrated family was: - POSIX process, exec, descriptor, and stdio (14 recipes): test-posix-args-smoke, test-posix-cwd, test-posix-env-smoke, test-posix-execve-inherit-smoke, test-posix-fcntl, test-posix-fd-inherit-default, test-posix-identity, test-posix-isatty, test-posix-open-dir-fd, test-posix-open-smoke, test-posix-pipe-smoke, test-posix-spawn-smoke, test-posix-stdio-smoke, and test-posix-stdio-terminal-smoke. - POSIX libc, networking, and shell (10 recipes): test-posix-file-backing-smoke, test-posix-getaddrinfo, test-posix-printf, test-posix-read-builtin, test-posix-setjmp, test-posix-shell-smoke, test-posix-signal-time, test-posix-socket-poll-select, test-posix-strftime, and test-posix-test-builtin. - DDF hardware-grant, interrupt, and audit-service (9 recipes): test-devicemmio-grant, test-devicemmio-grant-exit, test-dmapool-grant, test-dmapool-grant-exit, test-interrupt-grant, test-interrupt-grant-x2apic, test-ddf-interrupt-stale-notification, test-ddf-audit-reader-smoke, and test-ddf-audit-service-smoke. The keyed-signature and runtime- admission targets alias the audit-service recipe and therefore reuse its two artifacts; the persist-reboot proof uses temporary files. - Cloud DDF grants and provider cap waiter (4 recipes): test-cloud-devicemmio-grant, test-cloud-dmapool-grant, test-cloud-interrupt-grant, and test-cloud-provider-cap-waiter. - Lua runtime (1 recipe): test-lua-smoke. - Session-bound invocation context (1 recipe): test-session-context. - User-fault containment (1 recipe): test-user-fault. For every listed recipe test-<suffix>, the two old paths were exactly target/run-<suffix>-kernel.log and target/run-<suffix>-terminal.log. No listed path was shared by two recipes.

    The dedicated follow-up renamed all 80 paths to
    `target/test-<suffix>-{kernel,terminal}.log` and ratcheted
    `docs/workflow/run-target-artifact-log-budget.toml` to zero. No direct
    migrated `test-*` recipe body carries a `run-`-prefixed artifact path.
    `test-ddf-iommu-abort-leak-accounting` remains an alias of the retained,
    registry-budgeted `run-iommu-remapping` target and therefore still emits
    `target/run-iommu-remapping-{kernel,terminal}.log`; that retained target
    is outside this direct-body artifact inventory and follow-up.
    Prior per-recipe evidence in the
    [Gate C changelog section](../changelog.md#gate-c-migrated-family-evidence)
    remains citable and unchanged: those records name the migrated `test-*`
    recipes and outcomes, while this residual records the exact historical
    `run-*` path mapping.
    
  • Move every scripted input driver, transcript assertion, timeout wrapper, harness invocation, and log grep currently embedded in a run-* recipe into a new test-* recipe. The run-* side, where retained, becomes a one-line qemu-system-x86_64 ... $(QEMU_COMMON) $$serial_args invocation against the same ISO.

  • Keep tools/qemu-*-smoke.sh, tools/qemu-*-harness.sh, and the ringtap viewer assertion out of run-* recipes. They are acceptable inside test-* recipes or as standalone host scripts.

  • Stale citation audit (closed 2026-08-02 13:51 UTC): derived the authoritative 18-target run-* set (17 Gate C naming-debt targets plus run-display) with python3 tools/run_target_inventory.py, then audited make run-* citations with rg -n --no-heading -o 'make[[:space:]]+run-[A-Za-z0-9_-]+' papers docs README.md CLAUDE.md AGENTS.md REVIEW*.md .github tools. The paper’s historical Gate 4 record preserves the then-named run-chat and run-adventure targets without presenting them as current commands; the direct-IPC evidence bundle likewise preserves the original run-measure target history while giving make test-measure as the reproduction command. The obsolete paper and benchmark command-form exceptions were removed from docs/workflow/doc-make-target-exceptions.toml. The audit changed the paper, the direct-IPC evidence bundle, that exception registry, this Gate C record, and the repository workflow hygiene entry in docs/status.md. Ten deliberate historical references remain there for eight retired names: run-default-web-ui, run-cloud-prod-network-address-abi-ipv6, run-capnp-chat-interop, run-remote-session-adventure-interop, run-remote-session-capset-ui, run-tcp-listen-authority, run-telnet, and run-measure. Changelog entries remain path-exempt historical records. All other scoped make run-* citations resolve to the current inventory and therefore remain owned by the separate 17-target Gate C migration work.

Gate D: Default-run feature integration

The authoritative default-run integration checklist is the CLAUDE.md Stage Implementation Workflow. This backlog records only the backfill status.

  • Define the milestone integration checklist (2026-07-27 06:46 UTC).
  • Resolve the already-shipped milestone backfill (2026-07-27 07:02 UTC). Local-user setup and terminal-session are present in the default MOTD, with rendering asserted by make test-default-boot. The former Telnet and SSH gateway terminal-host paths are retired with the kernel socket owner, so neither is a backfill candidate. The future SSH Shell Gateway successor remains governed by the checklist and milestone checkpoint below.
  • Add the authoritative checklist to the CLAUDE.md Stage Implementation Workflow (2026-07-27 06:46 UTC).

Interaction With Paused SSH Shell Gateway Milestone

Loopyard currently pauses the SSH Shell Gateway behind Service Object Identity Migration. When SSH work resumes, it will still have a visible goal of default-boot SSH shell access plus focused make test-ssh-* proofs. Without an explicit checkpoint, that milestone can land more non-compliant proof recipes before this backlog is applied.

  • Before the SSH Shell Gateway milestone closes, add Gate A’s naming decision and Gate C’s test split as a milestone-level prerequisite: focused proofs use test-ssh-*, host harnesses live under tools/, and user-visible SSH access is integrated into make run under Gate D rather than left as a separate run-ssh-* recipe. Record the requirement in the SSH milestone checkpoint or block its closeout.

Sequencing

Gate A is purely policy and naming and unblocks the others. Gate B (init mandate) and Gate C (test split) can proceed in parallel on separate branches per affected manifest area, because they touch different files: B rewrites system-*.cue and may add services to init/src/main.rs, while C touches Makefile and the tools/qemu-* harnesses. Gate D follows once the test split lands so MOTD updates land alongside system.cue changes without competing with make run’s recipe.

Out Of Scope

  • Renaming or relocating tools/qemu-*-smoke.sh and tools/qemu-*-harness.sh scripts. They stay where they are; only their callers change.
  • Producing a new test runner that aggregates all test-* targets. That is a separate CI ergonomics task.
  • Reworking the focused-proof transcript content. The intent is to preserve current proof coverage, not extend it.