# Build, Boot, and Test

The commands below are the current local workflow for the x86_64 QEMU target.
The root Cargo configuration defaults to `x86_64-unknown-none`, so host tests
must use the repo aliases instead of bare `cargo test`.

## Prerequisites

Expected host tools:

- Rust nightly from `rust-toolchain.toml`
- `make`
- `qemu-system-x86_64`
- `xorriso`
- `curl`, `sha256sum`, and standard build tools for pinned tool downloads
- Go, used by the Makefile to install the pinned CUE compiler when needed
- A Telnet client for the optional focused loopback shell demo
- Chromium, Chromium Browser, or Google Chrome for the optional remote-session
  CapSet browser UI automation
- Optional policy and proof tools for extended checks: `cargo-deny`,
  `cargo-audit`, `cargo-fuzz`, `cargo-miri`, and `cargo-kani`

The Makefile pins and verifies:

- Limine at the commit recorded in `Makefile`
- Cap'n Proto compiler version `1.2.0`
- CUE version `0.16.0`

Pinned repo-selected tools are installed under `CAPOS_TOOLS_ROOT`, which
defaults to the per-user `$HOME/.capos-tools` cache. Override
`CAPOS_TOOLS_ROOT=/path/to/cache` when a host needs a different cache
location.

## Build the ISO

Use the default target when you need the current bootable capOS image.

```bash
make
```

This builds:

- the kernel with the default bare-metal target;
- the standalone `init` userspace binary used by focused spawn proofs;
- release-built demo service binaries under `demos/`;
- the `capos-rt` userspace binaries, including the shell proof;
- `manifest.bin` from `system.cue`;
- `capos.iso` with Limine boot files.

Relevant files: `Makefile`, `limine.conf`, `system.cue`, `tools/mkmanifest/`.

## Compare Build Provenance

Use `make build-provenance` to write the local build record at
`target/build-provenance.txt`. To compare two retained records locally:

```bash
make build-provenance-compare \
  BASE_PROVENANCE=path/to/base-build-provenance.txt \
  CANDIDATE_PROVENANCE=path/to/candidate-build-provenance.txt
```

The comparison ignores the generated timestamp and allowed local path-root
movement under worktree `target/` directories or `.capos-tools/` caches. It
fails for material provenance drift, including source commit changes, manifest
or artifact hash changes, embedded binary hash changes, OVMF identity/hash
changes, Rust compiler date/commit changes, host-tool version or package
identity changes, and operating-system identity changes.

For PR base-vs-head CI comparison, use the environment policy:

```bash
make build-provenance-compare \
  BUILD_PROVENANCE_COMPARE_POLICY=ci-environment \
  BASE_PROVENANCE=path/to/base-build-provenance.txt \
  CANDIDATE_PROVENANCE=path/to/candidate-build-provenance.txt
```

That mode allows expected source and artifact hash changes while still failing
for runner, GitHub-hosted image, Rust, selected-tool, package-identity, OVMF
selection, and OVMF hash drift. It is a PR environment gate, not a production
reproducibility claim.

Local synthetic comparison checks may create scratch records under
`target/provenance-fixtures/` or Python bytecode caches under `tools/`. Clean
those scratch artifacts with:

```bash
make build-provenance-compare-clean
```

## Boot QEMU

Use the default run targets to boot either the operator-facing system or the
scripted login-path smoke.

```bash
make run
make run-smoke
```

`make run` is the operator-facing boot path. It builds the ISO with the `qemu`
feature, boots QEMU with the interactive terminal UART on stdio, attaches
virtio-net with host-local remote CapSet forwarding, and writes the separate
kernel/debug UART log to `target/qemu-console.log`. The run output prints the
actual forwarded port as `remote CapSet: tcp 127.0.0.1 <port> -> guest :2327`.

The plaintext loopback Telnet research demo was a Phase B fixture, not part of
the default operator path. `make run-telnet` and `make run-telnet-vm` are now
retired because they depended on the removed qemu-only kernel TCP listener. Use
the SSH gateway smokes for current remote-shell coverage and rebuild any
socket-backed terminal proof on the Phase C userspace network stack before using
it as validation.

The same `make run` boot starts the remote-session CapSet gateway. To run the
host CLI against it, use the printed port:

```bash
cargo run --manifest-path tools/remote-session-client/Cargo.toml \
  --target x86_64-unknown-linux-gnu \
  --bin remote-session-client -- --host 127.0.0.1 --port <port>
```

