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
make run-*targets only start QEMU. Any scripted input driving, transcript assertion, timeout-based pass/fail, log greps, or harness script wrapping must live outside therun-*recipe – either in a siblingtest-*target or in a host harness invoked by the user directly.initusage is MANDATORY in every boot manifest. The boot init binary must beinit(thecapos-initELF). Service or demo binaries such ascapos-shell,credential-store,terminal-session,network-client,revocable-read,memoryobject-shared-parent, and per-demo entrypoints must be declared as services and launched byinit, never as the top-level init binary.make runstays the default user-facing target demonstrating a sane, safe, full-featured (as of the current state) capOS instance. When a milestone introduces a user-visible common service or binary, it must be integrated intomake run– either auto-started or advertised through MOTD instructions describing how the operator reaches it – as part of the milestone’s doc-update gate.
Current State
run-* recipes that contain test logic
Snapshot from Makefile at branch base. All targets in this list embed
input drivers, asserts, or harness invocations and therefore violate
policy 1:
run-smoke,run-uefi,run-netrun-spawn,run-shell,run-restricted-shell-launcherrun-chat,run-adventure,run-terminalrun-credential,run-login,run-login-setup,run-local-usersrun-network-client,run-tcp-listen-authorityrun-telnet,run-telnet-vmrun-revocable-read,run-memoryobject-sharedrun-ssh-host-key,run-ssh-authorized-key,run-ssh-public-key-session,run-ssh-public-key-auth,run-ssh-feature-policy,run-ssh-gateway-terminal-host,run-ssh-gateway-terminal-host-vmrun-ringtap-failing-callrun-measure
Compliant run-* recipes (QEMU-only):
run– interactive, manifest-driven, terminal on stdio.run-display– interactive variant with QEMU display.
Manifests violating the init mandate
Init binary is something other than init:
system-smoke.cue– init binarycapos-shellsystem-shell.cue– init binarycapos-shellsystem-login.cue– init binarycapos-shellsystem-login-setup.cue– init binarycapos-shellsystem-local-users.cue– init binarycapos-shellsystem-credential.cue– init binarycredential-storesystem-terminal.cue– init binaryterminal-sessionsystem-network-client.cue– init binarynetwork-clientsystem-revocable-read.cue– init binaryrevocable-readsystem-memoryobject-shared.cue– init binarymemoryobject-shared-parent
Manifests already compliant: system.cue, system-adventure.cue,
system-chat.cue, system-spawn.cue, system-measure.cue,
system-restricted-shell-launcher.cue, system-telnet.cue,
system-tcp-listen-authority.cue, all system-ssh-*.cue.
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, and the host-local
Telnet gateway. Milestones still absent from the default path or its MOTD are
local-user setup, terminal-session focused proofs, SSH gateway terminal host,
and any future SSH shell milestone.
The default make run recipe now attaches virtio-net with
127.0.0.1:2323 -> guest :23 forwarding for the Telnet gateway. Other
network-backed milestones, such as the SSH gateway terminal host and future
SSH shell, still require their own safe default forwarding or an explicit
deferral before they can be called integrated into make run.
Open Gates
Gate A: Naming and contract
- Decide the rename split. Pick one of the two consistent options
and apply it uniformly:
- Strict:
runandrun-displayare the onlyrun-*entrypoints; every other currentrun-*recipe (includingrun-uefi,run-net,run-measure) becomestest-*regardless of whether its body is reduced to a plain QEMU start, because the policy is enforced by name, not by current contents. - Permissive: any QEMU-only recipe against the default manifest with documented firmware/device flag variations may keep arun-*name, withtest-*reserved for recipes that script input or assert output. Pick this only if the policy text inCLAUDE.md/REVIEW.mdcan spell out the boundary unambiguously so reviewers do not have to relitigate the split per target. - Document the chosen policy in
CLAUDE.md“Build and Test” section andREVIEW.mdso future targets are added under the right prefix without case-by-case judgement.
Gate B: Init mandate enforcement
- For every non-compliant manifest above, restructure so the init
binary is
initand 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. - Add a manifest-loader validation rule (or
mkmanifestcheck) that rejects any manifest whoseinitConfig.init.binaryis notinit. The rule should also reject the field being missing. Update host tests to cover the negative case. - Update every doc that currently describes shell-led or
service-led manifests as having the service as init. A 2026-04-28
12:48 UTC docs pass reconciled the current default
system.cuepath as standalone-init-owned while preserving focused shell-led smoke descriptions wheresystem-smoke.cueandsystem-shell.cuestill bootcapos-shelldirectly. Gate B remains open until the focused manifests themselves are migrated or documented as explicit exceptions, the loader/manifest validation rule lands, and a final re-grep confirms no stale default-boot wording remains.
Gate C: Test split
- Move every scripted input driver, transcript assertion, timeout
wrapper, harness invocation, and log grep currently embedded in a
run-*recipe into a newtest-*recipe. Therun-*side, where retained, becomes a one-lineqemu-system-x86_64 ... $(QEMU_COMMON) $$serial_argsinvocation against the same ISO. - Keep
tools/qemu-*-smoke.sh,tools/qemu-*-harness.sh, and the ringtap viewer assertion out ofrun-*recipes. They are acceptable insidetest-*recipes or as standalone host scripts. - Update CI hooks, developer docs, and
WORKPLAN.mdcheckpoints that referencemake run-<x>for verification to callmake test-<x>instead. AuditREVIEW_FINDINGS.mdand the recent changelog updates so historical entries stay accurate while new gates use the renamed targets.
Gate D: Default-run feature integration
- Define an integration checklist that every milestone’s doc-update
step must satisfy before close: either auto-start the new
user-visible service from
system.cuewith safe defaults, or extend the MOTD with a clear, copy-pasteable instruction block describing how to reach the feature from the default boot. - Backfill the integration for already-shipped milestones whose
user-visible services are still absent from
make run: local-user setup, terminal-session, and the SSH gateway terminal host slice. Telnet gateway is already wired intosystem.cue, MOTD, and default host-loopback QEMU forwarding. For each remaining milestone, either wire the service intosystem.cue(preserving the default-safe posture) or add a MOTD section with the exact command. Network-backed milestones must also record the QEMU device and forwarding posture. Telnet gateway is already wired through the defaultmake runvirtio-net path with host-loopback forwarding. SSH gateway terminal-host integration remains deferred until its production/non-loopback gates pass or a separate host-local development forwarding rule is reviewed. A MOTD-only addition is not sufficient for a network-backed milestone. - Add the integration checklist to the “Stage Implementation
Workflow” section of
CLAUDE.mdso future milestones cannot land without it.
Interaction With Paused SSH Shell Gateway Milestone
WORKPLAN.md currently pauses the SSH Shell Gateway behind Service Object
Identity Migration. When SSH work resumes, it will still have a visible goal of
make run-ssh-shell and additional make run-ssh-* proofs. Without an
explicit checkpoint, that milestone can land more non-compliant run-* recipes
(scripted host harnesses, transcript asserts, network-only smokes) 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: the user-visible target name (
run-ssh-shellvstest-ssh-shell) and the location of any host harness must conform to the chosen rename split, andmake runintegration must be addressed under Gate D rather than left as a separaterun-ssh-*recipe. Record the decision 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.shandtools/qemu-*-harness.shscripts. 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.