Permanent, local memory for AI coding agents.
OptMem gives an agent continuity across sessions, compaction, models, and vendors. Memories are local plain text records, immutable by default: one focused store per project, plus one small global store for facts that follow you everywhere. There is no account, server, background daemon, or required Python package.
This fork builds on VictorTaelin/OptMem and adds project-scoped memory, native Windows support, optional FFF recall, optional QMD semantic recall, and a polished agent/install workflow. See the changelog for release history.
Everything reads and extends an earlier store in place — no migration.
- Memories can be corrected. Amend or retract anything — even history that has already been compressed — without losing what was said before.
- Search is forgiving. Recall survives typos and can optionally match by meaning, not just exact words.
- Every project gets its own memory. Wake up in a repo knowing that repo; what is true everywhere follows you everywhere.
- Parallel sessions stay distinguishable. Each entry names the session that wrote it, so an agent knows what it saw firsthand and what it heard.
- Writing never becomes a fight. Over-long entries say exactly what to cut — or trim themselves — and an entry can carry the day or moment something actually happened.
- It bends to you. Entry length, reading budget, and merge size are per-store settings, and your own commands can run before a memory is written or over what is shown.
- It fits agent harnesses. Waking never overflows a tool's output window, and it says what was left out.
- History is portable and safe. Back up, restore, permanently erase something sensitive, and verify every record on demand.
- Setup is one command. It teaches your agent files, diagnoses itself, and upgrades in place.
- Windows is first-class. Installed, locked, and completed natively in PowerShell.
Prerequisite: Python 3.7 or newer. FFF-powered fuzzy recall is optional and requires Python 3.10 or newer. QMD-powered semantic recall is separately optional and requires Node.js 22 or newer only when enabled.
curl -fsSL https://raw.githubusercontent.com/doeixd/OptMem/main/install.sh | shirm https://raw.githubusercontent.com/doeixd/OptMem/main/install.ps1 | iexThe installer validates the download, installs the tool under ~/.optmem,
adds the memo command to your user PATH, registers completion for your
shell, and creates the global store without touching existing memories. It
then prints a block between
BEGIN OPTMEM AGENT INSTRUCTIONS and
END OPTMEM AGENT INSTRUCTIONS. Open a new Unix shell after installation;
the PowerShell installer updates the current session immediately.
From the project you want to connect, teach your agent how to use the memo
CLI, then verify the automatic project scope:
cd /path/to/project
memo setupOn Windows:
Set-Location C:\path\to\project
memo setupmemo setup adds a managed OptMem instruction block to AGENTS.md and
CLAUDE.md when those files exist. The block explains how the agent should
use the CLI: when to wake memory, what belongs in a note, how project and
global scopes differ, and how to recall and compress memories. Missing files
are skipped by default; use memo setup --create to explicitly create them.
Existing files keep all of their other content. It is safe to run setup again:
current blocks are left byte-for-byte unchanged and older managed blocks are
updated in place.
To target another existing instruction file, pass it explicitly:
memo setup path/to/agent-rules.mdAdd --create when that explicit file does not exist yet. --no-create is
also available when a script should state the safe default explicitly.
If you prefer manual setup, copy the block printed by the installer into your agent's persistent instruction file. Existing hand-copied blocks are detected and are never duplicated.
Start a new agent session inside the project after connecting the files. Generated agent instructions still use the full executable path, so they work even before a new shell picks up PATH changes.
setup manages instruction files only; it does not create or select a memory
store. Scope is detected when memo runs. memo scope is a read-only preview
of the project identity, selected store, and reason for the selection.
Review the installer before running it
Linux/macOS:
curl -fsSLo install-optmem.sh https://raw.githubusercontent.com/doeixd/OptMem/main/install.sh
less install-optmem.sh
sh install-optmem.shWindows PowerShell:
irm https://raw.githubusercontent.com/doeixd/OptMem/main/install.ps1 -OutFile install-optmem.ps1
Get-Content .\install-optmem.ps1
powershell -ExecutionPolicy Bypass -File .\install-optmem.ps1Once the generated block is in the agent's instructions, normal operation is automatic:
- At session start, the agent runs
memo wakeand reads global context followed by this project's context. - During work, it records durable decisions and discoveries with
memo note "...". - When an earlier memory changes, it uses
memo amendormemo retractinstead of silently contradicting history. - If a note requests a compression, the agent completes that
memo napbefore continuing. - When older information is needed, the agent uses exact or fuzzy
recall, optional semantic recall, thenzoomto inspect a summary in more detail.
Good project memory:
The API client retries 429 responses with capped exponential backoff.
Good global memory:
The user prefers concise status updates and PowerShell examples.
Do not record temporary progress, guesses, secrets, or facts already captured. See AGENT_SETUP.md for setup patterns, a first-session walkthrough, and guidance for subagents.
| Scope | How to address it | What belongs there |
|---|---|---|
| Current project | memo note "..." |
Architecture, commands, decisions, failed approaches, repository-specific preferences |
| Global | memo --global note "..." |
User preferences, machine/tooling facts, durable information true across unrelated repositories |
| Explicit override | Set MEMORY_DIR |
Advanced use: pin every command to one chosen store and bypass project/global scoping |
Each store has an append-first raw log and a rebuildable binary tree of lossy
summaries. wake reads a bounded frontier with coarser summaries for older
history and finer detail toward the present; recall searches the full raw
log, while zoom opens a summary toward the entries beneath it. Compression
makes startup context smaller—it never deletes the raw memories.
Raw memories have stable #IDs, and later memories may cite those IDs to
anchor durable facts or decisions. Corrections are later events: amend
appends a replacement and retract appends that an older claim is no longer
authoritative. Only explicit user-directed redaction rewrites a payload.
When explicitly enabled for a scope, QMD gets a disposable Markdown
projection of the same raw log in fixed 16-memory segments. QMD chooses
relevant segments, but OptMem rereads the selected stable #IDs from
LOG.txt before displaying them. QMD never writes memories and does not
participate in note, nap, or wake.
memo wake is special: without MEMORY_DIR, it reads global memory first and
project memory second. Other commands target only one scope. Put --global
before the command—not after it.
Hosted Git projects use their full host/namespace/repository identity, so
worktrees and differently named checkouts share memory while different hosts
and deep GitLab-style namespaces remain isolated. OptMem prefers origin,
then the current branch's tracked remote, then a sole usable remote. Set
OPTMEM_REMOTE=<name> when a multi-remote checkout needs an explicit choice.
Without a usable remote, OptMem uses the Git root or current directory. On
first memory use it writes a tiny stable identity marker inside .git for a
Git checkout, or .optmem-scope for a non-Git directory. That lets the project
keep its memory when moved or renamed, including across filesystems. Read-only
commands such as scope and doctor never create the marker or a store.
| Command | Purpose |
|---|---|
memo version / memo --version |
print the installed OptMem release |
memo init |
create the global memory and print the current agent instructions |
memo setup [--create|--no-create] [FILE ...] |
teach agents to use the memo CLI by updating existing instruction files; defaults to AGENTS.md and CLAUDE.md, with creation opt-in |
memo completion <shell> |
print completion for Bash, Zsh, Fish, or PowerShell |
memo upgrade |
install the latest GitHub release, validate it, and refresh PATH/completion setup |
memo uninstall |
remove the command and shell integration while preserving every memory |
memo scope |
show the automatically detected project, store, remote/path source, and compatibility layout without creating anything |
memo doctor [--deep] |
explain setup and scope; optionally verify the raw log, tree, lifecycle references, and QMD projection state |
memo qmd enable |
explicitly enable optional QMD semantic recall for this scope |
memo qmd help |
explain the integration’s commands, isolation, and lazy behavior |
memo qmd status |
inspect the QMD executable, projection, collection, and embeddings |
memo qmd sync |
update the projection, index, and embeddings before they are needed |
memo qmd rebuild |
rebuild this scope's disposable projection and QMD collection |
memo qmd config [FALLBACK=on|off] |
inspect or opt into semantic fallback after exact and FFF misses |
memo qmd disable [--purge] |
disable QMD; optionally remove its projection |
memo wake |
read both memories — global, then project; first command of every session |
memo note [--fit] [--date YYYY-MM-DD[THH:MM]] "..." |
record one memory: one line, up to 280 UTF-8 bytes (project by default); --fit trims at a word boundary, --date backfills a past day or moment (also on amend/retract) |
memo show <id|lo-hi> |
show one canonical raw memory — or a summary block — and later records that reference it |
memo amend [--fit] <id|lo-hi> "..." |
append a corrected replacement; a lo-hi block supersedes an already-compressed range |
memo retract [--fit] <id|lo-hi> "<reason>" |
append that an earlier memory or summarized range is no longer authoritative |
memo nap |
answer the merges that came due |
memo nap --batch N |
print up to N independent compression jobs |
memo nap --apply <file> |
preflight and atomically apply TAB-separated batch summaries |
memo recall [--limit N] [--context N] <regex> |
search the complete raw log while controlling matches and neighboring entries |
memo recall --fuzzy [--limit N] [--context N] "<text>" |
typo-tolerant raw-memory search with optional FFF |
memo recall --semantic "<meaning>" |
meaning-based raw-memory recall with explicitly enabled QMD |
memo recall --semantic --fast "<meaning>" |
semantic recall without QMD reranking, useful for repeated related searches |
memo zoom [--depth N] <lo>-<hi> |
open one to six levels of a summary-tree node |
memo resummarize <lo>-<hi> |
drop a bad summary; the next nap rebuilds it (forget remains an alias) |
memo redact <id> --force |
permanently erase one sensitive payload, preserve its ID, and invalidate derived caches |
memo config [NAME=N] |
inspect or change the active store's sizes: reading budgets, merge granularity, and — while empty — record widths |
memo export [--with-ids] [file] |
write a portable history; IDs are omitted by default so the output can be imported |
memo import [--dry-run] <file> |
validate or restore YYYY-MM-DD <text> records into an empty store |
memo --help |
show the complete command overview |
Put --global before any command to reach the memory that follows you into
every project. Merges arrive one at a time, in the output of note. Nothing
ever runs in the background.
memo note "Mutation requests may be retried automatically."
memo show 42
memo amend 42 "Mutation requests are not retried; only idempotent reads are."
memo retract 42 "Obsolete after the HTTP client rewrite."amend and retract are ordinary later memories:
#81 2026-07-27 Amends #42: Mutation requests are not retried; only idempotent reads are.
#82 2026-07-27 Retracts #42: Obsolete after the HTTP client rewrite.
The original remains visible as history, but compression treats later
amendments, corrections, and retractions as authoritative. Agents may also
reference earlier #IDs in ordinary notes when a stable fact, decision, or
causal link benefits from an exact anchor.
Supersession outlives compression: once the authoritative statement lives in
a summary line #a-b, memo amend a-b "..." targets the whole block with
Amends #a-#b: ..., and memo show on the block or on any raw memory inside
it lists that supersession as a later reference. (amend/retract write
only aligned blocks; import also tolerates plain #a-#b ranges from
foreign histories.)
A correction never rewrites an existing summary — LOG.txt is authoritative
and the tree is a rebuildable cache — so it reaches the tree only through
later merges. Two things keep that from losing it. When the target is already
inside a built summary, amend/retract say so and name the block form. And
a compression prompt lists lifecycle records that target its range from
outside it, marked as context rather than content, so the session merging
#0-3 is shown the Amends #0 that was written at #57.
Three optional environment variables name commands that process memories.
The write hooks run for every memory written by note, amend, and
retract (never import or nap); the show hook runs on display:
OPTMEM_HOOK_PRE— receives the candidate line on stdin before validation; its stdout replaces the line, and a nonzero exit refuses the write entirely. A secret scanner, a normalizer, or a policy gate lives here. The refusal message is the hook's own stderr.OPTMEM_HOOK_POST— receives the exact record just written (#id date @tag text) on stdin. The memory is already durable, so a failing post hook prints a warning and never unwrites — use it for sync, notification, or external indexing.OPTMEM_HOOK_SHOW— post-processes displayed memory lines inwake,show,recall(exact and fuzzy), andzoom: stdin gets one line per memory or summary shown, stdout must return exactly as many lines, in order. Protocol text (part footers,You are awake., nap prompts) is never touched, the store and what recall searches never change, and any hook failure or line-count mismatch falls back to the raw lines — display cannot lose records. Semantic (QMD) output is not filtered.
Hooks are deliberately environment variables, not files inside the store: a
synced or imported store directory must never be able to execute code.
memo doctor lists any active hooks.
Every entry written by note, amend, and retract is stamped with an
opaque session tag inside its payload:
#83 2026-07-29 @9845 The staging cluster pins Postgres 16.
Set OPTMEM_SESSION to choose the tag; otherwise one is derived from the
harness process that owns the session (or the controlling terminal), so
parallel agent sessions on one machine are distinguishable in wake,
recall, and the compression prompts. memo doctor reports the active tag
and where it came from. Three honest limits: tags are cooperative claims,
not authenticated identities — any process may set OPTMEM_SESSION to any
value; when no stable identity exists, entries are simply written untagged;
and a pre-2.0 entry whose text happened to begin @word reads as if tagged.
An entry's date defaults to today. --date backfills a real past day
(YYYY-MM-DD) or moment (YYYY-MM-DDTHH:MM[:SS], no timezone offset — ISO
order is lexicographic order, and an offset would break it) — useful when
recording something learned earlier. The log stays chronological by day: the
stamp may not be in the future and may not precede the newest memory's day,
while time of day is informational, so bare dates and timestamps coexist. To
reference an out-of-order past event, name it in the text instead.
redact is intentionally different and requires --force: it replaces the
payload with [REDACTED BY USER], preserves the ID and date, invalidates
summaries, and rebuilds or invalidates optional QMD data. Use it only when text
must actually be erased—not for routine corrections.
Portable backups use the same format as import:
memo export memories.txt
memo import --dry-run memories.txt
memo import memories.txt # destination must be emptyDefault export omits IDs. Importing the records in order into an empty store
recreates the same IDs, so amendment and retraction references remain valid.
--with-ids is an inspection format and is not importable.
Recall always searches the complete raw log. Its options control only what is returned:
memo recall --limit 5 "retry|backoff"
memo recall --context 2 "migration failed"
memo recall --fuzzy --limit 3 --context 1 "aproximate memry"--limit keeps the newest exact matches or strongest fuzzy matches.
--context includes that many adjacent raw memories on each side, merges
overlapping windows, and marks actual matches with >.
Tree depth belongs to zoom, not recall:
memo zoom --depth 3 0-255Depth defaults to one and is capped at six so one command cannot flood an agent's context. Existing byte and line output limits still apply.
The installer registers completion for the active shell and does not duplicate
profile entries when run again. After opening a new shell, type memo and
press Tab to complete commands, flags, configuration names, and setup/import
paths.
For a custom shell configuration, print the completion script directly:
memo completion bash
memo completion zsh
memo completion fish
memo completion powershellOptMem has no required Python packages. On Python 3.10+, install FFF to add typo-tolerant recall:
python3 -m pip install fff-search
memo recall --fuzzy "aproximate memry"Normal recall <regex> remains an exact, dependency-free scan. When it finds
nothing and FFF is installed, OptMem automatically retries fuzzily and ranks
the strongest matches first. FFF is instantiated only for that recall command;
OptMem remains a one-shot CLI, so this integration uses FFF for match quality,
not its long-lived warm-index performance.
QMD adds local BM25, vector retrieval, query expansion, and reranking without becoming an OptMem dependency. Install it only if you want meaning-based recall:
npm install -g @tobilu/qmd
memo qmd help
memo qmd enable
memo recall --semantic "Why did we stop retrying mutation requests?"
memo recall --semantic --fast "Where does the retry policy live?"QMD currently requires Node.js 22 or newer. The first semantic recall runs lazy indexing and may download QMD's local embedding, query-expansion, and reranking models. Those models can require roughly 2 GB in total; later unchanged recalls reuse the index and embeddings.
The integration is per OptMem scope. Enable project memory from that project;
use memo --global qmd enable separately for global memory. Both live in a
dedicated QMD index named optmem, with a collision-resistant collection per
store, so they do not enter the user's ordinary QMD knowledge base.
memo qmd status
memo qmd sync
memo qmd rebuild
memo qmd config FALLBACK=on
memo qmd disable
memo qmd disable --purgememo qmd sync prepays the same lazy projection, update, and embedding work
that semantic recall would otherwise perform. Full semantic recall uses QMD's
hybrid retrieval and reranking; --fast keeps hybrid retrieval but skips the
reranker.
FALLBACK=on is deliberately opt-in and per scope. With it enabled, ordinary
memo recall <regex> tries exact recall, then FFF fuzzy recall, then QMD only
if both return nothing. Invalid regular expressions still fail immediately,
and explicit --fuzzy never escalates. Use FALLBACK=off to restore the
default. The setting is retained by disable and removed by --purge, but it
is inactive whenever QMD itself is disabled.
disable unregisters the collection but keeps the disposable Markdown
projection for a cheap re-enable. --purge removes the projection too.
Neither command changes LOG.txt, TREE/, or any memory. QMD synchronization
is lazy: note, nap, and wake never launch Node or generate projection
files. When QMD is enabled, the final wake page only adds a small capability
line; it does not invoke QMD. If semantic recall fails, OptMem reports that
failure explicitly while exact and FFF recall remain available.
A single log is one identity, and wake spends its reading budget on the present. That is right for one continuous workstream and wrong for several: interleaved projects make each one's detail decay while work happens elsewhere, so an old project can wake up with its memories intact in the log but out of reach of the context budget.
Every command therefore speaks to the automatically detected project in
$PWD. Hosted repositories use the complete remote identity; projects without
a usable remote use a portable local marker. --global reaches the one memory
that follows you everywhere. wake alone reads both: who you are, then where
you are. Almost everything belongs in the project; use --global only for
what would still be true tomorrow in a repository you have never seen.
~/.optmem/
memo the tool: one file of Python 3, no required dependencies
memo.cmd Windows launcher
memory/ the global memory (create with `memo init`)
LOG.txt authoritative fixed-width records; append-only except redact
TREE/ the summaries: a cache, rebuildable from the log alone
QMD/ optional 16-memory Markdown projection, fully disposable
config the sizes, written by `memo config`
scope.json project stores only: canonical identity and safe aliases
$XDG_DATA_HOME/optmem/ (default: ~/.local/share/optmem)
repo-v2/<name>-<hash>/ collision-resistant hosted-repository stores
path-v2/<name>-<hash>/ local/path project stores
repo/ and path/ compatible stores retained from older releases
scope-map.json links stable local identities to compatible stores
New hosted-project directory names use a readable repository label plus a
SHA-256-derived identity suffix; scope.json retains the full human-readable
identity. Existing compatible stores continue in place. If an old
owner/repo store is already claimed by a different host or namespace, OptMem
selects an isolated new store instead of mixing the histories.
memo config # show the sizes
memo config WAKE_LINES=300 # how many lines wake prints (208 ≈ 16k tokens)
memo config WAKE_LINES= # back to the defaultWAKE_LINES is usually the only size worth touching, and it is a reading
budget, not a storage budget: change it whenever, in either direction, and
nothing is recomputed. The same is true of RAW_MAX, the merge granularity —
how many raw memories one compression prompt shows before a block merges from
its two half summaries instead (default 16).
RAW_MIN (default 2) is the floor of the merge tree: the smallest block it
builds, and so how often you are asked to compress at all. Levels start
there instead of at 2, so N memories owe about 2N/RAW_MIN merges rather
than N, and the first summary covering any range is written from RAW_MIN
raw entries instead of from a pair — fewer prompts and less lossy ones, since
the merges it skips are the narrowest, least useful in the tree:
memo config RAW_MIN=8 # ~4x fewer compressions; a summary per 8 memoriesRAW_MIN |
merges per 64 memories | first summary built from |
|---|---|---|
| 2 (default) | 63 | 2 raw entries |
| 8 | 15 | 8 raw entries |
| 32 | 3 | 32 raw entries |
It must be a power of two from 2 to RAW_MAX. Below the floor there are no
summaries, so wake prints that span raw and one zoom opens a whole block of
raw memories at once — which also means a store carries up to RAW_MIN - 1
uncompressed memories at the present edge. Changing it is safe at any time:
raising it prunes the finer levels (a cache no read reaches again, reported as
Pruned TREE/2), lowering it makes them pending. LOG.txt is never touched.
Records are fixed width, so position is identity and every lookup is one
seek. At a million memories (608 MB), wake takes 0.03s.
The widths themselves are per-store sizes too, which is how a store can hold entries longer than 280 bytes — but they are physical, so they may only be set while the store is empty:
memo config LOG_REC=640 TREE_REC=576 ENTRY_CHARS=560 # on a fresh storeENTRY_CHARS is always capped at min(TREE_REC - 8, LOG_REC - 40) so every
entry and summary fits its record.
To widen an existing memory, migrate it — the one workflow where moving a store directory by hand is sanctioned, because the moved directory doubles as the migration backup:
memo export wider-backup.txt # portable history; IDs are implied by order
memo scope # note the Store path (memo doctor for global)
mv <store> <store>.pre-widen # set the old store aside, keep it as backup
memo config LOG_REC=640 TREE_REC=576 ENTRY_CHARS=560
memo import wider-backup.txt
memo nap --batch 8 # rebuild the summaries, a few jobs at a timeA project store reappears empty on first use, so config can size it
directly; for the global store (or a MEMORY_DIR store) run memo init
once before config. Amendment and retraction references survive because
import recreates the same IDs in order. Delete <store>.pre-widen only
after memo doctor --deep reports the new store healthy.
Set $MEMORY_DIR to pin a single store and skip scoping — a synced folder, a
git repo. See WINDOWS.md for native PowerShell usage and locking
details.
LOG.txt is the source of truth. Raw records are immutable unless the user
explicitly invokes redact --force. TREE/ is a rebuildable summary cache.
Backing up the memory directories is sufficient; never hand-edit them while an
agent may be writing.
Upgrade from any directory:
memo upgradeThis downloads the current installer over HTTPS. The installer validates the new CLI before replacing the installed copy, refreshes PATH and completion setup idempotently, and preserves logs, summaries, and configuration.
Remove OptMem's executable, PATH/profile hooks, and shell completion:
memo uninstallUninstall deliberately preserves the global store at ~/.optmem/memory and
all project stores under ${XDG_DATA_HOME:-~/.local/share}/optmem, so
reinstalling restores access to the same history. Open a new shell afterward
to discard the old process PATH. It also leaves managed blocks in connected
AGENTS.md, CLAUDE.md, and other instruction files; remove those blocks
manually if you are permanently retiring OptMem. Delete memory directories
manually only when you intentionally want to erase that data.
If QMD was enabled, run memo qmd disable --purge in each enabled scope
before uninstalling when you also want its external collection and local
projection removed.
Start troubleshooting with:
memo scope
memo doctor
memo --helpCommon fixes:
memo: command not found: open a new shell after installing, or re-run the installer to repair the PATH entry.- The wrong project memory appears: run
memo scopeand check the current directory, selected remote, and detection source. In a checkout with several remotes and no suitableoriginor tracked branch, setOPTMEM_REMOTE=<remote-name>. - No global memory exists: run
memo init. - Fuzzy recall is unavailable: exact regex recall still works; install
fff-searchunder Python 3.10+ to enable it. - A command names
MEMORY_DIR: verify that the environment variable points to the intended existing store.
Developing or contributing? See CONTRIBUTING.md.
memo setup writes the authoritative block between managed markers, using a
fully qualified executable path. This reference omits those markers and uses
the shorter PATH-based command for readability. Run memo setup (or copy the
version printed by memo init) instead of hand-editing this example.
## Memory
Your memory is OptMem:
- The tool is `memo`
- Each automatically detected project has its own memory
- One global memory, `~/.optmem/memory`, follows you into all of them
OptMem outlives every session, compaction, model and vendor change.
Without it you do not know who you are, or what was decided and tried.
### Mental model
Each scope is an append-first log. `note` adds one raw memory with a stable
`#ID`; raw memories remain the source of truth. Later memories may cite earlier
`#IDs` when that makes a durable fact or decision unambiguous. `amend` appends a
corrected replacement; `retract` appends that an earlier memory is no longer
authoritative. The earlier record remains useful history. Only explicit,
user-directed `redact --force` rewrites a raw payload, to erase sensitive text.
Adjacent memories are also represented by a binary tree of lossy one-line
summaries. `wake` shows a bounded frontier from that tree—not full history—
with coarser summaries for older history and finer detail toward the present.
`recall` searches the raw log; `zoom` expands a summary toward its raw entries.
### At startup: activating OptMem (mandatory)
Run `memo wake` before any other tool call, in every session, and
then do exactly what it prints, through the end of its output. Read every
continuation until it says `You are awake.` and run any compression command it
prints before your next action. Without a `MEMORY_DIR` override, `wake` reads
the global memory first, then the automatically selected project.
If the selected project is ever unclear, `memo scope` reports the identity,
store, and detection source without changing memory.
### While working: register memories (mandatory)
Call `memo note "<1 line, max 280 UTF-8 bytes>"` whenever you learn
something durable enough to change future work. That covers the outcome
of a task worth real effort, a decision or constraint, a fact or insight
the user teaches you, or a preference they would reasonably expect retained.
That writes to the automatically selected project memory by default, which is
where almost everything belongs. Add `--global` ONLY if the memory would still
be true tomorrow in a repository you have never seen: who the user is, how they
want to be worked with, this machine, your own tooling. How one project does
something is not global, however much it feels like a lesson -- write it to
that project. A `MEMORY_DIR` override intentionally pins commands to one store.
If a line is over the byte limit, `--fit` on `note`, `amend`, or `retract`
trims it at a word boundary and reports exactly what was cut; rewrite only
if the cut loses something essential.
Prefer why over what: commits and diffs already record what changed. A memory
earns its place by holding what they cannot -- reasoning, constraints, the
rejected alternative, the reason an approach failed.
So do not write what the code or git history answers, the status of work in
progress, what stops mattering when this task ends, or a memory already held
(`recall` first when unsure).
A memory must stand alone months from now: name things specifically, resolve
relative time and reference, one fact per memory. Point at the authoritative
file or doc; do not restate it.
Never record secrets, credentials, authentication material, or raw
sensitive data.
Every memory you write is stamped with this session's opaque `@tag`.
Entries bearing another tag are a parallel session's testimony: weigh them
as reports, not as your own observations, and never restate them as yours.
Set OPTMEM_SESSION to name the tag; otherwise one is derived automatically.
If a durable memory changes, do not contradict it with an unexplained note.
Use `memo amend <id> "<replacement>"`; use
`memo retract <id> "<reason>"` when it has no replacement. When the
authoritative statement already lives in a compressed summary line `#a-b`,
amend the whole block: `memo amend <a>-<b> "<replacement>"` supersedes the
summarized range and stays linked to every raw memory inside it. Ordinary
memories may reference earlier `#IDs` to anchor stable facts and reasoning.
Use `memo show <id>` when you need the exact record and its later
references, including block supersessions that cover it;
`memo show <a>-<b>` shows a summary block and what supersedes it.
Redaction is not correction: only the user may request it, and it exists for
content that must actually be erased.
If `memo note` asks a compression, follow its prompt and run the exact
`nap` command before your next action. If `nap <range>` reports the wrong
block, a parallel session settled it first: run bare `memo nap` to get
the current job, and treat entries you did not write as another session's
testimony.
A compression is a lossy retrieval cue for the supplied range, not a
deletion: the raw memories remain searchable. Write one self-contained line.
Preserve durable decisions, outcomes, constraints, causal links, preferences,
and useful failure reasons. Drop transient status, incidental chronology, and
repetition. Use specific names; invent nothing and never imply a link between
unrelated facts. Later amendments, corrections, and retractions override the
records they reference. Preserve the final outcome; retain the earlier account
only when its history or failure reason remains useful.
Never edit or delete a memory directory: the tool manages it.
### When you need an old memory: search, or navigate
`memo recall <regex>` searches the complete raw log with a case-insensitive
regular expression and, when `fff-search` is installed, retries a zero-result
search fuzzily. Use
`memo recall --fuzzy "<text>"` to request typo-tolerant FFF recall
directly. Add `--limit N` to cap returned matches and `--context N` to
include neighboring raw memories; these control output without reducing the
history searched. Recall and `zoom` target project memory by default; put
`--global` before the command for global memory.
If QMD was explicitly enabled for this scope, use
`memo recall --semantic "<meaning>"` for meaning-based raw-memory recall;
add `--fast` to skip reranking for repeated related searches. QMD can also be
configured as the last fallback after exact and fuzzy recall both miss.
A `#a-b` line from `wake` is one summary node covering raw memory IDs
`a` through `b`. `memo zoom <a-b>` opens one level; add `--depth N`
to open up to six levels in one bounded call. Repeat until the relevant
raw memories appear.
### If you're a subagent: skip everything above
Parallel sessions on this machine are all you, and may all write memories.
A subagent is not: it must never run `memo`, because it cannot judge what
is already known, and its notes would arrive duplicated and incorrectly.
When you spawn one, write: `You are a subagent. Don't run memo.`
The parent agent remains responsible for recording the durable outcome.