Architecture
OpenSpine is the self-hosted system. Lyra is the default assistant package. This page covers the governed runtime underneath it: the part that verifies requests, creates task permissions, holds credentials, checks actions, and records outcomes.
The runtime is small on purpose: one fixed pipeline, five crates, one trust boundary. This page walks the spine from an inbound event to its audit record.
The pipeline
Section titled “The pipeline”Every inbound event runs through the same fixed sequence before an agent ever does anything:
flowchart LR A[event] --> B[source verification] B --> C[identity] C --> D[route] D --> E[authority composition] E --> F[task grant] F --> G[agent / workflow] G --> H[gated effects] H --> I[audit / memory]- Source verification: is this event’s claimed origin real? For example, did a Telegram message’s sender ID arrive through the verified owner channel?
- Identity: who is this, structurally, never “what can they do.”
- Route: which workflow and agent pairing handles this event, resolved declaratively rather than by an LLM. Route conflict resolution affects authority, so the model does not own it.
- Authority composition: deterministic, deny-by-default intersection across every relevant route, agent manifest, workflow, capability pack, policy, caveat, approval, and runtime limit.
- Task grant: the one live authority object a worker holds. It contains a short-lived token, scoped actions, approval requirements, budgets, and any selection tokens.
- Agent / workflow: runs in a contained shell process with no I/O except the kernel API.
- Gated effects: effectful actions requested by a worker pass through
gate()before dispatch. - Trusted pre-gate paths: a small, enumerated set of owner-selected metadata reads may occur before grant composition. Each path is separately classified and audited; it is not controlled by model output.
- Audit / memory: every decision is appended to a hash-chained audit log. Memory and learned behaviour update through governed lifecycles rather than free mutation.
The order is the security model. Authority is settled before model-driven worker code runs, so nothing the model generates can reach back and renegotiate the task grant.
Crate map
Section titled “Crate map”openspine-schemas: versioned,deny_unknown_fieldsobject kinds for every runtime concept, plus canonical-JSON digest functions. Pure data, no I/O.openspine-authority: route resolution and authority composition as pure functions that merge route, workflow, agent, pack, policy, caveat, and runtime inputs into a task grant or denial.openspine-gate: the mediation boundary for effectful worker actions before connector dispatch.openspine-kernel(binopenspine): the trusted process. It owns storage, the artifact store, connectors, model gateway, audit chain, and kernel HTTP API.openspine-shell(binopenspine-shell): the contained per-task worker that runs agent and workflow logic. Its only I/O is the kernel API.
The split mirrors the trust argument: schemas and authority are pure functions; the kernel is the only process that holds secrets; the shell is the place model-driven code runs, and it holds no connector credential.
The kernel/shell trust boundary
Section titled “The kernel/shell trust boundary”The shell is never trusted with anything the kernel needs to keep secret. The full contract lives in docs/kernel-http-contract.md.
- The shell process or container receives exactly two environment variables:
KERNEL_ENDPOINTandTASK_TOKEN. It receives no provider API key, artifact encryption key, Gmail credential, or Telegram bot token. - The shell does not compute trusted digests or encrypt artifacts. It submits intents to the kernel, which constructs the real digested and artifact-referenced request.
- The kernel and shell communicate over the Compose internal network. The contained shell has no route to the public internet.
- Under the
dockersandbox driver, task workers run in ephemeral containers. Under the development-onlyprocessdriver, an explicitunsafe_allow_uncontained_private_dataflag is required before the kernel routes a private external-communication task.
Why this is a personal AI system, not only a library
Section titled “Why this is a personal AI system, not only a library”The runtime is reusable, but a user does not interact with compose_authority() or gate() directly. They talk to Lyra. The assistant package declares the conversation, workflows, skills, persona, and memory scope. The runtime turns those declarations into enforceable task boundaries.
That separation is the product:
Lyra decides what work to propose.OpenSpine decides what work may happen.