Architecture · ruling R5, 2026-09-02

The appliance

The appliance is a Linux VM. Inside it the KOS console runs natively as a service, the harness CLIs are installed locally, and Cortex with its services runs as podman containers. Commercial ships Linux only. The macOS development box has the same shape with the containers in podman machine. Windows is not a target. Every object cites its backing file.

LINUX VM · ROCKY / ALMA 10 · RHEL FOR CUSTOMERS · UBUNTU BEHIND THE PREFLIGHTKOS consolenative service on the VMSPA · orchestrator · dispatchterminal PTY lane · settingssystemd unit · service userHarness lanes · local CLIsopenkaiprimary · first-party · pinned releaseompinstalled · supported until OpenKai is matureclaude-codeoptional · customer-installed · supportedcodexoptional · customer-installed · supportedspawns · PTYCortex and services · seven podman containersdb · pgvector 0.8.2 / Postgres 18migrate · schema ledgercortex-api · memory, handoffs, bootproject-bootstrap · roster seedgraph-workerembed-workerpdf-workerMANAGED BY kos · CONTRACT IN THE CONTROL VOLUME · NAMED VOLUMES · LIFECYCLE JOURNAL (CAS)build · up · down · doctor · backup · restore · upgrade · prunepublished on 127.0.0.1 only · reached by the console and the local CLIsloopback
Objects of the deployment domain · each with its backing file
Appliance
the VM (image or host install) + appliance/appliance.yml (service roles) + appliance/bin/kos (operator)
one host, three parts: NativeConsole · HarnessInstall · ServiceRoles; the volumes plus the console's state directory are the appliance's state
NativeConsole
local-cortex/console/app/main.py under a systemd unit (install.sh lane; launchd on the Mac dev box), deployment_contract.py profile native
the KOS app: SPA, orchestrator, dispatch, terminal PTY lane, settings; runs as the console service user; reaches the services on loopback published ports
HarnessInstall
the host installer (M12: openkai, omp, node runtime; optional claude-code, codex), app/harness.py support tiers
local CLIs the console spawns as PTY-attached children; OpenKai's provider store ~/.openkai/.env is owned by OpenKai
ServiceRole
appliance/Containerfile.{cortex,db} + per-role stages
seven podman containers: db (pgvector 0.8.2 on Postgres 18), migrate, cortex-api, project-bootstrap, graph-worker, embed-worker, pdf-worker; Cortex vendored as a hash-pinned wheel; only loopback ports published
Contract
control volume <project>_kos-control:/appliance.env (bin/kos CONTRACT_KEYS, schema 2)
secrets (KOS_DB_PASSWORD, KOS_CORTEX_ADMIN_TOKEN…), KOS_EDITION, KOS_VERSION, KOS_SOURCE_REVISION, volume names, db tuning keys (KOS_DB_*); the console reads the tokens it needs from its runtime env, never from the browser
VolumeSet
named volumes kos-control, kos-state, kos-config, kos-secrets, kos-graphs, kos-models, kos-home-*
the services' state; generation-scoped with promotion roll-forward; liftable
LifecycleOperation
lifecycle.operation in the control volume (CAS: build, up, down, backup, restore, upgrade, abandon, prune)
journaled, crash-safe under a Linux subreaper; a failed up leaves up:claimed for the next command's recovery
Edition
app/edition.py, baked at build (KOS_EDITION ∈ {dev, open-source, commercial})
structural provider gate; commercial ships Linux only
HostFamily
design 26 (rulings R2, R5), podman host preflight (tasklist B7)
reference = Fedora/RHEL family (Rocky/Alma 10 for hosts we control, RHEL for customers); Ubuntu supported behind the podman ≥ 5 preflight; rootless podman ≥ 5, crun, SELinux labels :z, linger, subuid/subgid
HostBootstrap
install.sh (host lane) + M1/M3/M12
installs podman ≥ 5, node, the harness CLIs, the console unit, kos; preflights old engines, stale ports, machine sizing (Mac)
PackageChannel
dist/release.sh, scripts/release/*, RELEASE_MANIFEST.json
commercial = VM image (AMI/OVA) and/or the RHEL-family host installer + seven digest-pinned service images; source lane = kos build from a clean checkout (dev)
BackupSnapshot
kos backup / kos restore (appliance/bin/kos) + the console state directory
pg_dump -Fc of both databases + volume manifests; the ONLY sanctioned direct-Postgres path (E021 lifecycle boundary), never --no-owner/--no-privileges
DevProfile (macOS)
deployment_contract.py (KAIDERA_CONSOLE_RUNTIME=native), .agents/docker-compose.cortex.yml, launchd agents, podman machine (Fedora CoreOS guest, never Apple Container)
the same shape as the product; no package, no isolation promise, never customer-facing
How the parts relate

Links. Appliance —hosts→ NativeConsole · Appliance —hosts→ HarnessInstall · Appliance —runs→ ServiceRole[7] · NativeConsole —spawns→ HarnessInstall (PTY) · NativeConsole —reads→ Contract · ServiceRole —configured by→ Contract · ServiceRole —persists in→ VolumeSet · LifecycleOperation —mutates→ VolumeSet (CAS) · Edition —gates→ Provider list · HostFamily —hosts→ Appliance · HostBootstrap —installs→ NativeConsole · HostBootstrap —installs→ HarnessInstall · PackageChannel —ships→ Appliance · BackupSnapshot —restores into→ Appliance · DevProfile —is→ Appliance (same shape).

hostshostsrunsspawnsreadsconfigured bypersists inmutatesgateshostsinstallsinstallsshipsrestores intoisApplianceNativeConsoleHarnessInstallServiceRoleContractVolumeSetLifecycleOperationEditionHostFamilyHostBootstrapPackageChannelBackupSnapshotDevProfile (macOS)Provider listDevProfile
What an operator does

Actions. installer (host bootstrap) · kos build | up | down | doctor | backup | restore | upgrade | prune | abandon | contract-migrate | admin-bootstrap (services) · systemctl --user (console, beat) · openkai / omp / claude / codex (harness lanes, spawned by the console).

Harness lanes · support tiers
LaneTierWho installsSupport
openkaiprimary, first-partythe appliance installer, pinned releasesupported; the default lane
ompsupportedthe appliance installersupported until OpenKai is mature
claude-codeoptionalthe customer, with their own subscriptionsupported when present locally
codexoptionalthe customer, with their own subscriptionsupported when present locally

Every lane is a local child process of the console with a real PTY, so the terminal surface is the same for all of them and nothing is reconstructed from parsed output.