Hosting applications — gaps, and containers
What ctos can host today under the scoped Track A product claim (a loaded freestanding user-mode binary with a stable ABI on an OS/app slot), what is still missing for stronger isolation, and whether it can host containers.
Today you also extend the kernel (Building or porting). Samples that exist: What can run today. Isolation notes: el0.md. Kernel SVC numbers: syscall.md.
Do not say ctos hosts Linux programs, POSIX apps, or containers. The scoped freestanding slot-hosting claim is Verified under ADR-048 / ADR-052.
Today vs the slot split (A9 + product claim)
Today (Verified miles + product claim): QEMU -kernel still loads one OS ELF. Published freestanding samples live on FAT /hello (A9), /fsdemo (ADR-059), /fatdemo (ADR-061), and /yldemo (ADR-062). A2–A4 load /hello (no production embed). The same hello ELF boots on this OS and on ba6541c (ADR-032). Under ADR-048 criteria Met×5 (ADR-052), the product sentence “apps run independently of the OS” / “app hosting is done” is Verified for that freestanding slot path. It is not containers, not OTA, and not Linux/POSIX.
Product claim (Verified): “apps run independently / hosting done” is Verified under ADR-048 (checklist below). Scope stays freestanding slots — not Linux userspace.
flowchart LR OS["OS ELF<br/>QEMU -kernel"] --> FAT["FAT16 volume"] H["/hello"] --> FAT F["/fsdemo"] --> FAT D["/fatdemo"] --> FAT Y["/yldemo"] --> FAT FAT --> LOAD["Guest PT_LOAD<br/>standing EL0"] LOAD --> CLAIM["Product hosting<br/>Verified — ADR-048/052"]
Freestanding slot-hosting is Verified (Met×5). Catalog samples deepen recipes; they do not reopen the claim. Do not say Linux hosting, containers or OTA. Say “EL0 isolated” only as the accepted ADR-091 sentence. Runtime cost vs embed is a lab measurement pair (ADR-046), not a marketing delta.
Gaps before hosting applications
These are missing pieces for richer hosting / isolation, not a schedule. Rows without a probe stay Planned or unbuilt. “Later” is not a promise.
A supervisor call (SVC) is how user-mode code asks the kernel for help. Reserved SVC #0–#2 stay test miles. A1 documented exit / uart_write / yield (syscall.md). That is not a CRT or loader.
| Gap | Why it matters | Status |
|---|---|---|
| Stable SVC ABI | A1 documented exit / uart_write / yield (ADR-021). That is a kernel contract, not a loader. | ABI mile — Verified only when the ledger has svc: ok on this tip. Mile ≠ whole product claim. |
| libctos / CRT | A2: libctos wrappers + _start CRT. Hello is host-built and published for the slot path (ADR-022). | CRT mile — Verified only when the ledger has libctos: ok on this tip. Not a guest loader. |
| ELF / user loader | A3: guest ELF64 PT_LOAD into user TTBR0, then ERET to e_entry (ADR-023). A2–A4 load FAT /hello (no production embed, ADR-032). Not a Linux ELF ABI. | Loader mile — Verified only when the ledger has loader: ok on this tip. Not a Linux ABI. |
| OS vs app slots | A9: host kernel ELF + hello-libctos.elf; guest FAT /hello (ADR-030). Same ELF on this OS and ba6541c (ADR-032). | Slot first cut + leftover — Verified only when the ledger has slot: ok and the cross-update host lines on this tip. Product claim uses this mile under ADR-048. |
| Standing user mode as normal | A4: loaded image stands until exit; fail-closed restore (ADR-024). Not a process table. | Standing-task mile — Verified only when the ledger has el0: task-ok on this tip. Not isolation. |
| Stronger isolation | Umbrella “EL0 isolated” accepted by the sponsor 2026-09-28; revision 4 accepted 2026-10-02 (ADR-091; checklist ADR-055 all Met; sponsor closure ADR-060); PAN enabled (ADR-080); _start stub page stays the one identity exception (ADR-089); stock-QEMU taken SError still parks (ADR-053) | Verified only as the ADR-091 sentence: one core, the TCG default smoke machine; not a speculative-execution or side-channel claim, not a real-hardware claim, not a certification; app text is EL0 execute-only; EL1 can still read it (no FEAT_EPAN); no multi-core race story |
| VFS + memfs | Thin VFS + in-RAM named buffers (ADR-027); see Filesystem | memfs mile — Verified only when the ledger has fs: ok on this tip. Not POSIX. Not FAT. |
| On-disk FS | virtio-blk + FAT16 behind the same VFS (ADR-028); write depth (ADR-050) | block + FAT mile — Verified only when the ledger has blk: ok / fat: ok (and fat: write / fat: create for write). Not POSIX. Not “supports FAT” as a product. |
| Richer I/O | UART byte in/out only; no TTY, disk beyond FAT, or sockets | UART probed; the rest unbuilt |
| Preemption / extra CPUs / net | Cooperative one-CPU yield; no NIC | Later — not required for the ADR-048 claim |
“Host an application independently of the OS” / “app hosting is done” is Verified under ADR-048 (documented recipes + slot cross-update + no production embed + honesty about missing Linux/POSIX/containers + sponsor accept / ADR-052). That block is Track A. A1–A9 first cuts alone were never enough; the checklist Met×5 is. A5: PAN ID-field Verified; enable is non-goal on default cortex-a57 (ADR-047). A8 documented rebuild recipes (what-can-run.md). A9 + leftover: FAT /hello, no production embed, cross-update on ba6541c. See Immutability.
Containers
Non-goal. ctos cannot host OCI / Docker / Kubernetes workloads, and it is not aiming to.
Those need Linux kernel features (namespaces, cgroups, a Linux ABI, usually overlay or equivalent, a rich syscall surface) that this learning kernel does not have. Decision: ADR-029. Track B B7 (#47).
Today the arrow is the other way: Docker on a host (arm64 workstation linux/arm64) runs the ctos smoke image. That is “Docker hosts ctos,” not “ctos hosts containers.” See the README Docker notes and the Docker rows in the ledger.
flowchart LR HOST["Linux host + Docker"] -->|"builds and QEMU-smokes"| CTOS["ctos guest"] CTOS -.->|"does not host"| OCI["OCI / Docker / k8s"]
Host harness ≠ guest runtime. File presence of this page is not a container probe.
Container support is not Planned on this page. Do not add a Planned row. Reopen only with a new GitHub epic plus a new ADR — not a Track B win, and not a new FR/NFR ID.
Claim criteria (ADR-048)
Product “apps run independently / hosting done” is Verified when all of the following are ledger-Verified and sponsor-accepted (ADR-048 / ADR-052):
- Documented freestanding-app recipes (existing markers only).
- Slot cross-update (same published ELF on this OS and a documented prior OS).
- No production hello embed (
slot: embednever appears on the production path). - Docs still refuse Linux ABI / POSIX / guest containers (ADR-029).
- Explicit sponsor accept on the flip PR (no self-merge).
Progress vs tip main (honesty checklist)
Tip audited: 190ef5a (Merge #106 / docs polish; or newer main with ADR-062). Product row Verified — criteria 1–5 Met. Catalog samples /fsdemo / /fatdemo / /yldemo deepen recipes; they do not reopen ADR-048/052.
| # | Criterion | Status | Tip evidence (cite ledger / tip) |
|---|---|---|---|
| 1 | Documented recipes (A8) | Met | Ledger “Documented sample apps (Track A A8)” Verified; hub what-can-run.md / apps-today.md / user/README.md. |
| 2 | Slot cross-update | Met | Ledger “A9 cross-update …” Verified: cross-update prior-os=ba6541c… slot:ok + cross-update this-os=… slot:ok (ADR-032). Re-probed on later tips (incl. ADR-046 / amd64 workstation Docker rows). |
| 3 | No production embed | Met | Ledger “A2–A4 hello without include_bytes! (ADR-032)” Verified; smoke rejects slot: embed. Probe-only include_bytes! in src/slot.rs only (ADR-046). |
| 4 | Honesty: no Linux/POSIX/containers | Met | Containers non-goal (ADR-029); this page + Track B frame refuse Linux userspace / POSIX / guest OCI. |
| 5 | Explicit sponsor accept | Met | Sponsor: “address 1. app hosting” after still-Planned #5-only review. ADR-052. Flip PR; no self-merge. |
A1–A9 first cuts alone remain insufficient without the checklist. Matching ledger section: honesty-ledger.md — ADR-048 progress.
Honesty
| Claim | Status |
|---|---|
| ctos hosts freestanding slot apps / “hosting done” (ADR-048 scope) | Yes — Verified (ADR-048 / ADR-052) |
| ctos hosts Linux programs / POSIX / glibc/musl | No |
| ctos hosts OCI/Docker containers | No — non-goal (ADR-029) |
| Linux-compat research (Track B) | Frame (ADR-031) + B2 gap map (linux-aarch64-syscall-gap.md) + B3 process-model stance (ADR-035) + B4 ELF/auxv gap (ADR-033) + B5 VFS compare (ADR-034). Not claiming Linux userspace yet. Not claiming dynamic Linux ELF. Not claiming a Linux filesystem. |
Host Docker runs ctos-smoke | Separate ledger row (host tool, not a guest runtime) |