Main Components
| Component | Location | Responsibility |
|---|---|---|
| Protocol types | crates/protocol/src/memory.rs | Public DTOs, semantic write contracts, candidates, notifications, schemas. |
| Memory service | crates/memory | Recall, ranking, semantic write pipeline, candidate policy, tombstones, memvid integration. |
| Control plane | crates/crud and gateway.db | Memory records, candidates, policy decisions, scopes, provenance, repair jobs. |
| Capsule backend | memvid-core through MemvidMemoryBackend | Searchable payload storage split by scope capsules. |
| Gateway runtime | crates/gateway/src/memory_runtime.rs and crates/gateway/src/lib.rs | Enables/disables memory, resolves runtime config, wires service, hook package config, and operation context. |
| Memory hooks | crates/memory/src/hooks | Memory policy, deterministic recall, active recall, tool materialization, prompt contract, and post-turn extraction. |
| Agent hook bridge | crates/agent/src/hooks.rs and crates/agent/src/chat/mod.rs | Dispatches lifecycle phases and consumes typed contributions without owning memory-domain rules. |
| Prompt contracts | crates/promt | Memory recall prompt and post-turn extractor prompt. |
Storage Model
Memory has two stores with different authority: Memvid is optimized for retrieval. SQLite is authoritative for policy and visibility. If memvid returns a stale hit, the service checks the control plane before exposing it. Deleted, superseded, expired, repair-needed, sensitive, or out-of-scope records are suppressed.Scopes
Memory scopes prevent leakage across unrelated work:| Scope kind | Use |
|---|---|
user | User identity, biography, global preferences. |
workspace | Project-local policies, decisions, procedures, facts. |
agent | Agent-specific facts when allowed by config. |
thread | Narrow turn/thread references for future context systems. |
task | Task-local operational context and future extensions. |
gateway.memory:
.., and unsafe runtime escapes are rejected.
Configuration Flow
Configuration flows through typed boundaries: The desktop settings are a product control surface for the same memory switches. They should not create a second memory policy language. If a setting is exposed to users, it must map to a real gateway/hook behavior or stay hidden. The hook package is the boundary where product switches decide which hooks are registered:- deterministic recall:
HookPhase::TurnPrePromptContext; - active recall:
HookPhase::TurnPostPreflightPromptContext; - tool bundle:
HookPhase::TurnPreToolMaterialization; - prompt contract:
HookPhase::TurnPrePromptCompile; - post-turn extraction:
HookPhase::TurnPostTurn.
MemoryService.
Recall Flow
The recall prompt is not enough by itself and tool exposure is not enough by itself. Pioneer uses both:- prompt policy tells the model when and how to use memory;
- recalled context gives the model relevant facts without forcing a tool call;
- memory tools let the model search, get exact records, remember, or forget when policy allows.
Model-Visible Tools
In agent mode, memory can expose:| Tool | Purpose |
|---|---|
memory_search | Search durable memory in active scopes and return compact hits with snippets and ids. |
memory_list | List durable memory inventory in active scopes without semantic search. |
memory_get | Fetch the exact full record by memory id or scoped key. |
memory_remember | Store durable memory when policy allows. |
memory_forget | Tombstone/suppress memory by id or scoped key. |
request_tools with the memory domain to reveal all registered memory tools. Chat mode keeps memory-domain tools unavailable.
Semantic Write Pipeline
All durable writes flow through service-owned semantic contracts:- The caller supplies
MemorySemanticFields, content, optional normalized value, evidence, provenance, confidence, importance, and disposition. - The service resolves scope and generates the canonical key.
- The service computes a semantic fingerprint.
- Existing active memories and candidates are checked for duplicate, compatible update, contradiction, novel fact, or suppressed-by-rejection.
- Candidate policy scores explicitness, durability, scope clarity, repetition, contradiction, sensitivity, and extractor certainty.
- The service creates or updates active memory, creates/rejects/suppresses a candidate, or merges evidence.
Candidate Policy
Candidate policy is the gate between extracted facts and durable memory:| Case | Default behavior |
|---|---|
| High-confidence explicit durable fact | May become active when policy allows. |
| High-confidence implicit durable fact | May become active only when proactive writes are enabled and policy allows. |
| Extremely low score | Rejected or suppressed. |
| Middle score | Rejected or suppressed while review routing is disabled. |
| Secret/transient fact | Rejected/suppressed; should not become active. |
| Duplicate | Evidence merged or duplicate suppressed. |
| Contradiction | Routed by policy; no silent overwrite. |
Post-Turn Extraction
MemoryPostTurnExtractorHook runs after a successful turn on HookPhase::TurnPostTurn.
It is deliberately not a subagent:
- no child thread;
- no task artifact;
- no model-facing memory tools;
- no normal assistant answer;
- no direct CRUD writes.
MemoryService::write_semantic_memory with RouteToCandidatePolicy.
This is the proactive write path. Pioneer can notice durable facts after the turn, but the service still owns dedupe, scoring, and final state.
Forgetting
Forgetting creates a control-plane tombstone. It is not just removing a vector payload. Future searches consult the control plane and suppress tombstoned ids even when the backend returns stale results. Forget can be invoked by:memory_forgetmodel-visible tool in agent mode;memory/forgetJSON-RPC method;- future UI management surfaces.
Observability
Memory behavior is observable through several layers:- prompt manifests show memory prompt sections and diagnostics;
- hook-run persistence records hook lifecycle, latency, failures, timeouts, and safe diagnostics;
- memory policy decisions and candidate policy outputs are stored in the control plane;
- memory notifications tell clients when active memory changes or is forgotten.
- memory debug APIs summarize recall diagnostics, hook runs, candidate decisions, and missing data without exposing raw secrets.
Troubleshooting
When memory was not saved:- Check
gateway.memory.enabledandgateway.memory.proactive_writes_enabled. - Check the desktop Memory settings if the desktop is the control surface.
- Inspect the
TurnPostTurnhook run for timeout, failure, or skipped status. - Inspect post-turn extraction diagnostics. Provider failures should not block the user turn.
- Inspect candidate policy output. Low-quality, transient, sensitive, duplicate, contradictory, thread/task-owned, or review-disabled middle-confidence facts may be rejected or suppressed.
- Confirm the source turn succeeded. Failed, interrupted, provider-failed, system-only, tool-only, and task-runtime-owned sources are not ordinary durable-memory writes.
- Check
gateway.memory.enabled,gateway.memory.deterministic_recall_enabled, andgateway.memory.active_recall_enabled. - Confirm the record is active, in scope, not expired, not deleted, not superseded, and not blocked by sensitivity policy.
- Check whether the turn had a workspace id. Workspace-scoped memory should not leak into unrelated workspaces.
- Inspect
TurnPrePromptContextandTurnPostPreflightPromptContexthook runs, plus preflight diagnostics. - Confirm the prompt section was rendered by
MemoryPromptContractHook. - If the expected context lives only in raw thread history, it will not be recalled until the episodic/thread transcript system exists.
Safety Invariants
Keep these invariants when changing memory:- The service owns canonical keys and final write state.
- Hooks never write active memory or candidates directly through CRUD.
- Memvid search results are always filtered through the control plane.
- Chat mode does not mutate memory.
- No-save/no-memory policies must disable inferred writes.
- Prompt context is context, not an instruction that overrides the user.
- Sensitive and secret-like facts must not leak through diagnostics.
- The classifier is advisory, not authority. Fallbacks must not disable memory by default.
- The quality gate owns write safety.
- Hook runtime carries lifecycle phases and typed contributions; domain logic belongs in memory hooks and service code.
Related Pages
- Desktop Memory explains the user-facing behavior.
- Hook Runtime explains lifecycle phases and typed contributions.
- Prompt And Context explains memory prompt injection.
- Memory Protocol documents JSON-RPC methods and notifications.