Kiro Crew has persistent memory that survives across sessions. It remembers your preferences, project context, daily activity, and corrections you teach it.
A member with Memory V2 receives its identity, permanent rules, current briefing, manual preference/project anchors, and admitted project guides when a conversation starts. Unchanged follow-up turns do not resend that complete snapshot. Changes refresh it once; a replacement also retires guides removed from the current source list. Resume, compaction and a new provider conversation restore it.
Rules, ownership and required source readability are checked on every turn, even when no snapshot is resent. Missing declared files or oversized required guides stop the turn rather than silently dropping instructions. Failed, cancelled or empty attempts do not count as delivery. Native-loaded persona/resources are not copied into the initial prompt again when their exact startup content is known. Manual, auto and file-matched steering are not promoted to always-on guidance. This does not erase text already retained in a conversation or change Global V1.
Memory V2 keeps each member's learned facts, rules, experiences, daily summaries, source history, revisions, text index and vectors in one SQLite database. A member's stable identity selects that database; renaming a member or changing its provider or project does not move learned memory. Manual persona, rules, briefing and project guides remain documents. Preference/project anchors are owner-managed for V2.
V2 recall does not update access timestamps or repair storage. Missing or damaged memory is reported without replacing it; manual member essentials remain usable. Backups include the SQLite database and manual preference/project anchors. Restore validates the same member identity and waits for live handles to close.
The file layouts and age tiers below describe Global V1 and legacy named V1. V2 retains full daily summaries and revisions in its database without age pruning or learned Markdown/JSONL copies. Its summaries, accepted facts, rules and source receipt publish atomically; retries do not duplicate an acknowledged source span.
Your personal preferences — coding style, tools you prefer, communication style. Updated automatically by the consolidator after ~30 messages.
Active project context — what you're working on, key decisions, blockers. Updated alongside preferences.
Conversation summaries organized by date. What a READ returns decays with age:
- Last 14 days: full detail (days 0–13)
- 14–60 days: first entry per day + count
- 61–180 days: date + entry count only
- 181–365 days: retained on disk, not returned by a read
- 365+ days: pruned automatically
The tiers above govern a dated READ (read_recent_history), not search: the
full-text index holds each history file's complete content, so memory_recall
can still surface a line from a day the dated read would have collapsed to a
count.
A new session carries none of these bodies either way. It carries a bounded index
of excerpts from the last three days (headings, bullets and each paragraph's
first line), and the body arrives only when memory_recall
asks for it.
Corrections and rules you teach Kiro Crew. Two ways to create:
- Explicit: say "remember to always use pytest" → saved immediately
- Implicit: correct Kiro Crew during conversation → extracted during consolidation
Member lessons live in the member's SQLite database. Global V1 also supports the
legacy lessons.jsonl fallback when vector memory is unavailable.
Lessons have two scopes:
- Global (default): shared across all workspaces
- Repository-scoped: an optional
repo_scopepath fragment restricts a lesson to sessions whose active project is inside that repository tree
Each lesson records its source, the writer that saved it: user_explicit for a
lesson saved on purpose through learn_add, the dashboard or kirocrew learn add,
consolidation for one extracted from a conversation. learn_list and the
Lessons table on the Memory page show it.
Steering, preferences, lessons and memory reach a session as separate blocks, and each block states how much weight it carries. When two of them disagree, the order is:
- The current user message. Every stored block says that stored inferences do not override the current user.
- Steering files and the agent's own prompt. The harness loads them as standing instructions; see Steering files.
- Preferences (
preferences.md). Injected as rules: "Preferences in the user preference document remain rules." - Lessons. Injected as retained rules, filtered to the session's repository
and capped by the context budget. Lessons tagged with
appliesrank ahead of untagged ones; within that, ranking is by relevance, whatever thesource. - Semantic memory, experience, the activity index and recent-session snippets. Reference data, not instructions.
Switches that change what is written or injected:
| Key | Writes | Injection |
|---|---|---|
memory.persistence_enabled: false |
No automatic writes | Stored memory and lessons withheld |
memory.writes_enabled: false |
No automatic writes | Unchanged |
memory.lesson_extraction_enabled: false |
No extracted lessons; other writes and learn_add unchanged |
Unchanged |
memory.kind_routing: "enforce" |
Consolidation skips a state fact; facts and events are written as before ("shadow" only logs; default "off" does neither) |
Unchanged |
memory.lesson_origin_gate: "enforce" |
A lesson from turns no person sent is saved as an on_topic finding, never a standing rule ("shadow" only counts; default "off" does neither) |
Unchanged |
memory.lesson_tier_policy: "enforce" |
A new consolidation lesson is a standing rule only when your own words in a message back it; otherwise it is saved as an on_topic finding ("shadow" only counts; default "off" does neither) |
Unchanged |
memory.lesson_fold: "enforce" |
Unchanged | A rule that repeats another one takes no room in the rule block; the block says how many were folded, learn_list shows all, and rules you taught are never folded ("shadow" only records what would fold; default "off" does neither) |
memory.rule_authority_order: "enforce" |
Unchanged | Rules saved as yours (learn_add, dashboard, CLI) come first in the rule block, then inferred rules ("shadow" only records what would change; default "off" does neither) |
memory.member_lesson_dedup: "enforce" |
A private store skips a lesson that copies a stored one, and retires a new near-copy before a dashboard turn sees it (turning it off restores them); lessons you taught are never folded ("shadow" only counts; default "off" does neither) |
Unchanged |
memory.relevance_rule: "enforce" |
Unchanged | Past findings, task facts and project and history sections join a new session only when they share a word of 3 or more letters, or a two-character Chinese or Japanese pair, with your first message; a fact also needs the private store's evidence check. The rule block is unchanged ("shadow" only records what would change; default "off" does neither) |
memory.dream: "propose" |
While no chat runs, an offline pass lists copies, near-copies, work status and old untagged rules it would clean up; read the list with kirocrew memory dream list. Nothing is applied, and lessons you taught are never proposed for change |
Unchanged |
memory.inject_memory: false |
Unchanged | Stored memory block withheld |
memory.inject_lessons: false |
Unchanged | Lessons and user-profile blocks withheld |
Incognito sessions still read stored memory but write none, and Temporary sessions neither read nor write it, whatever these keys say. The keys apply to every surface (dashboard, channels, cron, sub-agents) at once, where a memory mode is chosen per session.
Each session can operate in one of three memory modes:
| Mode | Reads Memory | Writes Memory | Consolidates | Use Case |
|---|---|---|---|---|
| Persistent (factory default) | ✅ | ✅ | ✅ | Normal work |
| Incognito | ✅ | ❌ | ❌ | Sensitive tasks — reads context but blocks learn_add and consolidation |
| Temporary | ❌ | ❌ | ❌ | Isolated experiments — no memory interaction at all |
For new dashboard chats, choose the default under Settings → Chat → Sessions →
Default Memory Mode. The choice is stored as
dashboard.default_memory_mode. An explicit Incognito or Temporary choice still
wins for that chat. App-owned chats, messaging channels, cron jobs, and direct API
callers keep their own mode selection and do not inherit this dashboard preference.
If config.json or its dashboard section cannot be read, new chats fail closed
to Temporary until the file is fixed and the gateway restarts.
Set via the dashboard Welcome view (ghost button), the mode icon in the chat
header, Slack (!incognito / !temporary prefix), or Telegram (/incognito /
/temporary). Telegram spells them as commands because it has a command grammar;
the modes, the guarantees and the durability are the same on both channels, and
both accept a question after the modifier to mark the conversation and answer in
one message. The gateway keeps one small record per private conversation and
retains at most 10,000 of them; if that limit is ever reached, a modifier on a
conversation that is not yet private is refused with a message saying so, and the
message it was attached to is NOT processed -- it is never run with the mode
silently dropped, and no existing private conversation is forgotten to make room.
Conversations already private keep their mode and can still be tightened.
Every dashboard mode keeps its chat history. An Incognito or Temporary dashboard
chat is saved under Older Sessions (the footer at the bottom of the Sessions
list) exactly like a Persistent one, so you can reopen it -- before or after a
gateway restart -- to look up a question you asked or a command you ran.
Channel-origin Incognito and Temporary chats are still not written to session
history. What the two restricted modes withhold is learning FROM the chat: nothing
in it is consolidated
into memory, no lesson is written (including lesson deletion), no session summary
is generated, and it is never written into a workflow or task snapshot. Incognito
still reads your existing memory into the chat; Temporary additionally blocks
memory reads, including learned lessons and memory preference/history injection,
so it starts from a blank slate. Manual member persona, rules and project context
remain available without opening memory. The agent's own chat-history tools
(search_chat_history, get_chat_session, list_sessions) never return an
Incognito or Temporary chat, so what you said there does not reach another
session.
Just tell it naturally:
- "Always use dark mode"
- "Never use
rm -rfwithout confirmation" - "Remember that our team uses pytest-asyncio strict mode"
- "Prefer ruff over flake8 for linting"
Kiro Crew saves these via the learn_add MCP tool. View them with learn_list
or on the dashboard Overview → Lessons tab.
To change whether a saved lesson applies in every session (always) or only
when the task is about it (on_topic), ask Kiro Crew: the learn_update tool
changes that one setting in place and keeps the lesson's wording and history.
Markdown memory is workspace-scoped: each workspace stores memory/preferences.md, memory/projects.md, and memory/history/{date}.md beneath its workspace directory. Legacy JSONL lessons are also workspace-local; vector memory defaults to memory.db under the Kiro Crew data directory. Lessons are global unless their optional repo_scope restricts them to a project tree.
The vector-memory subsystem is always enabled:
- Semantic memory: structured key-value store with confidence scoring
- Episodic memory: conversation fragments searchable by meaning
- Embeddings: Qwen3-Embedding-0.6B running in-process by default (no Ollama or any other server to install — the runtime is bundled; no data leaves your machine). An Ollama server can serve them instead; see Using an Ollama server.
The embedding model (~610MB) downloads automatically in the background the
first time the gateway starts, over HTTPS from the Kiro Crew CDN — failed
downloads retry automatically with backoff, and again on the next gateway
start; the Memory tab shows download progress. Once downloaded, the model
loads in the background too, so nothing ever waits on it. While the model is
downloading or loading, memory falls back to keyword search and switches to
semantic search as soon as the model is ready — no restart needed. Requires
~610MB disk for the model and ~700MB RAM once the model is loaded. The model
loads when something first needs a vector and unloads after 60 minutes without
one (memory.embedding_idle_evict_secs, 0 keeps it loaded); the first search
after that waits a few seconds for it to load again.
The bundled model is qwen3-embedding:0.6b (1024 dimensions). KIROCREW_EMBED_MODEL_URL overrides memory.embed_model_url for the download URL; KIROCREW_EMBED_MODEL_PATH or memory.embed_model_path selects a local GGUF instead of the bundled model.
A machine short on RAM, or one that already runs Ollama on a GPU, can embed through an Ollama server instead of the bundled model:
kirocrew config set memory.embedding_provider ollama_http
kirocrew config set memory.ollama_model nomic-embed-text
kirocrew config set memory.embedding_dim 768 # the model's output width
kirocrew restartmemory.ollama_url defaults to http://127.0.0.1:11434. The server must list
the model in /api/tags (ollama pull nomic-embed-text). Kiro Crew calls
/api/embed with truncate on, so the server cuts an input longer than the
model's context instead of failing it.
- Your text goes to the server. A loopback URL keeps it on this machine. To
use another host, set
memory.ollama_allow_remotetotrueand give anhttps://URL; a plainhttp://remote host is refused. An SSH tunnel to a loopback port is the simplest way to reach a server elsewhere. - Switching re-embeds everything. The vector space is
ollama:<model>atmemory.embedding_dim, so switching provider or model regenerates every stored embedding in the background, the same as a model change in Settings. Moving the server to another URL does not. - When the server is down, memory falls back to keyword search, and picks vectors up again once the server answers. The log warns once per outage.
- The width must match. If the model returns vectors of another width,
embedding stops and the log names the
memory.embedding_dimto set; set it and restart. - With
ollama_httpthe bundled model is not downloaded at startup, andmemory.embed_model_pathis ignored.
In Memory settings, use the warning's link to Embedding Model, then apply the model again. Applying the same file is supported. This rebuilds vectors even when an earlier apply missed a closed member store. Saved memories are retained; keyword search remains available while vectors are rebuilt.
The request survives a gateway restart. Open stores are repaired first. Closed or unavailable stores are reported as deferred and handled by explicit maintenance. A loaded model does not mean every store has finished rebuilding. An unknown repair scope means some stores could not be checked, not that they are empty or repaired.
Known setup warnings and errors follow the dashboard language. Paths and system error details remain exact. Older servers and unknown status codes retain their original diagnostic text.
Kiro Crew automatically consolidates conversations into memory:
- Preferences/projects: every 30 messages per session
- Daily history + lessons: after 3 hours idle per session
No manual action needed — it happens in the background. The manual trigger
(Overview → Memory tab → Summarize now, or POST /api/memory/consolidate) refuses
an Incognito or Temporary session with a 403 no matter which session triggers it,
and the background paths skip those sessions — including a Slack or Telegram
thread marked !incognito / !temporary, whose mode is recorded in the thread's
own transcript header so it holds across restarts — so the mode table above holds
for every route. Summarize now reports those sessions as skipped, not failed.
A real failure shows as an error notice with the server's reply and a link to
the affected session; press Summarize now again to retry. The button writes
summaries into memory and leaves your conversations untouched.
The markdown layer is readable through the CLI, so consumers depend on an interface rather than the on-disk layout:
kirocrew memory show [preferences|projects|history]— print the markdown layer (all three when no target is given).--format jsonreturns structured entries withpath,updated_at, andcontent;--since YYYY-MM-DDlimits history to days on or after that date.kirocrew memory export --include-markdown— add amarkdowncollection to the JSON export. Without the flag the export shape is unchanged.
Both run non-interactively (no TTY or editor needed), so they work from scheduled jobs.
- Dashboard: Overview → Memory tab → edit preferences.md or projects.md
- Chat: ask Kiro Crew to remember or correct a fact through its memory tools