# Sibyl Save

> 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.

- Skill: `sibyl-labs/sibyl-save` (Agent Skill, multi-file: 8 files)
- Install (CLI): `npx skillmds@latest add sibyl-labs/sibyl-save`
- Raw SKILL.md: https://api.skillmd.com/api/skills/sibyl-labs/sibyl-save/raw
- Safety review: pending (external: skill-scanner PASS, skillspector PASS)
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: Sibyl-Labs (https://skillmd.com/u/sibyl-labs)
- Updated: 2026-09-22
- Page: https://skillmd.com/skills/sibyl-labs/sibyl-save

---

<!-- SIBYL-SKILL-WATERMARK-BEGIN
  origin:  sibyl-labs
  build:   2026-06-17T19:19:06Z
  release: v1.0.0
  file:    SKILL.md
  hash:    sha256:68d324246fcd4f5316d369990a0778e54e023af60d6aa83359080e1d37aca916
  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.
SIBYL-SKILL-WATERMARK-END -->

# /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:

```bash
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.

1. **Harness.** Detect or ask which harness this is (claude-code, codex, cursor, hermes, other). This drives where Phase 2 writes skill files.
2. **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}`.
3. **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.
4. **Entity categories.** Which WARM categories you track (default `project`, `person`, `product`). User adds or removes.
5. **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.
6. **Dry-run default.** Toggle `dry_run_default` (default false).
7. **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.

1. **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.
2. **Journal event** - `memory_record_event("session_save", { evaluated, acted, forward, extra })`. One event per save (append-only by design).
3. **Priorities** - `memory_set_state(<priorities key>, { updated, cap, items })`, capped. Overflow to a backlog state doc.
4. **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.
5. **Closed / dead** - `memory_forget(category, name, reason)`.
6. **Additional captures** - apply each configured extra state key / category.
7. **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`.

