Hall memory
What ivar records from each session, the pages your agent writes under docs/memory, how it finds them again, the review before delivery, and handoffs between sessions.
The hall remembers in two layers. ivar records what happens in each session
into .ivar/memory.db, a local SQLite file. Your agent writes what is worth
keeping as markdown pages under docs/memory/, which you commit with the hall.
The same MCP server that serves the code graph serves both
to the agent. Nothing leaves the machine.
What gets recorded
Each session records four events: session.started, session.prompted,
session.tool and session.ended. A provider hook runs
ivar memory capture, which redacts known secret patterns and the values of
the hall's .env before the event reaches disk, then appends one line to a
spool under .ivar/spool/memory/. The ivar graph mcp leader drains the spool
into .ivar/memory.db within about a quarter of a second. The hook never opens
the database and always exits 0, so it cannot block a prompt.
A provider records only the events its hooks expose:
- OpenCode has no session end, so no
session.endedis recorded for it. - T3 records the session end when you archive the thread, not when a turn finishes. An idle open thread has no end yet.
The binary also records delivery events into the same database: push, pull request, rebase, integrate, merge, cleanup, close and delete. Pages written through the memory tools and each memory review are recorded too.
Capture is on by default. To turn it off, set the key in ivar.json and
rewrite the provider hooks:
{
"memory": { "capture": false }
}ivar syncThe ivar graph mcp leader deletes session events 30 days after the session's
last observation, at start and then every hour. Delivery, memory, handoff and
message events are kept. ivar memory status shows the counts per event, the
spool, the last drain and the retention sweep.
Pages
A page is a markdown file at docs/memory/<kind>/<slug>.md. The durable kinds
are product, update, decision, gotcha, procedure and concept.
product and update pages carry an NNN- number prefix. Pages are files in
the hall, so they are committed, reviewed and shared like any other file.
The memory tools write files and never commit. A page your agent writes stays
uncommitted until you commit it, and ivar doctor reports it as
memory.page_uncommitted until then.
ivar also writes one session page per provider conversation under
.ivar/memory/session/, from the template and its observations, with no model
call. A conversation gets its page once it ends, after 30 minutes without
observations, or on ivar session stop. These pages are not committed and
expire 30 days after the conversation's last observation; pinned: true keeps
one longer.
.ivar/memory.db holds an index of the pages. It follows the files on disk,
committed or not, and refreshes on ivar memory query, ivar memory status,
ivar sync and every 5 seconds in the MCP leader. Rebuild it by hand, or check
every page against the page rules:
ivar memory reindex
ivar memory lintlint exits non-zero when a page breaks a rule. The
reference lists the front matter fields and the
rules.
Finding them again
Your agent searches with the memory_query tool. From a terminal, the same
search runs as:
ivar memory query "release lanes" --kind decision --kind gotcha--kind, --tier and --tag narrow the results, and --limit caps them
(10 by default, 20 at most). Expired pages stay hidden unless you pass
--include-expired.
A page cites code as anchors: the code spans and links in its body that resolve to a file or symbol in the graph. Each hit lists its anchors, broken ones first, so the agent sees which pages still point at real code.
graph_explore works the other way round. An answer ends with a
Related memory section that names up to 3 durable pages anchored to the
files it returns. The agent reading code learns that a decision or a gotcha
covers it, without asking.
When no page matches and no filter is set, the retained observations answer in a separate section. A query with a filter never falls back.
Writing during a feature, reviewing before delivery
During a feature, the agent writes a page once an insight is settled, not at the end:
- a
decisionwhen an option is chosen, with the alternatives and why; - a
gotchawhen a trap is found, with its symptom, cause and fix; - a
productpage for what a delivered capability does today; - an
updatepage for what this delivery changed and what stayed open.
Before delivery, the agent calls memory_review. It returns three lists:
- Written: the pages written in the feature.
- Gaps: a failed tool with no
gotcha, noupdatepage, or an Analysis approved without amemory_query. - Stale: durable pages anchored to files the feature's diff changed, or with a broken anchor.
The agent gives each stale page a verdict, updated or still_valid, and
confirms. The confirmation records the review. Gaps never block it.
ivar memory review <feature> prints the same report from a terminal and
records nothing.
ivar feature deliver refuses to apply without that review, with
deliver.memory_not_reviewed. When you have a reason to deliver without it,
say so:
ivar feature deliver <feature> --fingerprint <fp> --skip-memory-review "docs-only change"The skip lifts only the memory blocker, records its reason, and never counts
for a later delivery. ivar feature cleanup warns when the review is missing
but does not refuse; like any warning, it makes the CLI exit 1.
Commit what the review wrote
A page updated after a stale verdict is a file in docs/memory/ like any
other. Commit it with the hall before you deliver.
Handoffs and messages
A session can leave a handoff for the next one: a summary, pending tasks,
open decisions and changed files. The agent opens one with
memory_handoff_begin; from a terminal:
ivar memory handoff begin --summary "Lanes split; rollback guard left" --pending "Add the per-target guard"
ivar memory handoff list
ivar memory handoff cancel <id>A handoff goes to the feature's queue, or to the hall's outside a feature. A session sees its feature's queue and the hall's. Accepting a handoff is MCP-only, and only one session wins the claim.
On Claude Code, T3 and OMP, ivar memory brief runs when a session starts and
shows up to five open handoffs and the count of pending messages, framed as
untrusted historical data. OpenCode has no brief because its plugins cannot
inject context at session start, so its agent calls memory_handoff_list and
memory_message_list instead.
Messages carry a note from one session to another, addressed to a provider or
a session, through memory_message_send and memory_message_pop. They are
MCP-only.
Handoffs and messages expire after memory.handoff_ttl_days days, 7 by
default:
{
"memory": { "handoff_ttl_days": 14 }
}ivar session stop warns with session.handoff_missing when the session
worked and left no handoff. The stop still goes through.
Limits
- Capture records only what a provider's hooks expose. OpenCode reports every tool as succeeded, so no OpenCode tool counts as a failure and the "failed tool without a gotcha" gap never fires for it.
- Redaction matches known secret patterns. A secret in a shape no pattern matches is stored as written.
- A session spool is capped at 8 MiB, which bounds the disk one session
can fill while no drain runs; past the cap events are dropped and
ivar doctorreportsmemory.spool_dropped. - The retention sweep runs in the
ivar graph mcpleader. A hall with no leader running never sweeps, andivar doctorreportsmemory.retention_overdueafter 37 days. - A
sessionpage is regenerated whenever its conversation gets new observations, so hand edits to its body are lost. - A stale page is found only through its anchors. A page that cites changed code in prose without an anchor is not listed.
- The MCP server runs outside the session write guard. The write tools confine
themselves to
docs/memory/<kind>/, and approving the server in Claude Code approves the write tools along with the read tools. - An
ivarthat predates thememorykeys ofivar.jsoncannot read a hall that sets them.
The rest of ivar's limits are in Limitations.
Every ivar memory verb, every memory tool, the page front matter and the
doctor findings are in the memory reference.