The platform

Memory for AI agents

How an agent stores what it learns and gets it back: memories and contexts, grades, documents and the facts extracted from them, closing and superseding instead of deleting, asking what was believed on a past date, and the kit that gives a coding agent all of it in one command.

The shape of a memory

A memory is a piece of text with a context, labels, a grade and provenance. It is embedded and stored once; everything after that is a stamp or a ledger row, never an edit. The create call:

POST /api/memory/memories
{
  "content": "...",                    // required
  "context": "handbook",               // required: a shelf name of your choosing
  "tags": ["billing"],                 // optional
  "metadata": {"source": "wiki/42"},   // optional, yours
  "user_id": "user:maeve",             // who contributed it: provenance, not a filter
  "compartment": "matter:acme",        // optional; default "public" (tenant-shared)
  "acl_classification": 0,             // 0..3
  "acl_owners": ["user:maeve"],        // optional: only these principals may see it
  "grade": 0.8, "grade_band": "decision",   // optional: how much weight it carries
  "occurred_at": "2026-10-01T09:00:00Z",    // optional: when the thing happened
  "reconcile": true                    // default: let the judge compare it with neighbours
}
→ 201 {"memory_id": "…"}

Two of those fields are easy to conflate. user_id records who said it and filters nothing. acl_owners decides who may see it and is enforced inside the query. Isolation between tenants is the key itself.

Recall

POST /api/memory/search
{
  "query": "what currency do we invoice in",
  "context": "handbook",        // optional: one shelf
  "limit": 20,                  // 1..100
  "identity": "user:maeve",     // who is asking; drives the gate
  "focus_matter": "matter:acme",       // optional: ONLY this compartment
  "min_grade": 0.3,                    // optional floor
  "grade_bands": ["decision", "fact"], // optional shelf inside the gate
  "grade_weight": 0.2,                 // 0..0.5: grade as a ranking signal
  "date_from": "2026-01-01", "date_to": "2026-06-30"   // facts dated in the window
}
→ {"query", "results": [{memory_id, content, score, created_at, occurred_at,
                          grade, grade_band, acl_matter, acl_classification, acl_owners,
                          outcome_helpful, outcome_harmful, metadata, …}], "total"}

Ranking is the vector score weighted by a bounded temporal factor: recent memory is favoured, but age is measured by activity, not by the calendar, so a thread that slept for a month does not come back stale. The gate, the lifecycle filter and the grade floor are all compiled into the same query; there is no post-filtering of results.

Grades

A grade (0 to 1) and a band (a label of your choosing: fact, decision, note, raw) say how much weight a memory carries. Grades are a value axis, not an access label: a search can floor on them, shelve on bands, or lean on them in ranking, and a memory can be regraded in place (POST /api/memory/memories/{id}/grade) with a ledger row holding the old and new grade. A consumer can ask chat to mark every source with its grade so the answer carries the weight of what it drew on (context.grade_view).

Documents

POST /api/documents/upload          (multipart)
file=@handbook.pdf  user_id=user:maeve  chunking_strategy=semantic_sections
title="Staff handbook"  matter=matter:acme  classification=1  owners=user:maeve
extract_facts=true  grade=0.7  grade_band=fact
→ 201 {document_id, filename, chunks_created, pages_processed, ocr_used, fact_extraction, …}

The platform extracts text (OCR when a PDF has none), chunks it, embeds the chunks and stores them with the document's labels and page numbers. With extract_facts on, each chunk also yields one-claim facts with a date where the passage supports one (fact_date, basis stated or inferred; a year that appears only inside a citation is never used). Chat answers cite the document, page and chunk. Retiring a document (DELETE /api/documents/{id}) closes its chunks and facts; reopening (POST /api/documents/{id}/reopen) brings the original points back, nothing re-embedded.

Close and supersede, never delete

The store's delete is a no-op by design. A finished memory is closed; a wrong one is superseded by a successor that inherits its labels unless told otherwise. Both leave the memory readable by id and out of retrieval, with a lifecycle event in an append-only ledger.

POST /api/memory/memories/{id}/close      {"reason": "done" | "obsolete" | "error" | "junk"}
POST /api/memory/memories/{id}/supersede  {"content": "corrected text", "reason": "..."}
GET  /api/memory/memories/{id}/lineage    the chain both ways, every hop gated

Physical erasure exists, but as a separate governed path with a plan, a permission and a receipt per memory; see erasure and the record.

What was believed on a date

GET /api/memory/as-of?t=2026-06-30T00:00:00Z&q=invoice+terms
GET /api/memory/as-of?t=2026-06-30T00:00:00Z&context=handbook      (everything the shelf held then)

The as-of read answers with what existed at T and had not been retired by then, each hit marked with its later_status. It is the one read that consults the lifecycle ledger instead of the live filter, and it is gated and audited like any other.

Session distillation

POST /api/memory/consolidate-session turns a conversation into a summary, an entity graph and one-claim facts, reconciled against what is already held. The platform also summarises idle sessions on its own, so a long-running agent's threads do not grow without bound. Reconciliation runs in propose mode: a new belief that refines or contradicts an existing one lands in a review queue, and the store does not change until someone ratifies (outcomes and learning).

The kit: a coding agent that remembers

Yohanun Guilds is the same API packaged for Claude Code, Codex and any MCP host. Each project gets a named agent with private memory; a guild carries shared knowledge to every agent you run. Install, connect, onboard a project:

pip install yohanun
yohanun init --api-key sile_... --owner "Your Name"
cd ~/dev/myapp
yohanun agent add myapp --matter project:myapp --project-dir . --wire

--wire adds two hooks: one at session start (where you left off, what is still open) and one on every prompt (up to three relevant memories as context, searched with your actual question). Daily use is four verbs, by you or by the agent:

yohanun store "picked pnpm over npm — workspace protocol" --type decision
yohanun search "why did we pick pnpm"
yohanun due                      # open tasks
yohanun close <memory_id>        # done: retired, never deleted
yohanun supersede <memory_id> "corrected fact"
yohanun consolidate              # session end

For other hosts, yohanun mcp serve exposes the same memory as MCP tools. The kit's README on PyPI is the full reference, including backfilling a project's past sessions into memory. The longer story is on the Guilds page.

Why this matters. Memory that keeps its history is what separates an estate from a cache: Memory for AI agents that keeps its history, and the measured comparison with mem0 in A mem0 alternative, with the numbers.

Get a key

Yohanun is in invited beta. Tell us what you are building and we send a key with a developer account; a memory-profile key for your own model, or a chat-profile key if you want the platform to run the model and meter it. There is no card and no self-serve sign-up.

Request an invite