Skip to content
Open
8 changes: 8 additions & 0 deletions plugins/memory-bridge/.claude-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"name": "memory-bridge",
"description": "Structured context consolidation at session boundaries — prevents knowledge loss across sessions",
"version": "1.0.0",
"author": {
"name": "Jing Liang"
}
}
122 changes: 122 additions & 0 deletions plugins/memory-bridge/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
# Memory Bridge

Structured context consolidation at session boundaries. Prevents knowledge loss across Claude Code sessions.

## The Problem

Claude Code sessions accumulate valuable context — patterns discovered, user preferences expressed, debugging insights, architectural decisions. When the session ends, this knowledge is lost. While `MEMORY.md` and `CLAUDE.md` exist for persistence, there's no structured process to update them. Users either forget or do it inconsistently.

## The Solution

A consolidation cycle: **work → bridge → clear**.

1. You work normally. Context accumulates.
2. When you're done (or the session is getting large), run `/bridge`.
3. Claude reviews the session, consolidates learnings into persistent memory files.
4. You `/clear` to start fresh. The next session loads your updated memory automatically.

## Quick Start

1. Install this plugin in Claude Code
2. Work on your project as usual
3. Before ending your session, run `/bridge`
4. After consolidation, run `/clear` to start fresh

Claude monitors its own context and suggests `/bridge` at natural breakpoints — when learnings are rich, when a task completes, or when focus shifts. A Stop hook warns (never blocks) when context approaches auto-compaction (~1.5MB). The user is always the final decision maker — they can initiate `/bridge` any time, follow or ignore Claude's suggestions, and dismiss the hook warning if they prefer to let auto-compact happen.

## How It Works

The `/bridge` command triggers a 5-step consolidation process:

### 1. Scan
Review the session for new learnings: patterns, preferences, failures, cross-project insights.

### 2. Classify
Route each learning to the appropriate persistence level:

| Level | Location | What belongs here |
|-------|----------|-------------------|
| Project memory | Project's `MEMORY.md` or memory directory | Project state, confirmed project-specific patterns |
| Global config | `~/.claude/CLAUDE.md` | Cross-project principles, user preferences |
| Skill | `~/.claude/skills/<name>/SKILL.md` | Reusable operational procedures |

**Promote** when a pattern appears in 2+ projects or user says "always."
**Retire** when an entry is superseded, contradicted, or promoted to a higher level.

### 3. Act
Write, update, or retire entries. Always check for duplicates first — one canonical location per fact.

### 4. Resume
Write a snapshot to the project's `MEMORY.md` so the next session can pick up without re-discovery:
- **Goal**: What you were working on
- **Status**: Last completed step, next step
- **Pending**: Open decisions or blockers
- **Key context**: File paths, branch names, IDs

### 5. Signal
Create a marker file so the Stop hook knows bridging is done.

## Configuration

| Variable | Default | Description |
|----------|---------|-------------|
| `BRIDGE_THRESHOLD_KB` | `1500` | Safety-net threshold (KB) — warns when approaching auto-compaction |

Set in your shell profile or `.env`:
```bash
export BRIDGE_THRESHOLD_KB=1200 # adjust safety-net threshold
```

## Components

| Component | File | Purpose |
|-----------|------|---------|
| Command | `commands/bridge.md` | `/bridge` slash command with project context injection |
| Skill | `skills/bridge/SKILL.md` | The consolidation methodology |
| Stop hook | `hooks/stop.py` | Safety net — warns (never blocks) near auto-compaction (~1.5MB) |

## Philosophy

**User agency first.** This plugin builds better tools for users to exercise their agency, not replace it. Every intervention is advisory — the user can always initiate, follow, ignore, or override.

**Consolidate, don't accumulate.** Memory grows stronger over time, not larger. Each bridge pass should result in fewer, more precise entries — not a growing append-only log.

The guiding principle:

> Keep as much as possible that is not already there. Keep as little as possible that is already there.

### Ontological ground

