Browse the documentation

bmad-plus mem

Recall past decisions and events, journal what an agent did, reinforce a pattern with reward signals and tie lessons to accepted Nexus work. Flags, files, exit codes, output and errors.

On this page
  1. Synopsis
  2. What it reads and writes
  3. The five actions
  4. Exit codes
  5. Reading the output
  6. Errors and what to do
  7. Examples

The memory pack stores what a project has learned in Markdown files: decisions, lessons and patterns. bmad-plus mem is the small, deterministic toolbox that lets any assistant use those files the same way, whether it runs in Claude Code, Gemini CLI, Codex CLI, Cursor, OpenCode, Aider or Antigravity. It has five actions: recall finds relevant past notes and events, write appends an event to a journal, reinforce raises or lowers the score of a pattern, observe ties a lesson to work that was independently verified and accepted, and outcomes lists those ties. It needs no terminal prompts and never calls a model, so an agent can run it and parse the result. This page is for anyone who wants an agent to remember with evidence, and for people who audit that memory.

Synopsis

In your project terminal
npx bmad-plus mem recall <query...> [--scope project|portfolio] [--portfolio <path>] [--limit <n>] [--ranking lexical|evidence] [--context-scope <paths>] [--json]
npx bmad-plus mem write --agent <name> [--cli <name>] [--model <id>] [--task <text>] [--outcome <outcome>] [--eval <0-1>] [--accept <bool>] [--ci <result>] [--json]
npx bmad-plus mem reinforce --pattern <id> [--eval <0-1>] [--accept <bool>] [--ci <result>] [--evidence <ids>] [--json]
npx bmad-plus mem observe --input <file> [--json]
npx bmad-plus mem outcomes [--json]

Arguments and flags of mem
FlagArgumentDefaultWhat it does
<action>recall, write, reinforce, observe, outcomesrequiredWhich action to run.
[query...]wordsnoneThe search text of recall. Several words are joined with spaces.
-d, --directory <path>pathcurrent directoryProject folder holding .agents/memory/ and .bmad/memory/.
--scope <scope>project or portfolioprojectrecall only. portfolio also searches the memory folder of a portfolio brain.
--portfolio <path>pathnonePortfolio brain folder; its memory/ subfolder is searched with --scope portfolio.
--limit <n>number8recall: how many matches to keep.
--ranking <mode>lexical or evidencelexicalrecall: evidence boosts notes backed by an accepted outcome. Project scope only.
--context-scope <paths>comma-separated relative pathsnoneRequired with --ranking evidence: the project paths the question is about.
--input <file>project-relative pathnoneobserve: JSON file describing the outcome.
--agent <name>textnonewrite: the agent that produced the event. Required.
--cli <name>textnonewrite: the assistant that drove it (for example claude-code, gemini-cli, codex-cli, cursor, opencode, aider, antigravity). Stored as given.
--model <id>textnonewrite: model identifier, stored as given.
--task <text>textemptywrite: what was attempted.
--outcome <outcome>success, failure, partial, abandonednonewrite: result of the attempt.
--pattern <id>textnonereinforce: the pattern heading in patterns.md. Required.
--eval <score>number from 0 to 1noneReward signal: score of an evaluation suite.
--accept <bool>true, false (or yes, no), or a number from 0 to 1noneReward signal: whether the person accepted the result.
--ci <result>pass, fail, or a number from 0 to 1noneReward signal: continuous-integration outcome.
--evidence <ids>comma-separated event idsnonereinforce: journal events backing the reinforcement; copied into a promotion proposal.
--jsonnoneoffPrint JSON instead of text. Errors become {"error": "..."}.

What it reads and writes

Files used by mem
FileRoleWritten by
.bmad/memory/journal.ndjsonAppend-only journal of events, one JSON object per line.write
.bmad/memory/pattern-scores.jsonScore of each reinforced pattern (an Elo rating and a Beta distribution).reinforce
.bmad/memory/promotions.ndjsonPromotion proposals. Always status PROPOSED.reinforce
.bmad/memory/outcomes.ndjsonReceipts that tie a memory section to accepted Nexus work.observe
.bmad/memory/writer.lockShort-lived lock that serialises writers.every writing action
.agents/memory/ and .bmad/memory/ decisions.md, lessons.md, patterns.mdHuman notes, split into sections at each ### heading. Read only.you and your agents

