marchliu/hypatia/hypatia-memory
Claude Code and agent skill by marchliu/hypatia
- community
Checking that the SKILL.md file is still in the repository.
Automatic memory extraction and management for hypatia knowledge graph
Install
npx vskill@latest install marchliu/hypatia/hypatia-memorySKILL.md
Hypatia Memory System
You are an automatic memory management system built on hypatia. Your job is to:
- Log every conversation turn into the knowledge graph (messages, sessions, hierarchical summaries).
- Construct AI API messages with system prompt + uncompressed history + reference info + latest user input.
- Extract semantic memories (rules, taboos, work units) using the original extraction rules.
All layers run in the same hook invocations; conversation logging always runs first.
Trigger Conditions
This skill is activated via hooks in ~/.claude/settings.json (or Cursor equivalent):
| Hook Event | When | Output Signal | AI Response | |
|---|---|---|---|---|
UserPromptSubmit | Every user message | TRIGGER:log | Record user message + check summary cascade + optional semantic extract | |
UserPromptSubmit | Every user message (if remember/forget) | TRIGGER:immediate | Explicit remember/forget (semantic layer) | |
UserPromptSubmit | Every 5 turns | TRIGGER:extract | Scan for completed work units (semantic layer) | |
Stop / assistant turn hook | Session end or each assistant reply | TRIGGER:log | Record assistant message + check summary cascade | |
Stop | Session ending | TRIGGER:session-end | Record session summary if available + final semantic extract pass |
On every `TRIGGER:log`: always execute Conversation Logging Protocol first.
If the hook outputs nothing (no trigger), no action is needed.
Codex Hooks Integration (Codex CLI / Desktop App)
The same protocol runs natively in Codex via ~/.codex/hooks.json (see codex-integration/ in the Hypatia repo). The bundled scripts translate Codex lifecycle events into the exact trigger signals above:
| Codex event | Hook script | What it does | |
|---|---|---|---|
SessionStart | hypatia_session_start.sh | Loads project/global rules + taboos and injects them as additionalContext | |
UserPromptSubmit | hypatia_user_prompt_submit.sh | Logs the user message, recalls relevant memories, emits TRIGGER:log + optional TRIGGER:immediate / TRIGGER:extract (every 5 turns) / TRIGGER:summary (≥16 unsummarized) | |
Stop | hypatia_stop.sh | Logs the assistant message (side-effect only; Codex Stop hooks cannot inject context) |
Installation: ./codex-integration/install.sh, restart Codex, then review and trust the hooks (CLI: /hooks; desktop app: Settings → Hooks).
OpenCode Integration
OpenCode runs the same policy natively via the plugin in opencode-integration/ of the Hypatia repo (installed at ~/.opencode/hypatia-memory-plugin/, registered in opencode.json). It logs user messages in full, accumulates assistant text/tool parts itself, applies the content policy above (intent shaping, tool-call ledger, stack stripping, secret redaction, date absolutization) in the hook process with zero model calls, and writes msg-<session>-<turn> entries directly. When following this skill in an OpenCode session, do not duplicate those writes — only perform the summary cascade and semantic extraction on top of them.
The hook scripts are thin, deterministic shells: they write message entries (msg-<session_id>-<turn_id>, tag message, kept out of the vector index) and retrieval context, and emit trigger signals. The AI-heavy steps in this document (summary synthesis, work-unit extraction) are still performed by the agent following this skill — the hooks never make model calls.
Session Startup
When a new session begins, load relevant rules and taboos:
- Determine the current project name from the working directory (use
basenameof the git root or CWD) - Run these queries to load rules and taboos for the current project and global scope:
- Confirm the scope spelling this shelf already uses, so the session's writes land
in the same scope its reads come from:
exists exits 0 when the scope is in use and 1 when it is not. On 1, list shows what is there: if the shelf already holds my-app and the working directory is my_app, write my-app. A scope nobody else uses is a new island — every later lookup by the spelling the rest of the shelf uses will miss everything written under it. The same holds for tags: check hypatia tag list before introducing a label outside the vocabulary below.
list prints the global scope as (global), which is a label and not the value; use hypatia scope list --json when you are going to write a value back verbatim.
- Internalize these rules and taboos for the current session. Follow rules and avoid taboos in all interactions.
Conversation Logging Protocol
This protocol runs on every user and assistant message (TRIGGER:log). It is independent of semantic work-unit extraction.
Identifiers
Resolve from hook context when available; otherwise derive:
| Field | Source | |
|---|---|---|
<PROJECT> | basename of git root or CWD | |
<SESSION_ID> | Hook session_id, Cursor conversation_id, or stable hash of transcript path | |
<TURN> | Monotonic turn counter within session (increment per logged message) | |
<ROLE> | user or assistant |
Step 1: Record the message
Every conversational turn becomes one knowledge entry.
Rules:
- One message → one knowledge entry. Never batch multiple turns.
- Tag is
message(no role tag; use content to determine role). - Name is auto-generated:
msg-<SESSION_ID>-<TURN>. - Do not skip trivial messages (greetings, "ok", etc.) — the log layer is complete.
- Never store secrets (passwords, API keys, tokens) — redact before writing.
--no-embedkeeps the raw turn out of the vector index. The log layer is not on
the retrieval hot path — precise recall goes through the summaries and drills down — so embedding it costs a forward pass on every turn and lets raw wording outrank the knowledge distilled from it. The entry is still stored and still found by search and query. A shelf can set the same rule once instead, in shelf.toml:
``toml [embedding] skip_tags = ["message", "session"] ``
With that in place the flag is redundant for knowledge entries. A change to skip_tags applies to entries written after it; run hypatia backfill once to settle the ones already stored.
Content policy for assistant messages (MANDATORY)
Shape what you save by what the user asked for, not by what the assistant produced:
| User intent (from the triggering question) | Save as | |
|---|---|---|
| Data-analysis / report request (报告/分析/统计/summary…) | Report summary: heading structure + opening + conclusion paragraphs (≈500 chars each) — not the full report | |
| Operation task (运行/修复/部署/安装/create/fix…, or tools were invoked) | Operation ledger: 用时 (wall time) / 手段 (tools used × count) / 结果 (final outcome statement, ≤600 chars) | |
| Discussion (default) | Markdown context: the full reply body |
Tool-call ledger (applies to EVERY intent)
For tool calls, bash, MCP and other external invocations, record what was called, how long, and whether it succeeded — never raw outputs:
- Repeated identical calls collapse into one entry with a repeat count.
- On failure keep only a one-line error description: strip JS/Python/Rust stack traces (
at ...frames,Traceback (most recent call last):,stack backtrace:,note:lines); keep the final exception line. - Native crash dumps with no readable message (e.g. Windows access violation: hex addresses +
module!symbolframes) reduce to a one-line brief such as原生崩溃: 内存访问违例 (access violation)(无有效错误消息,地址与堆栈细节已省略).
Write-time transforms (both roles)
- Secret redaction:
sk-…,Bearer …,apiKey=…,password=/token=/secret=…, AWSAKIA…, GitHubghp_…, GitLabglpat-…, Slackxox…, PEM private-key blocks. - Relative → absolute dates: convert
今天/昨天/明天/上周/本周/下周/刚才/现在/N 天(小时/分钟)前/today/yesterday/N days agoagainst the actual write time (e.g.昨天→2026-09-07).
Step 2: Record session knowledge (when summary available)
If the hook or environment provides a session-level summary (e.g. compaction summary, session title, or end-of-session digest):
- Create
session-<SESSION_ID>the first time a summary arrives;knowledge-createfails on an existing name. When newer summary text arrives, replace it withhypatia knowledge-update "session-<SESSION_ID>" -d "<session summary text>". Its tags, scopes andcreated_atare kept, and thebelongTolinks are untouched. - If no session summary is available, skip this step — do not fabricate session summaries.
Step 3: Link message to session
When both msg-<SESSION_ID>-<TURN> and session-<SESSION_ID> exist:
Predicate is exactly belongTo (message → session).
--no-embed is needed here even on a shelf that sets embedding.skip_tags: statements carry no tags, so skip_tags cannot reach them and this per-turn link would otherwise be the one embedding the log layer still pays on every turn. The link is for graph traversal, not semantic search — nothing looks for "belongTo" by meaning. Unlike a knowledge entry, a statement has no update command, so this choice is made once at creation.
Step 4: Hierarchical summary cascade
After writing each new message, run the cascade from level 1 upward.
Constants: BATCH_SIZE = 16 (for L2+)
Predicate: All summary triples use predicate summary.
| Triple | Meaning | |
|---|---|---|
<summary-name> summary <item-name> | Summary condenses the item |
| Level | Tag | Triggers when | Summarizes | |
|---|---|---|---|---|
| 1 | ["summary", "summary 1"] | Token count ≥ max_tokens × 0.9 | message entries | |
| 2 | ["summary", "summary 2"] | Count ≥ 16 unlinked L1 | summary 1 entries | |
| N | ["summary", "summary N"] | Count ≥ 16 unlinked L(N-1) | summary (N-1) entries |
Token-based L1 threshold:
- Estimate tokens by character count / 4 (agent-side estimation).
max_tokensdepends on the model in use (e.g. GLM-5.1: 200k, DeepSeek V4 Pro: 1M).- When the accumulated token count of unsummarized messages reaches 90% of the model's max_tokens, trigger L1 summary generation.
Context compression trigger:
- If context tokens reach
settings.max_token × 0.9, also trigger summary generation and start a new session. This is independent of the L1 count/trigger — it's an emergency compression.
4a. Check unsummarized items at level L
Use $not-summarised (native JSE operator with LEFT JOIN):
Or use the shorthand:
| Level | <TAG> | |
|---|---|---|
| 1 | message | |
| 2 | summary 1 | |
| N | summary (N-1) |
Results are sorted oldest first (ASC). For L1: count tokens (estimate chars/4). For L2+: take first 16 if count ≥ 16.
This is the start of the file. Read the full SKILL.md on GitHub.
Security
- Security scanPassed, 95 of 100Pattern checks on the skill's files.
- Model reviewPassed
Quality evaluation
- Task evaluationNot runNo evaluation yet. Run one in Skill Studio.
Source
- SKILL.md in the repositoryCheckingskills/hypatia-memory/SKILL.md
Popularity
- Repository stars
- 226
- Repository forks
- 14
- 7-day trend score
- 27
Stars and forks are for the whole GitHub repository, not this skill alone. Not refreshed yet.
Works with
Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.
- Claude Code
- Cursor
- GitHub Copilot
- Windsurf
- Codex
- Gemini CLI
- Cline
- Amp
- Roo Code
- Goose
- Continue
- Kilo Code
- Junie
- Trae
- OpenHands
- Qwen Code
- AI Agent
- Tabnine Chat
- Sourcegraph Cody
- Amazon Q
- Firebase Genkit
- Sweep
- Devin
- Phind
- Mentat
- Claude Desktop
- Aider
- GPT Pilot
- Plandex
- bolt.new
- v0
- Replit Agent
- Anse
- TypingMind
- BetterChatGPT
- LibreChat
- Warp AI
- Pieces
- Fig AI
Embed badge
[](https://verified-skill.com/skills/marchliu/hypatia/hypatia-memory)