a73x

b6a96396

docs: index the doc set, record decisions, and set the v0.0.1 roadmap

a73x   2026-07-26 10:52

Commit message
docs: index the doc set, record decisions, and set the v0.0.1 roadmap

README.md
Old New
@@ -79,6 +79,15 @@ Guests boot from cloud images (the default is Ubuntu resolute) via UEFI firmware
79 (`CLOUDHV.fd`) shipped to each host, so the guest owns its kernel and any 79 (`CLOUDHV.fd`) shipped to each host, so the guest owns its kernel and any
80 disk-only image boots unmodified. 80 disk-only image boots unmodified.
81 81
82 ## Documentation
83
84 [docs/](docs/README.md) is indexed by what you're trying to do — understand it
85 ([architecture](docs/architecture.md), [ethos](docs/ethos.md)), run a fleet
86 ([cert rotation](docs/cert-rotation.md), [revocation](docs/credential-revocation.md)),
87 use a fleet ([ssh access](docs/ssh-access.md), [mcp](docs/mcp.md)), or see why
88 it's built this way ([decisions](docs/decisions.md)). What ships next is in
89 [ROADMAP.md](ROADMAP.md).
90
82 ## Repository layout 91 ## Repository layout
83 92
84 ``` 93 ```
ROADMAP.md
Old New
@@ -0,0 +1,49 @@
1 # Roadmap
2
3 ## v0.0.1 — installable
4
5 The goal: someone with a Linux box goes from [eitri.sh](https://eitri.sh) to a
6 booted VM they can `eitri-ssh` into. Prebuilt binaries fetched from stable
7 URLs — no toolchain, no curl-pipe installer. This is the first tag; history is
8 frozen from here.
9
10 **Binaries & releases**
11
12 - Version-stamped binaries (`--version`), cross-compiled release tarballs +
13 SHA256SUMS (linux amd64/arm64; darwin for `eitri-ssh`)
14 - Artifacts at stable URLs: `eitri.sh/dl/v0.0.1/...` with a `latest` alias, so
15 tooling can bootstrap from them, not just humans
16
17 **eitri.sh**
18
19 - Landing page, rendered docs, downloads, and a `CLOUDHV.fd` firmware mirror —
20 one static site image, replacing the current site
21
22 **Upgrades**
23
24 - Agent: replace binary + restart in place; running VMs survive and are
25 re-adopted
26 - cloud-hypervisor: swap the binary in place; new/restarted VMs use the new
27 version, running VMs keep their old process
28 - Server: stop → replace → start; downtime acceptable, VMs unaffected;
29 migrations run on boot; version skew with agents stays safe
30
31 **Docs**
32
33 - Quickstart: zero-to-first-VM on one host, then add a second host
34 - Upgrade guide, release notes
35
36 **Gate**
37
38 - Clean-slate rehearsal: the quickstart followed verbatim on a fresh host,
39 end-to-end, before the tag exists
40
41 Out of scope: curl installer, OS packages, live cloud-hypervisor handover for
42 running guests, new features.
43
44 ## v0.0.2 — candidates
45
46 - macOS host support: a Mac joins the fleet as a host
47 (Virtualization.framework backend)
48 - Live cloud-hypervisor handover for running guests
49 - Public gateway: route inbound traffic to guest services through eitri
docs/README.md
Old New
@@ -0,0 +1,32 @@
1 # eitri docs
2
3 By what you're trying to do:
4
5 **Understand it**
6
7 - [architecture.md](architecture.md) — the architectural invariants and the
8 executable governance that enforces them
9 - [ethos.md](ethos.md) — the design principles; what to fall back on when a
10 debate stalls
11 - [shape.html](shape.html) — the generated, explorable package graph
12 (`make shape` regenerates)
13
14 **Run a fleet**
15
16 - [cert-rotation.md](cert-rotation.md) — rotating the server's QUIC identity,
17 and why expiry is never an emergency
18 - [credential-revocation.md](credential-revocation.md) — leaked host
19 credentials, leaked SSH certs, and the disaster levers
20 - Quickstart and upgrade guide are planned for v0.0.1 — see
21 [ROADMAP.md](../ROADMAP.md)
22
23 **Use a fleet**
24
25 - [ssh-access.md](ssh-access.md) — reaching a guest through the jump gate with
26 your own tenant CA
27 - [mcp.md](mcp.md) — `eitri-mcp`, the MCP server that lets Claude drive VMs
28
29 **Why it's this way**
30
31 - [decisions.md](decisions.md) — the settled decisions, the alternatives they
32 beat, and the reasons
docs/cert-rotation.md
Old New
@@ -49,3 +49,10 @@ during a window where that is acceptable, host by host.
49 listener support. 49 listener support.
50 - Pushing new pins over the existing authenticated channel (would remove the 50 - Pushing new pins over the existing authenticated channel (would remove the
51 re-enroll requirement). 51 re-enroll requirement).
52
53 ## Related
54
55 - [credential-revocation.md](credential-revocation.md) — revoking a leaked host
56 credential (generation bump), the complementary emergency lever
57 - [ssh-access.md](ssh-access.md) — the SSH CAs, which are separate from the
58 QUIC identity rotated here
docs/decisions.md
Old New
@@ -0,0 +1,63 @@
1 # Decisions
2
3 Settled ground: the irreversible or contested choices, what they beat, and why.
4 Three lines each — when a rationale needs more, it lives in the relevant doc.
5 For *how* we decide, see [ethos.md](ethos.md).
6
7 ### Desired-state loop, not RPC
8
9 The server streams desired state; agents converge toward it and report actual
10 state back. Instead of imperative RPC per operation. Level-triggered convergence
11 survives disconnects, crashes, and missed messages — a host re-derives
12 everything from persisted records plus what it observes. Details in
13 [architecture.md](architecture.md).
14
15 ### Guests boot their own kernel (UEFI firmware)
16
17 VMs boot via UEFI firmware (`CLOUDHV.fd`) into the image's own bootloader.
18 Instead of a host-supplied kernel/initrd (cloud-hypervisor's direct-boot path).
19 The guest owns the guest: any disk-only cloud image boots unmodified, and guest
20 kernel upgrades are the guest's business, not the fleet's.
21
22 ### Bring-your-own tenant user CA
23
24 Each tenant signs its own SSH user certs; eitri stores only CA public keys.
25 Instead of the server minting user certs from an eitri-held CA. A compromised
26 eitri server cannot mint access to any tenant's guests — the user-auth trust
27 root lives with the tenant. Details in [ssh-access.md](ssh-access.md).
28
29 ### SSH-CA jump gate, not a mesh
30
31 Guest access is plain OpenSSH through a certificate-verified bastion. Instead
32 of an overlay mesh with per-node identity. Both ends speak stock ssh,
33 verification is by certificate in both directions, and there is no fabric
34 dependency to operate or trust.
35
36 ### Agent-local resource admission
37
38 Each host admits vCPU / memory / disk / address through one serialized gate on
39 the agent. Instead of a server-side scheduling ledger. The host is the source
40 of truth for its own capacity — admission that consults reality cannot drift
41 from it, and a partitioned host stays correct on its own.
42
43 ### Embedded DHCP owns guest addressing
44
45 The agent runs a DHCP server handing each VM a sticky, deterministic address,
46 reserved at create through the same admission gate. Instead of static IP
47 injection via cloud-init or an external DHCP daemon. Addressing is a host
48 resource like memory; owning it host-locally keeps images untouched and needs
49 no external service.
50
51 ### No superuser principal
52
53 Every API principal is `{Tenant, Fleet}`; fleet-level endpoints are gated
54 fleet-only, and no principal crosses tenant boundaries. Instead of a global
55 admin identity. Cross-tenant capability is the thing multi-tenancy exists to
56 prevent, so it is unrepresentable rather than merely forbidden.
57
58 ### Agents pin the server cert by fingerprint
59
60 Agents trust the server's self-signed QUIC cert by fingerprint from the join
61 blob — not by CA path, not by expiry. Instead of a CA hierarchy or expiring
62 trust. An expired cert can never brick a fleet; rotation is deliberate hygiene,
63 not an emergency. Details in [cert-rotation.md](cert-rotation.md).
docs/ssh-access.md
Old New
@@ -15,7 +15,8 @@ host-key-changed warnings when VM names or IPs are recycled.
15 15
16 Two CAs, two directions: **your tenant's user CA** (private key on your machine) 16 Two CAs, two directions: **your tenant's user CA** (private key on your machine)
17 signs what you present; **eitri's host CA** (private key on the server) signs 17 signs what you present; **eitri's host CA** (private key on the server) signs
18 what the gate and VMs present. 18 what the gate and VMs present. See [decisions.md](decisions.md) for why eitri
19 holds no user signing key.
19 20
20 ## Bring your own CA (once per tenant) 21 ## Bring your own CA (once per tenant)
21 22