From rune
Persists architectural decisions, conventions, and progress across sessions by auto-saving to .rune/ files. Loads state at session start for continuity when skills establish patterns.
How this skill is triggered — by the user, by Claude, or both
Slash command
/rune:session-bridgeThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Solve the #1 developer complaint: context loss across sessions. Session-bridge auto-saves critical context to `.rune/` files in the project directory, and loads them at session start. Every new session knows exactly where the last one left off.
Solve the #1 developer complaint: context loss across sessions. Session-bridge auto-saves critical context to .rune/ files in the project directory, and loads them at session start. Every new session knows exactly where the last one left off.
checkpoint.request — explicit checkpoint from cook/team mid-phase/checkpoint — manual checkpoint (save exact resume point)/rune status — manual state checkintegrity-check (L3): verify .rune/ file integrity before loading statecook (L1): auto-save decisions during feature implementationrescue (L1): state management throughout refactoringcontext-engine (L3): save state before compactioncontext-pack (L3): coordinate state for sub-agent handoffneural-memory (L3): sync key decisions back to .rune/ files after Capture Modeadversary (L2): (oracle-mode) detach protocol when target model is opus-class for non-blocking dispatch.rune/
├── decisions.md — Architectural decisions log
├── conventions.md — Established patterns & style
├── progress.md — Task progress tracker
├── session-log.md — Brief log of each session
├── instincts.md — Learned project-specific patterns (trigger→action)
├── cumulative-notes.md — Living project understanding (profile, themes, relationships)
├── learnings.jsonl — Structured learning log (append-only, queryable)
└── checkpoint.md — Exact resume point for cross-session continuity
Collect from the current session:
Python project context (if pyproject.toml or setup.py detected):
.python-version, pyproject.toml requires-python, or python --version)[dev], [test], [embeddings])Use Glob to check if .rune/decisions.md exists. If not, use Write to create it with a # Decisions Log header.
For each architectural decision from this session, use Edit to append to .rune/decisions.md:
## [YYYY-MM-DD HH:MM] Decision: <title>
**Context:** Why this decision was needed
**Decision:** What was decided
**Rationale:** Why this approach over alternatives
**Impact:** What files/modules are affected
Use Glob to check if .rune/conventions.md exists. If not, use Write to create it with a # Conventions header.
For each pattern or convention established, use Edit to append to .rune/conventions.md:
## [YYYY-MM-DD] Convention: <title>
**Pattern:** Description of the convention
**Example:** Code example showing the pattern
**Applies to:** Where this convention should be followed
Python example:
## [YYYY-MM-DD] Convention: Async-First I/O
**Pattern:** All I/O functions use `async def`; blocking calls (`requests`, `open`, `time.sleep`) are forbidden in async modules
**Example:** `async def fetch_data(): async with httpx.AsyncClient() as client: ...`
**Applies to:** All modules in `src/` — sync wrappers only in CLI entry points
Use Glob to check if .rune/progress.md exists. If not, use Write to create it with a # Progress header.
Use Edit to append the current task status to .rune/progress.md:
## [YYYY-MM-DD HH:MM] Session Summary
**Completed:**
- [x] Task description
**In Progress:**
- [ ] Task description (step X/Y)
**Blocked:**
- [ ] Task description — reason
**Next Session Should:**
- Start with X
- Continue Y from step Z
**Python Context** (if Python project):
- Python: [version] ([venv type])
- Installed extras: [list of optional dependency groups]
- mypy: [error count] ([strict/normal])
- Coverage: [percentage]%
- Migration: [version or N/A]
Use Glob to check if .rune/session-log.md exists. If not, use Write to create it with a # Session Log header.
Use Edit to append a one-line entry to .rune/session-log.md:
[YYYY-MM-DD HH:MM] — [brief description of session accomplishments]
When session-bridge is invoked by cook running inside team or in autonomous mode (claude -p), persist iteration state to .rune/task-notes.md:
# Task Notes: [task name]
## What Worked (with evidence)
- [approach]: [outcome, test output, or file path as proof]
## What Failed
- [approach]: [why it failed, error message]
## What's Left
- [ ] [remaining task with specific next step]
## Key Context for Next Iteration
- [critical info that would be lost on context reset]
Why: In autonomous loops, each claude -p invocation starts with zero context. Without this file, the next iteration repeats failed approaches and loses progress. The notes bridge the gap between independent invocations.
Rules: Agent reads .rune/task-notes.md at start (Step 1 of Load Mode), updates at end. Keep concise — max 50 lines. Prune completed items.
Extract atomic "instincts" — learned trigger→action patterns — from this session and persist to .rune/instincts.md. Instincts are project-scoped by default to prevent cross-project contamination.
Instinct format:
## [YYYY-MM-DD] Instinct: <short name>
**Trigger:** <when this pattern applies — specific condition>
**Action:** <what to do — specific behavior>
**Confidence:** <0.3–0.9>
**Evidence:** <what happened that taught this — file, error, outcome>
Extraction rules:
| Signal | Example | Confidence |
|---|---|---|
| Repeated manual correction by user | "Don't use X, use Y here" (2+ times) | 0.7–0.9 |
| Failed approach → successful pivot | Tried approach A, failed, approach B worked | 0.5–0.7 |
| Project-specific convention discovered | "This codebase uses X pattern for Y" | 0.4–0.6 |
| One-off preference (may not generalize) | User chose a specific library once | 0.3–0.4 |
Promotion to global: When the same instinct (matching trigger+action) appears in .rune/instincts.md across 2+ projects at confidence ≥0.8, promote it to Neural Memory via Step 6 with tag [cross-project, instinct]. Until then, it stays project-local.
Pruning: At session start (Load Mode Step 1), review instincts older than 30 days with confidence <0.5 — remove them. Instincts that conflict with current conventions should be removed immediately.
Max instincts: Keep .rune/instincts.md under 20 entries. When full, evict the lowest-confidence entry.
Append structured learning entries to .rune/learnings.jsonl — an append-only log that captures decisions, insights, and error resolutions in a machine-queryable format. Unlike markdown state files (which are for human reading), JSONL enables fast filtering and "latest winner" lookups.
Entry schema — one JSON object per line:
{"ts":"2026-04-04T14:30:00Z","skill":"cook","type":"decision","key":"state-lib","insight":"Chose Zustand over Redux — fewer re-renders in dashboard with 50+ real-time widgets","confidence":0.8,"files":["src/store/index.ts"]}
| Field | Type | Description |
|---|---|---|
ts | ISO 8601 | When the learning was captured |
skill | string | Which skill produced this learning |
type | enum | decision · error · insight · convention · performance |
key | string | Dedup key — latest entry per key+type wins on read |
insight | string | 1-2 sentences, causal language ("Chose X because Y", "Root cause was X") |
confidence | 0.1–1.0 | How certain this learning is (0.3=hunch, 0.7=validated, 0.9=battle-tested) |
files | string[] | Optional — affected file paths |
Write rules:
auth-lib, db-migration-strategy, react-hook-pitfall)Read rules (latest-winner):
key+type and take the entry with the latest tsQuery patterns (for other skills or session-start):
.rune/learnings.jsonl, parse line-by-linetype === "error" to surface past mistakes before codingskill === "cook" to see cook-specific learningsts descending, take top NPruning: When file exceeds 100 entries, compact by keeping only the latest-winner per key+type. Write compacted entries to a new file, replace original.
Why: Markdown state files (decisions.md, conventions.md) are great for human reading but hard to query programmatically. JSONL enables structured recall — "show me all errors from last week" or "what did we decide about auth?" — without parsing markdown headers.
Maintain a running cumulative notes file at .rune/cumulative-notes.md that evolves across sessions. Unlike progress.md (which tracks tasks) or decisions.md (which logs choices), cumulative notes capture the living understanding of the project — patterns learned, relationships discovered, recurring themes, and open threads.
Format — use these fixed sections (add content, never remove prior entries):
# Cumulative Project Notes
## Project Profile
- [Core purpose of the project — 1 sentence]
- [Primary users/audience]
- [Key technical constraints — e.g., "must run offline", "latency-critical", "multi-tenant"]
## Architecture Map
- [Key modules and their responsibilities — discovered over sessions]
- [Critical data flows — e.g., "user input → validation → API → DB → cache invalidation"]
- [Integration points — external APIs, services, databases]
## Recurring Themes
- [Patterns that keep coming up across sessions — e.g., "auth edge cases", "migration complexity"]
- [Common failure modes — what breaks and why]
- [Technical debt hotspots — areas that repeatedly cause issues]
## Active Topics
- [What's currently being worked on — updated each session]
- [Open questions that haven't been resolved yet]
- [Experiments in progress]
## Relationship Map
- [Key files and their dependencies — "changing X requires updating Y"]
- [People and their areas — "Alice owns auth, Bob owns payments"]
- [External service dependencies — "Stripe webhook → order.complete handler"]
## Follow-Up Items
- [ ] [Things noted but not yet addressed — carry forward until done]
- [ ] [Ideas that came up during work but were out of scope]
## Attention Points
- [Things the next session should be aware of — fragile areas, pending PRs, deadlines]
- [Temporary workarounds that need proper fixes]
Update rules:
## Resolved section at the bottom (keep last 10)Why: Individual state files (decisions.md, progress.md) capture discrete events. Cumulative notes capture the emergent understanding that develops over many sessions — the kind of knowledge that's lost when context resets. This is the project's "institutional memory."
Before committing, extract generalizable patterns from this session for cross-project reuse:
nmem_remember with rich cognitive language (causal, comparative, decisional)[cross-project, <technology>, <pattern-type>]Why: This turns every project session into learning that compounds across ALL projects. A pattern discovered in Project A auto-surfaces when Project B faces a similar problem.
Stage and commit all updated state files:
git add .rune/ && git commit -m "chore: update rune session state"
If git is not available or the directory is not a repo, skip the commit and emit a warning.
Use Glob to check for .rune/ directory:
Glob pattern: .rune/*.md
If no files found: suggest running /rune onboard to initialize the project. Exit load mode.
Before loading state files, invoke integrity-check (L3) to verify .rune/ files haven't been tampered:
REQUIRED SUB-SKILL: rune:integrity-check
→ Invoke integrity-check on all .rune/*.md files found in Step 1.
→ Capture: status (CLEAN | SUSPICIOUS | TAINTED), findings list.
Handle results:
CLEAN → proceed to Step 2 (load files)SUSPICIOUS → present warning to user with specific findings. Ask: "Suspicious patterns detected in .rune/ files. Load anyway?" If user approves → proceed. If not → exit load mode.TAINTED → BLOCK load. Report: ".rune/ integrity check FAILED — possible poisoning detected. Run /rune integrity for details."Before loading the usual state files, run the invariants loader so the agent sees active discipline rules without being told to look:
Execute: node skills/session-bridge/scripts/load-invariants.js --root <project-root> --json
The loader:
.rune/INVARIANTS.md (silent no-op if missing)## Archived section (retired rules don't re-activate){ section, title, what, where, why }Emit signal: invariants.loaded with payload { loaded, count, rules, stats, stale, overflow, path } where:
loaded (boolean) — whether any active rules were parsedcount (number) — total active rules (convenience alias for stats.total)rules (array) — full rule objects [{ section, title, what, where: string[], why }] — consumers cache these for glob matchingstats — { danger, critical, state, cross, total, archivedSkipped }stale (boolean) — mtime > 30 daysoverflow (number) — rules present but not shown in preview (budget overflow)path (string) — absolute path to .rune/INVARIANTS.mdDownstream listeners (logic-guardian, Pro autopilot) consume rules[] directly — no second file read needed.
Present to agent (injected verbatim into the Load Mode summary):
📎 Active Invariants (.rune/INVARIANTS.md)
⚠ skills/skill-router/** — L0 router, never bypass
🔒 compiler/parser.js — IR schema is the adapter contract
🔁 compiler/hooks/dispatch.js — phase order is pre → run → post
🔗 .claude-plugin/marketplace.json — mirrors plugin.json
…+2 more rules in .rune/INVARIANTS.md
Staleness warning (emit ONCE per session, not per tool call):
⚠ Invariants file is stale (> 30 days since last onboard). Consider `rune onboard --refresh`.
Failure modes:
loaded: false, rules: []. Log a single-line warning, continue.integrity-check in Step 1.5 → this step is skipped entirely (load already blocked).Use Read on all four state files in parallel:
Read: .rune/decisions.md
Read: .rune/conventions.md
Read: .rune/progress.md
Read: .rune/session-log.md
Read: .rune/cumulative-notes.md
Present the loaded context to the agent in a structured summary:
"Here's what happened in previous sessions:"
- Last session: [last line from session-log.md]
- Key decisions: [last 3 entries from decisions.md]
- Active conventions: [count from conventions.md]
- Current progress: [in-progress and blocked items from progress.md]
- Project understanding: [Active Topics + Attention Points from cumulative-notes.md]
- Next task: [first item under "Next Session Should" from progress.md]
Identify the next concrete task from progress.md → "Next Session Should" section. Present it as the recommended starting point to the calling orchestrator.
Unlike Save Mode (which captures session state broadly), Checkpoint Mode creates an exact resume point — a single file that tells the next session precisely where to pick up, what's in-flight, and what decisions are load-bearing.
Trigger: User says /checkpoint, or cook/team emits checkpoint.request signal when pausing mid-phase.
Collect into a structured checkpoint:
# Checkpoint — [YYYY-MM-DD HH:MM]
## What I Was Doing
[1-2 sentences: the exact task and sub-step in progress]
## Current Git State
- Branch: [branch name]
- Last commit: [short hash + message]
- Uncommitted changes: [list of modified/untracked files, or "clean"]
- Stashed: [yes/no — if yes, stash message]
## Decisions Made This Session (Load-Bearing)
[Only decisions that affect the remaining work — not all decisions]
- [Decision 1]: [choice + why]
- [Decision 2]: [choice + why]
## What's Left (Ordered)
1. [Next immediate step — be specific: file, function, what to change]
2. [Step after that]
3. [Remaining steps...]
## Context the Next Session Needs
[Critical info that's NOT in the code or git history — mental model, gotchas discovered, things tried and failed]
- [Item 1]
- [Item 2]
## Resume Command
[Exact instruction for the next session to pick up — e.g., "Continue Phase 2 Task 3: implement the retry logic in src/api/client.ts, the happy path is done, need error handling"]
Write to .rune/checkpoint.md (overwrite — only one active checkpoint at a time).
## Checkpoint Saved
- **Resume point**: [1-line summary of what to continue]
- **Git state**: [branch] @ [commit hash] — [clean/N uncommitted files]
- **Remaining tasks**: [count]
- Next session will auto-detect this checkpoint and offer to resume.
At Load Mode Step 1, after checking .rune/*.md existence, also check for .rune/checkpoint.md:
## Checkpoint Detected — [date]
**Resume**: [Resume Command from checkpoint]
**Git state**: [branch] @ [commit] — [clean/dirty]
**Tasks remaining**: [count]
mv .rune/checkpoint.md .rune/checkpoint-[date].resolved.md
Why: Save Mode captures everything broadly. Checkpoint captures the exact needle position — like a bookmark in a book vs. a summary of chapters read. The next session doesn't need to scan all state files to figure out what to do; the checkpoint tells it directly.
## Session Bridge — Saved
- **decisions.md**: [N] decisions appended
- **conventions.md**: [N] conventions appended
- **progress.md**: updated (completed/in-progress/blocked counts)
- **session-log.md**: 1 entry appended
- **Git commit**: [hash] | skipped (no git)
## Session Bridge — Loaded
- **Last session**: [date and summary]
- **Checkpoint**: [detected — resume point] | [none]
- **Invariants**: [N loaded from .rune/INVARIANTS.md] | [none] | [stale — run rune onboard --refresh]
- **Decisions on file**: [count]
- **Conventions on file**: [count]
- **Learnings on file**: [count] (top 5 surfaced if 10+)
- **Next task**: [task description]
## Checkpoint Saved
- **Resume point**: [1-line summary]
- **Git state**: [branch] @ [hash] — [clean/N files]
- **Remaining tasks**: [count]
Triggered by oracle.dispatched from adversary oracle-mode. Decouples the primary agent from a slow heavy-model call so the agent can continue adjacent work while the second model reasons.
Why: Opus-class reasoning takes 1-10 minutes wall time. Synchronous waits kill primary-agent throughput, especially in team parallel workstreams.
When oracle.dispatched arrives, payload contains:
sessionId — caller-provided unique idtriggerSignal — agent.stuck or manualsourceSkill — debug | fix | manualtargetModel — concrete model name (e.g. gpt-5-pro, gemini-3-pro, claude-opus-4-7)bundleHash — sha256 of the bundled context (idempotency key)Look up .rune/oracle-pending/<sessionId>.json AND any pending file with matching bundleHash. If a pending record with status=pending and the same bundleHash exists, return the existing sessionId — do NOT dispatch a duplicate.
Create .rune/oracle-pending/<sessionId>.json:
{
"sessionId": "oracle-1714234500-abc123",
"dispatchedAt": "2026-04-27T12:34:56Z",
"triggerSignal": "agent.stuck",
"sourceSkill": "debug",
"targetModel": "claude-opus-4-7",
"bundleHash": "sha256:9f3a...",
"status": "pending",
"timeoutAt": "2026-04-27T12:44:56Z",
"responseId": null,
"responseExcerpt": null
}
timeoutAt defaults to dispatchedAt + 10min.
Caller (adversary) receives the sessionId and returns to the primary orchestrator. Primary agent (cook/team) continues adjacent phases.
Invocation: session-bridge --reattach <sessionId> (or via oracle.dispatched listen → poll).
Behavior:
.rune/oracle-pending/<sessionId>.jsonstatus=complete → return responseExcerpt to caller, mark record as consumedstatus=pending AND now >= timeoutAt → set status=failed, emit oracle.failed reason=timeoutstatus=pending AND now < timeoutAt → return not_ready to caller, primary agent works on next independent taskOn every session start, scan .rune/oracle-pending/ for records older than 24h. Delete them — they are orphaned.
| Field | Type | Required |
|---|---|---|
| sessionId | string (matches ^oracle-\d+-[a-z0-9]+$) | yes |
| dispatchedAt | ISO 8601 timestamp | yes |
| triggerSignal | string | yes |
| sourceSkill | enum: debug | fix | manual | yes |
| targetModel | string | yes |
| bundleHash | string (matches ^sha256:[a-f0-9]{8,64}$) | yes |
| status | enum: pending | complete | failed | yes |
| timeoutAt | ISO 8601 timestamp | yes |
| responseId | string | null | yes (null until status=complete) |
| responseExcerpt | string ≤500 chars | null | yes |
Known failure modes for this skill. Check these before declaring done.
| Failure Mode | Severity | Mitigation |
|---|---|---|
| Overwriting existing .rune/ files instead of appending | HIGH | Constraint 3: use Edit to append entries — never Write to overwrite existing state |
| Saving only a status line, missing decisions/conventions | HIGH | Constraint 1: all three files (decisions, conventions, progress) must be updated |
| Load mode presenting stale context without age marker | MEDIUM | Mark each loaded entry with its session date — caller knows how fresh it is |
| Silent failure when git unavailable | MEDIUM | Note "no git available" in report — do not fail silently or skip without logging |
| Loading poisoned .rune/ files without verification | CRITICAL | Step 1.5 integrity-check MUST run before loading — TAINTED = block load |
| Learnings JSONL grows unbounded | MEDIUM | Auto-compact at 100 entries — keep only latest-winner per key+type |
| Checkpoint stale after code changes | MEDIUM | Checkpoint includes git state — if branch/commit differ at resume, warn user that checkpoint may be outdated |
| Multiple checkpoints overwrite each other | LOW | By design — only one active checkpoint. Resolved ones archived with date suffix |
| (Detach) Pending file orphaned forever — process crashed mid-dispatch | MEDIUM | Step D6 cleanup runs every session start; records >24h auto-deleted |
| (Detach) Two adversary calls dispatch same bundle simultaneously | MEDIUM | Step D2 idempotency: bundleHash-keyed lookup returns existing sessionId |
| (Detach) Reattach polls indefinitely without timeout | HIGH | Step D5 enforces timeoutAt — exceeded → emit oracle.failed reason=timeout, free the primary agent |
.rune/oracle-pending/<sessionId>.json with valid schemacomplete / pending / failed based on record status + timeoutoracle.failed emitted with reason=timeout if timeoutAt exceeded~100-300 tokens per save. ~500-1000 tokens per load. Always haiku. Negligible cost.
npx claudepluginhub rune-kit/rune --plugin @rune/analyticsManages persistent state across Claude Code agent sessions: load context at start, track progress/decisions/learnings, save for next session. Use when resuming work or hitting blockers.
Saves session progress by committing changes, pushing to remote, creating/updating pull requests, persisting decisions/patterns to memory layers, compiling briefings, and archiving features. Use for checkpointing work or PRs.
Manages cross-session learning and memory persistence by recording session logs, decisions, patterns, and project context in .claude/memory/. Invoked automatically for session handoff and history queries.