Module map, dependency graph, trait boundaries, and extension points. Covers the Rust crate workspace.
Technology choices and dependency policy: TECHNOLOGY.md. Project roadmap: PROJECT.md.
Module and crate names use Greek terms reflecting their essential nature (nous = mind, mneme = memory, hermeneus = interpreter). See lexicon.md for the full registry.
The current runtime is a 44-crate workspace plus the excluded proskenion
desktop shell. The compact generated inventory lives in
_llm/L1-workspace.md; this document describes the
human architecture and invariants.
Key substrate properties as of the 2026-05-08 refresh:
- Working-memory continuity:
nousinjects agent-curated<key_info>from the previous working checkpoint before recall/history assembly. - Composite loop defense: tool execution combines
hermeneus::LoopGuardsignals for ping-pong, no-progress, and repeated args/result doom loops. - Tool receipt integrity:
organonemits HMAC-SHA256 receipts and an in-memory receipt ledger so the pipeline can detect hallucinated tool results. - External tool plane:
diaporeiacan bridge external MCP servers into theorganonregistry while preserving RBAC claims and shared-state boundaries. - Auth facade:
symbolon::AuthFacadeis the admin-token verification and revocation boundary shared bypylonanddiaporeia. - Bounded stages:
nouscarries per-stage timeout configuration for LLM execution and actor-manager operations. - Knowledge schema v11:
eidos::Visibilityandeidos::MemoryScopetravel through facts, Datalog schema, recall filtering, and MCP/API surfaces. - Operator-independent verification:
integration-testsowns the sharedTestHarnessplus a 15-scenario substrate canary suite.
aletheia
├── koina - errors, tracing, safe wrappers, fs utils
├── taxis - config, path resolution, oikos hierarchy, secret refs
├── mneme - thin facade re-exporting eidos, graphe, episteme, krites
│ ├── eidos - shared knowledge types (Fact, Entity, Relationship, Visibility, MemoryScope)
│ ├── graphe - fjall session/message store, retention, archive support
│ ├── episteme - knowledge pipeline: extraction, recall, consolidation, embeddings
│ └── krites - embedded Datalog engine + HNSW vectors (mneme-engine feature gate)
├── hermeneus - LLM provider registry, fallback chains, loop guard, credentials
├── organon - tool registry + 49 built-in tools + receipt ledger
├── nous - agent pipeline, bootstrap, recall, finalize, actor model
├── dianoia - planning / project orchestration
├── pylon - Axum HTTP gateway, SSE streaming, auth enforcement
├── diaporeia - MCP server interface and external tool-plane bridge
├── symbolon - JWT auth, admin facade, sessions, RBAC
├── agora - channel registry + ChannelProvider trait
│ └── semeion - Signal (signal-cli subprocess)
├── daemon - oikonomos: per-nous background tasks, cron, prosoche
├── melete - context distillation, compression, token budget management
├── thesauros - domain pack loader (knowledge, tools, config overlays)
└── theatron - presentation umbrella (crates/theatron/)
├── core - shared API client, types, SSE infrastructure (crates/theatron/skene/)
└── tui - terminal dashboard (crates/theatron/koilon/)
Platform (tracked) vs. instance (gitignored). One directory, one boundary.
aletheia/ # git root - the platform
├── crates/ # Rust workspace
├── docs/ # platform docs
│
├── instance/ # GITIGNORED - all instance state
│ ├── theke/ # Tier 0: human + nous collaborative space
│ │ ├── USER.md # Canonical user profile (one copy)
│ │ ├── AGENTS.md # Team topology
│ │ ├── tools/ # Tools for human + all nous
│ │ ├── research/ # Shared research
│ │ ├── deliberations/ # Multi-agent deliberations
│ │ └── projects/ # Active work products
│ │
│ ├── shared/ # Tier 1: nous-only shared
│ │ ├── tools/ # Nous-only tools
│ │ ├── skills/ # Extracted skill patterns
│ │ ├── hooks/ # Global event hooks
│ │ ├── templates/ # Prompt templates
│ │ └── coordination/ # Blackboard, task state
│ │
│ ├── nous/ # Tier 2: individual nous workspaces
│ │ ├── <agent-id>/ # See WORKSPACE_FILES.md for full reference
│ │ │ ├── SOUL.md # Character, principles (operator-owned)
│ │ │ ├── IDENTITY.md # Name and emoji (required)
│ │ │ ├── GOALS.md # Active goals (operator-owned)
│ │ │ ├── MEMORY.md # Persistent knowledge (agent-writable)
│ │ │ ├── TOOLS.md # Tool inventory (auto-generated)
│ │ │ ├── PROSOCHE.md # Attention directives (auto-generated)
│ │ │ ├── CONTEXT.md # Session state (runtime-written)
│ │ │ ├── tools/ # Nous-specific tools
│ │ │ ├── hooks/ # Nous-specific hooks
│ │ │ └── memory/ # Daily memory files
│ │
│ ├── config/ # Deployment config
│ │ ├── aletheia.toml
│ │ ├── credentials/
│ │ └── bindings.yaml
│ │
│ ├── data/ # Runtime stores
│ │ ├── sessions.db
│ │ └── engine/ # Datalog engine persistent storage (embedded)
│ │
│ └── signal/ # signal-cli data
│
└── instance.example/ # TRACKED - scaffold template
Three-tier cascading resolution: nous/{id} -> shared -> theke. Most specific wins. Presence is declaration - drop a file in the right directory, it's discovered.
The oikos hierarchy is described in CONFIGURATION.md.
44 crates in the workspace, with proskenion excluded and built via its own
manifest. The table below calls out the primary architecture crates; the full
generated inventory is _llm/L1-workspace.md.
| Crate | Directory | Domain | Depends On |
|---|---|---|---|
koina |
crates/koina |
Errors (snafu), tracing, fs utilities, safe wrappers | nothing (leaf) |
taxis |
crates/taxis |
Config loading (owned TOML cascade), path resolution, oikos hierarchy | koina |
eidos |
crates/eidos |
Shared knowledge types: Fact, Entity, Relationship, EpistemicTier, Visibility, MemoryScope | nothing (leaf) |
graphe |
crates/graphe |
fjall session/message store, retention, archive support | eidos, koina |
episteme |
crates/episteme |
Knowledge pipeline: extraction, trace ingest, query rewrite, recall, consolidation, embedding provider | eidos, koina, graphe, krites (opt) |
krites |
crates/krites |
Embedded Datalog and graph query engine with HNSW support | eidos |
mneme |
crates/mneme |
Thin facade re-exporting eidos, graphe, episteme, krites | eidos, graphe, episteme, krites |
hermeneus |
crates/hermeneus |
LLM provider registry, fallback chains, token redaction, provider trait, loop guard | koina, taxis |
organon |
crates/organon |
Tool registry, tool definitions, tags, HMAC receipts, 49 built-in tools, sandbox | koina, hermeneus |
symbolon |
crates/symbolon |
JWT tokens, password hashing, admin auth facade, RBAC policies | koina |
melete |
crates/melete |
Context distillation, compression strategies, token budget management | hermeneus |
agora |
crates/agora |
Channel registry, ChannelProvider trait, Signal JSON-RPC client | koina, taxis |
daemon (oikonomos) |
crates/daemon |
Per-nous background task scheduling, cron jobs, prosoche | koina |
dianoia |
crates/dianoia |
Multi-phase planning orchestrator, project context tracking | nothing (leaf) |
thesauros |
crates/thesauros |
Domain pack loader: external knowledge, tools, config overlays | koina, organon |
nous |
crates/nous |
Agent pipeline, NousActor (tokio), working-memory injection, bootstrap, recall, execute, finalize | koina, taxis, mneme, hermeneus, organon, melete, thesauros |
pylon |
crates/pylon |
Axum HTTP gateway, SSE streaming, auth middleware, meta-insights endpoints | koina, taxis, hermeneus, organon, mneme, nous, symbolon |
diaporeia |
crates/diaporeia |
MCP server interface and stdio/external tool bridge for external AI agents | koina, taxis, nous, organon, mneme, symbolon |
skene |
crates/theatron/skene |
Shared API client, types, SSE infrastructure for UIs | koina |
koilon |
crates/theatron/koilon |
Terminal dashboard | koina, skene |
proskenion |
crates/theatron/proskenion |
Dioxus desktop UI (excluded from workspace, requires GTK3) | skene |
aletheia |
crates/aletheia |
Binary entrypoint (Clap CLI), wires all crates together | koina, taxis, hermeneus, organon, mneme, nous, symbolon, pylon, agora, thesauros, daemon, dianoia, dokimion, diaporeia (opt), koilon (opt) |
Support crates (not part of the application dependency graph):
hermeneus owns the provider trait and concrete provider clients. taxis
owns the serialized [[providers]] config shape, including providerType,
baseUrl, apiKeyEnv, models, and deploymentTarget. The aletheia
binary joins those layers in runtime/setup.rs by registering the configured
providers in list order.
Current provider families:
| Provider family | Config type | Wire/runtime shape | Deployment target |
|---|---|---|---|
| Anthropic cloud | anthropic |
Anthropic Messages API | cloud |
| Claude Code | claude-code |
claude CLI subprocess adapter |
operator-local process, with provider egress controlled by Claude Code |
| OpenAI-compatible local/third-party | openai-compatible |
/v1/chat/completions HTTP wire format |
explicit per provider: usually embedded or localhosted |
| OpenAI cloud | openai |
currently /v1/chat/completions; target state is OpenAI Responses API |
cloud |
Codex routing decision, recorded 2026-05-22: Codex/OpenAI cloud model access should move to a first-class OpenAI Responses API provider path. The existing OpenAI-compatible Chat Completions provider remains valid for local servers such as llama.cpp, ollama, and vllm, but it is not the preferred long-term Codex path because Codex Chat Completions support is deprecated upstream. A dedicated Codex CLI adapter is deferred until Aletheia has a concrete need for Codex-specific session, tool, or local-environment semantics that Responses does not cover.
Planned Responses-backed config shape after the provider lands:
[[providers]]
name = "openai-codex"
providerType = "openai"
apiKeyEnv = "OPENAI_API_KEY"
deploymentTarget = "cloud"
models = ["gpt-5.3-codex"]Local OpenAI-compatible servers continue to use the Chat Completions-compatible shape:
[[providers]]
name = "local-qwen"
providerType = "openai-compatible"
baseUrl = "http://127.0.0.1:8088/v1"
deploymentTarget = "embedded"
models = ["Qwen3.5-35B-A3B-Q8_0"]deploymentTarget is load-bearing for sovereignty filtering. OpenAI cloud
entries must be cloud; local servers must declare whether traffic terminates
on the same host (embedded) or an operator-trusted local endpoint
(localhosted).
| Crate | Directory | Domain | Depends On |
|---|---|---|---|
dokimion |
crates/eval |
Behavioral and cognitive eval framework (HTTP scenario runner) | koina |
integration-tests |
crates/integration-tests |
Cross-crate integration test suite | dokimion, koina, taxis, mneme, hermeneus, nous, organon, pylon, symbolon, thesauros |
Additional workspace crates include aletheia-classify, aletheia-lexica,
aletheia-memory-mcp, aletheia-routing, aletheia-sessions-migrate,
gnosis, and the poiesis backend/helper crates (poiesis-doc,
poiesis-diff, poiesis-inspect, poiesis-intake, poiesis-scaffold,
poiesis-typst). Keep the generated _llm/L1-workspace.md list in sync when
workspace membership changes.
Mneme was decomposed into four sub-crates. The mneme crate is a thin facade
over their downstream-facing APIs. Application crates should import memory,
session, recall, verification, tracing, and knowledge-store types through
mneme so the sub-crate layout can move without changing their imports. Direct
sub-crate imports are reserved for the sub-crates themselves and for specialized
tools that intentionally own a lower-level boundary.
| Sub-crate | Re-exports | Feature gate |
|---|---|---|
eidos |
bookkeeping, id, knowledge, meta, training |
always |
graphe |
error, metrics, portability, store, types |
always |
episteme |
consolidation, embedding, embedding_eval, extract, ingest, instinct, manifest, metrics, query_rewrite, recall, side_query, skill, skills, trace_ingest, verification |
reranker for reranker implementations |
episteme |
knowledge_store |
mneme-engine |
krites |
engine |
mneme-engine |
Downstream application crates depend on mneme for this public surface. When a
new downstream use needs a sub-crate item, add an explicit mneme re-export
instead of reaching through to the sub-crate from the application layer.
aletheia (binary)
/ / / | \ \ \ \
/ / / | \ \ \ \
pylon nous agora melete organon taxis ...
/|\ \ |\ \ |\ | |\ |
/ | \ \ | \ \ | \ | | \ |
symbolon | organon | taxis hermeneus koina
| | \ | |
| hermeneus mneme (facade)
| | / | \ \
koina koina eidos graphe episteme krites
Layer rules:
- Leaf (no workspace deps):
koina,eidos,dianoia - Low (one workspace dep):
taxis,hermeneus,symbolon,krites(eidos only),daemon(koina),melete(hermeneus),skene(koina),dokimion(koina) - Mid:
graphe(eidos + koina),episteme(eidos + koina + graphe + krites),mneme(facade),organon(koina + hermeneus),agora(koina + taxis),thesauros(koina + organon) - High:
nous(multiple mid+low deps),pylon(multiple deps including nous),diaporeia(MCP server, multiple deps including nous) - Top:
aletheiabinary,koilon(koina + skene),proskenion(Dioxus desktop, excluded from workspace) - Support:
integration-tests
Imports flow downward only. Lower-layer crates must not depend on higher layers.
| Trait | Crate | Purpose |
|---|---|---|
EmbeddingProvider |
episteme | Vector embeddings from text |
ChannelProvider |
agora | Send/receive on a messaging channel |
LlmProvider |
hermeneus | LLM API calls |
- Create
crates/<name>/withCargo.tomlandsrc/lib.rs - Add to workspace
membersin rootCargo.toml - Declare its layer in the dependency graph
- Update this file
- Workspace lints apply automatically
[profile.dev]
opt-level = 1
[profile.dev.package."*"]
opt-level = 2 # optimize deps in dev - faster iteration
[profile.release]
lto = "thin"
codegen-units = 1
strip = "symbols"A dense dependency graph (many edges per node) signals that new work may fit better as a function inside an existing crate instead of as a new crate. We track the ratio of inter-crate edges to workspace crates:
./scripts/topology-metric.shBaseline: crates=29, edges=102, ratio=3.51
When adding a component, prefer extending an existing edge (dependency or trait boundary) over introducing a new node, unless the new crate provides a clean abstraction boundary or is consumed by multiple unrelated crates.
- koina, eidos, and dianoia are true leaf nodes. No workspace deps in Rust.
- symbolon depends only on koina (plus external crates: reqwest, fjall, hmac/sha2/aes-gcm, argon2).
- mneme is a thin facade. It re-exports from eidos (types), graphe (session store), episteme (knowledge pipeline), and krites (Datalog engine). No logic of its own.
- krites contains the Datalog+HNSW engine, gated behind the
mneme-enginefeature. - Boundary:
kritesis the embedded Datalog and graph query engine. It decides whether rules and facts satisfy a query; it does not judge agent behavior. - Boundary:
dokimionis the behavioral and cognitive evaluation runner. It runs scenarios, benchmarks, and agent-behavior checks against live Aletheia instances. - EmbeddingProvider lives in episteme, not mneme.
- Trait boundaries are extension points.
EmbeddingProvider,ChannelProvider,LlmProvider- implement the trait, swap the provider. - daemon depends only on koina - lightweight scheduling, not a high-layer crate. No other application crate imports it.
- dianoia has no workspace dependencies - planning context fully decoupled from the agent pipeline. No other application crate imports it.
- thesauros loads domain packs - knowledge, tools, config overlays bundled as portable extensions. Depends on koina + organon.
- nous requires a multi-thread Tokio runtime (
rt-multi-thread). The actor model and spawn-based timeout machinery depend on multiple OS threads. Single-thread runtime will deadlock.
Some architectural decisions look binary but aren't. When the tension between options carries information, model both states.
Examples in aletheia (correctly preserved):
EpistemicTier(Verified/Inferred/Assumed): facts have confidence, not just yes/no- Hot vs cold config classification
DegradedEmbeddingProvider: embedding can be unavailable AND system continues
Examples audited for premature resolution:
- Conflict resolution (
episteme/conflict.rs): when supersession happens, the original fact is preserved as historical evidence viasuperseded_byandvalid_to- correctly binary. - Tool execution (
organon/dispatch.rs,ToolResult):is_error: boolis a strict success/fail collapse. Partial states (e.g. some prompts succeeded in a dispatch batch, tool produced output but also emitted warnings) are lost - premature collapse; see #3633. - Consolidation (
episteme/consolidation/): original facts are superseded, not deleted, andconsolidation_auditrecords provenance. However, the consolidatedFactitself carries nosource_countor multiplicity metadata, so independent-evidence signal is lost after merge - premature collapse; see #3634. - Actor shutdown (
nous/manager.rs):ShutdownOutcomealready distinguishesClean/Panicked/TimedOut, and #3472 addresses further graceful-degradation phases - correctly non-binary.
When adding a new feature, ask: does this decision collapse information that downstream code might need? If so, model the tension explicitly.
Tracks aletheia's main branch with zero divergence - no custom code, no feature additions. Ergon exists as a client-deliverable identity: same runtime, different branding. Changes flow from aletheia to ergon, never the reverse. Do not add ergon-specific code to this repository.