Daemion docs

What is the Daemion kernel?

The kernel is the core of Daemion — 6 substrates that manage AI resources, conversation state, and runtime behavior. Everything else in the system — agents, jobs, themes, commands, integrations — exists as an extension that plugs into one or more substrates. You extend the kernel; you don’t modify it.

Extensions are JSON data stored in SQLite, not compiled code. An agent can create a new extension at runtime without touching the codebase.

Architecture

┌─────────────────────────────────────────────────────────┐
│                      KERNEL                             │
│                                                         │
│  ┌─────────────┐  ┌─────────────┐  ┌─────────────────┐ │
│  │  Extension  │  │   Context   │  │    Execution    │ │
│  │  Substrate  │  │  Substrate  │  │    Substrate    │ │
│  └─────────────┘  └─────────────┘  └─────────────────┘ │
│  ┌──────────────┐  ┌──────────────┐  ┌──────────────┐  │
│  │ Presentation │  │   Trigger    │  │   Storage    │  │
│  │  Substrate   │  │  Substrate   │  │  Substrate   │  │
│  └──────────────┘  └──────────────┘  └──────────────┘  │
└─────────────────────────────────────────────────────────┘
              ▼                    ▼
┌─────────────────────────────────────────────────────────┐
│                    EXTENSIONS                           │
│  command  theme  job  renderer  integration  action     │
│  widget   app    artifact  capability  control          │
└─────────────────────────────────────────────────────────┘

1. Extension Substrate

Registers, loads, and validates all 12 extension types at runtime. Extensions are rows in SQLite — not compiled-in modules. The system resolves them by type and name, validates them against their Zod schema, and makes them available to the rest of the kernel.

Because extensions are data, an agent can create, update, or disable an extension mid-conversation — no deploy, no restart needed. The gateway also supports reseeding (POST /reseed) to re-sync built-in extensions and disk-backed configs without restarting the process.

12 extension types: command, theme, job, renderer, integration, action, widget, app, artifact, capability, control, plus agent itself.

Source: src/gateway/storage.ts, src/schema/extension.ts


2. Context Substrate

The context substrate decides what an agent knows before it generates a response. It is RLM-inspired: rather than compressing history into summaries, context is externalized into queryable stores and the agent decides what to retrieve.

RLM (Recursive Language Models) is a design philosophy from Alex Zhang’s 2025 post where models recursively decompose large context by calling themselves on subsets. Daemion takes the same philosophy — externalize context, let the model control retrieval — but implements it with search tools over SQLite and Engram rather than recursive self-calls.

Three layers are assembled in parallel via Promise.all before each response:

Layer 1 — Recent turns (~10) pulled from SQLite. These are always in context. They represent the live thread the agent is participating in.

Layer 2 — Engram recall — semantic search (vector + BM25 hybrid) over the Neo4j knowledge graph. Entities, facts, and insights stored across sessions. The agent can also call engram_recall mid-response as a tool if it needs more.

Layer 3 — History tools — five search tools the agent calls on demand:

ToolWhat it does
list_threadsDiscover all conversation threads with metadata
search_historyFull-text search within the agent’s own threads
get_threadRetrieve a specific thread with cursor pagination
find_relevantTime-scoped search with recency re-ranking
search_allCross-agent full-text search across all threads

No running summaries. No compression. Every message is stored at full fidelity in SQLite. The agent pulls what it needs; it doesn’t get handed a lossy digest.

Q How does context assembly work?
On each message, the gateway fires two parallel fetches: recent turns from SQLite and Engram recall for the incoming query. Both resolve before the agent SDK is called. The assembled context is prepended to the prompt. During the response, the agent can pull additional context using the history tools.
Q Why no summaries?
Summaries are lossy. A summary of a debugging session drops the exact error message. A summary of a decision drops the reasoning. Daemion keeps everything and lets the agent search for what matters. Storage is cheap; lost context is expensive.
Q How is this related to RLM?
RLM lets models recursively decompose massive context by calling themselves on subsets — the model controls what gets loaded, not a fixed window. Daemion applies the same principle: the agent controls retrieval via search tools rather than receiving a predetermined context dump. Daemion does not implement full recursive decomposition; the inspiration is the retrieval-control philosophy.

