Architecture
AideMemo is one Rust core with several access surfaces. The same typed facts, entities, relations, validity windows, BM25 index, semantic HNSW sidecar, and archive semantics are exposed through the CLI, MCP tools, Python agent SDK, and native bindings.
System map
The public dispatch point is AideMemo in aidememo-core. Storage selection is
centralized behind StoreKind: SQLite / libsqlite is the default runtime
backend, while redb is selected only when the crate is built with the optional
Cargo feature and the config or CLI asks for it.
The solid storage and retrieval path runs without an external LLM API. The
dotted model edges are explicit local opt-ins, not hidden dependencies:
LFM2.5 Embedding can supply vectors to the existing HNSW path, ColBERT can
rerank an already-recalled candidate set, the 1.2B LoRA path emits review-only
fact_type_hint values from shadow data, and the privacy model runs before
persistence when its policy is enabled.
| Boundary | Concrete opt-in used by the measured path |
|---|---|
| Semantic fallback | mlx-community/LFM2.5-Embedding-350M-4bit via model.provider=lfm-sidecar |
| Candidate rerank | mlx-community/LFM2.5-ColBERT-350M-4bit through a compatible local scorer |
| Shadow fact typing | LiquidAI/LFM2.5-1.2B-Instruct-MLX-4bit + LoRA, review hints only |
| Write-time privacy | OpenAI Privacy Filter MLX mxfp4, policy opt-in |
Retrieval flow
Use search for direct ranked hits, query for a focused context pack, and
context for the broad opening-turn envelope. The CLI defaults to the
auto-hybrid policy: a BM25 probe stays lexical when confidence is good and
promotes weak or CJK queries to semantic retrieval when the semantic path is
ready. --hybrid forces semantic ranking for every query. MCP callers can pass
bm25_only:true when they need deterministic low-latency behavior.
model2vec remains the global default semantic provider. The LFM embedding
sidecar is selected only with model.provider=lfm-sidecar and participates in
the same auto-hybrid + HNSW contract; daemon startup prewarms it when that path
is configured. ColBERT remains off by default and belongs after candidate
recall, not in place of retrieval.
Write and lifecycle flow
Facts are intentionally explicit. AideMemo does not need a built-in hosted
extractor for normal agent loops because the calling agent already has the
stronger model and should classify durable facts before writing them. The
extract and pending commands exist for opt-in capture and review workflows.
The local 1.2B + LoRA path is deliberately outside the persistence edge: it
learns from reviewed shadow logs and emits hints, but never silently changes an
explicit type or writes a fact. The privacy sidecar has the opposite placement:
when enabled, its policy executes synchronously before persistence.
Cloud and branch-log flow
Branch logs are append-only artifacts for cloud agents and speculative memory
experiments. They are not full multi-master conflict resolution: duplicate
records are skipped through sync_import, independent facts are appended, and
semantic conflicts between competing decisions remain application policy.
Source map
| System area | Primary implementation | Public docs |
|---|---|---|
| CLI commands and parsers | crates/aidememo-cli/src/cmd/mod.rs, crates/aidememo-cli/src/main.rs | CLI Usage, Feature Inventory |
| MCP tools and schemas | crates/aidememo-cli/src/cmd/mcp_tools.rs | MCP Setup, Agent Workflows |
| Core API and retrieval | crates/aidememo-core/src/lib.rs, search.rs, graph.rs | Architecture, Operations |
| Storage dispatch | crates/aidememo-core/src/backend.rs, sqlite_store.rs, store.rs | Operations, Feature Inventory |
| Python agent SDK | packages/aidememo-agent-sdk/src/aidememo_agent/sdk.py | Python SDK, Agent Workflows |
| Native bindings | crates/aidememo-python, crates/aidememo-napi, crates/aidememo-nif, crates/aidememo-ffi | Python SDK, package READMEs |
| Local model sidecars and evaluation | scripts/lfm_mlx_embedding_sidecar.py, scripts/lfm_colbert_rerank.py, scripts/lfm_fact_type_sidecar.py, scripts/privacy_filter_mlx_sidecar.py | Operations, Measurements |
| Validation and release gates | scripts/changelog-release-check.py, scripts/registry-readiness-check.py, scripts/cargo-package-readiness.sh, scripts/docs-feature-gate.py, scripts/docs-i18n-status.py, scripts/docs-site-e2e.py, scripts/*smoke*.sh, scripts/ci-local.sh | Measurements, Release Checklist |
Documentation contract
Documentation validation has two layers:
scripts/docs-feature-gate.py is the source-level public-docs drift gate. It
currently checks:
- every top-level CLI command and subcommand listed by
aidememo --helpappears inFeature Inventory; - every MCP tool declared in
cmd/mcp_tools.rs::list_tools()appears inFeature Inventory; - public numeric claims such as MCP tool counts, CLI command counts, architecture diagram counts, and AGENTS core-tool counts match implementation-derived values; the count-claim detector self-tests this rejection path on every run;
- core explanatory docs such as this page,
Agent Workflows, andMeasurementsare exposed through Docusaurus; - Mermaid is enabled so system diagrams render as diagrams, not inert code;
- README and English/Korean architecture diagrams retain the default local path plus the opt-in LFM embedding, ColBERT rerank, fact-type hint, and privacy sidecar boundaries;
- Korean translation coverage and source fingerprints match the public English docs, with intentional English fallbacks recorded explicitly;
- public wording keeps SQLite as the default backend and redb as the optional Cargo-feature backend.
scripts/docs-site-e2e.py is the rendered-site gate. It builds Docusaurus and
checks that the English and Korean sitemaps, sidebar, homepage cards,
locale-specific page H1s, html lang / hreflang, baseUrl-scoped links,
static assets, anchors, and architecture-doc implementation paths still match
the current repo.
Run it before publishing docs:
python3 scripts/docs-feature-gate.py
python3 scripts/docs-site-e2e.py