# engramory

> Inject Engramory memory discipline

## Metadata

- Author: [@tinqiao-oss](https://github.com/tinqiao-oss)
- Repo: <https://github.com/tinqiao-oss/engramory.git>
- GitHub: [tinqiao-oss/engramory](https://github.com/tinqiao-oss/engramory)
- Stars: 165
- Language: Python
- License: [MIT](https://spdx.org/licenses/MIT.html)
- Topics: `agent-memory`, `ai-agents`, `claude-code`, `codex`, `deepseek-harness`, `dsh-plugin`, `knowledge-base`, `llm-memory`, `long-term-memory`, `markdown`, `memory`, `prompt-engineering`, `zero-dependency`
- Forks: 12
- Open Issues: 2
- Last push: 2026-08-20T07:29:09.000Z
- Added: 2026-08-16T00:00:00.000Z

## Install

```bash
dsh plugin --profile web add github:tinqiao-oss/engramory
```

## Wiki

## One-Line Pitch
engramory brings Engramory's memory discipline to DSH: always load a resident rule in the host with "index no more than 200 lines / 25 KB", and make this limit a **hard stop that actually rejects** (once a rejection reason is returned, subsequent listeners cannot overturn it), while registering a same-named skill with the host to ensure the protocol comes with the plugin.

## Core Capabilities
- Takes the 200 line / 25 KB dual-dimension limit from MEMORY.md as a synchronous rejection rule and embeds it into DSH's pre-write guard; writes that exceed cap and continue to grow are blocked directly
- Progressive compression always passes: exceeded-cap indexes that are reduced are allowed to write, 210 → 205 → 198 such gradual shrinking can proceed all the way
- Smart judgment of "read-only vs rewrite": read, view, ls and any unrecognized tools are always allowed; exceeded-cap indexes must still be readable, otherwise compression cannot proceed
- Automatically simulates reducible partial edits (edit / str_replace with old_str/new_str), rejecting based on **simulation results** rather than parameter size
- Full file overwrite and str_replace_editor's create / str_replace / insert commands are all covered; unsimulated partial writes on exceeded-cap indexes are rejected with guidance to use full file overwrite
- Index filename matches case-insensitively (memory.md equals MEMORY.md on Windows/macOS), but only checks basename, not affecting unrelated files in other same-named directories

## Technical Implementation
- **Language**: JavaScript (ESM)
- **Key Dependencies**: Zero dependencies (only uses `node:fs`'s `readFileSync`, `node:path`'s `basename`); declares interface dependency on `@deepseek-ai/dsh-tools >=0.0.1-rc.1` through `peerDependencies`
- **Architecture Pattern**: Injects `cordis.patch.yml` into the profile's plugin tree via `dsh.bundle`, inserting a line of `id: engramory` config (with indexName / maxLines / maxBytes defaults); at runtime registers a synchronous pre-write guard via `ctx.tools.guard()`, and optionally contributes a same-named skill via `ctx.skills.register()` with `source: 'runtime'`
- **Entry File**: `adapters/dsh/plugin/index.js`

## Use Cases
You run long tasks in DSH and want to use a lightweight local file memory bank (one MEMORY.md index + multiple detail notes) to remember key facts across sessions, but worry about the index getting out of control—the part exceeding the loading window gets silently dropped and can never be recalled. After installing this plugin, out-of-bounds writes are directly rejected, prompting you to compress according to the spec, while normal reads still work. If you only use DSH but other hosts (like Claude Code) already have sufficient native caps, this plugin's role is upgrading the weak guarantee of "rules + model running check tool itself" into a strong guarantee of "tool calls get blocked at the tool layer".

## Prerequisites & Compatibility
| Dependency | Minimum Version | Description |
|---|---|---|
| Node | >=18 | Explicitly declared in `adapters/dsh/plugin/package.json#engines.node` |
| DSH Host (`@deepseek-ai/dsh-tools`) | >=0.0.1-rc.1 | `peerDependencies` in package.json; runtime requires exposing `ctx.tools.guard()` and optional `ctx.skills.register()` |
| Operating System | Cross-platform | No `os` restrictions, no native modules; pure ESM, only uses node built-ins `fs` / `path` |
| Native Modules | None | No node-gyp, no system C library dependency, runs on all three major OSes |
| Memory Bank Itself | — | Plugin doesn't create MEMORY.md or generate AGENTS.md resident rules; run `python tools/engramory_init.py dsh --install-skill` separately |

## Installation
```bash
dsh plugin --profile web add github:tinqiao-oss/engramory
```

## Configuration Options
The DSH profile's patch layer inserts a line of `id: engramory` when the plugin loads; its `config` field is the table below; to customize, override the entire block in your profile with `- id: engramory` and list all keys you want to keep (patch replaces the whole block rather than merging).

| Config | Type | Description | Default |
|---|---|---|---|
| indexName | string | File name treated as index (only basename, case-insensitive); guard only applies to it; empty string or non-string falls back to default | MEMORY.md |
| maxLines | integer | Hard line limit; non-finite or non-positive integer falls back to default | 200 |
| maxBytes | integer | Hard UTF-8 byte limit (25 KB); non-finite or non-positive integer falls back to default | 25600 |
| registerSkill | boolean | When false, only installs guard, no runtime skill registration (for profiles where host doesn't mount skill registry) | true |
| skill | string | Custom skill body markdown; empty uses plugin's built-in slim protocol (includes Recall / Write / Sync / index cap rules) | Built-in markdown |

## FAQ
**Q: Does installing this plugin automatically generate my memory bank?**

A: No. The plugin only enforces the 200 line / 25 KB limit as a hard stop and registers a skill named `engramory` with the host; the memory bank and rule files need to be created separately by running `python tools/engramory_init.py dsh --install-skill` from the Engramory repository.

**Q: Can I still compress after the index exceeds the cap?**

A: Yes, and you must be able to. The rule is: reject only if the write **causes** the index to exceed the limit **and** is **larger than the current file**—a 210-line index being compressed to 205, then to 198, will all pass; progressive compression is always feasible and won't lock you out.

**Q: What do I do when I see a rejection prompt?**

A: The rejection reason directly tells you the current line count / byte count and the limit. Split long lines into "one-sentence summary + link", merge duplicate entries, archive cold notes, then use full file overwrite (`write` or `str_replace_editor`'s `create`) to compress in one go; the next full file write will pass.

**Q: Where do I go to adjust the cap size?**

A: Don't add another `- insert:` in the original profile—that creates two engramory lines and the original caps still take effect. The correct approach is to override that line's config in your profile's own patch layer with `- id: engramory`, and list all keys you want to keep (patch replaces the whole block).

**Q: Does it include native modules?**

A: No. The plugin is pure ESM, only uses `node:fs` and `node:path` two built-in modules, no node-gyp, doesn't care about Node ABI, runs on all three major operating systems.

**Q: Will reading MEMORY.md be blocked?**

A: No. The guard only makes decisions on tools known to modify files (write/edit/str_replace etc.); read, view, ls and any unrecognized tools are always allowed—this is by design: exceeded-cap indexes must still be readable, otherwise you'd be stuck in a deadlock of "wanting to compress but can't see the content".

**Q: Why does `dsh plugin add` fail to install on dsh 0.1.0-rc.6?**

A: This is an upstream dsh preview packaging issue: the `dsh plugin` command uses unbundled pnpm, and the dependency `@deepseek-ai/dsh-type-meta` cannot be found on the registry. Before the fix is released, the plugin's decision table is still guarded by the 21 `node --test` test cases in the repository, credibility unaffected.

## Learning Curve
Beginner — installation is one command; `cordis.patch.yml` has already injected reasonable default caps into the profile, ordinary users basically don't need to change configuration; only advanced users who want to "change index filename" or "relax the cap" need to touch the patch.

## Known Issues & Limitations
- For partial writes like `insert` where the result cannot be还原 from parameters, if they jump from "not exceeding cap" to "exceeding cap" in one go, the current guard won't catch it immediately; the next full file overwrite will be blocked, or caught by external `engramory_check.py`. Partial writes that cannot be simulated on already exceeded-cap indexes will definitely be blocked.
- The guard's tool whitelist covers dsh's documented tool-fs contracts (`write`/`edit` use `file_path`, `str_replace_editor` uses `path`); unknown tools are always allowed; this is a discipline guardrail rather than a security boundary—the cost of wrongly blocking `read` is far higher than missing one write.
- DSH is still developer preview, host plugin APIs may change; this plugin only touches `ctx.tools.guard()` and `ctx.skills.register()` two surfaces, migration cost is deliberately kept minimal.
- Third-party plugins installed via `dsh plugin` command to profiles are not yet usable on dsh 0.1.0-rc.6 (upstream packaging issue, not a plugin defect), during this period can only mount the plugin body directly at source code level.
- The plugin won't create MEMORY.md or rule files for you—the memory bank itself needs to be initialized separately according to the Engramory protocol.

---

This document is auto-generated by [deepseek-plugin.org](https://deepseek-plugin.org). HTML page: [engramory](https://deepseek-plugin.org/plugins/tinqiao-oss/engramory)
Wiki generated by AI (model: `MiniMax-M2.5`)
