{"id":51401453,"url":"https://github.com/tinqiao-oss/engramory","last_synced_at":"2026-07-04T07:00:50.519Z","repository":{"id":364990490,"uuid":"1268424426","full_name":"tinqiao-oss/engramory","owner":"tinqiao-oss","description":"A portable memory protocol for AI agents — load it as standing rules; a curation discipline + reference spec + optional cap hook.","archived":false,"fork":false,"pushed_at":"2026-07-04T05:06:00.000Z","size":553,"stargazers_count":59,"open_issues_count":1,"forks_count":3,"subscribers_count":0,"default_branch":"master","last_synced_at":"2026-07-04T05:27:12.067Z","etag":null,"topics":["agent-memory","ai-agents","claude-code","codex","knowledge-base","llm-memory","long-term-memory","markdown","mcp","memory","prompt-engineering","zero-dependency"],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/tinqiao-oss.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-06-13T14:15:28.000Z","updated_at":"2026-07-04T05:05:45.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/tinqiao-oss/engramory","commit_stats":null,"previous_names":["tinqiao-oss/engramory"],"tags_count":17,"template":false,"template_full_name":null,"purl":"pkg:github/tinqiao-oss/engramory","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tinqiao-oss%2Fengramory","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tinqiao-oss%2Fengramory/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tinqiao-oss%2Fengramory/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tinqiao-oss%2Fengramory/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tinqiao-oss","download_url":"https://codeload.github.com/tinqiao-oss/engramory/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tinqiao-oss%2Fengramory/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35112708,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-07-04T02:00:05.987Z","response_time":113,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["agent-memory","ai-agents","claude-code","codex","knowledge-base","llm-memory","long-term-memory","markdown","mcp","memory","prompt-engineering","zero-dependency"],"created_at":"2026-07-04T07:00:48.772Z","updated_at":"2026-07-04T07:00:50.512Z","avatar_url":"https://github.com/tinqiao-oss.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"**English** | [简体中文](README.zh-CN.md)\n\n# Engramory\n\n[![CI](https://github.com/tinqiao-oss/engramory/actions/workflows/test.yml/badge.svg)](https://github.com/tinqiao-oss/engramory/actions/workflows/test.yml)\n[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)\n[![Python 3.9+](https://img.shields.io/badge/python-3.9%2B-blue.svg)](https://www.python.org/)\n\n**An opinionated, zero-infrastructure memory *protocol* for small-scale, local,\nfile-based agent memory** — a strict curation discipline plus a validator\n(`tools/engramory_doctor.py`), loaded as **standing rules** (`CLAUDE.md` /\n`AGENTS.md` / your host's rules file). It is not a database, a framework, or a\nrelevance-loaded skill. Memory is a folder of small, human-readable markdown files\nplus one always-loaded index. No database, no embeddings, no server — just\nplain-text files you can open, read, edit, and diff in any editor (the live store\nitself stays git-ignored).\n\n\u003e *Engramory* — coined from *engram* (the physical trace a memory leaves in the\n\u003e brain) + *memory*. Here: one file = one fact.\n\n\u003e **Status: 0.5.0 — experimental.** The hard index cap (a `PreToolUse` hook) is\n\u003e deterministic for the matched direct-edit tools (`Edit | Write | MultiEdit`) but\n\u003e NOT a global write guard (Bash / MCP file tools / external editors / sync clients\n\u003e bypass it); the discipline loads as standing rules the model follows, so it's\n\u003e best-effort, not guaranteed on every task (see [SKILL.md](SKILL.md) §8). Assumes a\n\u003e single writer / serialized writes. Don't rely on it as a \"mandatory, reliable,\n\u003e cross-agent\" memory layer yet.\n\n---\n\n## What this is — and is NOT\n\nEngramory is **not a new memory architecture**. The \"markdown files + a small index\nloaded into context + the model curates it\" pattern is now the mainstream shape\nfor agent memory, and it ships in several places already. Engramory stands on:\n\n- **Claude Code native auto-memory** — the same markdown-`MEMORY.md`-index +\n  lazy detail-file pattern; its system prompt even uses the same\n  `user | feedback | project | reference` type vocabulary (per\n  [anthropics/claude-code#58840](https://github.com/anthropics/claude-code/issues/58840);\n  the *public docs* describe only the index + topic files). Engramory is a\n  disciplined superset of this default.\n- **[basic-memory](https://github.com/basicmachines-co/basic-memory)** — markdown\n  source-of-truth, YAML frontmatter `type`, `[[wikilink]]` graph, local-first.\n- **[obsidian-second-brain](https://github.com/eugeniughelbur/obsidian-second-brain)**,\n  **[claude-memory-compiler](https://github.com/coleam00/claude-memory-compiler)**\n  (\"a loaded index beats vector search at personal scale\"), and the broader family\n  of markdown-memory skills.\n\nWhat Engramory contributes is the **opinionated bundle + the discipline**, not the\nprimitives. Do not claim novelty on markdown, frontmatter, wikilinks, a loaded\nindex, atomic notes, or curation hygiene — all are prior art.\n\n## What's actually differentiated\n\n1. **A role/purpose ontology, headed by `feedback` = procedural memory.** The\n   semantic / episodic / **procedural** split is established prior art — the CoALA\n   taxonomy, and a named procedural type in LangMem and mem0 — so Engramory does not\n   claim the category. What it does is make procedural `feedback` the *spine* of a\n   deliberately tiny, hand-authored, human-readable set, with required **Why:** /\n   **How to apply:** lines, instead of auto-extracting it into a vector/graph store.\n   The contribution is the packaging and discipline, not the ontology.\n\n2. **The curation contract as concrete behaviour** the protocol applies (model-followed, not a hard gate): dedup-before-write,\n   update-don't-duplicate, delete-when-wrong, and a negative-scope rule (\"don't\n   store what git/CLAUDE.md/the code already records\"). Surveys consistently name\n   *modify/delete/forget* as the most under-implemented memory operation — Engramory\n   makes it the spine.\n\n3. **A bounded index designed not to silently rot.** The index loads every session and\n   Claude Code reads the first 200 lines / 25 KB (documented behavior), so an unbounded index silently\n   drops memories off the end. Engramory warns at 150 lines / 20 KB, compacts-or-asks\n   before 200 / 25 KB, and ships a hard `PreToolUse` hook backstop (it blocks only\n   *growth* past the cap — shrinking/compaction edits always pass). Both the line and\n   byte caps apply — whichever is hit first triggers (an index can be under the line\n   count yet over on bytes when the lines run long).\n\n## How it compares\n\n| | storage | recall | human-readable | typed ontology | curation discipline | bounded index | infra |\n|---|---|---|---|---|---|---|---|\n| **Engramory** | md files | loaded index → open file | ✅ | ✅ role-based (4) | ✅ contract (model-run) | ✅ 150/200 + hook | none |\n| CC auto-memory | md files | loaded index → open file | ✅ | ✅ same 4 types | partial (auto) | ~200-line window* | none (built-in) |\n| basic-memory | md + SQLite | semantic/FTS search | ✅ | ✅ freeform type | schema + overwrite checks | ❌ (no loaded index) | SQLite + embeddings |\n| obsidian-second-brain | md vault | index-first + search | ✅ | folder-typed | ✅ reconcile/lint | partial | none |\n| mem0 / Zep | vector/graph DB | semantic | ❌ (DB) | typed (prefs/episodic/proc.; Zep custom) | auto-extract | n/a | DB + embeddings |\n| [agentmemory](https://github.com/rohitg00/agentmemory) | SQLite + vector index (+opt. graph) | hybrid BM25+vector (+opt. graph), RRF | ❌ (DB/engine) | ✅ 4-tier lifecycle (work./epis./sem./proc.) | auto (capture + dedup + decay) | n/a | iii engine (local) + opt. embeddings |\n\nEngramory's lane: **minimalism + actionable role typing + curation discipline, zero\ninfra.** It does *not* try to out-search basic-memory, out-scale mem0, or\nout-capture agentmemory — those solve a different problem (auto-capture /\nauto-ingest at volume) at a different cost point. agentmemory is the closest\nheavyweight foil: also local-first, but it bets on automatic capture (lifecycle\nhooks) + hybrid retrieval (BM25 + vectors + optional graph) on a SQLite/`iii`\nengine, where Engramory bets on hand-curation + a tiny always-loaded index and\nships no engine at all.\n\n\\* Claude Code's [memory docs](https://docs.claude.com/en/docs/claude-code/memory)\ndocument this exactly: *\"the first 200 lines of `MEMORY.md`, or the first 25KB,\nwhichever comes first, are loaded at the start of every conversation.\"* Other hosts\nvary, so the window stays configurable via the hook's env vars.\n\n## Where it fits — and the goal\n\nEngramory is a **portable memory *discipline*, not a product** — not a database, not a\nframework, not a relevance-loaded skill, not a Claude-Code-only plugin. The plumbing it rides on (a markdown index +\natomic notes, the `user | feedback | project | reference` types, a bounded loaded index)\nis increasingly shipped *natively* by the host — Claude Code's built-in auto-memory\nalready does it. So Engramory's value is the part hosts **don't** ship: the explicit\ncuration contract (dedup-before-write, delete-when-wrong, don't-store-what-the-repo-\nalready-has), procedural `feedback` notes with required Why/How, and a portable way to\nenforce the size cap.\n\n**The goal is the same discipline on *any* agent — by riding the real cross-agent rails,\nnot by inventing a new standard.** Paste [`rules-snippet.md`](rules-snippet.md) into the\nhost's always-loaded rules so the discipline fires every task; an **Engramory MCP server\n(planned)** would then let any MCP-capable agent (Claude Code, Cursor, Cline, Codex,\nWindsurf, …) share the same store, the same tools, and a **server-enforced cap** — making\nthe one deterministic guarantee cross-agent instead of per-host. On a host that only gives\nyou a flat rules file or a raw file store, that is a real upgrade; on a host that already\nships structured memory, Engramory is a thin discipline layer on top — and says so.\n\n---\n\n## Install\n\n\u003e Requires **Python 3.9+** for the hook and the `tools/` scripts (`python3` on\n\u003e most systems).\n\n### Claude Code\n1. **Load the discipline as standing rules (primary):** paste\n   [`rules-snippet.md`](rules-snippet.md) into your always-loaded rules —\n   `~/.claude/CLAUDE.md` (all projects) or the project `CLAUDE.md` — so the protocol\n   fires on every task, not just when a skill happens to load by relevance.\n2. **(Optional) register the full spec as a skill:** copy or symlink this folder\n   into your Claude Code skills directory as `engramory/`, so [`SKILL.md`](SKILL.md)\n   is available on demand as the detailed reference (path in `hooks/INSTALL.md`).\n3. **Add the hard-cap hook:** register the hook from `hooks/` in your `settings.json`\n   (snippet in `hooks/settings.snippet.json`).\n4. Point `\u003cMEMORY_ROOT\u003e` at your memory directory; ensure it's `.gitignore`d if\n   inside a repo.\n\n### Codex\n\nUse the Codex init helper to wire the discipline into `AGENTS.md`, create the\nmemory template, optionally install the full protocol as a Codex skill, and add a\n`.gitignore` entry when the store lives inside the project:\n\n```sh\npython tools/engramory_init.py codex --project-root /path/to/project --install-skill\n```\n\nBy default this creates `\u003cproject\u003e/.engramory-memory/`. Pass `--memory-root` to\nuse an existing folder. Keep this store separate from Codex native Memories:\nCodex Memories are generated state, while Engramory is a user-auditable plain\nfolder. Full Codex notes are in [adapters/codex/README.md](adapters/codex/README.md).\n\n### Read-only readers (recall another agent's memory)\n\nPoint **any** host at a store **another agent owns and writes** (e.g. Claude Code's native\nauto-memory) so a delegated run is grounded in the same project memory — read-only, so the\nowner stays the sole writer (Engramory assumes a single writer; many readers are fine):\n\n```sh\npython tools/engramory_init.py codex-reader   --project-root ~/.codex \\\n  --memory-root ~/.claude/projects/\u003cproject\u003e/memory\n# same shape for any host — it lands in that host's own rules file:\npython tools/engramory_init.py cursor-reader  --project-root /path/to/repo --memory-root \u003cstore\u003e\n```\n\nReader hosts: `codex-reader` (dogfooded) plus `claude-reader`, `cursor-reader`, `kiro-reader`,\n`cline-reader`, `windsurf-reader`, `openclaw-reader`, `hermes-reader` (wired from each host's\ndocumented rules-file format, printed with an \"unverified\" note). It creates no store and never\nwrites; `--memory-root` must be an existing store. See\n[adapters/reader/README.md](adapters/reader/README.md) (incl. the tested-host table + data-egress note).\n\n### OpenClaw\n\nUse the OpenClaw init helper (defaults to the workspace `~/.openclaw/workspace`):\n\n```sh\npython tools/engramory_init.py openclaw --install-skill\n```\n\nIt writes a marked Engramory block into the workspace `AGENTS.md` (auto-loaded every\nsession), installs the protocol under `.agents/skills/engramory` (OpenClaw\nauto-discovers it), and keeps a separate `.engramory-memory/` store. The index cap on\nOpenClaw is rules + `engramory_check.py`, **not** a deterministic deny hook (that would\nneed a `before_tool_call` plugin) — see\n[adapters/openclaw/README.md](adapters/openclaw/README.md).\n\n### Kiro\n\nKiro (AWS's agentic IDE/CLI) is a strong host — always-loaded steering files, an agent\nthat reads/writes workspace markdown, and a real pre-write deny hook. Wiring is manual\n(no init helper yet): copy\n[`adapters/kiro/steering-engramory.md`](adapters/kiro/steering-engramory.md) to\n`.kiro/steering/engramory.md` (it is `inclusion: always` and pulls in the live index via\n`#[[file:.engramory-memory/MEMORY.md]]`), and keep your notes in a **non-steering**\n`.engramory-memory/` folder.\n\n\u003e ⚠️ **Do not drop notes into `.kiro/steering/`.** A steering file with no `inclusion`\n\u003e front-matter defaults to `inclusion: always`, so every note would load into every\n\u003e request and **blow up your context** — the #1 Kiro install mistake. Only the index\n\u003e belongs in always-loaded steering; notes stay in `.engramory-memory/` and open on\n\u003e demand. Cap is rules + `engramory_check.py` for now (a deterministic Kiro `PreToolUse`\n\u003e hook is possible but not yet shipped/tested). Full notes:\n\u003e [adapters/kiro/README.md](adapters/kiro/README.md).\n\n### Any other agent (Hermes, Cursor, Cline, Windsurf, …)\nEngramory is model-agnostic (DeepSeek, GPT, Llama, …) and rides on the host's own\nmemory store. Full wiring is in **[PORTING.md](PORTING.md)**; in short: paste\n[`rules-snippet.md`](rules-snippet.md) into the host's always-loaded rules (so the\ndiscipline is always-on, not just a by-relevance skill), import [`SKILL.md`](SKILL.md)\nif the host supports skills, point `\u003cMEMORY_ROOT\u003e` at the host's memory dir, and\nwire the size cap at the strongest rung the host supports: PreToolUse hook →\n`tools/engramory_check.py` after each index write → model discipline, with\n`tools/engramory_doctor.py` as a periodic backstop. A deterministic cap needs a\npre-write *deny* hook. Only Claude Code's is written and tested here; some other hosts\nexpose one too (Hermes; Cursor, though its is newer/flaky), so the cap is portable with\na per-host I/O shim you write and verify yourself — while OpenClaw can only block via a\n`before_tool_call` plugin and some hosts have none. See [PORTING.md](PORTING.md) for the\nper-host picture. Where no such hook exists (or plain chat), the cap degrades to\nbest-effort discipline (see [SKILL.md](SKILL.md) §9).\n\nFirst connecting a *pre-existing* store to the strict `doctor` surfaces a wall of\nmechanical issues (missing `created`/`updated`, Why/How not yet in canonical form) —\ndon't blindly fix them. See PORTING.md's [Adopting an existing store](PORTING.md): run\n`--no-schema` for structure first, batch-backfill dates with the snippet, then\nhand-write Why/How.\n\nA plain chat UI with no file access / no rules mechanism cannot run Engramory — it\nneeds a host that executes skills/rules and can read \u0026 write files.\n\n## Configuration\n\n- **`\u003cMEMORY_ROOT\u003e`** — where memory lives. Keep it somewhere you'll actually\n  look; `.gitignore` it inside repos.\n- **Index limits** — soft warn / hard cap default 150 / 200 lines and 20 / 25 KB;\n  override via the hook's env vars (see `hooks/`).\n\n## Security \u0026 privacy\n\nThe store is **plain, unencrypted text** that any local process can read. `.gitignore`\nkeeps it out of git — it is **not** encryption, and it does nothing against\ncloud-sync clients (Dropbox / iCloud / OneDrive), OS backups, or desktop search. If\nyour `\u003cMEMORY_ROOT\u003e` sits in a synced or backed-up folder, its contents leave your\nmachine.\n\n- **Never write a secret's *value*** into memory — keys, tokens, passwords,\n  cookies, recovery codes. Record only *where* the secret lives (e.g. \"in the\n  password manager / env var `FOO`\"). An IP / path / serial used as a locator is\n  fine; a credential value never is.\n- Minimize partial PII (phone, email, address) — prefer a pointer.\n\nThis discipline is **unenforced** (no hook scans memory content — see\n[SKILL.md](SKILL.md) §5/§8); treat it as best-effort and be deliberate.\n\n## Known limitations\n\nEngramory is a **single-project, single-writer, personal-scale** protocol. It does\n*not* yet have:\n\n- **Versioning / migration** — no `schema_version`; no defined upgrade path if the\n  frontmatter format changes. (For onboarding a *pre-existing* store, PORTING.md's\n  \"Adopting an existing store\" has a triage recipe + a date-backfill snippet.)\n- **Provenance / trust** — no `source`, `confidence`, `last_verified`, expiry, or\n  `superseded-by` fields. Recalled memory is advisory and attacker-influenceable\n  (see [SKILL.md](SKILL.md) §4); there is no authentication of memory content.\n- **Scope / multi-project** — no `scope` / `project_id`; one flat slug namespace, so\n  a store shared across projects/agents would hit slug collisions and project bleed.\n  A store-level manifest (protocol version + scope + host config) is the planned\n  first step — not built yet.\n- **Concurrency** — single writer / serialized writes assumed (no locking).\n- **Scale** — the always-loaded flat index bounds the *active* set to what fits the\n  cap (~200 pointers). It is a personal / curated-scale tool, not a large corpus;\n  above that, a retrieval-based system (basic-memory, mem0) is the right tool.\n\n## Prior art \u0026 credits\nAndrej Karpathy's **LLM Wiki / Knowledge Base** (the markdown-over-RAG pattern, the\nmost prominent statement of this approach — note it targets a knowledge\n*encyclopedia*, where Engramory targets agent *working* memory: who the user is,\nhow the agent should behave, project state) · Claude Code auto-memory · basic-memory ·\nobsidian-second-brain · claude-memory-compiler (itself Karpathy-inspired) · the\nAnthropic memory tool · OpenAI Codex memory (and its earlier topics-memory proposal\n#19758) · [agentmemory](https://github.com/rohitg00/agentmemory) (a heavyweight,\nlocal-first counterpart — auto-capture + SQLite/`iii` engine + hybrid BM25/vector\nretrieval; the opposite design point to Engramory's zero-infra hand-curation) ·\nthe wider markdown-memory community.\n\n## License\nMIT — see [LICENSE](LICENSE).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftinqiao-oss%2Fengramory","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftinqiao-oss%2Fengramory","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftinqiao-oss%2Fengramory/lists"}