Skip to content

Latest commit

 

History

History
305 lines (242 loc) · 17.7 KB

memory-and-learning.md

File metadata and controls

305 lines (242 loc) · 17.7 KB

Memory & Learning

Kiro Crew has persistent memory that survives across sessions. It remembers your preferences, project context, daily activity, and corrections you teach it.

Private member context

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.

Member database

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.

Memory Types

Preferences (preferences.md)

Your personal preferences — coding style, tools you prefer, communication style. Updated automatically by the consolidator after ~30 messages.

Projects (projects.md)

Active project context — what you're working on, key decisions, blockers. Updated alongside preferences.

Daily History (history/{date}.md)

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.

Lessons

Corrections and rules you teach Kiro Crew. Two ways to create:

  1. Explicit: say "remember to always use pytest" → saved immediately
  2. 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_scope path 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.

How instructions rank

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:

  1. The current user message. Every stored block says that stored inferences do not override the current user.
  2. Steering files and the agent's own prompt. The harness loads them as standing instructions; see Steering files.
  3. Preferences (preferences.md). Injected as rules: "Preferences in the user preference document remain rules."
  4. Lessons. Injected as retained rules, filtered to the session's repository and capped by the context budget. Lessons tagged with applies rank ahead of untagged ones; within that, ranking is by relevance, whatever the source.
  5. 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.

Memory Modes

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.

Teaching Kiro Crew

Just tell it naturally:

  • "Always use dark mode"
  • "Never use rm -rf without 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.

Workspaces

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.

Vector Memory

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.

Using an Ollama server

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 restart

memory.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_remote to true and give an https:// URL; a plain http:// 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> at memory.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_dim to set; set it and restart.
  • With ollama_http the bundled model is not downloaded at startup, and memory.embed_model_path is ignored.

Rebuilding vectors after a model change

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.

Consolidation

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.

Reading Memory Programmatically

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 json returns structured entries with path, updated_at, and content; --since YYYY-MM-DD limits history to days on or after that date.
  • kirocrew memory export --include-markdown — add a markdown collection 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.

Editing Memory

  • Dashboard: Overview → Memory tab → edit preferences.md or projects.md
  • Chat: ask Kiro Crew to remember or correct a fact through its memory tools