The consolidation methodology is rooted in [Not a ToE](https://github.com/powerpig99/not-a-toe) — an ontological clarity framework. Key projections into this design:

- Memory as *generative ground*, not comprehensive description — minimal entries that reconstruct understanding
- Consolidation toward *shared priors* — two entries with common ground become the ground
- Selective forgetting as *the feature* — intelligence is knowing what to discard
- Single mentions as *the real signals* — what can't be found elsewhere is what's worth keeping

This is a specific ground, not a neutral one. The methodology and the ontology are inseparable — the principles determine what "consolidation" means in practice.

Every part of this process is refinable by each user. Fork it, reshape it, bring your own ground. That's user agency applied one level up.

### Anti-patterns

- **Adding without checking** — search existing memory before writing
- **Duplicating across levels** — one canonical location per fact
- **Documenting speculation** — only confirmed patterns
- **Comprehensive description** — aim for generative ground
- **Accumulating over time** — fewer and stronger entries, not more

## How It Integrates

This plugin works with Claude Code's existing memory system:
- **`MEMORY.md`** in your project's `.claude/` directory — loaded into the system prompt each session
- **`~/.claude/CLAUDE.md`** — global instructions loaded for all projects
- **Skills** in `~/.claude/skills/` — reusable procedures available across sessions

The bridge process simply provides structure for maintaining these files.

## Related Issues

- [#18417](https://github.com/anthropics/claude-code/issues/18417) — Session persistence and context continuity
- [#14941](https://github.com/anthropics/claude-code/issues/14941) — Post-compaction behavior loses context
- [#14228](https://github.com/anthropics/claude-code/issues/14228) — Cross-session memory
25 changes: 25 additions & 0 deletions plugins/memory-bridge/commands/bridge.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
---
description: Consolidate session learnings into persistent memory before exiting
allowed-tools: Read, Write, Edit, Glob, Grep, Bash(touch:*), Bash(git status:*), Bash(git add:*), Bash(git commit:*)
---

## Context

- Current project memory files: !`find .claude -name "MEMORY.md" -o -name "*.md" -path "*/memory/*" 2>/dev/null | head -20`
- Global CLAUDE.md exists: !`test -f ~/.claude/CLAUDE.md && echo "yes" || echo "no"`
- Skills directory: !`ls ~/.claude/skills/ 2>/dev/null || echo "none"`
- Git status: !`git status --short 2>/dev/null || echo "not a git repo"`

## Your task

Use the **bridge** skill to consolidate this session's learnings into persistent memory.

Follow the skill's process exactly:
1. **Scan** the session for new learnings
2. **Classify** each to the right persistence level (project memory, global config, or skill)
3. **Act** — write, update, or retire entries (check for duplicates first)
4. **Re-evaluate** — consolidate existing memory in light of additions (merge, retire, replace with shared priors)
5. **Resume** — write the cursor snapshot
6. **Signal** — create the marker file so the Stop hook passes

After consolidation, tell the user they can `/clear` to start fresh.
15 changes: 15 additions & 0 deletions plugins/memory-bridge/hooks/hooks.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"hooks": {
"Stop": [
{
"hooks": [
{
"type": "command",
"command": "python3 ${CLAUDE_PLUGIN_ROOT}/hooks/stop.py",
"timeout": 10
}
]
}
]
}
}
95 changes: 95 additions & 0 deletions plugins/memory-bridge/hooks/stop.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
#!/usr/bin/env python3
"""Stop hook for memory-bridge plugin.

Advisory only: warns when context approaches auto-compaction (~1.5MB).
Claude self-monitors and suggests /bridge at natural breakpoints.
This hook is the last resort — if it fires, context management failed.
The user is always the final decision maker.
"""

import json
import os
import sys
import glob


def get_threshold_bytes():
"""Get context size threshold from env var (default 1500KB ~ 1.5MB)."""
kb = int(os.environ.get("BRIDGE_THRESHOLD_KB", "1500"))
return kb * 1024


def get_marker_base():
"""Get the marker file base path for this session."""
ppid = os.getppid()
return f"/tmp/claude-bridge-{ppid}"


def get_transcript_path(hook_input):
"""Get transcript path from hook input, fall back to glob."""
# Prefer transcript_path from hook input
path = hook_input.get("transcript_path")
if path and os.path.exists(path):
return path

# Fall back to most recent JSONL
home = os.path.expanduser("~")
pattern = os.path.join(home, ".claude", "projects", "*", "*.jsonl")
transcripts = sorted(glob.glob(pattern), key=os.path.getmtime, reverse=True)
return transcripts[0] if transcripts else None


def is_context_critical(hook_input):
"""Check if context is approaching auto-compaction danger zone."""
threshold = get_threshold_bytes()
transcript = get_transcript_path(hook_input)
if not transcript:
return False
try:
return os.path.getsize(transcript) >= threshold
except OSError:
return False


def main():
try:
hook_input = json.load(sys.stdin)

marker = get_marker_base()

# Already bridged this session
if os.path.exists(f"{marker}-done"):
print(json.dumps({}))
sys.exit(0)

# Already reminded once — don't nag
if os.path.exists(f"{marker}-reminded"):
print(json.dumps({}))
sys.exit(0)

# Only warn when approaching auto-compaction
if not is_context_critical(hook_input):
print(json.dumps({}))
sys.exit(0)

# Mark as reminded so we only ask once
open(f"{marker}-reminded", "w").close()

# Advisory: warn but never block — user is the final decision maker
print(
"\n⚠️ Context approaching auto-compaction. "
"Consider running /bridge to consolidate before stopping.\n",
file=sys.stderr,
)
print(json.dumps({}))

except Exception:
# On any error, allow the stop — never trap the user
print(json.dumps({}))

finally:
sys.exit(0)


if __name__ == "__main__":
main()
98 changes: 98 additions & 0 deletions plugins/memory-bridge/skills/bridge/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
---
name: bridge
description: Consolidate session learnings into memory and skills. Run at session end before exiting. Stop hook advises (never blocks) for substantial sessions.
---

# Bridge — Knowledge Consolidation

Memory is a bridge — a living derivation path from generative ground to the current question. It grows when understanding deepens, not when words accumulate. Selective forgetting is the feature, not the bug — intelligence is knowing what to discard, not just what to retain.

**Saving principle**: A single mention is exactly what's worth remembering — it can't be found or regenerated from anywhere else. Those are the real independent signals. Frequency measures redundancy, not importance. Only discard through logic and intentional choice, never from pattern-matching speculation.

**Consolidation direction**: Entries consolidate *toward their shared priors*. Two entries with common ground become the ground. The count goes down over time, each entry carrying more weight.

Nothing in this process is static — every rule here is itself refinable through use.

## When to bridge

The user is the final decision maker. Claude suggests `/bridge` at natural breakpoints when learnings have accumulated — task complete, rich exploration, shift in focus. Don't interrupt mid-flow. A Stop hook at ~1.5MB warns (never blocks) before auto-compaction. The user can follow, ignore, or override at every step.

After `/bridge` completes, create the marker so the safety-net hook passes:
```bash
touch "/tmp/claude-bridge-${PPID}-done"
```

## Process

### 1. Scan — What's new this session?

Review session context for learnings not yet in persistent memory:
- New patterns, workflows, or tools discovered
- User preferences expressed (explicit or through correction)
- Failures and their root causes
- Cross-project insights (project-specific discovery that generalizes)

### 2. Classify — Where does it go?

| Level | Location | What belongs here |
|-------|----------|-------------------|
| Project memory | Project's `MEMORY.md` or memory directory | Project state, confirmed project-specific patterns |
| Global config | `~/.claude/CLAUDE.md` | Cross-project principles, user preferences |
| Skill | `~/.claude/skills/<name>/SKILL.md` | Reusable operational procedures |

**Promote** when a pattern appears in 2+ projects or user says "always" / "system wide."
**Retire** when an entry is superseded, contradicted, or promoted to a higher level.

### 3. Act — Update files

For each learning:
- Check if it's already documented (search existing memory + skills)
- If new: write to the appropriate level
- If confirms existing: no action needed
- If contradicts existing: update or remove the stale entry
- If promoted to higher level: remove from the lower level

### 4. Re-evaluate — Consolidate in light of additions

After adding, read the full memory and ask:
- Can any entries now be merged? Two entries sharing common ground become one.
- Is any entry now derivable from others? Retire it.
- Has a new addition revealed the shared prior beneath older entries? Replace them with the prior.

Memory should get *shorter* through consolidation, not just avoid growing. Without this step, memory grows monotonically because the default rewards completeness over minimality.

### 5. Resume snapshot

Write the resume as a cursor — where the project stands right now.

If the project has a `## Resume` section in MEMORY.md, update it there. Otherwise, save to a separate file in the memory directory (e.g., `memory/resume.md`) to preserve previous snapshots as reference.

Contents:
- **Goal**: What we were working on (one line)
- **Status**: Last completed step, next step
- **Pending**: Open decisions, blockers, or things the user asked for
- **Key context**: File paths, branch names, IDs — anything needed to pick up without re-discovery

If the session was exploratory with no resumable task, set: `No active task.`

### 6. Signal completion

Create the marker file so the Stop hook won't fire again this session:

```bash
touch "/tmp/claude-bridge-${PPID}-done"
```

### 7. Done

Brief summary of what was added, updated, or retired — including net change in entry count. The user can then `/clear` to start fresh.

## Anti-patterns

- Adding without checking for duplicates
- Duplicating across levels (one canonical location per fact)
- Documenting speculation (only confirmed patterns)
- Comprehensive description instead of generative ground
- Growing memory session over session — if entry count is rising, consolidation is failing
- Discarding novel signals because they were only mentioned once
- Treating any part of this process as settled — everything here is a projection, refinable through use