Every store is limited to 2 MiB, the outcome store to 1000 receipts, and paths must stay inside the project without following symbolic links. A damaged line in the journal is skipped when reading, never fatal.

The five actions

recall

Searches the journal events and the ### sections of decisions.md, lessons.md and patterns.md, in both .agents/memory/ and .bmad/memory/. Ranking is lexical: words of the query found in an entry, with diminishing returns for repeats, a bonus for how much of the query matched and a length normalisation. Journal events lose half their weight every 30 days. No search service or Python is needed. With --scope portfolio --portfolio <path> the memory/ folder of a portfolio brain is searched too. With --ranking evidence (project scope only, and --context-scope is then mandatory) a note that has a valid accepted outcome receipt for the given paths has its score multiplied by 1.25; a note whose receipts are all stale, superseded or contradicted is dropped instead of silently falling back; notes without any receipt stay, marked unverified.

write

Appends one event to .bmad/memory/journal.ndjson with the time of the call, the agent, the optional assistant, model, task, outcome and the reward signals you passed. The event id is derived from the time, the agent and the task, so it is reproducible. Nothing in the event is a measurement made by BMAD+: the signals are what the caller reports.

reinforce

Folds the signals into one reward between 0 and 1: --eval weighs 0.5, --accept 0.3 and --ci 0.2, and signals you leave out are ignored with the weights renormalised, so a CI-only call still gives a usable reward. The reward moves the pattern’s Elo rating (starting at 1200, K factor 32) and its Beta distribution (starting at 1 and 1, with decay so old evidence fades). When the Beta mean reaches 0.7 over at least 3 updates, a promotion from candidate to validated is written to promotions.ndjson, always with status PROPOSED. Applying it needs a human or Shield approval that this command can never record. The result says evidenceStatus: self-reported and rankingEligible: false: a reinforcement is the caller’s claim, not accepted evidence.

observe and outcomes

observe is the only way a lesson gets evidence. It reads a JSON file and writes a receipt only when the Nexus task it names is accepted, its latest attempt completed, its independent verification passed and its evidence still current, and only when the memory section it names exists exactly once. The receipt records the hash of that section and the task, and states lessonCausality: unmeasured: BMAD+ does not claim the lesson caused the success. outcomes re-checks every receipt against today’s files and prints accepted-current or the reason it no longer counts: superseded, contradictory, stale-memory-section (the section text changed), stale-outcome-source (the Nexus task changed) or unavailable-or-ineligible-source.

Input file of observe
{
  "runId": "<nexus run id>",
  "taskId": "<accepted task id>",
  "memory": { "file": ".agents/memory/lessons.md", "heading": "<exact ### heading>" },
  "scope": ["src/auth"],
  "interpretation": "Why this accepted work supports the lesson.",
  "supersedes": [],
  "contradicts": []
}

memory.file must be decisions.md, lessons.md or patterns.md under .agents/memory/ or .bmad/memory/. scope lists 1 to 30 relative paths and must stay inside the scope of the accepted task. supersedes and contradicts name earlier receipt ids that overlap the same scope; no id can be in both. A task attempt can produce only one receipt.

Exit codes

Exit codes of mem
CodeMeaning
0The action ran. A recall without matches is still 0.
1Unknown action, missing required flag, invalid value, locked store or any other failure. With --json the error is printed on standard output as {"error": "..."}; otherwise on the error stream as mem <action>: <message>.

Reading the output

recall (scores and note illustrative)Simulated
npx bmad-plus mem recall auth strategy
mem recall: 1 match(es) for "auth strategy" (scope: project)
  1. [0.412] note decisions.md § Auth strategy
     Use short-lived sessions with server-side revocation.

Illustrative transcript, not captured from a real run. Source: tools/cli/commands/memory-journal-cmd.js (runRecall message templates); scores and text are made up

write, then reinforce (computed from the formulas, ids illustrative)Simulated
npx bmad-plus mem write --agent forge --cli claude-code --task "Add login rate limit" --outcome success --ci pass
mem write: event 3f9a1c7b02de appended (2026-10-18T09:30:00.000Z)
  agent=forge cli=claude-code model=- outcome=success
  task: Add login rate limit