Add `--launch-adventure` to that command when you want the CLI to start the
default-manifest Adventure service graph through `serviceLaunch` and require a
`running` status.

To run the trusted local web bridge against the same QEMU instance:

```bash
CAPOS_REMOTE_SESSION_PORT=<port> make remote-session-ui
```

Then open `http://127.0.0.1:3337/`. The Rust bridge holds the TCP stream,
remote session state, and backend-held remote CapSet; the browser receives
only view models, launch/status descriptors, denial diagnostics, call results,
and redacted transcript rows. The former automated focused proof,
`make run-remote-session-capset-ui`, is retired because it depended on the
removed qemu-only kernel TCP listener. The replacement browser proof belongs to
the future Phase C Web UI L4 gate.

A Tauri desktop wrapper is available as a repo-local check/dev layer over the
same Rust backend. The repo-local `make remote-session-tauri` target first
runs a policy preflight over the reviewed scaffold, then checks for the Tauri
CLI and Linux build prerequisites, reports dependency and scaffold status, and
runs a deterministic wrapper check when those prerequisites are present. It
follows the official Tauri v2 Linux prerequisite shape, including WebKitGTK
4.1, `libxdo`, OpenSSL, AppIndicator, and Rsvg development packages where
applicable. Missing dependencies fail with explicit diagnostics and point back
to the supported local web bridge. The operator command shape is:

```bash
CAPOS_REMOTE_SESSION_PORT=<port> make remote-session-tauri
```

Set `CAPOS_REMOTE_SESSION_TAURI_MODE=dev` to launch `cargo tauri dev`.
`CAPOS_REMOTE_SESSION_TAURI_MODE=policy tools/remote-session-tauri.sh` runs
only the scaffold guardrail and does not require Tauri system packages or a
desktop session. `CAPOS_REMOTE_SESSION_TAURI_MODE=package` and
`CAPOS_REMOTE_SESSION_TAURI_MODE=automation` are intentionally blocked with
diagnostics describing the remaining packaging and desktop-automation review
work. This policy preflight proves only that the current wrapper remains a
check/dev scaffold with packaging disabled, the loopback URL pinned, a single
`main` window, default `core:default` permission scope, and no app-specific
Tauri command/plugin authority. It is not a distributable packaging or desktop
automation proof. `make remote-session-ui` remains the supported fallback host
UI path and uses the same backend-held authority boundary.

Default `make run` starts chat, the remote-session gateway, and shell
services. It embeds Adventure server/NPC/client binaries and the terminal
Paperclips binary. The current remote-session Adventure slice makes
`serviceLaunch` a real restricted backend launch in that default manifest:
the trusted backend/gateway starts `adventure-server` plus simple NPC
companions through an approved service-runner profile and attaches or retains
backend-held descriptors/caps for the Adventure/chat-facing services. Run it
by starting `make run`, noting the printed remote CapSet forwarding port, and
then using either the host CLI or
`CAPOS_REMOTE_SESSION_PORT=<printed-port> make remote-session-ui`.
`make run-paperclips` remains the focused authoritative Paperclips server
proof; default-manifest Paperclips launch is not implemented by this slice.
Raw `ProcessSpawner`, process owner handles, endpoint owner caps, local cap
ids, result-cap slots, and browser-held capOS caps are non-goals for this UI
path. Process handles stay backend-local.

### GCE Web UI Proof Target Map

Use the selected-milestone proof targets below to choose the narrowest evidence
gate for the GCE self-hosted Web UI ladder. Local QEMU/cloudboot targets do not
prove live provider reachability, and private GCE targets do not authorize
public ingress or TLS exposure.

