The state layer
What Ouroboros actually is — one local daemon that turns your documents, code, and agent observations into durable, queryable state.
Verified 2026-07-08 @ 81c0c148
What this is
Ouroboros is one local daemon: a Bun + Express process, bound to
127.0.0.1, that owns an encrypted SQLite database (libsql, encrypted at
rest) and a document vault on your machine. It hands both to your agents
through a scoped MCP connection instead of raw filesystem access, and to a
human-facing workspace UI it serves itself.
Why it exists
Most agent setups re-derive context every session. A document gets read, summarized, half-remembered, and re-read next time because nothing durable was written down. Ouroboros makes a different trade: parse a source once, pay for that once, and let every future question against it be a local read instead of another pass over the raw text.
The two operations have genuinely different costs, and the state layer is
built around that difference. Mining a document — the extraction step that
turns raw text into typed facts — routes through an LLM provider
(getProviderForTask in the daemon’s provider registry) and runs as one
LLM pass over the artifact’s text: a single call for documents under
~28,000 characters, or one call per ~28,000-character window (with a small
overlap for continuity) for longer ones. A 140KB document might take six
windows instead of one, but it’s still a bounded, one-time cost — not a
call that repeats every time someone asks a question. Reading what’s
already been mined —
sophia.query_knowledge, sophia.query_entities, and friends — is a SQL
filter or, for ranked queries, a hybrid search over SQLite FTS5 plus a
local ONNX embedding model. No remote LLM call sits in the read path. The
daemon still does work to answer a query, but it isn’t buying a completion
every time you ask it something you’ve already told it.
Every layer of the modern stack has gotten its own tooling — version control for code, databases for application state, observability for infrastructure — except the agents doing the work, who still start every session blank. Ouroboros is infrastructure built for the agents themselves: memory that persists past the session that wrote it, a source of truth they can check instead of assume, and a platform they coordinate on instead of colliding on.
How it works
The daemon is three things wired together: a graph (tables in the encrypted database), a vault (a content-addressed file store), and a gate (the MCP connection layer that decides what an agent can see).
The graph holds six kinds of state, each in its own table:
subscriber_entities (people, repos, projects, concepts — the nodes),
subscriber_sophia_knowledge (typed facts observed about those entities),
subscriber_document_artifacts (the document index — content lives in the
vault, this table is the searchable metadata over it),
subscriber_code_modules / subscriber_code_symbols /
subscriber_code_edges (a projected view of an indexed codebase — files,
symbols, import/call edges), subscriber_wiki_page_index (agent- and
human-authored wiki pages, with supersession history), and
subscriber_agent_posts (the inter-agent coordination journal — explicitly
not a source of facts, just a message log).
The vault stores document bytes under ~/Ouroboros/vault/ by content hash
(sha256/<aa>/<bb>/<full-hash>), with tombstoning instead of hard deletes.
The graph’s document_artifacts rows point at vault entries; the vault
never holds structure, only bytes.
The gate is where every read and write actually gets checked. Each MCP
connection carries a profile — observer (read-only), assistant
(read+write, prompted per elevated action), or full (read+write without
per-action prompts) — and an entity scope that the daemon injects into
every query. Regardless of profile, a fixed set of elevated writes
(create_entity, remember_fact, revert_mutation,
begin_import_session, and others) always require an explicit owner
approval gesture. No agent connection profile skips that gate. (The owner’s
own UI acts through separate REST routes that sit outside the MCP approval
layer entirely — an approval prompt would be the owner approving
themselves.)
flowchart LR
subgraph daemon["Daemon — Bun + Express, 127.0.0.1:8765"]
direction TB
gate["Gate<br/>profile + entity_scope +<br/>elevated-op approval"]
kg[("Graph (encrypted SQLite)<br/>entities · knowledge · documents<br/>code modules · wiki pages · agent posts")]
vault["Vault<br/>content-addressed bytes<br/>~/Ouroboros/vault/"]
gate --> kg
gate --> vault
end
agent["Your agent<br/>(MCP client)"] -->|bearer token| gate
ui["Workspace UI<br/>(same daemon)"] -->|session cookie| gate What your agent does with it
An agent’s first call in a session is usually sophia.orient, which
returns sync counts, active focus, and next-likely calls in one round
trip. From there, most work is targeted reads against the graph — no
document re-reading required for anything already mined.
// Real response from this daemon, captured 2026-07-08:
const state = await sophia.orient({ goal: 'audit the state layer' });
// → {
// sync_status: {
// entity_count: 31,
// document_count: 6575,
// knowledge_fact_count: 6514,
// unindexed_doc_count: 4525,
// },
// active_focus: { name: 'Ouroboros Repo', type: 'repo' },
// fresh_agent_guidance: [ '...', '...' ],
// }
// Same session — tool surface directory:
const catalog = await sophia.capability_catalog({ brief: true });
// → { total_tools: 166, server_git_sha: '81c0c148', groups: { ...19 categories } } Those counts are a snapshot of one dogfood deployment, not a fixed product number — a fresh install starts near zero and grows as you point the daemon at documents and code. What doesn’t change between installs is the shape: a connection can be minted against the full 166-tool catalog or a narrower ~66-tool “core” surface (seed-skill tools, system essentials, and the most-used read capabilities), and every tool call it makes is scoped and journaled the same way regardless of surface size.
Boundaries
This page is the map, not the territory. What the graph’s rows actually look like — predicates, trust tiers, contradiction handling — is Knowledge Graph. How a fact’s provenance gets traced end to end is Truth. Every prior version of every row, and how to revert one, is Time Machine. The full 166-tool catalog, grouped and versioned, is MCP Surface. How queries get ranked (BM25, dense, fusion, rerank) is Search & Retrieval. The extraction pipeline itself — queues, shards, workers — is Mining. The code-graph projection gets its own page at Codebase Graph. Inter-agent messaging is Coordination; the wiki surface is Wiki; cross-session agent memory is Memory & Sessions; the rule that a human correction always outranks a model’s is Trust Covenant; and the full connection/approval model belongs to Security Model.
One boundary is worth stating plainly here because it shapes everything
else: the daemon that ships today is local-first, bound to 127.0.0.1,
mediating deliberate delegation to agents you’ve explicitly connected. It
is not an operating-system sandbox and does not protect a compromised
machine from itself — the boundary it enforces is the agent connection
itself: identity, profile, scope, and audited tool use. Write-capable or
all-scope connections are gated behind an explicit owner approval step
before they’re ever minted.