Skip to content

Architecture

cairn is built around a strict one-way dependency: a domain-neutral engine plus packs that carry all domain knowledge. The engine never imports a pack.

LayerWhat it holdsExample
Packintent — templates, skills, policies, and descriptors for a domainthe training pack’s finetune template
Profiletechnology choices — which provider backs each capability ([profile.bindings])bind storage.put to S3 or to local disk
Environmentglue — secrets, endpoints, and per-deployment env varsOPENAI_API_KEY, GPU/backend URLs

A pack declares what it needs (a capability); a profile decides which provider satisfies it; the environment supplies the credentials. The same pack runs against different backends by changing the profile, with no code change.

Packs are classified on two axes:

  • kinddomain (a multi-step workflow for a domain, e.g. fine-tuning or incident response), operator (executes a workflow node — a GPU job, an eval, a registry push), or service_provider (backs a cross-cutting service like memory, RAG, redaction, artifact storage, or audit).
  • trust tierbuiltin (engine substrate) or official (first-party add-ons); community/private/local packs install as separate wheels and are sandboxed by trust level.

On disk this is kind-first: operators live under operators/{builtins,official}/, domain packs under packs/. An operator is referenced everywhere by its stable capability name — never by its tier or path — so moving it between tiers is a metadata change, not a code change. Any operator that satisfies the contract inherits the budget, policy gate, and audit automatically.

  • engine — template schema, compiler, and runner. Templates come in three flow types: prompt, agent_loop, and state_machine.
  • dispatch — realtime and background lanes, deduplication, the scheduler, and the bus bridge.
  • guards — citation validation and capped self-critique.
  • actions — the executor registry plus in-process and durable handlers.
  • runtime — checkpointer tiers and the durable runtimes: in_process, dbos (SQLite or Postgres, library — no server), and temporal (scale/HA).
  • storage — run store, memory, and RAG-catalog tiers (in-memory / SQLite / Postgres).
  • llm / obs — the LLM gateway chokepoint and the cost / events / redaction / audit seams.
  • pack — the pack contract, the entry-point loader, the registry, and profiles.
flowchart LR
  T[Trigger: webhook / schedule / manual] --> SK[Skill match]
  SK --> TMPL[Template compiled to a graph]
  TMPL --> RUN[Run: LLM gateway + tools]
  RUN --> G[Guards: citation validation + budget]
  G --> POL[Policy gate]
  POL -->|low risk| EX[Executor]
  POL -->|high risk| HITL[Human approval]
  HITL --> EX
  EX --> STORE[Run + events stored, audit recorded]

A trigger is matched to a skill, which binds it to a template. The template compiles to a graph and runs through the LLM gateway with the pack’s tools. Guards verify the output, the budget is enforced, the policy gate decides whether an action may run automatically or needs human approval, and the run, its events, and the audit record are persisted.

The internal decision record — architecture decisions (ADRs), the live roadmap, and probe-backed status — lives in the repository’s docs/ tree. This site documents the shipped, externally-facing surface only.