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-tcp-listen-authorityrun-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-policyrun-ringtap-failing-callrun-measure
(run-network-client, run-telnet(-vm), and
run-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.
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-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-tcp-listen-authority.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 make run-telnet / system-telnet.cue path and its
gateway demo are removed with the kernel socket owner).
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
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. 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
docs/tasks/README.mdcheckpoints that referencemake run-<x>for verification to callmake test-<x>instead. Audit the migrated review-finding task records, theREVIEW_FINDINGS.mdtombstone history, and 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. The Telnet gateway remains a focused research fixture undermake run-telnetand is deliberately absent from the default operator path. 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. 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
docs/tasks/README.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.