Skip to main content

Memory

EstaCoda memory is durable context stored in files. It helps future sessions remember reviewed preferences, project facts, and operator-curated notes.

Memory is not a hidden authority layer. System instructions, developer instructions, repo instructions, AGENTS.md, security policy, and the current user request still win.

Use this page to understand what can be remembered, where it is stored, how promotion works, and how to inspect or repair it.


What Memory Is

EstaCoda has several related stores. They are not interchangeable.

StoreWhere it livesWhat it is for
Session historySession databasePast turns and events. Used for transcripts, recall, and promotion evidence.
Profile memory~/.estacoda/profiles/<id>/USER.md, MEMORY.md, SOUL.mdDurable context for one profile.
Project/workspace memoryUsually MEMORY.md plus repo context such as AGENTS.mdProject facts, conventions, and workflow notes.
Shared memory~/.estacoda/memory/shared/Global snippets available across profiles.
Promotion metadata~/.estacoda/profiles/<id>/promotions.jsonTracks promoted facts, active/inactive state, source sessions, and confidence.

AGENTS.md is not memory. It is workspace instruction context. It is not promoted, compacted, or edited by memory tools.


What Memory Is Not

Memory does not:

  • learn broad semantic preferences from one sentence
  • promote assistant output, tool output, child-session output, resumes, or delegated text
  • let recalled history override security policy or the current user request
  • store secrets or prompt-injection-looking text
  • use a model to decide promotion eligibility, equivalence, or conflicts
  • automatically trust old session content as an instruction

Session recall and external recall are reference context. They are labeled as untrusted historical context. Curated memory files are stronger than recall, but still below current instructions and safety policy.


Profile Files

Profile-local memory lives under:

~/.estacoda/profiles/<id>/

Important files:

FilePurposeDefault budget
USER.mdUser preferences and communication style1,375 characters
MEMORY.mdProject, workflow, and durable operational facts2,200 characters
SOUL.mdIdentity and safety guidanceConfigurable
promotions.jsonPromotion metadataNo markdown budget

Shared memory lives under:

~/.estacoda/memory/shared/

Prompt render order is:

memory/shared/ -> USER.md -> SOUL.md -> MEMORY.md

How Promotion Works

Promotion is deterministic. It runs after a turn and looks only at direct user input from the current turn plus matching historical root-session evidence.

Promotion can create:

Promoted contentDestination
Repeated user preferencesUSER.md
Repeated project factsMEMORY.md

The runtime passes the original input.text to promotion. Resume-expanded text and runtime scaffolding are not promotion input.

Promotion requires:

  1. The current direct user input contains a supported promotion candidate.
  2. At least two matching prior root sessions contain the same deterministic candidate.
  3. The matching historical messages are user messages.
  4. The content passes memory safety scanning and file budget checks.

Child sessions are excluded from promotion evidence. Delegated work can be useful context, but it cannot teach durable user preferences by itself.


What Can Promote

Supported user preference patterns are intentionally narrow.

English examples:

InputPromoted memory
I prefer TypeScriptPrefer TypeScript.
I'd prefer TypeScriptPrefer TypeScript.
My preference is TypeScriptPrefer TypeScript.
We prefer TypeScriptPrefer TypeScript.
Default to TypeScriptPrefer TypeScript.
Use TypeScript by defaultPrefer TypeScript.
Please switch to TypeScript by defaultPrefer TypeScript.
I prefer concise repliesPrefer concise replies.

Arabic examples:

InputPromoted memory
أفضل TypeScriptPrefer TypeScript.
أفضّل TypeScriptPrefer TypeScript.
افضل TypeScriptPrefer TypeScript.
استخدم pnpm افتراضياًPrefer pnpm.
استخدم pnpm افتراضياPrefer pnpm.
استخدم pnpm كافتراضيPrefer pnpm.
خلّي الردود مختصرةPrefer concise replies.
خلي الردود مختصرةPrefer concise replies.
خلّي الردود مفصلةPrefer detailed replies.
خلي الردود مفصلةPrefer detailed replies.

