1
0
forked from jason/echo
Files
chorus/docs/USAGE.md
T
2026-07-15 15:56:28 -05:00

8.8 KiB
Raw Blame History

ECHO Memory — Usage Guide

Written for Bryan (and anyone else coming back to ECHO after a break). Current as of v1.5.1, July 2026.

ECHO gives Claude persistent memory across sessions. Everything durable — people, companies, projects, decisions, preferences, session history — lives as markdown notes in an Obsidian vault, read and written over the Obsidian Local REST API. The plugin ships the whole toolchain (pure Python, stdlib only — works the same on Windows/macOS/Linux) plus the operating procedure Claude follows.

The short version of how to use it: you mostly don't have to do anything. Since v1.5 the system loads itself at session start and nudges itself to save at session end. The slash commands below are for when you want to drive it explicitly.


One-time setup

If Jason handed you a per-user baked plugin (echo-memory-1.x.x-bryan.plugin), just install it. Your vault credentials are baked into the artifact — no config file, no key pasting, works on desktop and in every CoWork session. This is the normal path.

If you have the generic plugin instead, it will report NOT CONFIGURED on first use and ask for your config file. Install it once with:

python3 echo.py config import <your-config.json>

That writes ~/.claude/echo-memory/config.json (owner, endpoint, API key). It survives plugin updates — one time per machine.

Verify either way: run /echo-doctor. Green across the board (Python, vault reachable, auth, bootstrapped, key source) means you're live.


Day-to-day usage

What happens automatically (v1.5+)

  • Session start — a hook runs the cold-start load and injects your memory into context: your profile/preferences, current scope, the last session log, today's journal note, and inbox depth. You don't have to ask Claude to "load memory" anymore.
  • Session end — if the session was substantive and nothing was saved, a hook nudges (once) to run /echo-reflect and write the session log. Reflection always previews before writing — nothing lands without your OK.
  • If the vault is unreachable, writes queue to a local outbox and replay automatically next time it's up; reads fall back to a cached last-known-good. An outage degrades gracefully instead of erroring.

The slash commands

Command When to use it
/echo-load Manually load memory context. Rarely needed now — the session-start hook does this — but useful mid-session after a lot of vault writes, or if the hook didn't fire.
/echo-save <thing> Save something right now: "remember the Henagar tower password is in the vault", "log that we decided X". Routes it to the right note automatically.
/echo-recall <topic> Ask what memory knows about a topic. Returns ranked matches plus their linked neighbourhood — a project comes back with its people, decisions, and recent session mentions attached.
/echo-reflect End-of-session sweep: extracts durable facts, decisions, and new entities from the conversation, shows you the proposed writes, applies on confirm. The main way memory grows.
/echo-triage Empty the inbox: classifies each quick capture, previews destinations, routes accepted items with an audit trail. Run when load reports the inbox is getting deep.
/echo-doctor Readiness check — Python, vault reachability, auth, bootstrap/schema version, where the key came from. First stop when anything seems off.
/echo-health Full vault lint: routing violations, broken wikilinks, orphan notes, stale scope, incomplete frontmatter, index drift. Run occasionally or when things feel inconsistent.
/echo-sweep Bring the vault up to the current plugin spec after an upgrade — rebuilds the entity index, backfills frontmatter, fixes one-way links. Dry-run by default; run this once right after updating from an old version.

A typical session

  1. Start a conversation — memory loads itself. Claude knows who you are, what's active, and what happened last session.
  2. Work normally. Say "save that" / "remember this" whenever something durable comes up (or /echo-save explicitly). Not sure where something belongs? Save it anyway — it lands in the inbox and /echo-triage sorts it later.
  3. At the end, accept the reflection nudge (or run /echo-reflect yourself). Confirm the preview. Done — next session picks up from here.

What the memory system can do (current capabilities)

Smart, deduplicating capture. One capture call routes content to its canonical home via an entity index, stamps complete frontmatter (status, tags, timestamps), cross-links every entity it mentions, and logs the write. Names resolve through aliases and fuzzy matching, so "echo memory" finds the echo project instead of spawning a duplicate note. If a new title strongly resembles an existing same-kind entity, a pre-write duplicate gate stops the write and shows you the candidates — you choose merge or create. Duplicates get blocked before they exist, not cleaned up after.

Real retrieval, not keyword grep. Recall fuses BM25 full-text search with graph expansion along note links, over entities and session logs and journal entries. Ranking is freshness- and status-aware: recently updated and active notes float up, archived sinks. You get a topic's connected neighbourhood, not one isolated file.

Structured memory model. Working (transient) / episodic (what happened, when) / semantic (durable facts and preferences) memory layers, plus a current-context scope, per-session logs, an append-only journal with rollups, and PARA-style projects/areas/resources/decisions. A machine-readable routing manifest defines what may be written where, and the linter enforces it.

Reflection. /echo-reflect turns a conversation into memory: extract → classify → dedup against the index → confidence-filter → preview → apply. Low-confidence items go to the inbox instead of polluting the graph.

Durability and safety. Every write is HTTP-status-checked and read-back-verified (a failed write fails loudly, never silently). Appends are idempotent — retries can't double-write. Offline writes queue and replay. A cooperative advisory lock keeps Claude Code and CoWork from trampling each other on the shared vault.

Self-maintaining. The vault bootstraps itself from an empty Obsidian vault, migrates its own schema on version bumps, and /echo-sweep + /echo-health keep the graph honest (index rebuilds, link symmetry, frontmatter backfill, orphan/broken-link detection).

Fast. Connection pooling + concurrent reads mean full-vault operations that used to time out in the sandbox now finish in under a second.


What's new since 0.7 (your last consistent version)

You left off right after the toolchain got its executable spine (echo.py, routing manifest, linter). Since then, in rough order of what you'll actually notice:

  • You don't route anything by hand anymore. 0.7 was "pick the path, write with the right verb." Now capture/recall/resolve/link do routing, frontmatter, indexing, and cross-linking in one call — and in practice you just talk to Claude and it uses them.
  • Memory loads and saves itself (v1.5 hooks). No more remembering to run the loading procedure or write the session log.
  • Recall is actually good now (v0.91.5): entity index + hybrid BM25/graph search + freshness/status ranking, spanning sessions and journal too.
  • Duplicates get blocked at write time (v1.5 gate) instead of accumulating.
  • Offline resilience (v1.0): vault down ≠ data lost; writes queue and replay.
  • Everything is pure Python (v0.8): no bash, works identically on Windows.
  • Credentials moved out of the plugin (v1.31.4): generic builds prompt once per machine; your baked build carries them invisibly. Treat a baked .plugin file like a password — it contains your vault key. Don't share or commit it.

After installing the new version, run /echo-doctor, then /echo-sweep once to bring your vault up to the current schema (it dry-runs first and shows the plan).


Troubleshooting

Symptom Fix
NOT CONFIGURED banner / doctor shows red config Generic build with no config on this machine — echo.py config import <file>, or ask Jason for your baked build.
Vault unreachable Check that Obsidian + the Local REST API plugin are running on the backend and the endpoint is reachable. Meanwhile writes queue safely and replay on reconnect.
Save blocked with "duplicate gate" (exit 76) Not an error — it found a likely-existing entity. Review the candidates: merge into the existing note, or force-create if it's genuinely distinct.
Memory feels stale or inconsistent /echo-health to see what's off, /echo-sweep to repair index/links/frontmatter.
Inbox keeps getting mentioned at load /echo-triage — one pass empties it.
Anything else weird /echo-doctor first, then ask Jason.