| Proof class | Target or command shape | Proves | Closest non-goal |
| --- | --- | --- | --- |
| Landed local Phase C L4 substrate | `make run-cloud-prod-userspace-network-stack-smoltcp` | A non-`qemu` cloudboot kernel under QEMU starts the userspace smoltcp network-stack process and completes one hostfwd TCP request/response through a userspace-served `TcpListenAuthority`. See [`cloud-prod-userspace-network-stack-smoltcp-local-proof`](tasks/done/2026-06-07/cloud-prod-userspace-network-stack-smoltcp-local-proof.md). | Does not prove DHCP/IPv4 configuration, `remote-session-web-ui`, live GCE reachability, or public ingress. |
| Landed local IPv4 configuration | `make run-cloud-prod-network-stack-dhcp-ipv4-config` | The userspace network-stack process acquires the QEMU SLIRP DHCPv4 lease, serves `NetworkManager.getConfig`, installs the default route, and resolves gateway plus same-subnet ARP neighbors. See [`cloud-prod-network-stack-dhcp-ipv4-config-local-proof`](tasks/done/2026-06-08/cloud-prod-network-stack-dhcp-ipv4-config-local-proof.md). | Does not prove a Web UI listener bound through that route, live GCE reachability, DNS, TLS, or public exposure. |
| Retired legacy local self-served Web UI | `make run-remote-session-self-served-web-ui` | Pre-Phase-C proof that served the immutable full UI bundle from a focused QEMU manifest through the kernel `tcp_listen_authority` socket owner. The target is not current production L4 evidence after [`cloud-prod-phase-c-kernel-smoltcp-virtio-net-removal`](tasks/done/2026-06-08/cloud-prod-phase-c-kernel-smoltcp-virtio-net-removal.md) retires that kernel owner. | Does not prove the non-`qemu` cloudboot Phase C L4 path, and should not be used as a passing selected-milestone gate until rebuilt on the userspace network-stack substrate. |
| Landed cloudboot Web UI authority inventory | No run target; docs-status contract | The Gate 1B inventory records the required and forbidden `remote-session-web-ui` grants, trusted listener/source metadata, browser-visible forbidden markers, and expected local L4 proof markers. See [`remote-session-webui-cloudboot-authority-inventory`](tasks/done/2026-06-08/remote-session-webui-cloudboot-authority-inventory.md). | Does not prove runtime listening, browser automation, GCE reachability, or public operator access. |
| Landed local cloudboot Web UI L4 proof | `make run-cloud-prod-remote-session-web-ui-l4` owned by [`cloud-prod-remote-session-web-ui-l4-local-proof`](tasks/done/2026-06-09/cloud-prod-remote-session-web-ui-l4-local-proof.md) | Proves `remote-session-web-ui` listens on guest port 8080 through the Phase C L4 path on the non-`qemu` cloudboot kernel under QEMU: the userspace network-stack process serves the scoped `TcpListenAuthority`, the Web UI serves the full fixed-name bundle, login, one backend-held capability call, logout, stale-call failure, the manual viewer, and a `cloudboot-evidence: remote-session-web-ui-l4` marker. | Local cloudboot/QEMU evidence only; it does not prove live GCE NIC reachability, private provider probing, public ingress, TLS, or production release authority. |
| On-hold private GCE Web UI proof | Future `tools/cloudboot/run-test.sh --require-web-ui-proof` gate owned by [`cloud-gce-private-self-hosted-webui-proof`](tasks/on-hold/cloud-gce-private-self-hosted-webui-proof.md) | Must launch the self-hosted Web UI cloudboot image in the no-public-IP GCE posture, use a reviewed private probe that crosses the live GCE virtual network boundary, record the private endpoint and Web UI/L4 markers, and tear down all created resources. | On hold (2026-06-09): the cloudtest credential lacks the firewall IAM a private same-VPC probe needs against GCE default-deny ingress, and the live legacy virtio 0.9 GCE NIC has no reviewed userspace-stack serving story. It will not create public IPs, public firewall rules, DNS, TLS certificates, or browser-facing public operator ingress. |
| On-hold public ingress/TLS proof | Future `tools/cloudboot/run-test.sh --require-public-web-ui-proof` gate owned by [`cloud-gce-public-self-hosted-webui-ingress-tls`](tasks/on-hold/cloud-gce-public-self-hosted-webui-ingress-tls.md) | After explicit authorization, must prove the selected GCE external HTTPS load-balancer ingress posture, Google-managed certificate termination, browser-session hardening, and teardown evidence. | On hold. No local target, private proof, or selected milestone status grants public exposure, broad firewall changes, certificate issuance, TLS key custody, or release authority. |

`make run-smoke` preserves the focused legacy shell-led `system-smoke.cue`
verification path. It drives the login and shell session through the terminal
UART, captures the kernel log and terminal transcript separately, and checks
that the kernel boot-launched only the first `init` service (`capos-shell`),
granted only the shell bootstrap cap bundle, and then reached the expected
audit, shell-bundle, child-isolation, stale-handle, and no-password-echo
assertions before QEMU exits. This is distinct from the default `system.cue`
path, where the kernel boot-launches standalone `init` and init starts
operator-facing services.

## Spawn Smoke

Use the spawn smoke when changes affect manifest-owned process creation,
ProcessSpawner behavior, or bootstrap capability wiring.

