# Boot Flow

Boot flow defines the trusted path from firmware-owned machine state to the
first user processes. It establishes memory management, interrupt/syscall
entry, capability tables, process rings, and the boot manifest authority graph.


## Current Behavior

Firmware loads Limine, Limine loads the kernel and exactly one module, and the
kernel treats that module as a Cap'n Proto `SystemManifest`. The kernel rejects
boots with any module count other than one.

`kmain` initializes serial output, x86_64 descriptor tables, memory, paging,
SMEP/SMAP, the kernel capability table, the idle process, PIC, and PIT. It then
parses the manifest, validates the kernel-owned boot boundary, loads only
`initConfig.init.binary` into a fresh `AddressSpace`, builds init's bootstrap
capability table and read-only CapSet page from `initConfig.init.caps`, enqueues
init, and starts the scheduler.

Default boot uses the standalone `init` ELF as that init process. It receives
the bootstrap authority needed to read BootPackage, validate the service graph,
spawn child services, and supervise them. The foreground `capos-shell` is now
an init-started service with the terminal, credential, session, audit, and
broker capabilities needed for the local shell flow; it does not receive
BootPackage or broad ProcessSpawner authority. Focused shell-led manifests such
as `system-smoke.cue` and `system-shell.cue` still boot `capos-shell` directly
as `initConfig.init` for narrow login/shell proofs until the run-target/init
policy cleanup migrates them.

```mermaid
flowchart TD
    Firmware[UEFI or QEMU firmware] --> Limine[Limine bootloader]
    Limine --> Kernel[kmain]
    Limine --> Module[manifest.bin boot module]
    Kernel --> Arch[serial, GDT, IDT, syscall MSRs]
    Kernel --> Memory[frame allocator, heap, paging, SMEP/SMAP]
    Kernel --> Manifest[validate kernel manifest boundary]
    Manifest --> InitImage[parse and map init ELF]
    Manifest --> InitCaps[build init CapTable and CapSet page]
    InitImage --> InitProcess[create init Process and ring]
    InitCaps --> InitProcess
    InitProcess --> Scheduler[start round-robin scheduler]
    Scheduler --> Init[enter init]
    Init --> DefaultPath[default init-owned service graph]
    DefaultPath --> Shell[spawn capos-shell service]
    DefaultPath --> Gateway[spawn remote-session gateway and resident services]
    Init --> SpawnPath[focused system-spawn executor path]
    SpawnPath --> BootPackage[read BootPackage manifest]
    SpawnPath --> Spawner[spawn child services]
    Spawner --> Children[focused demo processes]
```

The invariant is that the kernel starts only `initConfig.init` after validating
the kernel-owned manifest boundary, and no child service starts until
mkmanifest/init validation has accepted service binary references, authority
graph structure, and bootstrap capability source/interface checks.

## Design

The boot path is deliberately single-shot. The kernel receives a single packed
manifest and validates only the kernel-owned boot contract before creating
init. Init then performs the userspace execution step: it reads manifest chunks
from BootPackage, validates a metadata-only `ManifestBootstrapPlan`, resolves
kernel and service cap sources, and asks ProcessSpawner to load each child ELF
into its own address space with its own user stack, TLS mapping if present, ring
page, and CapSet mapping.

The default manifest (`system.cue`) now boots an init-owned local path: the
kernel launches the standalone `init` binary described by `initConfig.init`,
and init spawns the shell, remote-session CapSet gateway, and resident services
from `initConfig.services`. The shell mints an anonymous `UserSession` on
startup through `SessionManager.anonymous()`, receives an empty-allowlist
`anonymous` launcher from the broker, and waits at its own interactive prompt.
The user types `login` (or `setup` on a fresh image) to upgrade in place. The
smoke and shell manifests still provide focused shell-led proofs, while
`system-spawn.cue` remains the focused init-owned graph retained for
ProcessSpawner validation.

## Invariants

- Limine must provide exactly one boot module, and that module is the manifest.
- Kernel manifest validation must complete before init is enqueued, and init
  BootPackage validation must complete before any child service is spawned.
- Service ELF load failures roll back frame allocations before boot continues
  or fails.
- Kernel page tables are active and HHDM user access is stripped before
  SMEP/SMAP are enabled.
- The kernel passes `_start(ring_addr, pid, capset_addr)` in RDI, RSI, and RDX.
- CapSet metadata is read-only user memory; the ring page is writable user
  memory.
- QEMU-feature boots halt through `isa-debug-exit` when no runnable processes
  remain.

## Code Map

- `kernel/src/main.rs` - `kmain`, manifest module handling, validation,
  boot-only-init loading, process enqueue, halt path.
- `kernel/src/spawn.rs` - ELF-to-address-space loading, fixed user stack, TLS
  mapping, `Process` construction helpers.
- `kernel/src/process.rs` - process bootstrap context, ring page mapping, CapSet
  page mapping.
- `kernel/src/cap/mod.rs` - bootstrap capability resolution and CapSet entry
  construction for init.
- `capos-config/src/manifest.rs` - manifest decode and schema-version storage.
- `capos-config/src/validation.rs` - graph/source/binary validation policy.
- `tools/mkmanifest/src/lib.rs` - host-side manifest validation and binary
  embedding.
- `system.cue` and `system-spawn.cue` - default and spawn-focused boot graphs.
- `limine.conf` and `Makefile` - bootloader config, ISO construction, QEMU
  targets.

## Validation

- `make run-smoke` validates the scripted focused shell-led login path:
  single `capos-shell` init boot from `system-smoke.cue`, password prompt,
  failed-auth redaction, successful shell launch, narrow shell bundle, and
  clean QEMU halt.
- `make run` is the operator-facing interactive boot path with the terminal
  UART on stdio and console/debug output logged separately.
- `make run-spawn` validates that the kernel boot-launches only the standalone
  `init` with Console, BootPackage, and ProcessSpawner, and that init validates
  BootPackage metadata before running the focused ProcessSpawner, Timer, IPC,
  and memory smokes.
- `cargo test-config` covers manifest decode, roundtrip, and validation logic.
- `cargo test-mkmanifest` covers host-side manifest conversion and embedding
  checks.
- `make generated-code-check` verifies checked-in Cap'n Proto generated output.

## Open Work

- The run-target/init-policy backlog still needs to migrate remaining focused
  shell-led manifests onto standalone init or explicitly preserve them as
  compatibility smokes.
- A future manifest-loader or mkmanifest gate should reject accidental
  non-`init` default boot graphs once all focused exceptions are reconciled.
