memory_type (episodic = event/run · semantic = fact · procedural = how-to) and a scope layer (user | department | global | provider).
Routing rule: memories for conceptual recall; data_query for exact numbers; agent_search_runs for “what did I do last time”.
memory_search
Search memories (your own user layer + shared department/global ones). Lean rows; fetch the full body with memory_get. Returns only currently-valid memories by default.
Returns:
{ memories: [...], count }. Each row: id, title, intro, category, category_id, scope, importance, tags, source, user_id, department_id, created_at, updated_at, memory_type, valid_at, invalid_at, source_type, retrieval_class (no body).
Permissions: read; rights-filtered per user.
memory_get
One memory with full body — only if readable for this user.
Returns:
{ memory } — the full entry: all search columns plus body_markdown, confidence, needs_review, supersedes, source_id, source_uri, failure_count. Not readable/found → { error: "Memory not found" }.
Permissions: read; rights-filtered.
memory_save
Save a memory. scope=user (default) writes directly to your memory layer. Shared scopes (department/global): a Company-Admin writes directly, and so does a member of the named department (audited, status saved); any other shared write becomes a governance candidate (status pending_governance). scope=provider writes directly and requires Provider-Admin.
Returns: direct write →
{ status:"saved", layer, memory_id, audit }. Governance-routed shared write → { status:"pending_governance", candidate_id, note, audit }. dry_run:true → { dry_run:true, valid:true, would: { action, target_id:null, summary, changes: {<field>:{from,to}} }, note } — nothing written.
Permissions: write; role/scope rules as above.
memory_update
Edit an existing memory in place by id (the by-id counterpart to memory_save, which creates). Patchable: title, intro, body_markdown, category, importance, tags, memory_type. Pre-edit state is snapshotted (versioned, revertible); the row’s version is bumped under an optimistic lock. To replace a fact while keeping provenance use memory_save with supersedes; to hide a memory use memory_archive.
Returns:
{ status:"updated", id, version, updated, note, audit } — version is the bumped row version, updated lists the patched field names. A concurrent edit returns { error: "Edit conflict …" }.
Permissions: write; your own user-layer memory directly; editing a shared department/global memory (or one owned by another user) requires Company-Admin.
memory_archive
Archive a memory (soft + reversible) — hides it from normal recall without deleting; pass unarchive:true to restore. Pre-archive state is snapshotted.
Returns:
{ status:"archived"|"unarchived", id, archived_at, note, audit } — archived_at is the new timestamp (or null on unarchive).
Permissions: write; own user-layer memory directly; shared memories require Company-Admin.