# 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-*` targets only start QEMU.** Any scripted input driving,
   transcript assertion, timeout-based pass/fail, log greps, or harness
   script wrapping must live outside the `run-*` recipe -- either in a
   sibling `test-*` target or in a host harness invoked by the user
   directly.
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.
   When a milestone introduces a user-visible common service or binary,
   it must be integrated into `make 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-net`
- `run-spawn`, `run-shell`, `run-restricted-shell-launcher`
- `run-chat`, `run-adventure`, `run-terminal`
- `run-credential`, `run-login`, `run-login-setup`, `run-local-users`
- `run-network-client`, `run-tcp-listen-authority`
- `run-telnet`, `run-telnet-vm`
- `run-revocable-read`, `run-memoryobject-shared`
- `run-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-vm`
- `run-ringtap-failing-call`
- `run-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 binary `capos-shell`
- `system-shell.cue` -- init binary `capos-shell`
- `system-login.cue` -- init binary `capos-shell`
- `system-login-setup.cue` -- init binary `capos-shell`
- `system-local-users.cue` -- init binary `capos-shell`
- `system-credential.cue` -- init binary `credential-store`
- `system-terminal.cue` -- init binary `terminal-session`
- `system-network-client.cue` -- init binary `network-client`
- `system-revocable-read.cue` -- init binary `revocable-read`
- `system-memoryobject-shared.cue` -- init binary
  `memoryobject-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: `run` and `run-display` are the only `run-*` entrypoints;
        every other current `run-*` recipe (including `run-uefi`,
        `run-net`, `run-measure`) becomes `test-*` 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 a
        `run-*` name, with `test-*` reserved for recipes that script
        input or assert output. Pick this only if the policy text in
        `CLAUDE.md`/`REVIEW.md` can 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
      and `REVIEW.md` so 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 `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.
- [ ] Add a manifest-loader validation rule (or `mkmanifest` check) that
      rejects any manifest whose `initConfig.init.binary` is not `init`.
      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.cue`
      path as standalone-init-owned while preserving focused shell-led
      smoke descriptions where `system-smoke.cue` and `system-shell.cue`
      still boot `capos-shell` directly. 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 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.
- [ ] Update CI hooks, developer docs, and `WORKPLAN.md` checkpoints
      that reference `make run-<x>` for verification to call
      `make test-<x>` instead. Audit `REVIEW_FINDINGS.md` 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.cue` with 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 into `system.cue`, MOTD, and
      default host-loopback QEMU forwarding. For each remaining milestone,
      either wire the
      service into `system.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 default `make run`
      virtio-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.md` so 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-shell` vs
      `test-ssh-shell`) and the location of any host harness must
      conform to the chosen rename split, and `make run` integration
      must be addressed under Gate D rather than left as a separate
      `run-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.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.
