Memory

Memory overview

The IBEX memory substrate — writes, dedup, conflict candidates, temporal reads, and pgvector retrieval.
Implemented Ledger class: shipped-local
Verified 2026-10-21

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_id and agent_id are 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:

PathPurpose
Vector search (HNSW)Semantic recall through pgvector.
Full-text fallbackSupplements vector results when the requested page is not filled.
Hot cacheRedis sorted set of recent, high-value memories for an agent.
Historical candidatesInternal 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; SearchMode remains 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.

Evidence