Arabic mixed-language preference values are accepted only for bounded technical tokens, such as:

  • TypeScript
  • pnpm test
  • ~/.estacoda/foo
  • GPT-5

This preserves exact casing, spacing, paths, and provider/model tokens where supported. Natural-language Arabic or mixed-language phrases such as أفضل لغة آمنة or استخدم careful release notes كافتراضي do not promote.

Project fact promotion remains separate from user preferences. Examples include:

InputPromoted memory
project uses TypeScriptProject uses TypeScript.
run tests with pnpm testRun tests with pnpm test.
foo is stored under ~/.estacoda/fooFoo is stored under ~/.estacoda/foo.

What Cannot Promote

These inputs are rejected as promotion evidence:

  • quoted or backticked text
  • fenced code blocks
  • long incidental paragraphs
  • assistant notes
  • tool output
  • resume text
  • delegated or child-session text
  • prompt-injection-looking text
  • secret-looking content
  • text containing invisible or bidirectional control characters

Examples that do not promote:

Please summarize this: "I prefer concise replies."
The attached resume says: "I prefer concise replies."
Agent note: I prefer concise replies.
Earlier assistant said: "User prefers concise replies."
لخّص هذا: "أفضل TypeScript"
لخّص هذا: «أفضل TypeScript»
ملاحظة الوكيل: أفضل TypeScript
السيرة تقول: أفضل TypeScript
قال المساعد سابقاً: المستخدم يفضل TypeScript

Near-miss English phrases also do not promote:

I like TypeScript
It would be nice if TypeScript
Maybe use TypeScript
Could you use TypeScript
Can we use TypeScript
For this one, use TypeScript
Try TypeScript
Switch to TypeScript

Conflicts and Forgetting

Some preference categories are intentionally exclusive:

CategoryExamples
Reply verbosityPrefer concise replies., Prefer detailed replies.
Language defaultPrefer TypeScript., Prefer JavaScript.
Test commandPrefer pnpm test., Prefer npm test.
Package managerPrefer pnpm., Prefer npm.
Code styleAlways use strict mode., Always use semicolons.

When a new active preference in one of these categories promotes, it supersedes the old active preference in that category. Unrelated preferences coexist. Prefer TypeScript. does not conflict with Prefer careful release notes..

Conflict categories are derived at runtime from canonical content. They are not stored as schema fields in promotions.json, so existing promotion records still load and participate in conflict handling.

To forget a promoted preference, say a direct forget request such as:

forget that i prefer concise replies

If the active promoted preference exists, EstaCoda marks it forgotten in promotions.json and removes the corresponding line from USER.md.


Write Safety

Memory writes pass through safety checks before persistence.

The write path rejects:

  • credential-looking content, including env var names such as OPENAI_API_KEY when they would become durable memory
  • prompt-injection-looking content
  • unsafe compacted memory output
  • content that exceeds the target memory file budget

Arabic input such as استخدم OPENAI_API_KEY كافتراضي can match the deterministic syntax, but the provider/store safety path rejects it before persistence.

Memory writes use atomic replacement. EstaCoda writes a temporary file in the target directory and renames it into place. If a write fails, the previous file remains.

Memory persistence is also drift-aware. Before overwriting a file, the persistence service compares the current disk file with the snapshot loaded earlier. If another process edited the file, EstaCoda refuses to overwrite it by default.

Promotion writes roll back both markdown and promotions.json when a later step fails. This prevents stale active metadata from surviving a rejected markdown write.

Backups are not created for ordinary writes by default. They are created only by operations that explicitly request them, such as applied memory file compaction.


Inspect Memory

Use CLI read/search first:

estacoda memory read USER.md
estacoda memory read MEMORY.md
estacoda memory search <query>
estacoda memory read shared <key>

SOUL.md is protected. Read it only with an explicit protected-memory flag:

estacoda memory read SOUL.md --include-protected

Inspect the files directly when you need to repair state:

