Epistemic Kernel — Full Specification
Epistemic Kernel — Project Spec & Development Guide
Working title: Epistemic Kernel (a broker-mediated provenance system — the first buildable slice of a ground-up “AI OS”) Target platform: Linux (PC), single-machine MVP Language: Rust Audience: An implementing coding agent — this document defines what and why; implementation is left to that agent.
Table of Contents
- Core Concept
- MVP Definition
- Architecture Outline
- Data Model
- Protocol (Broker ⇄ Agent)
- Memory Subsystem
- Rules / Invariants
- Functional Requirements
- Non-Functional Requirements
- Roadmap / Phases
- Glossary
- Open Design Questions
1. Core Concept
Multi-agent LLM systems today have no structural distinction between fact and belief. Agent A summarizes something, Agent B treats the summary as ground truth, Agent C builds on B’s already-corrupted belief — and by the fourth hop nobody can trace where the error entered.
The Epistemic Kernel is a broker daemon that enforces one invariant everywhere:
A process may act on another process’s belief, but it can never receive that belief as if it were an attested fact.
This is the same shape as a traditional kernel’s job (mediate access to shared resources so processes can’t corrupt each other’s state) applied to a different substrate (truth, not memory/CPU). The mechanism is a real Linux privilege boundary plus a Rust type system that makes the fact/belief distinction impossible to accidentally erase.
2. MVP Definition
The MVP is not a full OS. It is:
- A broker daemon (single OS process, async runtime) that owns a Unix domain socket.
- A provenance type library (Rust crate) where
Attestedvalues can only be constructed inside the broker. - A client SDK crate that agent processes use to talk to the broker over the socket — no other path to shared state exists.
- A pluggable attestor interface with one real backend for the MVP: filesystem facts (mtime, content hash, existence).
- A belief store with TTL-based expiry.
- A demo: 2–3 toy agent processes that publish beliefs, forward each other’s beliefs, and query the broker — demonstrating that (a) forged “attested” claims are rejected, (b) belief chains nest instead of flatten, (c) expired beliefs force re-derivation, (d) an audit trail can be walked to find where any given belief originated.
Explicitly out of scope for MVP: multi-machine distribution, process-level UID isolation between agents (single-process async tasks are acceptable for v1), a semantic filesystem, a scheduler/context-window economy, any GUI, any LLM integration itself (agents in the demo can be scripted/fake — the point is proving the broker’s guarantees, not proving an LLM behaves).
3. Architecture Outline
┌────────────────────────────┐
│ Broker Daemon │
│ (owns Unix socket, owns │
│ the only Attested ctor) │
│ │
│ ┌────────────┐ ┌──────────┐│
│ │ Provenance │ │ Attestor ││
│ │ Store │ │ Registry ││
│ │ (TTL sweep)│ │(pluggable)││
│ └────────────┘ └──────────┘│
└──────────────┬───────────────┘
│ Unix domain socket
│ (request/response protocol)
┌─────────────────┼─────────────────┐
│ │ │
┌─────▼─────┐ ┌─────▼─────┐ ┌─────▼─────┐
│ Agent A │ │ Agent B │ │ Agent C │
│ (client SDK)│ │(client SDK)│ │(client SDK)│
└────────────┘ └────────────┘ └────────────┘
Components:
ek-provenance(crate/lib): definesProvenance,Tagged<T>, upgrade/downgrade functions, serialization.ek-broker(binary): the daemon; owns the socket, the store, the attestor registry, TTL sweeper.ek-sdk(crate/lib): what agent processes link against; wraps the socket protocol in an ergonomic async API.ek-attestors(crate/lib): pluggable traitAttestor+ a filesystem implementation for MVP.ek-demo(binary, or a few): scripted fake agents exercising the system for the acceptance test.
4. Data Model
enum SourceTrust {
UserControlled, // e.g. local files the user owns, direct device sensors
Untrusted, // e.g. email bodies, web content, third-party messages
}
enum Provenance {
Attested {
source: SourceId, // e.g. "file:/etc/hostname"
checked_at: Instant,
},
Believed {
by: AgentId,
from: Box<Provenance>, // nesting = audit trail, never flattened
confidence: f32,
source_trust: SourceTrust, // orthogonal to confidence — see R10
},
Synthesized {
by: AgentId,
method: String, // e.g. "image-gen:sdxl", "tool-authored"
based_on: Vec<Box<Provenance>>, // inputs that informed the generation, if any
},
}
struct Tagged<T> {
value: T,
provenance: Provenance,
}
Resolved design question (previously open in the future-directions doc): generated artifacts — images, audio, self-authored tools, any AI-produced content that isn’t a claim about the world — get their own Synthesized variant, distinct from both Attested and Believed. A synthesized value is never a fact and never someone’s belief about a fact; it’s a made thing. It can never silently convert into either of the other two variants.
Key rule: Provenance::Attested has no public constructor outside ek-broker. Every other crate can only ever build Believed or Synthesized, and building Believed always requires wrapping an existing Provenance (never fabricating one from nothing).
5. Protocol (Broker ⇄ Agent)
Minimum request set for MVP:
| Request | Behavior |
|---|---|
Attest(SourceId) | Broker re-touches the real source (re-stat, re-hash) and returns a fresh Attested value. Never served from cache. |
Publish(Tagged<Belief>) | Agent submits a belief to the store. Broker validates the submitted Provenance — rejects if it claims Attested without having come from a real Attest call. |
Query(BeliefId) | Returns the current Tagged<T> for a belief, or “expired” if past TTL. |
Trace(BeliefId) | Walks the nested Provenance chain and returns the full audit trail. |
Promote(BeliefId, reason) | Moves a belief from the ephemeral working store into the retained store past its natural TTL. Logged with its own provenance (who promoted it, when, why). |
Wire format: bincode or prost over the Unix socket; either is fine, pick one and be consistent. Framing: length-prefixed messages.
5a. Memory Subsystem
Agent memory is just the belief store, given durability and structure. Two tiers:
- Working memory — beliefs actively in play. High-confidence, short TTL, cheap to re-derive if lost. This is the
working_beliefstable already implied by the TTL sweep in Section 6/R5. - Retained memory — beliefs explicitly promoted to persist past their natural TTL, via the
Promoterequest. Retained beliefs are not exempt from provenance tracking — they carry a visible staleness marker (last-attested timestamp, promoted-by, promotion reason) so nothing pretends to be fresher than it actually is.
Storage shape: two tables, not one:
working_beliefs— TTL-swept, ephemeral, matches existing Phase 4 design.retained_beliefs— provenance chain preserved in full, plus promotion metadata (promoted_by: AgentId,promoted_at: Instant,reason: String,last_attested_at: Instant).
Hard rule: a retained belief can never upgrade to Provenance::Attested, no matter its age or how long it’s been trusted. “Believed for a long time” must stay visibly a belief — that’s precisely the pattern (old assumptions quietly calcifying into unexamined fact) the whole kernel exists to prevent.
6. Rules / Invariants (the non-negotiable “constitution”)
- R1 — Sole constructor: Only
ek-brokercan constructProvenance::Attested. Enforced by Rust visibility (private constructor,pub(crate)at most), not by convention. - R2 — No silent stripping: Any code path that would discard a
Provenancetag while keeping thevalueis a protocol violation and must not compile/must be rejected at the broker boundary. - R3 — No flattening:
Believed.frommust be the actual priorProvenance, boxed and nested — never replaced with a fresh unrelated tag. This nesting is the audit trail. - R4 — Mandatory revalidation path: Every
Attestedfact must be re-checkable viaAttest; there is no such thing as a permanently cached attested fact. - R5 — TTL on beliefs: Every
Believedvalue has an expiry. Expired beliefs are inaccessible viaQueryuntil re-derived or re-attested; the broker does not silently keep serving stale beliefs. - R6 — No direct cross-agent access: Agents never share a filesystem path, socket, or memory region directly. All state crosses the boundary through the broker’s protocol only.
- R7 — Reject forged attestation: If an agent’s
Publishclaims aProvenance::Attestedvariant, the broker rejects it outright (agents cannot serialize their way around R1). - R8 — Traceable by construction:
Tracemust always be able to walk any belief back to a realAttestedleaf (or explicitly report an untraceable/orphaned belief as an error condition, never silently). - R9 — No amnesty by age: A retained/promoted belief can never become
Provenance::Attestedregardless of how long it has persisted; retained beliefs must always expose their last-attested timestamp and promotion metadata, so age never quietly substitutes for verification. - R17 — Rate-bounded requests: The broker enforces a per-agent request-rate budget on all protocol calls (
Attest,Publish,Query, etc.). A runaway or malfunctioning client is throttled/disconnected rather than allowed to hammer the store or an underlying attestor indefinitely — this holds even when nothing the client sent was individually invalid. - R18 — Crash-safe writes: Any single
Publish/Promote/store-mutating operation is atomic — the broker must never leave the store in a state where a write is half-applied after an unclean shutdown. On restart, the broker must be able to determine, for any in-flight operation at crash time, that it either fully completed or never happened — never a silent partial or duplicate result.
7. Functional Requirements
- FR1: Broker starts, binds a Unix socket with
0700permissions owned by its own user. - FR2: Broker supports at least one real
Attestor(filesystem: existence, mtime, content hash). - FR3: Agents can connect,
Attesta fact,Publisha belief derived from it, and have another agentQuery/Tracethat belief. - FR4: Broker enforces R1–R9 and R17–R18 above at the protocol boundary (not just in the type system — a malicious/buggy client sending raw bytes must still be rejected).
- FR5: TTL sweep runs periodically (e.g. every N seconds) and expires stale beliefs.
- FR6: Demo suite proves: (a) a normal 2-hop belief chain works and traces correctly, (b) a forged “attested” claim from an agent is rejected, (c) an expired belief is inaccessible until re-derived, (d)
Traceon a multi-hop belief shows every intermediate agent, (e) a promoted/retained belief still exposes its staleness and never silently upgrades to attested.
8. Non-Functional Requirements
- NFR1: No
unsafeinek-provenance(the type-safety guarantee is the whole point; don’t undermine it for convenience). - NFR2: Broker must not panic on malformed/adversarial client input — return a protocol error instead.
- NFR3: Single-machine, single-process broker is acceptable for MVP; design the socket protocol so a future multi-process/UID-isolated version doesn’t require a protocol rewrite.
- NFR4: Reasonable test coverage on the rule-enforcement paths (R1–R9, R17–R18) specifically — these are the parts a code reviewer should trust least by default.
- NFR5: Reference local-LLM inference backend must be llama.cpp compiled with Vulkan support, so the demo agents run on Nvidia, AMD, and Intel Arc hardware without vendor-specific toolchains. CUDA/ROCm can be used as optional accelerated paths for matching hardware, but Vulkan is the baseline — no one is excluded from running the demo because they don’t own an Nvidia card.
- NFR6: Minimum viable hardware target for running the broker with real local-LLM demo agents (not just the broker alone, which needs far less): 8–12GB GPU VRAM, e.g. a used RTX 3060 12GB or equivalent, running quantized 7B–14B open-weight models at Q4/Q5.
- NFR7: Per-agent request-rate limiting (R17) must be configurable but on-by-default with a sane budget out of the box — not something the demo relies on disabling to work.
- NFR8: The persistent store (Phase 4 onward) must survive an unclean shutdown (
kill -9, power loss) without corruption; acceptance for this is a test that kills the broker mid-write and confirms the store is either pre- or post-write on restart, never in between (R18).
9. Roadmap / Phases
- Phase 0 (this doc): Spec, requirements, rules — done here.
- Phase 1:
ek-provenancecrate — types, constructors, visibility rules, serialization. No networking yet. - Phase 2:
ek-brokerskeleton — socket, connection handling, in-memory (non-persistent) belief store, protocol enforcement of R1/R2/R7. - Phase 3:
ek-attestors— trait + filesystem implementation; wire up realAttestcalls. - Phase 4: Persistence + TTL — swap in-memory store for
sledorrusqlite; background sweep task for R5; addretained_beliefstable andPromoterequest (R9). - Phase 5:
ek-sdk— ergonomic async client wrapper agents actually use. - Phase 6:
ek-demo— scripted agents; write the acceptance tests from FR6. - Phase 7 (stretch, post-MVP): process-level UID/cgroup isolation between agents; multi-machine transport; a second Attestor backend (e.g. a fake “sensor”).
10. Glossary
- Attested fact: state whose provenance traces to a real, broker-verified source (file, sensor, direct process output).
- Belief: state derived/inferred by an agent (a model), never directly ground truth.
- Synthesized: state that is a generated artifact (image, audio, self-authored tool, etc.) — neither a fact nor an inference about the world, and never convertible into either.
- Provenance: the tag carried by every value describing whether it’s attested, believed, or synthesized — and if believed, by whom, from what, and with what source trust level.
- Broker: the single daemon process that is the only entity allowed to mint attested provenance and mediate all cross-agent state access.
- Trace: walking a belief’s nested provenance chain back to its attested root(s).
11. Open Design Questions (for the implementing agent to flag back, not resolve unilaterally)
- Wire format choice:
bincodevsprost/protobuf — pick one, note tradeoffs, don’t block on it. - Exact TTL default and whether it’s global or per-fact-type configurable.
- Whether
Traceon an orphaned/untraceable belief should be anError a distinguishedOrphanedvariant.
This specification serves as the foundational architecture for Aurora’s provenance systems and trust boundaries. For more context on Aurora, see Aurora’s self-documentation. For future expansion ideas, hardware tiers, and security considerations beyond the MVP, see Future Directions & Hardware Tiers.