# Memory

**Long-term memory** extracted from conversations. The system
identifies facts, preferences, and context about the user and stores
them for injection into future conversations.

**Auth:** All user endpoints require authenticated session.
Admin endpoints require platform admin role.

---

### User Memory

```
GET    /memories                    → { "data": [memory objects] }
GET    /memories/count              → { "active": 5, "pending": 2 }
PUT    /memories/:id                ← { "key": "...", "value": "...", "confidence": 0.9 }
DELETE /memories/:id
POST   /memories/:id/approve        → approve a pending_review memory
POST   /memories/:id/reject         → reject (archive) a pending_review memory
```

Query params for `GET /memories`:

| Param | Default | Description |
|-------|---------|-------------|
| `status` | `active` | Filter by status: `active`, `pending_review`, `archived` |
| `query` | — | Keyword filter on key+value (PG: full-text, SQLite: LIKE) |

Memory object:

```json
{
  "id": "uuid",
  "scope": "user|persona|persona_user",
  "owner_id": "uuid",
  "user_id": "uuid|null",
  "key": "preferred language",
  "value": "Go with Gin framework for backend services",
  "source_channel_id": "uuid|null",
  "confidence": 0.85,
  "status": "active|pending_review|archived",
  "created_at": "...",
  "updated_at": "..."
}
```

**Scopes:**

| Scope | `owner_id` | `user_id` | Description |
|-------|-----------|-----------|-------------|
| `user` | user's ID | null | Personal facts, persist across all conversations |
| `persona` | persona's ID | null | Shared across all users of a Persona |
| `persona_user` | persona's ID | user's ID | Per-user facts within a Persona context |

**Ownership:** `PUT` and `DELETE` enforce ownership — a user can only
modify their own user-scope memories (`owner_id == user_id`).

### Admin Memory Review

```
GET  /admin/memories/pending        → { "data": [memory objects] }
POST /admin/memories/bulk-approve   ← { "ids": ["uuid1", "uuid2"] }
                                    → { "approved": 2 }
```

Platform admin can review and bulk-approve pending memories across
all users.

### AI Tools (non-REST)

Two tools are registered for AI use during completions:

| Tool | Description |
|------|-------------|
| `memory_save` | Save a fact with `key`, `value`, `confidence`. Saves as `active` (bypasses review). |
| `memory_recall` | Search memories by query. Uses hybrid semantic+keyword recall when embedder is configured. |

### Background Extraction

A background scanner periodically finds conversations with enough
new activity and calls the utility model to extract memorable facts.
Extracted memories are saved as `pending_review`.

Controlled by `memory_extraction_enabled` global config key and
per-persona `memory_enabled` flag.

### Memory Injection

Active memories are injected into the system prompt at completion
time via `BuildMemoryHint`. Uses hybrid semantic recall when an
embedder is available, falling back to keyword/confidence ranking.
Budget: ~6000 characters.

---
