Codymaster cm-continuity
Working memory protocol — maintains context across sessions via CONTINUITY.md. Inspired by Loki Mode. Read at turn start, update at turn end. Captures mistakes and learnings to prevent repeating errors.
git clone https://github.com/tody-agent/codymaster
T=$(mktemp -d) && git clone --depth=1 https://github.com/tody-agent/codymaster "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/cm-continuity" ~/.claude/skills/tody-agent-codymaster-cm-continuity-9a27a5 && rm -rf "$T"
skills/cm-continuity/SKILL.mdContinuity — Working Memory Protocol
Context persistence across sessions. Mistakes captured. Learnings applied. Inspired by Loki Mode's CONTINUITY.md protocol (Autonomi).
When to Use
ALWAYS — This is a background protocol, not an explicit invocation.
- Start of every session: Read
to orient yourself.cm/CONTINUITY.md - End of every session: Update
with progress.cm/CONTINUITY.md - On error: Record in Mistakes & Learnings section
- On key decision: Record in Key Decisions section
Setup
Prerequisite: The
CLI is the CodyMaster command-line tool. If not installed, you can managecmdirectly with your editor or the AI agent without the CLI commands..cm/CONTINUITY.md
# Initialize working memory for current project cm continuity init # Check current state cm continuity status # View captured learnings / decisions cm continuity learnings cm continuity decisions # ── Smart Spine v5 commands ────────────────────────────── # Regenerate L0 compact indexes (learnings-index.md, skeleton-index.md) cm continuity index # Show token budget allocation + usage per category cm continuity budget # Pretty-print current context bus state (active skill chain) cm continuity bus # Print Claude Desktop MCP config snippet for cm-context server cm continuity mcp # Migrate learnings.json + decisions.json → SQLite (one-time) cm continuity migrate # Export SQLite back to JSON (backup) cm continuity export # ── Legacy config note ──────────────────────────────────── # CodyMaster's supported default path is SQLite + FTS5. # Older configs may still say `storage.backend: viking`; CodyMaster now warns and falls back to SQLite.
The Protocol
AT THE START OF EVERY SESSION:
1. Read .cm/CONTINUITY.md to understand current state 2. Read "Mistakes & Learnings" to avoid past errors 3. Check "Next Actions" to determine what to do 4. Reference Active Goal throughout your work
DURING WORK:
PRE-ACT ATTENTION CHECK (before every significant action): - Re-read Active Goal - Ask: "Does my planned action serve this goal?" - Ask: "Am I solving the original problem, not a tangent?" - If DRIFT detected → log it → return to goal
AT THE END OF EVERY SESSION:
1. Update "Just Completed" with accomplishments 2. Update "Next Actions" with remaining work 3. Record any new "Mistakes & Learnings" 4. Record any "Key Decisions" made 5. Update "Files Modified" list 6. Set currentPhase and timestamp
ON ERROR (Self-Correction Loop):
ON_ERROR: 1. Capture error details (stack trace, context) 2. Analyze root cause (not just symptoms) 3. Write learning to CONTINUITY.md "Mistakes & Learnings" 4. Update approach based on learning 5. Retry with corrected approach 6. Max 3 retries per error pattern before ESCALATE
CONTINUITY.md Template
# CodyMaster Working Memory Last Updated: [ISO timestamp] Current Phase: [planning|executing|testing|deploying|reviewing] Current Iteration: [number] Project: [project name] ## Active Goal [What we're currently trying to accomplish — 1-2 sentences max] ## Current Task - ID: [task-id from dashboard] - Title: [task title] - Status: [in-progress|blocked|reviewing] - Skill: [cm-skill being used] - Started: [timestamp] ## Just Completed - [Most recent accomplishment with file:line references] - [Previous accomplishment] - [etc — last 5 items] ## Next Actions (Priority Order) 1. [Immediate next step] 2. [Following step] 3. [etc] ## Active Blockers - [Any current blockers or waiting items] ## Key Decisions This Session - [Decision]: [Rationale] — [timestamp] ## Mistakes & Learnings ### Pattern: Error → Learning → Prevention - **What Failed:** [Specific error that occurred] - **Why It Failed:** [Root cause analysis] - **How to Prevent:** [Concrete action to avoid this in future] - **Timestamp:** [When learned] - **Agent:** [Which agent] - **Task:** [Which task ID] ## Working Context [Critical information for current work — architecture decisions, patterns being followed. ⚠️ NEVER store API keys, secrets, or credentials here — use .env or a secrets manager instead] ## Files Currently Being Modified - [file path]: [what we're changing]
Memory Architecture (v5 — Smart Spine)
Tier 1: SENSORY MEMORY (seconds — within current tool call) → Internal variables, intermediate results → NEVER written to file — discarded when action completes Tier 2: WORKING MEMORY (current session → 7 days) → CONTINUITY.md — the active scratchpad (max 500 words / ~400 tokens) → Auto-rotates: entries > 7 days promote to Tier 3 or decay → Context bus (.cm/context-bus.json) — live skill chain state · initBus() on chain start, updateBusStep() on each advance · cm://pipeline/current resolves to bus JSON · Read via: cm continuity bus | cm_bus_read MCP tool Tier 3: LONG-TERM MEMORY (30+ days, only if reinforced) → Default: .cm/context.db (SQLite + FTS5) · learnings table + learnings_fts (BM25 keyword search) · decisions table + decisions_fts · skill_outputs per session/chain · indexes table (cached L0/L1 content + staleness hash) → Legacy config note: `storage.backend: viking` now falls back to SQLite · True vector semantic search — finds "async timeout" even when you query "network delay" · L0/L1/L2 auto-generated by engine — no manual cm continuity index needed · Session compression + long-term memory extraction built-in · Graph relations between memories (link/unlink) · No separate OpenViking setup remains in the supported runtime → Fallback: .cm/memory/learnings.json + decisions.json (kept for compat) → L0 indexes: .cm/learnings-index.md (~100 tok), .cm/skeleton-index.md (~500 tok) · Auto-regenerated on addLearning() + on demand via cm continuity index · File watcher auto-refreshes learnings L0 on JSON change (300ms debounce) · With Viking: engine generates L0/L1 automatically — no file watcher needed → Token budget: .cm/token-budget.json — 200k window, per-category soft limits · Enforced at load time: checkBudget() → allowed/remaining/suggestion · View: cm continuity budget Tier 4: EXTERNAL SEMANTIC MEMORY (optional — large projects) → tobi/qmd — BM25 + Vector + LLM re-ranking, 100% local → See cm-deep-search skill — ONLY when >50 docs or >200 source files Tier 5: STRUCTURAL CODE MEMORY (optional — code-heavy projects) → CodeGraph — tree-sitter AST → SQLite graph → MCP server → See cm-codeintell skill — ONLY when >50 source files
CONTINUITY.md = "what am I doing NOW?"
context bus = "what did upstream skills produce in this chain?"
L0 indexes = "cheapest possible memory load (~600 tokens)"
context.db = "keyword search across all learnings + decisions"
Legacy
config = "compatibility fallback to SQLite, not a separate backend"
qmd (optional) = "find what was written across hundreds of docs"viking
MCP Context Server (Claude Desktop, Goose, and any MCP client)
Fifteen tools exposed over stdio — start with
cm mcp-serve:
# Start MCP server (stdio) cm mcp-serve --project /path/to/project # Print config snippet for Claude Desktop or Goose cm mcp-serve --print-config
| Tool | Purpose | Since |
|---|---|---|
| FTS5 keyword search — learnings, decisions, or both | v4.5 |
| Load any URI at L0/L1/L2 depth | v4.5 |
| Read live context bus state | v4.5 |
| Publish skill output to the bus | v4.5 |
| Pre-flight token check by category | v4.5 |
| Archive expired learnings (supports dry_run) | v4.5 |
| Regenerate L0 indexes on demand | v4.5 |
| Sprint + pipeline snapshot bridge | v4.8 |
| Review artifact hints | v4.8 |
| QA workflow hints | v4.8 |
| Deploy workflow hints | v4.8 |
| Search learnings/decisions (alias) | v4.8 |
| Memory search (alias) | v4.8 |
| Persist a learning with auto-detected category, scope, TTL | v5.1 |
| NLI router: "remember that…" / "forget…" / "what did we learn…" | v5.1 |
cm:// URI Scheme
Reference any memory resource by URI — resolver handles depth + caching:
cm://memory/working → CONTINUITY.md cm://memory/learnings → learnings-index.md (L0) or SQLite (L1/L2) cm://memory/learnings/{id} → specific learning by ID cm://memory/decisions → decisions index cm://skills/{name} → SKILL.md at depth cm://skills/{name}/L0 → front matter + description only (~50 tokens) cm://resources/skeleton → skeleton-index.md (L0) or full cm://pipeline/current → live context bus state
Memory Audit Protocol (Auto — Every Session Start)
When reading CONTINUITY.md at session start, SIMULTANEOUSLY run audit:
Step 1: Decay Check
Scan
.cm/learnings.json:
For each learning where status == "active": daysSinceRelevant = today - lastRelevant IF daysSinceRelevant > ttl: → Set status = "archived" → Log: "Archived learning L{id}: {error} (TTL expired)" IF reinforceCount ≥ 2 AND ttl < 60: → Extend ttl = 60 (pattern emerging) IF reinforceCount ≥ 3 AND ttl < 90: → Extend ttl = 90 (proven pattern) IF reinforceCount ≥ 5 AND ttl < 180: → Extend ttl = 180 (fundamental knowledge)
Step 2: Conflict Detection
Scan
.cm/decisions.json:
For each pair of decisions with same scope: IF decisions contradict each other: → Older decision: set supersededBy = newer.id, status = "superseded" → Log: "Superseded D{old.id} by D{new.id}" IF ambiguous (can't auto-resolve): → Flag in CONTINUITY.md Active Blockers → Ask user to clarify
Step 2b: Integrity Scan
Scan learnings for red flags that may CAUSE bugs:
For each active learning in scope: IF lastRelevant > 30 days ago AND reinforceCount == 0: → Flag as LOW_CONFIDENCE (read but verify before applying) IF prevention pattern conflicts with current codebase patterns: → Flag as SUSPECT (do NOT apply blindly — verify first) IF multiple learnings for same scope have conflicting preventions: → Flag as CONFLICT (resolve immediately: keep newer, invalidate older) On flags found: LOW_CONFIDENCE → Read but treat as suggestion, not rule SUSPECT → Compare with actual code before following CONFLICT → Invalidate older, keep newer, log resolution
Step 3: Scope-Filtered Reading
When executing a task for module X:
ONLY load learnings where: scope == "global" OR scope == "module:X" OR scope starts with "file:src/X/" SKIP learnings for other modules entirely. Token savings: Read 5 relevant learnings (250 tokens) instead of 50 total learnings (2,500 tokens)
Step 4: Reinforcement (Anti-Duplicate)
When recording a new error/learning:
IF similar learning already exists in learnings.json: → DO NOT create duplicate → UPDATE existing: reinforceCount++, lastRelevant = today, reset TTL → Log: "Reinforced L{id} (count: {reinforceCount})" IF no similar learning exists: → CREATE new entry with scope, ttl=30, reinforceCount=0
.cm/learnings.json
Format (v2 — with Smart Fields)
.cm/learnings.json[ { "id": "L001", "date": "2026-03-21", "error": "i18n keys missing in th.json", "cause": "Batch extraction skipped Thai locale", "prevention": "Always run i18n-sync test after each batch", "scope": "module:i18n", "ttl": 30, "reinforceCount": 0, "lastRelevant": "2026-03-21", "status": "active" } ]
| Field | Purpose |
|---|---|
| / / — where this applies |
| Days until auto-archive (default: 30) |
| Times pattern repeated (+1 each hit) |
| Last date this learning was accessed or reinforced |
| / / / |
Status meanings:
— Trusted, applied when in scopeactive
— TTL expired, retrievable on demandarchived
— Proven wrong (caused bug) — NEVER read againinvalidated
— Was wrong, has been fixed — read with cautioncorrected
.cm/meta-learnings.json
Format (Memory Self-Healing Log)
.cm/meta-learnings.jsonWhen memory itself causes a bug, record a meta-learning:
[ { "id": "ML001", "type": "memory-caused-bug", "affectedLearning": "L003", "action": "invalidated", "reason": "Prevention pattern conflicts with new codebase architecture", "bugDescription": "Deploy failed because learning suggested fetch but project uses axios", "date": "2026-03-21" } ]
Meta-learnings are the system learning about its own mistakes. They prevent the same bad-memory pattern from recurring.
.cm/decisions.json
Format (v2)
.cm/decisions.json[ { "id": "D001", "date": "2026-03-21", "decision": "Use React Hook Form over Formik", "rationale": "Better performance with uncontrolled components", "scope": "module:forms", "supersededBy": null, "status": "active" } ]
| Field | Purpose |
|---|---|
| Where this decision applies |
| ID of newer decision that replaces this one (null if current) |
| / |
Decay Timeline (Ebbinghaus-Inspired)
First recorded: TTL = 30 days Reinforced 1x (count=1): TTL resets to 30 from today Reinforced 2x (count=2): TTL = 60 days (pattern emerging) Reinforced 3x+ (count≥3): TTL = 90 days (proven pattern) Reinforced 5x+ (count≥5): TTL = 180 days (fundamental knowledge) Not reinforced after TTL: status → "archived" (retrievable on demand)
Inspired by Ebbinghaus Forgetting Curve: Un-reinforced memories decay. Repeatedly reinforced memories become long-term knowledge.
Scope Tagging Rules (For All Skills)
When writing to Mistakes & Learnings or Key Decisions, ALWAYS tag scope:
scope: "global" → Applies to entire project (e.g., "Always run test before deploy") scope: "module:{name}" → Applies to specific module only (e.g., "module:auth", "module:i18n") scope: "file:{path}" → Applies to one file only (e.g., "file:src/api/routes.ts") RULE: When in doubt, choose the SMALLEST scope. file > module > global WHY: Smaller scope = less noise = AI only reads what's relevant.
Rules
✅ DO: - Check context bus FIRST at session start (free, ~50 tokens) - Load L0 indexes BEFORE full files (learnings-index + skeleton-index) - Use cm_query for keyword search — don't scan JSON manually - Read CONTINUITY.md after L0 indexes (not before) - Run Memory Audit at session start (decay + conflicts + scope filter) - Update CONTINUITY.md at session end (ALWAYS) - Tag EVERY learning/decision with scope (global/module/file) - Reinforce existing learnings instead of creating duplicates - Keep CONTINUITY.md under 500 words (rotate to Tier 3) - Be specific: "Fixed auth bug in login.ts:42" not "Fixed stuff" - Run cm continuity index after bulk learning additions ❌ DON'T: - Load full learnings.json or skeleton.md as first action (use L0 first) - Skip context bus check when inside a skill chain - Skip Memory Audit ("I'll read everything, it's fine") - Write learnings without scope ("it applies everywhere" = almost never true) - Create duplicate learnings (reinforce existing ones instead) - Let learnings.json grow unbounded (TTL + decay + cm_memory_decay handles this) - Read ALL learnings regardless of current module (use scope filter / cm_query) - Ignore superseded decisions (they cause conflicting code) - Inject skeleton.md (20KB) when skeleton-index.md (~2KB) is sufficient
The Bottom Line
Your memory is your superpower. Without it, you repeat every mistake forever.