Memory overview
The memory service is a Python/FastAPI process backed by PostgreSQL and pgvector. It stores tenant- and agent-scoped memories, computes embeddings, deduplicates near-identical content, records conflict candidates, and serves similarity search plus a Redis hot cache.
What the status means: the substrate is implemented and locally evidenced. It is not a claim of production isolation, complete deletion semantics, or an accepted typed lifecycle. GAP-007 remains open.
Write path
request → validate tenant/agent → PII policy → embed → near-dedup
→ historical conflict candidates → persist memory + links
→ hot-cache update → metrics/traces
Key properties:
org_idandagent_idare bound from the authenticated principal, not from arbitrary body fields.- Memory and label inserts share a transaction.
- Near-duplicate detection runs against historical conflict candidates, not the default user-read view.
- Idempotency uses the shared
(org_id, agent_id, key)ledger. If the ledger is unavailable, writes fail closed rather than silently duplicating. - PII detection and redaction are applied before persistence.
Read path
The default user read is validity-fenced and returns current memories only. Internal conflict and dedup paths can request historical candidates through a dedicated capability. This prevents normal search from surfacing superseded memories while preserving write-time conflict detection.
Search modes:
| Path | Purpose |
|---|---|
| Vector search (HNSW) | Semantic recall through pgvector. |
| Full-text fallback | Supplements vector results when the requested page is not filled. |
| Hot cache | Redis sorted set of recent, high-value memories for an agent. |
| Historical candidates | Internal conflict/dedup only; not a user-facing read mode. |
HTTP surface
The memory service exposes, under /v1/memories:
POST /v1/memories— create a memory.POST /v1/memories/search— semantic search.GET /v1/memories/hot— hot-cache memories for the current agent.POST /v1/memories/{memory_id}/feedback— record usefulness feedback.POST /v1/memories/{memory_id}/forget— lifecycle/forget path.
These routes are part of the local service. They are not evidence of a generally available hosted API.
Data model
Core tables live in ibex_core:
memories— content, category, confidence, validity timestamps, provenance, embedding.memory_labels— multi-label support; the primary category is synchronized by trigger.memory_relationships— reserved relationship graph.memory_conflicts— candidate/resolution records.- embedding and lifecycle support columns added by forward migrations.
All access is tenant-scoped with explicit org_id predicates in addition to RLS.
Limits and open work
- Typed lifecycle, provenance checkpoints, and a durable revision ledger are not implemented.
- Historical candidate search and temporal reads are fenced;
SearchModeremains an internal capability that must be audited at new call sites. - The deferred org-scope GDPR/MinIO purge path and stale-cache behavior remain open.
- Local tests do not certify hosted/HA operation or end-to-end deletion.