Source: src/gateway/agent.ts, src/core/history-tools.ts


3. Execution Substrate

Manages all Claude invocations via the Agent SDK. Responsible for model selection, turn budgets, cost limits, streaming, cancellation, and per-thread concurrency. Every chat message and job run flows through this substrate.

text

Mode Model Max Turns Budget ──────────────────────────────────────────────────── Chat (quick) claude-sonnet 10 turns $0.50 Chat (complex) claude-sonnet 25 turns $5.00 Job execution configurable 30 turns $5.00

The substrate streams partial responses over WebSocket as text-delta events, so the UI updates token-by-token. Tool calls emit tool-start events so the client can show progress in real time.

Never use child_process for Claude invocations

Spawning Claude as a subprocess causes a hang bug (#771). The Agent SDK handles the subprocess lifecycle correctly. All Claude calls go through invokeAgent() in src/core/invoker.ts or the gateway’s chat handler.

Source: src/core/invoker.ts, src/gateway/agent.ts


4. Presentation Substrate

Renders agent output to the client. Handles streaming text, tool call visibility, error states, and artifact display. Extension renderers can register custom display components for specialized content types — a code renderer, a diff renderer, a chart renderer.

The substrate is the bridge between the Execution substrate’s stream events and what the user actually sees in the PWA.

Source: app/components/


5. Trigger Substrate

Evaluates conditions that cause jobs or agents to fire. Five trigger types are supported:

TypeWhen it fires
messageOn incoming chat message
commandOn /, @, !, or # prefix
cronOn a schedule (standard cron, minute precision)
watchOn filesystem change
chainAfter a parent job completes
webhookOn external HTTP callback
Q How are cron schedules evaluated?
Standard 5-field cron expressions, normalized to minute precision. The scheduler ticks every minute and calls shouldJobFire() for each enabled job. Cron matching uses the croner library. Chain triggers are not evaluated by the scheduler — they fire directly in the engine after the parent job completes.

Source: src/core/triggers.ts, src/gateway/scheduler.ts


6. Storage Substrate

Three backends, each with a distinct role:

SQLite — the primary operational store. Messages, threads, extensions, projects, and job run history all live here. Zero network dependencies; the file lives at ~/.daemion/daemion.db.

Engram (Neo4j) — the knowledge graph. Entities, facts, relationships, and free-form insights. Queried via hybrid semantic + BM25 search. This is where agents accumulate long-term memory across sessions.

Filesystem — agent identity files (agents/*.yaml, agents/*/system.md), job prompts (jobs/*/prompt.md), app source bundles, and project configs. Readable at startup; hot-reloadable for agent configs.

Engram requires a running Neo4j instance and the memory-graph skill. If Engram is unavailable, context assembly degrades gracefully — recent turns and history tools still work, Engram recall is skipped.

Source: src/gateway/storage.ts


General FAQ

Q Can I modify the kernel?
You extend it, you don't modify it. Extensions plug into substrates via the SQLite registry. If you find yourself wanting to edit a substrate directly, the right move is to create an extension type that exposes the behavior you need.
Q What's the difference between the kernel and the gateway?
The kernel is the conceptual architecture — 6 substrates, their responsibilities, and how they relate. The gateway is the runtime implementation: an HTTP/WebSocket server (src/gateway/server.ts) that exposes kernel capabilities as API endpoints. The gateway is how the kernel runs in production.
Q Is this like a real OS kernel?
Same concept, different domain. A Linux kernel manages hardware resources and provides syscalls for userspace. Daemion's kernel manages AI resources — context, models, tools, storage — and provides an extension API for everything built on top. Extensions are the userspace programs.

The substrates above are implemented across: src/core/engine.ts, src/core/triggers.ts, src/core/invoker.ts, src/core/history-tools.ts, src/gateway/storage.ts, src/gateway/agent.ts, and src/gateway/websocket.ts.