A static-partitioning separation kernel for AArch64/EL2, built so that its claims can be checked rather than believed.
docs/ — what is in here, and what to read first37 documents. (Plus this index, which doc-index exempts from classification because it is
the thing doing the classifying, and the site landing page, which the gate never
sees at all — it collects .md only.)
They are not a manual and they are not in order; each one was
written to close a specific arc, and each records what was established, what was refuted, and what
was left open at the moment it closed.
⚠ This index is GATED (cargo xtask doc-index): every file in docs/ appears below exactly
once, and every entry resolves. A new document that is not listed here fails CI. That is deliberate
— an index maintained by memory is a corpus claim nothing checks, and this project has been bitten by
those enough times to gate all six of its other corpora.
“Is any of this real?” — the fastest honest answer is a command, not a document.
cargo xtask ci # fmt, clippy, tests, and every doc/corpus gate
cargo xtask qemu-test # the hypervisor boots on the metal, under QEMU
Then read the root README.md’s “What this is, honestly” section, which states the
limits before the claims, and QEMU-AND-METAL.md — what testing against QEMU
does and does not mean. Read that one before believing any sentence containing the word “metal”.
“Show me a defect that got past the tests.” — CASE-STUDY-WORK-CONSERVATION.md: a real defect, why three
green test tiers missed it, and what the harness did differently. Start here if you have an hour
and no context.
“How does the proof work?” — TIER-B-CUTOFF.md →
TIER-C-SPIKE.md → TIER-D-NONINTERFERENCE.md, in
that order. They build: bounded exhaustive checking, then a deductive spike, then the property that
makes “isolation” mean something.
“How does the code get from the proof to the hardware?” —
AUDIT-2-P2M-STAGE2.md (the refinement) →
STAGE2-REFINEMENT-FORALL-N.md (the same, ∀-N) →
ARC-6-M5-THESIS.md (the assembled claim).
“What is not proven?” — the honest ledger lives in the root README.md, not
here. Individual docs each end with their own residuals, which is where the ledger’s items come from.
“I am building something like this — what should I not repeat?” —
CARRY-FORWARD.md, which is the residue rather than the results: the open items
and the corrections, aimed at the next system rather than at this one.
The hyphen carries meaning that nothing else records. ARC-N-M5-* is the numbered arc itself —
what it built. ARCN-* (no hyphen) is a companion document for that same arc — a property it made
checkable, or a sub-arc. So there are two documents titled “M5 Arc 4” and two titled “M5
Arc 5”, and they are not duplicates:
| both say | the hyphenated one is | the unhyphenated one is |
|---|---|---|
| M5 Arc 4 | ARC-4-M5-VIRTIO-BLK-COW.md — what was built |
ARC4-CONCURRENCY-PREDICATE.md — the predicate made checkable |
| M5 Arc 5 | ARC-5-M5-GUEST-INTERFACE.md — what was built |
ARC5-CONTENT-NON-INHERITANCE.md — the property it had to establish |
⛔ And ARC-4-TRAP-AND-SERVICE.md is M4’s Arc 4, not M5’s — a third “Arc 4”, from an earlier
milestone entirely.
The files are not being renamed: 235 cited paths across the docs and READMEs point at them, and a rename trades a stated trap for a silent one.
Written for a reader who does not know this project and has an hour. Each one is a single defect, end to end: what was claimed, what was false, why the existing tests missed it, and what the proof did that they could not.
| document | what it establishes |
|---|---|
CASE-STUDY-WORK-CONSERVATION.md |
a scheduler property that was false while the whole suite passed — two tiers asserted it and shared a blind spot, the third could not reach the code. One pinned vCPU stopped every domain permanently, with every safety invariant holding: memory isolation held, temporal isolation did not. A plain unit test reproduced it first — the harness that generalised it uses the mechanism as its own oracle, which is the transferable technique; the lesson is count the axes your generators move, not the tiers that assert |
What is true of the hypervisor’s logic, independent of any hardware.
| document | what it establishes |
|---|---|
TIER-B-CUTOFF.md |
the cutoff / small-scope-completeness argument — why checking small configurations exhaustively says something about all of them |
TIER-C-SPIKE.md |
the deductive spike: the Kani bridge into Verus |
TIER-D-NONINTERFERENCE.md |
non-interference — the property definition and the bridge spike. The longest document here, and the one that defines what “isolation” is allowed to mean |
STAGE2-REFINEMENT-FORALL-N.md |
the Stage-2 refinement for all N — “Tier C for the metal” |
Each audit interrogates one boundary. They are the most useful docs for a reader who wants to know where the argument could be wrong.
| document | what it establishes |
|---|---|
AUDIT-1-HAL-FENCE.md |
the hv-hal fence — what the proven core is forbidden to know about hardware |
AUDIT-2-P2M-STAGE2.md |
the p2m → Stage-2 refinement: the proof’s page tables become the hardware’s |
AUDIT-3-NON-INTERFERENCE.md |
non-interference as the thesis, bridged to Tier D |
AUDIT-4-CONCURRENT-STAGE2.md |
two-set Stage-2 emission — isolation with two domains actually running |
AUDIT-5-VIRTQUEUE-GRANT.md |
the virtqueue is a proven grant, not a hole punched through the isolation |
AUDIT-6-VIRTIO-BLK-COW.md |
the copy-on-write disk keeps guest writes off the shared template |
AUDIT-7-INTERRUPT-SURFACE.md |
whether the interrupt/timer/PSCI surface opens a cross-domain channel |
The program that took the proven model to running hardware. Read ARC-6-M5-THESIS.md
first if you want the conclusion before the construction.
| document | what it establishes |
|---|---|
ARC-0-M5-LIFECYCLE.md |
the lifecycle: a reborn slot inherits nothing |
ARC-1-M5-SCHEDULER.md |
the concurrent scheduler — two vCPUs time-slicing on real hardware |
ARC-2-M5-CONCURRENT-ISOLATION.md |
concurrent inter-domain isolation: two domains, distinct VMIDs |
ARC-3-M5-VIRTIO-CONSOLE.md |
the virtio-mmio console — the ring is a proven grant |
ARC-4-M5-VIRTIO-BLK-COW.md |
virtio-blk with copy-on-write template storage |
ARC4-CONCURRENCY-PREDICATE.md |
the concurrency predicate, made checkable rather than argued |
ARC-5-M5-GUEST-INTERFACE.md |
the guest hardware interface: interrupts, timer, PSCI |
ARC5-CONTENT-NON-INHERITANCE.md |
content non-inheritance — the metal’s half of “a reborn tenant inherits nothing” |
ARC6A-SPAN-REFINEMENT.md |
the refinement learns SPAN |
ARC6B-LINUX-ON-THE-PROVEN-EMITTER.md |
a real Linux kernel running behind the proven emitter |
ARC-6-M5-THESIS.md |
the thesis assembled — the finale, and the shortest document here |
| document | what it establishes |
|---|---|
ARC-4-TRAP-AND-SERVICE.md |
the proof touches a guest: the first trap serviced by proven logic. ⚠ M4’s Arc 4 — see the filename trap above |
Can a device be given to a guest without giving it the machine? Rungs 2 → 3 → 4a → 4b.
| document | what it establishes |
|---|---|
SMMU-STREAM-TABLE.md |
rung 2 — ∀-StreamID stream-table default-deny |
SMMU-TRANSLATION.md |
rung 3 — translation: one proven p2m, two consumers |
SMMU-DEVICE-ASSIGNMENT.md |
rung 4a — device assignment in the model |
SMMU-STREAM-DERIVATION.md |
rung 4b — the metal derives the stream table |
SMMU-DEVICE-PATH-COMPOSITION.md |
the whole device path as one theorem — the arc’s headline sentence |
| document | what it establishes |
|---|---|
VGIC-SPI-ROUTING.md |
⑱-6 — the guest aims an interrupt and the hypervisor obeys |
INTERRUPT-CONFINEMENT.md |
⑱-7/⑱-8 — the peer probe, and the role that made the guard unnecessary |
GICD-RES0-SURFACE.md |
⑲ — a conforming guest was being killed for a legal read |
| document | what it establishes |
|---|---|
QEMU-AND-METAL.md |
★ what testing against QEMU does and does not mean. Read before trusting any “on the metal” claim |
ROADMAP.md |
from a proven model toward a “slim Qubes” — where this is going |
CONSUMER-CORTENFORGE.md |
⚠ a requirements derivation, not a commitment — what a named consumer would need, and the one place it collides with the Tier-D precondition. Read before reviving any rung parked “for want of a consumer” |
MILESTONES.md |
⛔ a LOG, not status — the append-only record, 23 entries from M1’s toy hypercall to two Alpine kernels on EL2. Moved out of the root README, where it was 561 of 850 lines |
CARRY-FORWARD.md |
★ the residue, not the results — what did not close here, turned into advice for building the next mixed-criticality system on seL4 + Microkit + libvmm. Every item says whether choosing a verified kernel removes the problem or merely relocates it, and most relocate. Read this one if you are picking up where this project stopped |
The live position — what main is at, what merged, what to do next — is not in docs/, and this
is not an oversight. A repository document stating the current state is a copy that goes stale
between commits; the state lives in the commit log and the CI runs, and the next move is a
judgement, not a document.
The honest ledger lives in the root README.md, beside the claims it qualifies —
a ledger of what is unproven, filed one directory away from the proof claims, is a ledger nobody
reads.