npx bmad-plus mem reinforce --pattern "Rate limit on auth routes" --accept true --ci pass
mem reinforce: pattern "Rate limit on auth routes"
  reward   1.000 (from {"acceptance":true,"ci":"pass"})
  elo      1200.0 -> 1216.0
  mean     0.667 (alpha=2.00, beta=1.00, updates=1)
  promotion: none proposed (needs mean >= 0.7 and >= 3 updates)

Illustrative transcript, not captured from a real run. Source: tools/cli/commands/memory-journal-cmd.js (runWrite, runReinforce) and lib/memory-journal.js (computeReward, updatePatternScore); event id and time are made up

Errors and what to do

Messages printed by mem
MessageCauseWhat to do
mem: unknown action '<x>' — expected recall | write | reinforce | observe | outcomesThe first word is not one of the five actions.Fix the action name.
mem recall: recall: query must be a non-empty stringrecall was called without words to search.Add the search words after recall.
mem recall: Evidence ranking supports project-local lexical recall only.--ranking evidence combined with --scope portfolio.Use project scope for evidence ranking.
mem recall: An explicit non-empty project scope is required.--ranking evidence without --context-scope.Pass --context-scope src/auth,src/session (1 to 30 relative paths).
mem write: appendEvent: event.agent is requiredwrite without --agent.Pass --agent <name>.
mem write: appendEvent: event.outcome must be one of success|failure|partial|abandonedInvalid --outcome.Use one of the four values.
mem reinforce: mem reinforce: --pattern <id> is required (the pattern heading in patterns.md)reinforce without --pattern.Pass the exact ### heading of the pattern.
mem observe: Outcome source is not an accepted task with current independently verified evidence.The Nexus task is not accepted, its verification did not pass, or its evidence is stale.Finish nexus verify and nexus accept first, then observe again.
mem observe: Memory heading must identify exactly one section.The heading is absent or appears twice in the file.Use the exact, unique ### heading text.
mem observe: Duplicate outcome: this task attempt already supplied a receipt.A receipt exists for this run, task and attempt.Nothing to do; use supersedes on a later attempt if the lesson changed.
mem observe: Outcome scope exceeds the accepted task scope.A scope path is outside the task’s declared scope.Narrow scope to paths the task owns.
... Memory writer lock is occupied. Inspect writer.lock and its owner; do not remove a live lock.Another process holds .bmad/memory/writer.lock for more than about two seconds, or a crash left it behind.Wait for the other writer. Remove the file only when you are sure no mem process is running.
... Memory store is full; archive it explicitly before adding records.A store reached 2 MiB.Archive or trim the file by hand, then retry.

Examples

Remember a past decision

Before touching authentication you want the agent to check what the project already decided.

In your AI assistant
Run `bmad-plus mem recall auth strategy --json` and quote the best three matches with their source file and section.

What you should get The command prints a JSON object with query, scope, ranking, count and a results array sorted by score. Each result is either a note (with source such as decisions.md, ref set to the ### heading and the section text) or an event from the journal. With no match, count is 0 and the exit code is still 0.

Journal a result and reinforce a pattern

A change was accepted and CI is green. You want the memory to record that and nudge the pattern that guided it.

In your AI assistant
Write a journal event for agent forge, task "Add login rate limit", outcome success, CI pass, then reinforce the pattern "Rate limit on auth routes" with acceptance true and CI pass.

What you should get mem write appends one line to .bmad/memory/journal.ndjson and prints its id. mem reinforce computes a reward of 1.000 (acceptance 0.3 and CI 0.2, renormalised), moves the pattern’s Elo from 1200.0 to 1216.0 on its first update, and shows a mean of 0.667. No promotion is proposed until the mean reaches 0.7 over at least 3 updates, and a proposal is only ever stored as PROPOSED.

Tie a lesson to accepted work

A Nexus task that adds a rate limit has been verified and accepted. You want the matching lesson to carry that evidence.

In your AI assistant
Write the outcome file for the accepted Nexus task T-12 of run <run id>, attached to the lesson "Rate limit on auth routes" in .agents/memory/lessons.md with scope src/auth, then run `bmad-plus mem observe --input` on it and `bmad-plus mem outcomes`.

What you should get mem observe prints mem observe: <receipt id> recorded; lesson causality remains unmeasured. and appends the receipt to .bmad/memory/outcomes.ndjson. mem outcomes then prints <receipt id>: accepted-current. If the task is not accepted, the section is missing or ambiguous, or the scope leaves the task’s scope, observe refuses with the message listed in the errors table and writes nothing.