```bash
make run-spawn
```

This boots with `system-spawn.cue`, the focused init-owned manifest retained
for ProcessSpawner checks. Only `init` is boot-launched by the kernel; `init`
uses ProcessSpawner to launch endpoint, IPC, VirtualMemory, Timer,
ThreadControl, the single-thread runtime checkpoint, FrameAllocator cleanup,
and hostile spawn demo children, wait for ProcessHandles, and exercise hostile
spawn inputs. The target captures the kernel log separately and runs
`tools/qemu-spawn-smoke.sh` to assert the single-init boot markers,
BootPackage validation, child spawn/exit records, Timer now/sleep and
per-process sleep quota proof lines, runtime FS-base proof lines, the
single-thread runtime map/protect/unmap plus park-fallback checkpoint,
manifest child waits, and clean halt.

## Shell and Terminal Smokes

Use these focused QEMU smokes for shell, terminal, credential, and login paths.

```bash
make run-shell
make run-terminal
make run-credential
make run-login
make run-login-setup
```

- `make run-shell` boots the focused `system-shell.cue` manifest (no
  pre-provisioned verifier) and exercises the shell entirely in its anonymous
  session: CapSet listing, typed capability inspection, typed application-error
  display, anonymous-session metadata, the anonymous launcher rejecting
  `spawn-test` because its allowlist is empty, and clean exit.
- `make run-terminal` boots the focused `system-terminal.cue` manifest and
  exercises the `TerminalSession` substrate: visible and hidden echo input,
  bounded `readLine`, structured cancellation, and stale-input scrubbing
  between prompts.
- `make run-credential` boots the focused CredentialStore proof manifest.
- `make run-login` boots the focused password-login manifest and proves the
  shell's `login` command prompting for `username>` before hidden `password>`,
  failing generically on a wrong password, succeeding for the demo account,
  swapping from the anonymous bundle to the operator bundle, and performing
  exact-grant child launch plus stale-handle release.
- `make run-login-setup` boots the no-password first-boot setup manifest and
  proves that `setup` creates a volatile credential, discloses that
  volatility, chains into the login upgrade path, and reaches the same narrow
  operator shell bundle.

Durable account storage and multi-verifier local accounts are still future
work; the current username-aware login path selects the manifest-seeded
operator-kind account and any volatile first-boot credential record that
`setup` creates.

## Focused Service Smokes

Use these targets to prove resident services and demo clients still launch
through the intended shell-granted authorities.

```bash
make run-chat
make run-adventure
make run-paperclips
make run-revocable-read
make run-memoryobject-shared
make run-ringtap-failing-call
```

- `make run-chat` boots the focused First Chat manifest and proves a
  shell-spawned client can send a line through the resident singleton chat
  service using the broker-issued operator `chat` endpoint and observe the
  resident bot reply.
- `make run-adventure` boots the focused adventure manifest and proves the
  shell-spawned client can drive the current scripted mission through explicit
  `StdIO`, `adventure`, and `chat` endpoint grants.
- `make run-paperclips` boots the focused Paperclips terminal demo manifest,
  authenticates the shell, starts Paperclips server services, first launches the
  clean-room terminal client with explicit `StdIO` plus the normal
  `PaperclipsGame` endpoint, proves normal server authority cannot invoke
  `run <ms>`, rejects a forged `proof_accelerator: @timer` grant, then
  relaunches against the proof server endpoint with the explicit
  `proof_accelerator` proof authority for the accelerated transcript. The server
  owns generated content, game state, regular timer cadence, unlock checks, and
  game-rule mutation, and server-mode client help is rendered from structured
  server command specs. That transcript rejects an early locked autoclipper
  purchase, rejects an over-budget wire purchase, rejects bulk manual
  production, rejects a high-price sale with zero current demand, rejects
  manual production after automation drains wire, drives one-at-a-time manual
  production, explicit sales, repeatable marketing, autoclipper unlock,
  real-time automation, generated typed Cap'n Proto content loading, scaled
  business-phase production, `precision-rollers`, `design-search`,
  `forecast-engine`, the `survey-drones` transition to `== autonomous phase ==`,
  representative autonomous drone/factory scaling with local-matter conversion
  and additional clip production, the `mesh-coordination` and `seed-probes`
  cosmic transition, bounded probe replication and production, locked
  `final-conversion`, and clean client/shell exit.
- `make run-revocable-read` exercises the revocation transcript for endpoint
  and boot-package authority loss.