ls ~/.estacoda/profiles/<id>/
sed -n '1,160p' ~/.estacoda/profiles/<id>/USER.md
sed -n '1,160p' ~/.estacoda/profiles/<id>/MEMORY.md
sed -n '1,160p' ~/.estacoda/profiles/<id>/promotions.json

Do not edit promotions.json casually. It tracks active, superseded, and forgotten promotions. If it disagrees with the markdown files, rendering may suppress or restore entries in surprising ways.


Edit Memory Safely

Memory files are plain Markdown. Stop the runtime before manual edits when possible, then edit the relevant file:

$EDITOR ~/.estacoda/profiles/<id>/USER.md
$EDITOR ~/.estacoda/profiles/<id>/MEMORY.md

Use one line per durable fact or preference. Keep entries short and reviewable.

Back up files before larger edits:

cp ~/.estacoda/profiles/<id>/USER.md ~/.estacoda/profiles/<id>/USER.md.bak
cp ~/.estacoda/profiles/<id>/MEMORY.md ~/.estacoda/profiles/<id>/MEMORY.md.bak

If you remove a promoted line manually, inspect promotions.json as well. Prefer the explicit forget path for user preferences so metadata and markdown stay aligned.


Local Lexical Retrieval

Local memory read/search is deterministic lexical retrieval over authoritative memory files. It is not semantic recall or vector search.

The rebuildable index is stored under profile state:

<profile-state-dir>/memory-index.sqlite

Deleting this SQLite file does not delete USER.md, SOUL.md, MEMORY.md, shared memory files, or promotions.json.

Repair the index with:

estacoda memory index path
estacoda memory index status
estacoda memory index rebuild

If the index is disabled, missing, or unavailable, memory.read, memory.search, and CLI read/search fall back to bounded direct file reads or substring search where possible.


Delegation Outcome Memory

Delegation outcome memory is separate from child transcript recall. It is disabled by default under delegation.outcomeMemory.enabled.

When enabled, it records bounded status metadata such as parent session id, child session id, role, depth, task index, status, reason, timestamp, token usage, and a bounded task preview.

It does not store raw child output, prompts, transcripts, tool arguments, file contents, diagnostic payloads, or credentials. Child transcripts remain excluded from promotion evidence.


Session Compression and Memory Compaction

Session compression and memory file compaction are different operations.

OperationWhat it changes
Session compressionOlder session history. Produces untrusted historical summaries.
Memory file compactionUSER.md or MEMORY.md. Produces replacement memory file content after checks.

Memory file compaction uses the memory_compaction auxiliary route, supports dryRun, and creates a timestamped backup before applying changes. It does not compact SOUL.md, AGENTS.md, shared memory, session history, or promotions.json.


External Memory

External memory is disabled by default. The implemented provider is file-backed and profile-local under:

~/.estacoda/profiles/<id>/external-memory/

External recall is untrusted reference context. External memory cannot replace USER.md, MEMORY.md, SOUL.md, shared memory, promotions.json, or session recall.


Troubleshooting

SymptomLikely causeFirst check
Expected preference did not promoteIt was seen fewer than two prior root sessions, used an unsupported phrase, or appeared only in delegated/quoted/resume textCheck root-session history and phrase shape
Arabic or mixed-language phrase did not promoteThe value was natural-language text instead of a supported technical token, or contained bidi/invisible controlsTry a supported form such as أفضل TypeScript or استخدم pnpm test افتراضياً
Wrong memory appearedActive promotion metadata and markdown may disagree, or an old active promotion is still presentInspect USER.md, MEMORY.md, and promotions.json
Memory file changed externallyDrift detection refused the writeRestart the runtime or reconcile the manual edit before retrying
Memory write failedScanner rejection, budget overflow, drift, or persistence errorCheck diagnostics and file sizes; compact or edit memory if needed
Secret-looking content did not saveSafety scanner rejected itKeep credentials in .env or secret storage, not memory
Index search is staleRebuildable lexical index is out of dateRun estacoda memory index rebuild

When debugging promotion, start with the current direct user input, then check matching root-session user messages, then inspect promotions.json.