/sibyl-save - Session Memory Sync + Skill Extraction (Sibyl Memory Plugin)
Part of the Sibyl Labs open skill collection. MIT licensed. Built by Sibyl Labs, LLC.
A companion skill for the Sibyl Memory Plugin. It captures everything that happened this session and injects it into the plugin's local memory database (~/.sibyl-memory/memory.db) through the plugin's own interface, then extracts reusable patterns into new skills.
It does not write raw memory files. All memory goes through the plugin so tiering, full-text indexing, and the free-tier cap are honored. Because the plugin exposes the same MCP tools on every harness it supports (Claude Code, Codex, and any MCP host; Hermes via the Python SDK), this one skill is multi-harness by construction.
Requirements
The Sibyl Memory Plugin, installed and wired:
pip install sibyl-memory-cli
sibyl init # browser/wallet activation, writes ~/.sibyl-memory/
sibyl setup claude-code # or: codex | hermes (wires the memory interface into your harness)
This skill then talks to the plugin through one of two surfaces:
- MCP (Claude Code, Codex, Cursor, any MCP host): the 8
memory_* tools below.
- Python SDK (Hermes or any Python agent):
sibyl_memory_client.MemoryClient / sibyl_memory_hermes.SibylMemoryProvider.
The plugin interface
| Purpose |
MCP tool |
Python SDK |
| Save a fact / entity |
memory_remember(category, name, body) |
client.set_entity(category, name, body) |
| Recall an entity |
memory_recall(category, name) |
client.get_entity(category, name) |
| List entities |
memory_list(category, limit) |
client.list_entities(category) |
| Full-text search |
memory_search(query, limit, tiers) |
client.search(query) |
| Set a state doc |
memory_set_state(key, body) |
client.set_state(key, body) |
| Get a state doc |
memory_get_state(key) |
client.get_state(key) |
| Record a journal event |
memory_record_event(kind, body, category, name) |
client.write_event(...) |
| Archive / forget |
memory_forget(category, name, reason) |
client.archive_entity(category, name, reason) |
Examples below use the MCP names. On Hermes or a Python agent, use the SDK column.
Tier mapping
| Session content |
Tier |
Call |
| Session pointer / summary / forward items |
HOT (state) |
memory_set_state("session", ...) |
| Ranked priorities |
HOT (state) |
memory_set_state("priorities", ...) |
| Session log entry |
COLD (journal) |
memory_record_event("session_save", ...) |
| Projects / people / products |
WARM (entities) |
memory_remember(category, name, body) |
| Closed / dead items |
ARCHIVE |
memory_forget(category, name, reason) |
| This skill's config + delta marker |
HOT (state) |
memory_set_state("sibyl_save:config" / "sibyl_save:last_save", ...) |
Modes
- run (default):
/sibyl-save, save session, sync memory. Inject session context into the plugin, then offer skill extraction.
- setup:
/sibyl-save setup, /sibyl-save config. Interactive. Build or edit the config (stored in the plugin at state key sibyl_save:config). Run once before first use.
- preview (dry run):
/sibyl-save preview, /sibyl-save --dry-run. Run the full analysis and report every planned write. Call nothing that mutates the DB. Do not advance the delta marker.
Mode: setup (dynamic config)
Goal: write the config to the plugin at state key sibyl_save:config. Be interactive and minimal. Infer what you can; ask only what you cannot.
- Harness. Detect or ask which harness this is (claude-code, codex, cursor, hermes, other). This drives where Phase 2 writes skill files.
- Skill output. Where new skills get written for this harness. Default for Claude Code:
.claude/skills/<name>/SKILL.md. For other harnesses, confirm the skill location and format. Store as skill_output: {dir, format}.
- Priorities. State key for the ranked list (default
priorities) and a cap. Default cap 15. Hard ceiling 30: never accept a value above 30. A list longer than 30 is a backlog, not a set of priorities.
- Entity categories. Which WARM categories you track (default
project, person, product). User adds or removes.
- Additional capture. Optionally name extra state keys or entity categories the save should populate each run (a metrics state doc, a contacts category). This is the extension point.
- Dry-run default. Toggle
dry_run_default (default false).
- Write the config via
memory_set_state("sibyl_save:config", {...}). Do not touch the delta marker.
Config shape: see examples/sibyl-save-config.example.json. Re-running setup edits it in place.
Mode: run
Phase 1: Memory Sync (into the plugin DB)
Step 0 - Load config + delta
memory_get_state("sibyl_save:config"). If absent, switch to setup. memory_get_state("sibyl_save:last_save") for the delta anchor (what changed since the last save). If dry_run_default is true and no mode was given, run as preview.
Step 1 - Read current state
memory_get_state("session") and memory_get_state(<priorities key>)
memory_list(category, limit) for tracked categories, and memory_recall / memory_search for entities touched this session
- any additional state keys or categories named in config
Step 1.5 - Priorities check + reconcile
Read the priorities state doc and reconcile in place (write back with memory_set_state). Conditions and the action each requires:
- COMPLETED item still listed: drop it; record the closure via
memory_record_event("priority_closed", {...}).
- RANK_DRIFT / DUP_RANK (ranks not contiguous 1..N, or a rank repeats): renumber to 1..N.
- OVER_CAP (more items than the cap): move the lowest-priority items to a backlog state doc until at or under cap.
- STALE_ITEM (>14 days untouched): surface it to the user.
- TERMINAL entity (the referenced entity is archived/dead): close the priority.
- BROKEN entity ref (points at no real entity): fix it to a real
category/name.
Enforce the cap on every write (never exceed 30).
Step 2 - Analyze the session
Review the conversation since the delta anchor (or since session start on first save). Extract:
- Entities touched - projects, people, products created, read, or modified
- Actions taken - concrete things that happened, with identifiers
- Decisions made - strategic choices and their rationale
- Forward items - next-session actions, verb-first ("deploy...", "follow up with...", "verify...")
- Warnings - active risks, blockers, deadlines, near-misses
- Lessons learned - operational improvements (these feed Phase 2)
- Additional captures - data for any extra state keys / categories in config
Step 3 - Inject into the plugin DB
In preview mode, call nothing that mutates. Report the planned writes (Step 4) and stop.
- Session state -
memory_set_state("session", { last_session, summary, forward, entities_touched, warnings }). Forward items are action references only, never balance snapshots or anything that goes stale.
- Journal event -
memory_record_event("session_save", { evaluated, acted, forward, extra }). One event per save (append-only by design).
- Priorities -
memory_set_state(<priorities key>, { updated, cap, items }), capped. Overflow to a backlog state doc.
- Entities - for each changed entity,
memory_remember(category, name, body). New entities are just new memory_remember calls; the plugin indexes them, so there is no separate registry to maintain.
- Closed / dead -
memory_forget(category, name, reason).
- Additional captures - apply each configured extra state key / category.
- Delta marker -
memory_set_state("sibyl_save:last_save", { ts: <now> }). Skip in preview.
Step 4 - Report
Concise summary: entities written, state docs updated, journal event id, priorities added/closed, additional captures, and forward items for next session. In preview mode, label every line "would" and confirm nothing was written.
Phase 2: Skill Extraction (harness-native)
Skills are presented the same way regardless of harness: identify, propose, then create as a native skill file for the current harness.
Step 5 - Identify reusable patterns
Scan the session for operations meeting ANY of these: repeated (more than once this session), recurring (likely again), multi-step (3+ sequential steps), non-obvious (a workaround worth keeping), error-prone (needs a checklist). For each candidate evaluate name (short imperative verb phrase), trigger, parameters, complexity (any dangerous steps), frequency.
Step 6 - Propose candidates
Present each as a one-liner with name, description, and estimated frequency. Then ask: "Create these? Or skip any?"
Step 7 - Create approved skills (harness-native)
Read skill_output from config to know where and in what format this harness expects skills. Defaults:
| Harness |
Skill location |
Format |
| claude-code |
.claude/skills/<name>/SKILL.md |
YAML frontmatter (name, description) + Markdown body |
| codex |
~/.codex/prompts/<name>.md (confirm in setup) |
Markdown prompt |
| cursor |
.cursor/ command/rule (confirm in setup) |
per Cursor convention |
| other |
from skill_output.dir |
from skill_output.format |
For each approved skill, write the file at the configured location with trigger phrases, step-by-step instructions, parameter descriptions, safety checks for any dangerous step, and an example invocation. Report the path.
Do NOT create skills that: duplicate an existing skill (check the skill location first), are too session-specific to recur, wrap a single trivial command, or require editing files your operating rules protect (surface those, do not self-edit).
Rules (non-negotiable)
- Never store live data (balances, prices, counts) as durable facts. Capture references, not snapshots.
- Session forward items are action-oriented and verb-first.
- One journal event per save (append-only; never rewrite history).
- Priorities are capped (default 15, never above 30). Overflow to a backlog state doc.
- Entities are addressed by
category + name; let the plugin be the index. No parallel registry.
- All memory writes go through the plugin interface. Never write
~/.sibyl-memory/ files or open memory.db directly: the client handles locking and the free-tier cap.
- Treat existing skills as read-only. Create new ones rather than editing in place unless explicitly asked.
License & provenance
MIT (see LICENSE). The watermark comment at the top of each Markdown file is attribution and provenance, not a usage restriction. Verify a copy with node scripts/watermark.mjs verify. Details in WATERMARK.md.
1---2name: sibyl-save3description: Session memory sync and skill extraction for the Sibyl Memory Plugin. Injects session context into the plugin's local memory DB (entities, state, journal) through the plugin interface, then extracts reusable patterns into harness-native skills. Use at the end of a session or after a major block of work. Triggers - /sibyl-save, save session, sync memory, /sibyl-save setup, /sibyl-save preview.4---5<!-- SIBYL-SKILL-WATERMARK-BEGIN6 origin: sibyl-labs7 build: 2026-06-17T19:19:06Z8 release: v1.0.09 file: SKILL.md10 hash: sha256:68d324246fcd4f5316d369990a0778e54e023af60d6aa83359080e1d37aca91611 notice: Part of the Sibyl Labs open skill collection. MIT licensed (see LICENSE). Free to use, modify, and redistribute with this notice preserved. Built by Sibyl Labs, LLC. Verify or report at sibyl@sibyllabs.org.12SIBYL-SKILL-WATERMARK-END -->1314# /sibyl-save - Session Memory Sync + Skill Extraction (Sibyl Memory Plugin)1516Part of the Sibyl Labs open skill collection. MIT licensed. Built by Sibyl Labs, LLC.1718A companion skill for the **Sibyl Memory Plugin**. It captures everything that happened this session and injects it into the plugin's local memory database (`~/.sibyl-memory/memory.db`) through the plugin's own interface, then extracts reusable patterns into new skills.1920It does not write raw memory files. All memory goes through the plugin so tiering, full-text indexing, and the free-tier cap are honored. Because the plugin exposes the same MCP tools on every harness it supports (Claude Code, Codex, and any MCP host; Hermes via the Python SDK), this one skill is multi-harness by construction.2122## Requirements2324The Sibyl Memory Plugin, installed and wired:2526```bash27pip install sibyl-memory-cli28sibyl init # browser/wallet activation, writes ~/.sibyl-memory/29sibyl setup claude-code # or: codex | hermes (wires the memory interface into your harness)30```3132This skill then talks to the plugin through one of two surfaces:3334- **MCP** (Claude Code, Codex, Cursor, any MCP host): the 8 `memory_*` tools below.35- **Python SDK** (Hermes or any Python agent): `sibyl_memory_client.MemoryClient` / `sibyl_memory_hermes.SibylMemoryProvider`.3637### The plugin interface3839| Purpose | MCP tool | Python SDK |40|---------|----------|------------|41| Save a fact / entity | `memory_remember(category, name, body)` | `client.set_entity(category, name, body)` |42| Recall an entity | `memory_recall(category, name)` | `client.get_entity(category, name)` |43| List entities | `memory_list(category, limit)` | `client.list_entities(category)` |44| Full-text search | `memory_search(query, limit, tiers)` | `client.search(query)` |45| Set a state doc | `memory_set_state(key, body)` | `client.set_state(key, body)` |46| Get a state doc | `memory_get_state(key)` | `client.get_state(key)` |47| Record a journal event | `memory_record_event(kind, body, category, name)` | `client.write_event(...)` |48| Archive / forget | `memory_forget(category, name, reason)` | `client.archive_entity(category, name, reason)` |4950Examples below use the MCP names. On Hermes or a Python agent, use the SDK column.5152### Tier mapping5354| Session content | Tier | Call |55|-----------------|------|------|56| Session pointer / summary / forward items | HOT (state) | `memory_set_state("session", ...)` |57| Ranked priorities | HOT (state) | `memory_set_state("priorities", ...)` |58| Session log entry | COLD (journal) | `memory_record_event("session_save", ...)` |59| Projects / people / products | WARM (entities) | `memory_remember(category, name, body)` |60| Closed / dead items | ARCHIVE | `memory_forget(category, name, reason)` |61| This skill's config + delta marker | HOT (state) | `memory_set_state("sibyl_save:config" / "sibyl_save:last_save", ...)` |6263## Modes6465- **run** (default): `/sibyl-save`, `save session`, `sync memory`. Inject session context into the plugin, then offer skill extraction.66- **setup**: `/sibyl-save setup`, `/sibyl-save config`. Interactive. Build or edit the config (stored in the plugin at state key `sibyl_save:config`). Run once before first use.67- **preview** (dry run): `/sibyl-save preview`, `/sibyl-save --dry-run`. Run the full analysis and report every planned write. Call nothing that mutates the DB. Do not advance the delta marker.6869---7071## Mode: setup (dynamic config)7273Goal: write the config to the plugin at state key `sibyl_save:config`. Be interactive and minimal. Infer what you can; ask only what you cannot.74751. **Harness.** Detect or ask which harness this is (claude-code, codex, cursor, hermes, other). This drives where Phase 2 writes skill files.762. **Skill output.** Where new skills get written for this harness. Default for Claude Code: `.claude/skills/<name>/SKILL.md`. For other harnesses, confirm the skill location and format. Store as `skill_output: {dir, format}`.773. **Priorities.** State key for the ranked list (default `priorities`) and a cap. Default cap 15. Hard ceiling 30: never accept a value above 30. A list longer than 30 is a backlog, not a set of priorities.784. **Entity categories.** Which WARM categories you track (default `project`, `person`, `product`). User adds or removes.795. **Additional capture.** Optionally name extra state keys or entity categories the save should populate each run (a metrics state doc, a contacts category). This is the extension point.806. **Dry-run default.** Toggle `dry_run_default` (default false).817. **Write the config** via `memory_set_state("sibyl_save:config", {...})`. Do not touch the delta marker.8283Config shape: see `examples/sibyl-save-config.example.json`. Re-running setup edits it in place.8485---8687## Mode: run8889### Phase 1: Memory Sync (into the plugin DB)9091#### Step 0 - Load config + delta92`memory_get_state("sibyl_save:config")`. If absent, switch to setup. `memory_get_state("sibyl_save:last_save")` for the delta anchor (what changed since the last save). If `dry_run_default` is true and no mode was given, run as preview.9394#### Step 1 - Read current state95- `memory_get_state("session")` and `memory_get_state(<priorities key>)`96- `memory_list(category, limit)` for tracked categories, and `memory_recall` / `memory_search` for entities touched this session97- any additional state keys or categories named in config9899#### Step 1.5 - Priorities check + reconcile100Read the priorities state doc and reconcile in place (write back with `memory_set_state`). Conditions and the action each requires:101102- **COMPLETED item still listed**: drop it; record the closure via `memory_record_event("priority_closed", {...})`.103- **RANK_DRIFT / DUP_RANK** (ranks not contiguous 1..N, or a rank repeats): renumber to 1..N.104- **OVER_CAP** (more items than the cap): move the lowest-priority items to a backlog state doc until at or under cap.105- **STALE_ITEM** (>14 days untouched): surface it to the user.106- **TERMINAL entity** (the referenced entity is archived/dead): close the priority.107- **BROKEN entity ref** (points at no real entity): fix it to a real `category/name`.108109Enforce the cap on every write (never exceed 30).110111#### Step 2 - Analyze the session112Review the conversation since the delta anchor (or since session start on first save). Extract:113114- **Entities touched** - projects, people, products created, read, or modified115- **Actions taken** - concrete things that happened, with identifiers116- **Decisions made** - strategic choices and their rationale117- **Forward items** - next-session actions, verb-first ("deploy...", "follow up with...", "verify...")118- **Warnings** - active risks, blockers, deadlines, near-misses119- **Lessons learned** - operational improvements (these feed Phase 2)120- **Additional captures** - data for any extra state keys / categories in config121122#### Step 3 - Inject into the plugin DB123In **preview** mode, call nothing that mutates. Report the planned writes (Step 4) and stop.1241251. **Session state** - `memory_set_state("session", { last_session, summary, forward, entities_touched, warnings })`. Forward items are action references only, never balance snapshots or anything that goes stale.1262. **Journal event** - `memory_record_event("session_save", { evaluated, acted, forward, extra })`. One event per save (append-only by design).1273. **Priorities** - `memory_set_state(<priorities key>, { updated, cap, items })`, capped. Overflow to a backlog state doc.1284. **Entities** - for each changed entity, `memory_remember(category, name, body)`. New entities are just new `memory_remember` calls; the plugin indexes them, so there is no separate registry to maintain.1295. **Closed / dead** - `memory_forget(category, name, reason)`.1306. **Additional captures** - apply each configured extra state key / category.1317. **Delta marker** - `memory_set_state("sibyl_save:last_save", { ts: <now> })`. Skip in preview.132133#### Step 4 - Report134Concise summary: entities written, state docs updated, journal event id, priorities added/closed, additional captures, and forward items for next session. In preview mode, label every line "would" and confirm nothing was written.135136---137138### Phase 2: Skill Extraction (harness-native)139140Skills are presented the same way regardless of harness: identify, propose, then create as a native skill file for the current harness.141142#### Step 5 - Identify reusable patterns143Scan the session for operations meeting ANY of these: **repeated** (more than once this session), **recurring** (likely again), **multi-step** (3+ sequential steps), **non-obvious** (a workaround worth keeping), **error-prone** (needs a checklist). For each candidate evaluate name (short imperative verb phrase), trigger, parameters, complexity (any dangerous steps), frequency.144145#### Step 6 - Propose candidates146Present each as a one-liner with name, description, and estimated frequency. Then ask: "Create these? Or skip any?"147148#### Step 7 - Create approved skills (harness-native)149Read `skill_output` from config to know where and in what format this harness expects skills. Defaults:150151| Harness | Skill location | Format |152|---------|----------------|--------|153| claude-code | `.claude/skills/<name>/SKILL.md` | YAML frontmatter (name, description) + Markdown body |154| codex | `~/.codex/prompts/<name>.md` (confirm in setup) | Markdown prompt |155| cursor | `.cursor/` command/rule (confirm in setup) | per Cursor convention |156| other | from `skill_output.dir` | from `skill_output.format` |157158For each approved skill, write the file at the configured location with trigger phrases, step-by-step instructions, parameter descriptions, safety checks for any dangerous step, and an example invocation. Report the path.159160**Do NOT create skills that:** duplicate an existing skill (check the skill location first), are too session-specific to recur, wrap a single trivial command, or require editing files your operating rules protect (surface those, do not self-edit).161162---163164## Rules (non-negotiable)165166- Never store live data (balances, prices, counts) as durable facts. Capture references, not snapshots.167- Session forward items are action-oriented and verb-first.168- One journal event per save (append-only; never rewrite history).169- Priorities are capped (default 15, never above 30). Overflow to a backlog state doc.170- Entities are addressed by `category` + `name`; let the plugin be the index. No parallel registry.171- All memory writes go through the plugin interface. Never write `~/.sibyl-memory/` files or open `memory.db` directly: the client handles locking and the free-tier cap.172- Treat existing skills as read-only. Create new ones rather than editing in place unless explicitly asked.173174## License & provenance175176MIT (see `LICENSE`). The watermark comment at the top of each Markdown file is attribution and provenance, not a usage restriction. Verify a copy with `node scripts/watermark.mjs verify`. Details in `WATERMARK.md`.