- `make run-memoryobject-shared` proves MemoryObject-backed parent/child
  sharing and cleanup.
- `make run-ringtap-failing-call` enables `debug_tap`, drives a known typed
  launcher failure, and runs the ringtap viewer over the captured log.

## Networking and Measurement Targets

Use these targets for the current network proof path and benchmark-only
measurement image.

```bash
make run-net
make qemu-net-harness
make run-measure
```

- `make run-net` attaches a QEMU virtio-net PCI device and exercises current
  PCI enumeration, virtio transport setup, and TX descriptor completion
  diagnostics, plus ARP resolution and ICMP echo validation against the QEMU
  user-mode gateway.
- `make qemu-net-harness` runs the scripted net smoke path.
- `make run-measure` enables the separate `measure` feature for benchmark-only
  counters and cycle measurements. It boots `system-measure.cue`, where init
  spawns `ring-nop` and grants the measurement-only NullCap and ParkBench
  caps through ProcessSpawner. The demo prints ring/NullCap baselines plus a
  park-shaped comparison between compact authority-checked SQEs and generic
  Cap'n Proto methods. The kernel summary includes per-segment dispatch counts,
  total cycles, and averages for SQE processing, validation, cap lookup, capnp
  decode, method body dispatch, CQE posting, and waiter wake/check. Do not
  treat it as the normal dispatch build.

## Formatting and Generated Code

Use these local checks before claiming source formatting or generated artifacts
are current.

```bash
make fmt
make fmt-check
make generated-code-check
```

- `make fmt` formats the kernel workspace plus standalone `init`, `demos`, and
  `capos-rt` crates.
- `make fmt-check` verifies formatting without modifying files.
- `make generated-code-check` verifies checked-in Cap'n Proto generated code
  against the repo-pinned compiler path and checks generated adventure plus
  Paperclips content against their CUE sources.

## Host Tests

Use these host-side checks for shared logic and userspace build surfaces that
do not require a QEMU boot.

```bash
cargo test-config
cargo test-ring-loom
cargo test-lib
cargo test-mkmanifest
tools/check-userspace-runtime-surface.sh
make capos-rt-check
make init-capos-build
make demos-capos-build
make shell-capos-build
make capos-rt-capos-build
```

- `cargo test-config` runs shared config, manifest, ring, and CapSet tests on
  the host target.
- `cargo test-ring-loom` runs the bounded Loom model for SQ/CQ protocol
  invariants.
- `cargo test-lib` runs host tests for pure shared logic such as ELF parsing,
  capability tables, frame allocation, and related property tests.
- `cargo test-mkmanifest` runs host tests for manifest generation.
- `tools/check-userspace-runtime-surface.sh` verifies `capos-rt` owns the
  userspace entry, panic, allocator, and raw syscall surface.
- `make capos-rt-check` builds the standalone runtime smoke binary against
  `targets/x86_64-unknown-capos.json`, matching the userspace target used by
  the boot image.
- `make init-capos-build`, `make demos-capos-build`, `make shell-capos-build`,
  and `make capos-rt-capos-build` expose focused custom-target build wrappers
  for the booted userspace crates and runtime smoke binary.

## Extended Verification

Use the extended verification set for shared logic, dependency policy, fuzz
targets, and bounded proof gates that are heavier than the normal host-test
loop.

```bash
make dependency-policy-check
make fuzz-build
make fuzz-smoke
make kani-lib
cargo miri-lib
```

These require optional tools. Use them when changing dependency policy,
manifest parsing, ELF parsing, capability-table/frame logic, or proof-covered
shared code. `make dependency-policy-check` covers Rust deny/audit checks and
the docs Node lockfile/audit gate with npm lifecycle scripts disabled. See the
[Security and Verification Proposal](proposals/security-and-verification-proposal.md)
for the rationale behind the extended verification tiers. `make kani-lib`
runs the bounded mandatory cap-table/frame gate.

## Validation Rule

For behavior changes, a clean build is not enough. The relevant QEMU process
must exercise the behavior and print observable output that proves the path
works. `make run-smoke` is the default login-path gate; `make run-spawn`,
`make run-shell`, `make run-terminal`, `make run-credential`,
`make run-login`, `make run-login-setup`, `make run-chat`,
`make run-adventure`, `make run-paperclips`, `make run-revocable-read`,
`make run-memoryobject-shared`, `make run-net`, `make qemu-net-harness`,
`make run-ringtap-failing-call`, or `make run-measure` are additional gates
for their specific features.
