The types, end to end.

Every public Rust struct and enum that crosses the HTTP/MCP/CLI boundary. Field-level types, defaults, serde tags, since-when annotations. The contract a client implements when it wires up to ai-memory.

5 enums 22 structs 5 consts v0.7.0 — Memory 26 fields / MemoryLink 6 relations
Quick jump

All 27 types, indexed.

Grouped by responsibility: core domain (Tier, Memory, MemoryLink), request/response shapes (Create/Update/Search/List/Recall), governance (GovernanceLevel, ApproverType, GovernancePolicy, GovernedAction, GovernanceDecision), federation (VectorClock, SyncStateEntry, AgentRegistration, NamespaceMetaEntry), pending-action queue (PendingAction, PendingDecision, Approval).

Core domain

Tierenumsince v0.1
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] · #[serde(rename_all = "snake_case")]
Memory tier — mirrors human memory systems. Default TTL: Short = 6h, Mid = 7d, Long = none.
Shortworking memory; short-lived contexts; default TTL 6h.
Midsession-spanning facts; default TTL 7d. Default tier for new memories.
Longdurable knowledge; no TTL; subject to governance gates on promote.
// helper API Tier::default_ttl_secs(self) -> Option<i64> Tier::as_str(&self) -> &'static str Tier::from_str(&str) -> Option<Tier>
Memorystructsince v0.1 · grew to 26 fields at v0.7.0
#[derive(Debug, Clone, Serialize, Deserialize)]
The stored record returned by HTTP GET /memories/:id and MCP memory_get. Persisted into the memories table; mirrored to FTS5 + HNSW vector index. 26 fields at v0.7.0 (was 15 at v0.6.x; canonical truth in src/models/memory.rs::Memory, FIELD_COUNT = 26) — adds reflection_depth (Task 1/8 recursive learning), memory_kind (Batman Form-6 vocabulary), entity_id + persona_version (QW-2 persona artefact), citations + source_uri + source_span (Form-4 fact provenance), confidence_source + confidence_signals + confidence_decayed_at (Form-5 calibration), and the version BIGINT (Gap-1 optimistic concurrency, schema v45).
fieldtypenotes
idStringREQUUIDv4 primary key.
tierTierREQOne of short · mid · long.
namespaceStringREQHierarchical path; up to 8 segments; default "global".
titleStringREQ1–512 chars (MAX_TITLE_LEN); required.
contentStringREQ1–65 536 bytes (MAX_CONTENT_SIZE).
tagsVec<String>DEFDefault []; max 50 tags (MAX_TAGS_COUNT), 128 bytes each (MAX_TAG_LEN).
priorityi32DEFDefault 5; range 1-10.
confidencef64DEFDefault 1.0; range 0.0-1.0.
sourceStringDEFDefault "api"; closed set (VALID_SOURCES): user · nhi · claude (deprecated) · hook · api · cli · import · consolidation · system · chaos · notify.
access_counti64Server-tracked; bumps on each memory_get/memory_recall hit.
created_atStringRFC3339; server-stamped.
updated_atStringRFC3339; updated on each memory_update.
last_accessed_atOption<String>OPTRFC3339; skip_serializing_if = None.
expires_atOption<String>OPTRFC3339; computed from ttl_secs or tier default.
metadataserde_json::ValueDEFDefault {}; carries governance, scope, agent_id, taxonomy fields.
reflection_depthi32DEFv0.7.0 Task 1/8: recursion depth in the substrate-native reflection tree. 0 for caller-minted (or legacy) rows; positive for reflection-pass outputs. Stored on memories.reflection_depth NOT NULL DEFAULT 0 (schema v29 sqlite / v31 postgres).
memory_kindMemoryKindDEFv0.7.0 L1-1: Batman Form-6 typed discriminator (observation / reflection / persona / concept / entity / claim / relation / event / conversation / decision). Schema v30 column default 'observation' for pre-v30 rows.
entity_idOption<String>OPTv0.7.0 QW-2: persona artefact subject. Populated only when memory_kind == Persona. Stored on memories.entity_id NULL (schema v36).
persona_versionOption<i32>OPTv0.7.0 QW-2: monotonic (entity_id, namespace) version counter; PersonaGenerator::generate bumps. Older rows remain queryable for audit/rollback.
citationsVec<Citation>DEFv0.7.0 Form 4 (#757): fact-provenance citation array. Each entry: { uri, accessed_at, hash?, span? }. Schema v38 column; legacy rows default to '[]'. Validator: validate_citation.
source_uriOption<String>OPTv0.7.0 Form 4 (#757): first-class URI pointer (uri: / doc: / file: schemes). Distinct from the role-label source column. Schema v38; validator: validate_source_uri.
source_spanOption<SourceSpan>OPTv0.7.0 Form 4 (#757): byte-range into the parent source body, JSON {start, end}. Populated by the WT-1-B atomisation writer per atom. Validator: validate_source_span.
confidence_sourceConfidenceSourceDEFv0.7.0 Form 5 (#758): typed discriminator naming the provenance of confidence. Defaults to CallerProvided. Schema v39 sqlite / v38 postgres column default 'caller_provided'.
confidence_signalsOption<ConfidenceSignals>OPTv0.7.0 Form 5: JSON snapshot of the signals that produced an auto-derived or calibrated confidence. NULL on legacy rows and on CallerProvided writes.
confidence_decayed_atOption<String>OPTv0.7.0 Form 5: RFC3339 stamp of the last decay-sweep touch. NULL on legacy / never-decayed rows.
versioni64DEFv0.7.0 Provenance Gap 1 (#884, schema v45 sqlite): optimistic-concurrency counter. Bumped on every storage::update; two writers against the same expected_version race; loser receives a typed CONFLICT envelope. Legacy rows land at version = 1 via SQL DEFAULT + serde default_memory_version.

Request shapes — write path

CreateMemorystructsince v0.1
#[derive(Debug, Deserialize)]
Body of POST /memories and memory_store. Every field has a server-side default except title + content.
fieldtypenotes
tierTierDEFDefault Mid.
namespaceStringDEFDefault "global".
titleStringREQ1–512 chars (MAX_TITLE_LEN).
contentStringREQ1–65 536 bytes.
tagsVec<String>DEFDefault [].
priorityi32DEFDefault 5.
confidencef64DEFDefault 1.0.
sourceStringDEFDefault "api".
expires_atOption<String>OPTRFC3339; explicit override.
ttl_secsOption<i64>OPTConvenience: expires_at = now + ttl_secs.
metadataValueDEFDefault {}.
agent_idOption<String>OPTAuto-resolved by identity when omitted.
scopeOption<String>OPTOne of VALID_SCOPES; default "private".
on_conflict / detect_conflicts / forceOption<String> / Option<bool> / boolOPTDedup-and-synthesis controls (Form 1): conflict disposition, contradiction probe, duplicate-gate override.
citations / source_uri / source_spanVec<Citation> / Option<String> / Option<SourceSpan>OPTv0.7.0 Form-4 fact provenance (#757).
kindOption<String>OPTv0.7.0 Batman Form-6 memory_kind discriminator.
signatureOption<String>OPTv0.7.0 Layer-3 — caller-presented Ed25519 write attestation (verified against the agent's bound key).
created_atOption<String>OPTRFC3339 backdating for imports; server-stamped when omitted.
UpdateMemorystructsince v0.1
#[derive(Debug, Deserialize)]
Body of PUT /memories/:id and memory_update. Every field is optional — only the present fields are mutated; the rest are preserved.
fieldtypenotes
titleOption<String>OPT1–512 chars (MAX_TITLE_LEN) when set.
contentOption<String>OPT1–65 536 bytes when set.
tierOption<Tier>OPTPromoting Mid→Long passes through governance.
namespaceOption<String>OPTRe-namespacing; depth ≤ 8.
tagsOption<Vec<String>>OPTReplaces tag set entirely (not merged).
priorityOption<i32>OPT1-10 range.
confidenceOption<f64>OPT0.0-1.0 range.
expires_atOption<String>OPTRFC3339.
metadataOption<Value>OPTReplaces metadata wholesale (not merged); metadata.agent_id is preserved.
source_uriOption<String>OPTv0.7.0 Form-4 provenance pointer update.
agent_idOption<String>OPTCaller identity for owner-write checks; the stored row's metadata.agent_id remains immutable.
LinkBodystructsince v0.1
#[derive(Debug, Deserialize)]
Body of POST /links and memory_link. Creates a directed edge in the KG.
fieldtypenotes
source_idStringREQUUID; must exist in memories.
target_idStringREQUUID; must exist in memories.
relationStringDEFDefault "related_to".
ForgetQuerystructsince v0.1
#[derive(Debug, Deserialize)]
Body of POST /api/v1/forget and memory_forget (v0.7.0: route registered at /api/v1/forget, not /api/v1/memories/forget). Pattern-based delete; archives matched memories rather than hard-deleting.
fieldtypenotes
namespaceOption<String>OPTRestricts the sweep to a namespace.
patternOption<String>OPTFTS5 pattern; matches title+content.
tierOption<Tier>OPTRestricts to one tier.

Request shapes — read path

SearchQuerystructsince v0.1 · agent fields v0.6
#[derive(Debug, Deserialize)]
Query string for GET /search and body for memory_search. FTS5-backed.
fieldtypenotes
qStringREQFTS5 expression; supports AND/OR/NEAR/"phrase".
namespaceOption<String>OPTRestricts to one namespace prefix.
tierOption<Tier>OPT
limitOption<usize>DEFDefault 20.
min_priorityOption<i32>OPT
since / untilOption<String>OPTRFC3339 created_at window.
tagsOption<String>OPTComma-separated; AND semantics.
agent_idOption<String>OPTFilters by metadata.agent_id exact.
as_agentOption<String>OPTQuerying agent's namespace position; drives scope filtering.
ListQuerystructsince v0.1
#[derive(Debug, Deserialize)]
Query string for GET /memories and memory_list. Pagination + filter by namespace/tier/tags.
fieldtypenotes
namespaceOption<String>OPT
tierOption<Tier>OPT
limitOption<usize>DEFDefault 20.
offsetOption<usize>OPT
min_priorityOption<i32>OPT
since / untilOption<String>OPTRFC3339 window.
tagsOption<String>OPTComma-separated.
agent_idOption<String>OPT
RecallQuerystructsince v0.1 · budget_tokens Task 1.11
#[derive(Debug, Deserialize)]
Query string for GET /recall. Hybrid FTS5 + HNSW fusion with adaptive blending — semantic weight 0.50 (short content) → 0.15 (long content), cosine gate RECALL_COSINE_GATE = 0.2; optional context-budget pruning.
fieldtypenotes
contextOption<String>OPTFree-form context to retrieve against.
namespaceOption<String>OPT
limitOption<usize>DEFDefault 10.
tagsOption<String>OPT
since / untilOption<String>OPT
as_agentOption<String>OPTVisibility filter (Task 1.5).
budget_tokensOption<usize>OPTCap on cumulative tokens; top-N items that fit (Task 1.11).
RecallBodystructsince v0.1
#[derive(Debug, Deserialize)]
JSON body of POST /recall and memory_recall. Same shape as RecallQuery but context is required.
fieldtypenotes
contextStringREQ
namespaceOption<String>OPT
limitOption<usize>DEFDefault 10.
tags / since / until / as_agent / budget_tokensSame as RecallQuery.

Response shapes — telemetry

Statsstructsince v0.1
#[derive(Debug, Serialize)]
Response of GET /stats and memory_stats.
fieldtypenotes
totalusizeCount of non-archived memories.
by_tierVec<TierCount>3 rows: short / mid / long.
by_namespaceVec<NamespaceCount>One row per distinct namespace.
expiring_soonusizeCount expiring within 24h.
links_countusizeTotal memory_links rows.
db_size_bytesu64SQLite file size.
TierCountstructsince v0.1
#[derive(Debug, Serialize)]
Embedded in Stats.by_tier.
fieldtypenotes
tierString"short" · "mid" · "long"
countusize
NamespaceCountstructsince v0.1
#[derive(Debug, Serialize)]
Embedded in Stats.by_namespace.
fieldtypenotes
namespaceString
countusize

Governance — Task 1.8 / 1.9 / 1.10

GovernanceDecisionenumsince Task 1.9 (v0.6)
#[derive(Debug, Clone, PartialEq, Eq)]
The outcome of a governance check. Callers MAY execute on Allow, MUST reject on Deny, and SHOULD queue + return the pending_id on Pending.
Allowproceed with the action.
Deny(GovernanceRefusal)reject; the typed envelope carries the canonical wire message (Display reads "<action> denied by governance: <reason>") plus the structured policy context (denied_level, namespace, owner, agent_id, reason). Wire shape byte-identical to the pre-#963 Deny(String) envelope; pattern-match consumers read refusal.reason for the bare string.
Pending(String)queued for approval; the caller receives the new pending_id.
GovernedActionenumsince Task 1.9 (v0.6)
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
Actions that governance gates. Stored as the action_type column in pending_actions; discriminator for enforcement calls.
Storecreating a new memory in a governed namespace.
Deletedeleting an existing memory.
Promotetier promotion (Mid → Long).
Reflectv0.7.0 L1-8 — memory_reflect approval gate; queued when the proposed reflection depth exceeds require_approval_above_depth.
GovernanceLevelenumsince Task 1.8 (v0.6)
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] · #[serde(rename_all = "snake_case")]
Who is permitted to perform a governed action. Stored in a namespace standard's metadata.governance.
Anyno gate; any caller succeeds.
Registeredcaller must be a registered agent (_agents namespace).
Owneronly the memory's metadata.agent_id owner may perform the action.
Approverequires explicit approval by an ApproverType.
ApproverTypeenumsince Task 1.10 (v0.6)
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] · #[serde(rename_all = "snake_case")]
Who approves actions gated by GovernanceLevel::Approve. Externally-tagged.
Humanserialized as "human"; interactive or out-of-band approval.
Agent(String)serialized as {"agent": "alice"}; specific registered agent must approve.
Consensus(u32)serialized as {"consensus": 3}; consensus of N approvers required.
GovernancePolicystructsince Task 1.8 (v0.6)
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
Attached to a namespace's standard memory at metadata.governance. Default policy: { write: Any, promote: Any, delete: Owner, approver: Human }. v0.6.2 (S34) made promote/delete/approver tolerant of missing fields for partial-policy payloads.
fieldtypenotes
writeGovernanceLevelREQRequired — core knob a policy is setting.
promoteGovernanceLevelDEFDefault Any.
deleteGovernanceLevelDEFDefault Owner.
approverApproverTypeDEFDefault Human.
// helper API GovernancePolicy::from_metadata(&Value) -> Option<Result<Self, _>> GovernancePolicy::default() // { write: Any, promote: Any, delete: Owner, approver: Human }
Approvalstructsince Task 1.10 (v0.6)
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
A single approval vote on a consensus-gated pending action.
fieldtypenotes
agent_idStringApproving agent's id.
approved_atStringRFC3339.
PendingActionstructsince Task 1.9 (v0.6)
#[derive(Debug, Clone, Serialize, Deserialize)]
Row returned by db::list_pending_actions. Mirrors the pending_actions table.
fieldtypenotes
idStringUUID.
action_typeStringstore · delete · promote · reflect (v0.7.0).
memory_idOption<String>Set for delete/promote; null for pending stores.
namespaceString
payloadValueAction-shaped JSON for replay.
requested_byStringagent_id of requester.
requested_atStringRFC3339.
statusStringpending · approved · rejected.
decided_byOption<String>OPT
decided_atOption<String>OPT
approvalsVec<Approval>Consensus vote log (Task 1.10); empty for Human/Agent paths.
PendingDecisionstructsince v0.6.2 S34
#[derive(Debug, Clone, Serialize, Deserialize)]
A pending-action decision (approve/reject) propagated to peers so callers on any peer see consistent state. Shipped as additive sync_push.pending_decisions field; peers apply via db::decide_pending_action.
fieldtypenotes
idStringpending_action UUID.
approvedbooltrue → approve; false → reject.
deciderStringagent_id of decider.

Federation — issue #224 / agent registry

NamespaceMetaEntrystructsince v0.6.2 S35
#[derive(Debug, Clone, Serialize, Deserialize)]
A namespace-standard metadata row propagated to peers. Without this, a peer sees the standard memory (fanned via broadcast_store_quorum) but not the (namespace, standard_id, parent_namespace) tuple, so inheritance-chain walks fall back to auto_detect_parent.
fieldtypenotes
namespaceString
standard_idStringUUID of the standard memory.
parent_namespaceOption<String>OPT
updated_atStringRFC3339.
RegisterAgentBodystructsince Task 1.3 (v0.6)
#[derive(Debug, Deserialize)]
Body of POST /agents/register. Persists into the _agents namespace.
fieldtypenotes
agent_idStringREQStable identifier; max 64 chars.
agent_typeStringREQOne of VALID_AGENT_TYPES.
capabilitiesOption<Vec<String>>OPTFree-form capability tags.
AgentRegistrationstructsince Task 1.3 (v0.6)
#[derive(Debug, Serialize)]
Response to POST /agents/register and rows in GET /agents.
fieldtypenotes
agent_idString
agent_typeString
capabilitiesVec<String>Empty when none registered.
registered_atStringRFC3339.
last_seen_atStringRFC3339; bumps on agent activity.
VectorClockstructsince v0.6.0 — Phase 3 foundation (#224)
#[derive(Debug, Clone, Serialize, Deserialize, Default, PartialEq, Eq)]
Tracks the latest updated_at this peer has seen from each known remote. Populated lazily on /sync/push and /sync/since. CRDT-lite merge semantics arrive in Task 3a.1; the foundation ships the wire format so adding semantics later does not force a schema migration.
fieldtypenotes
entriesBTreeMap<String, String>DEFpeer agent_id → latest RFC3339 updated_at.
// helper API VectorClock::observe(&mut self, peer_id: &str, at: &str) // monotonic: never overwrite newer VectorClock::latest_from(&self, peer_id: &str) -> Option<&str>
SyncStateEntrystructsince v0.6.0 — Phase 3 foundation (#224)
#[derive(Debug, Clone, Serialize, Deserialize)]
One row of the sync_state table serialized for diagnostic / API responses. Consumed by Task 3b.2 sync diagnostics.
fieldtypenotes
agent_idStringLocal agent's id.
peer_idStringRemote peer's id.
last_seen_atStringRFC3339; latest updated_at seen on receive.
last_pulled_atStringRFC3339; cursor advanced on send.

Constants — wire-format closed sets

MAX_CONTENT_SIZEconst
usize = 65_536 — hard cap on memory content bytes. Validated at write time.
MAX_NAMESPACE_DEPTHconst
usize = 8 — maximum number of /-delimited segments in a namespace path. Sample: alphaone/engineering/platform/team/squad/pod/role/agent.
VALID_SCOPESconst
&[&str] = &["private", "team", "unit", "org", "collective"] — closed set stamped into metadata.scope (Task 1.5). Drives hierarchical visibility matching.
VALID_AGENT_TYPESconst
Curated short-list of agent types accepted by POST /agents/register. NOT a hard closed set since red-team #235: any ai:<name> form matching ^ai:[A-Za-z0-9_.-]{1,60}$ is also accepted (max 64 bytes total), so operators can register future models without a code release.
&[ "ai:claude-opus-4.6", "ai:claude-opus-4.7", "ai:codex-5.4", "ai:grok-4.2", "human", "system", ] // plus the open form: ai:<alphanumeric _-.> (validate_agent_type)
AGENTS_NAMESPACEconst
&str = "_agents" — namespace reserved for agent registrations (Task 1.3). Listed via memory_agent_list.
namespace_depth(ns: &str) → usizefn
Free function. Returns the count of /-delimited segments. Flat namespaces return 1; empty returns 0.
namespace_depth("global") // 1 namespace_depth("alphaone/engineering") // 2 namespace_depth("alphaone/engineering/platform") // 3