Skip to content

Latest commit

Β 

History

300 Commits

Folders and files

NameName
Last commit message
Last commit date
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

spec-memo

Local working memory for coding agents outside the product repository. Version 0.26.0.

Documentation Website Β· Architecture & Specs Β· Changelog

Product git repositories should contain product code: source, tests, and shipped documentation. Agent working stateβ€”anti-regression traps, architecture decisions, feature specifications, implementation plans, execution state, and changelogsβ€”belongs in a curated vault outside the product repository, queried through an MCP server and matching CLI.


⚑ Simplified Quick Start

1. Installation & CLI Setup

spec-memo includes both the Model Context Protocol (MCP) server for AI coding environments and the memo CLI for interactive terminal usage and agent execution.

Quick Install

# Global install via npm from GitHub (adds `memo` to your npm global bin)
npm install -g github:jpolvora/spec-memo

# Or build from source clone
git clone https://github.com/jpolvora/spec-memo.git
cd spec-memo
npm install
npm run build
npm link

Making memo Available Globally on PATH (Windows, Linux, macOS)

The package.json declares "bin": { "memo": "./dist/cli.js" } and dist/cli.js includes the #!/usr/bin/env node shebang. Choose the method that best matches your workflow:

Option 1: Global Link from Clone (npm link β€” Recommended for Local Development)

When actively developing spec-memo or working from a local clone:

cd /path/to/spec-memo
npm install
npm run build
npm link
  • How it works: npm creates a global symlink/shim (memo on Unix; memo, memo.cmd, memo.ps1 on Windows) in your global npm prefix directory (e.g., %AppData%\Roaming\npm on Windows, /usr/local/bin or ~/.nvm/versions/node/<ver>/bin on Linux/macOS).
  • Live Rebuild Invariant: The link points directly to dist/cli.js. Whenever you compile changes with npm run build, your global memo command reflects the latest code immediately without needing to re-link or re-install.
Option 2: Global Install from Local Path
# Point npm install directly to your local clone directory
npm install -g "/path/to/spec-memo"
  • Installs a packaged copy to your npm global directory. Re-run this command after major rebuilds to refresh the global binary.
Option 3: Manual Executable Shim (Without npm link)

If you prefer not using npm global link or want a standalone wrapper script:

  • Linux / macOS: Create ~/.local/bin/memo (or /usr/local/bin/memo):

    #!/usr/bin/env bash
    exec node "/path/to/spec-memo/dist/cli.js" "$@"

    Make it executable: chmod +x ~/.local/bin/memo

  • Windows (Command Prompt / PowerShell): Create memo.cmd in a folder that is in your system or user PATH (e.g. C:\bin\memo.cmd or %USERPROFILE%\bin\memo.cmd):

    @echo off
    node "C:\path\to\spec-memo\dist\cli.js" %*

    (Optionally create memo.ps1 for PowerShell: & node "C:\path\to\spec-memo\dist\cli.js" @args)


PATH Verification & Troubleshooting

  1. Verify Binary Resolution:

    # Open a new shell/terminal session and run:
    memo --help
    memo check-version
  2. If memo: command not found persists:

    • Restart terminal: Fresh environment variables (like PATH changes) require a new shell or terminal window.
    • Check global npm PATH on Windows: Ensure %AppData%\Roaming\npm (or your custom npm config get prefix) is in your User or System PATH variable.
    • Check global npm PATH on Linux/macOS: Ensure ~/.local/bin or $(npm config get prefix)/bin is in your shell profile (~/.bashrc, ~/.zshrc).
  3. IDE MCP vs Terminal CLI:

    • Your AI editor (Cursor, VS Code, Claude Desktop, Antigravity) configures stdio MCP via memo setup --write-mcp or node /path/to/dist/cli.js serve.
    • Putting memo on your system PATH ensures that interactive terminal commands and AI agents executing shell scripts can call memo bootstrap, memo doctor --fix, memo search, etc. anywhere on your machine.
  4. After upgrading Node.js (FTS empty / GC_FAILED / ABI mismatch): better-sqlite3 is a native addon. A Node upgrade (for example 22 β†’ 24) leaves the old NODE_MODULE_VERSION binding in place. Search may error or look empty, gc returns GC_FAILED, and doctor must report unhealthy with rebuild steps rather than a stale healthy count.

    # Debian/Ubuntu (needed when no prebuild exists for your Node version)
    sudo apt install build-essential
    npm rebuild better-sqlite3
    memo doctor --rebuild

    spec-memo requires Node.js 22+ (package.json engines.node). CI runs the test suite on Node 22 and Node 24. FTS still uses better-sqlite3 (not node:sqlite); rebuild after every Node upgrade.

2. Deployment Modes & Agent Host Setup

spec-memo supports three operational deployment modes configured via memo setup:

  1. Local Mode (Default): All memory records, indexing, and queries run directly on the local machine in ~/.spec-memo/. Zero network dependencies.
  2. Hybrid Mode: Local vault remains the primary low-latency cache; transparently pulls updates from a shared daemon during bootstrap and debounces pushes on mutating operations (upsert, append, forget, gc). Manual sync via memo sync. Works offline seamlessly (fails open). When vaultGit.enabled is also set, memo sync runs hybrid HTTP and vault-git in parallel.
  3. Remote Mode: Agent hosts run a local stdio MCP proxy (memo serve) that forwards all 11 tools to a central remote daemon. Zero memory records stored on local disk. Fails closed with structured errors when unreachable.

Configure with memo setup

# Configure Local mode (default)
memo setup --mode local

# Configure Hybrid mode with a remote SSE daemon
memo setup --mode hybrid --url http://daemon.internal:3000

# Configure Remote mode with a remote SSE daemon
memo setup --mode remote --url http://daemon.internal:3000

Note on Authentication: Bearer tokens are read exclusively from environment variables (SPEC_MEMO_AUTH_TOKEN or SPEC_MEMO_SSE_TOKEN). memo setup verifies token presence in your environment without storing secrets in plain text on disk.

Generate or Write Host MCP Configuration

All agent hosts (Cursor, VS Code, OpenCode, Antigravity, Claude Desktop) use the same uniform stdio MCP wiring (memo serve). Mode switching is controlled entirely via ~/.spec-memo/config.json.

# Print MCP configuration snippet for your editor
memo setup --host cursor --print-mcp
memo setup --host vscode --print-mcp
memo setup --host opencode --print-mcp
memo setup --host claude --print-mcp

# Automatically write/merge MCP configuration directly to your editor's config file
memo setup --host cursor --write-mcp
memo setup --host vscode --write-mcp

Manual Host Configuration Snippets

Claude Desktop

Add to claude_desktop_config.json:

{
  "mcpServers": {
    "spec-memo": {
      "command": "memo",
      "args": ["serve"]
    }
  }
}

Cursor

Add to ~/.cursor/mcp.json or open Cursor Settings > MCP:

{
  "mcpServers": {
    "spec-memo": {
      "command": "memo",
      "args": ["serve"]
    }
  }
}

Antigravity / Gemini IDE

Add to ~/.gemini/config/mcp_config.json or active workspace config:

{
  "mcpServers": {
    "spec-memo": {
      "command": "memo",
      "args": ["serve"]
    }
  }
}

VS Code / Cline / Roo Code / Windsurf

Add to your extension's MCP configuration settings:

{
  "mcpServers": {
    "spec-memo": {
      "command": "memo",
      "args": ["serve"]
    }
  }
}

OpenCode

Add to ~/.config/opencode/config.json (type is local, command is an array β€” args is not valid here):

{
  "mcp": {
    "spec-memo": {
      "type": "local",
      "command": ["memo", "serve"],
      "enabled": true
    }
  }
}

Agent skill (ws-memo)

Day-to-day vault ops (all 10 MCP tools + CLI extras) are documented as a project skill:

Preferred install into a consumer repo:

memo install-skills --product-root /path/to/consumer
memo install-skills --global --force
# or MCP tool: install_skills { "productRoot": "/path/to/consumer" }
#            install_skills { "global": true, "force": true }

Manual copy/symlink of .agents/skills/ws-memo/ remains a fallback. Setup of specMemo.enabled in workflow-skills consumers remains ws-spec-memo β€” do not duplicate that bridge here.


πŸ–₯️ Run, serve, status monitor & autoboot

Audience: operators and humans. Agents: see AGENTS.md.

Default ports & Configuration

All daemon ports are fully configurable via ~/.spec-memo/config.json under the "ports" section (with aliases mcp for sse, ui for status):

{
  "ports": {
    "sse": 3123,
    "status": 3124,
    "canvas": 3125
  }
}
Service Default URL Start
MCP SSE transport http://127.0.0.1:3123 (/sse, /message, /health) memo serve --sse
Status monitor http://127.0.0.1:3124/ co-starts with --sse (disable: --no-status; override: --status-port)
Canvas graph viewer http://127.0.0.1:3125 memo canvas

How to run (local CLI)

# After global install or npm link
memo bootstrap
memo search "database lock" --kind trap
memo doctor

From a source checkout:

npm install
npm run build
node dist/cli.js bootstrap
# or: npm link  β†’  memo …

Vault root defaults to ~/.spec-memo/ ($SPEC_MEMO_ROOT to override). You can also persist a default vault path in bootstrap ~/.spec-memo/config.json:

{
  "vaultRoot": "/var/lib/spec-memo"
}

Resolution order: --vaultRoot flag β†’ $SPEC_MEMO_ROOT β†’ bootstrap config.json vaultRoot β†’ current directory when it contains config.json + projects/ β†’ ~/.spec-memo/.

Unusable candidates (not a directory, missing read/write permission, or not creatable) are skipped. Export, import/restore, backups, and reset always resolve through this same path and print the vault root they used.

One-time setup:

memo setup --vault-root /var/lib/spec-memo

How to serve (MCP)

Mode Command When to use
Stdio (default) memo serve Cursor / Claude Desktop / Gemini host spawns the process (see MCP configs above)
HTTP / SSE memo serve --sse Shared lab daemon, remote MCP URL, or bookmarkable status page
# Loopback SSE + status monitor
memo serve --sse
# β†’ MCP SSE:     http://127.0.0.1:3123/sse
# β†’ Health:      http://127.0.0.1:3123/health
# β†’ Status UI:   http://127.0.0.1:3124/

memo serve --sse --port 3123 --status-port 3124
memo serve --sse --no-status          # MCP only
memo serve --sse --json               # machine metadata (includes statusUrl)

Flags: --host (default 127.0.0.1), --port, --status-port, --no-status, --auth-token, --vaultRoot.

Managing Authentication Tokens & Remote Access

spec-memo secures non-loopback HTTP/SSE daemon traffic and status monitor access using a single shared Bearer token.

1. Security Principles

  • Zero Secrets on Disk: Tokens are never stored in vault config.json, product files, or Git repositories. They are resolved at runtime from environment variables or command-line flags.
  • Non-Loopback Safety: Binding beyond loopback (127.0.0.1, localhost, ::1) strictly refuses to start without a token.
  • Supported Environment Variables: SPEC_MEMO_AUTH_TOKEN (recommended) or SPEC_MEMO_SSE_TOKEN (alias).

2. Generate a Secure Token

# Linux / macOS
openssl rand -hex 32

# Windows (PowerShell)
[guid]::NewGuid().ToString('N')

3. Daemon / Server Configuration (Host Machine)

# Via Environment Variable (recommended)
export SPEC_MEMO_ROOT=/var/lib/spec-memo
export SPEC_MEMO_AUTH_TOKEN="your_generated_token_here"
memo serve --sse --host 0.0.0.0 --port 3000

# Or via CLI flag
memo serve --sse --host 0.0.0.0 --port 3000 --auth-token "your_generated_token_here"

For systemd autoboot, configure Environment=SPEC_MEMO_AUTH_TOKEN=your_generated_token_here in /etc/systemd/system/spec-memo.service (see systemd setup).

4. Client / Developer Machine Configuration

Option A: Stdio Proxy via memo setup (Hybrid / Remote Mode)

Export the token in your shell environment (~/.bashrc, ~/.zshrc, or Windows Environment Variables):

export SPEC_MEMO_AUTH_TOKEN="your_generated_token_here"
memo setup --mode hybrid --url http://daemon.internal:3000 --host cursor --write-mcp
Option B: Direct SSE MCP Connection

If connecting your IDE (Cursor, VS Code, Claude Desktop, Antigravity) directly to the remote SSE endpoint, provide the Authorization header in your MCP configuration:

{
  "mcpServers": {
    "spec-memo": {
      "url": "http://daemon.internal:3123/sse",
      "headers": {
        "Authorization": "Bearer your_generated_token_here"
      }
    }
  }
}

5. Status Monitor & API Health Checks

  • Status Monitor Web UI (Port 3124): Open http://daemon.internal:3124/ β€” when a token is configured, the UI redirects to /login (password-manager-friendly token field). The session is an HttpOnly cookie; the browser does not put the token in the address bar or API URLs.
  • Health & API Verification:
    # Check MCP daemon health (port 3123)
    curl -s -H "Authorization: Bearer your_generated_token_here" http://daemon.internal:3123/health
    
    # Check status monitor API (port 3124)
    curl -s -H "Authorization: Bearer your_generated_token_here" http://daemon.internal:3124/api/status

6. Diagnose Token Setup

Run memo doctor on the client or server to verify whether the deployment mode detects an active token in the environment:

memo doctor

How to check the SSE status monitor

  1. Start memo serve --sse (status companion on by default).
  2. Open http://127.0.0.1:3124/ in a browser (favorite that URL).
  3. Confirm health cards (MCP host/port, vault count, uptime) and the live activity log (tool + HTTP events).
  4. Filter by vault/project via the page control or ?project=<projectId>.

Quick machine checks:

curl -s http://127.0.0.1:3123/health
curl -s http://127.0.0.1:3124/api/status
curl -s http://127.0.0.1:3124/api/vaults
# JSON array of `{ id, displayName }` β€” the monitor sidebar and vault selectors use this array (not `{ vaults: [...] }`).
# Live stream (SSE): GET http://127.0.0.1:3124/api/events/stream

When a token is set, send Authorization: Bearer <token> (or a session cookie from /login). Diagnostic routes are read-only except explicit operator writes: backup/reset HTTP endpoints and POST /api/wiki/regenerate. Canvas remains a separate graph UI.

Status monitor backup (Backups tab)

The status monitor includes a dedicated Backups tab (?tab=backups or #tab-backups) for vault snapshot management:

  1. Create Backup β€” persists a timestamped .zip under $SPEC_MEMO_ROOT/backups/. With All vaults selected, a confirmation dialog is required (confirmFullBackup: true on the API). A selected project vault creates a single-project snapshot.
  2. Inventory β€” lists saved archives with filename, size, entry counts, scope (full / project), and encryption status. Filter by filename, scope, project, kinds present, date range, and encryption.
  3. Row actions β€” Restore (POST /api/vaults/restore), Download (GET /api/vaults/backups/{filename}), and Delete (DELETE /api/vaults/backups/{filename} with { confirm: true }). Click a row to open the details drawer (GET /api/vaults/backups/{filename}/inspect).
  4. Complete archives β€” backups include all durable record kinds (trap, decision, spec, plan, state, log, scratch, review, prompt, session). Restore rebuilds FTS automatically.

HTTP routes:

Method Path Role
POST /api/vaults/backups Persist snapshot (projectId or confirmFullBackup: true)
GET /api/vaults/backups List inventory (optional q, scope, projectId, encrypted, since, until, kind, size filters)
GET /api/vaults/backups/{filename} Download archive
GET /api/vaults/backups/{filename}/inspect Details drawer metadata
DELETE /api/vaults/backups/{filename} Remove archive file ({ confirm: true })

POST /api/vaults/export remains for scripted browser zip download (full vault requires confirmFullBackup: true when projectId is omitted).

Tip

CLI parity: memo backups, memo restore --backup …, and memo export-vault operate on the same backups/ folder. UI zips contain vault-backup.json β€” extract and run memo import-vault --archive vault-backup.json for CLI restore.

Status monitor Wiki tab

The Vaults tab (?tab=vaults) lists vault projects from GET /api/vaults (JSON array with id, displayName, aliasOf, recordCount). Operators can create projects, set aliases, merge sources into a canonical id (optional copyRecords), edit display names, and delete with confirmation. Mutating routes use the same auth and path sanitization as backup/reset.

CLI extra (not an MCP tool): memo vault list|alias|merge|create|update|delete (see Command Reference).

The Wiki tab (?tab=wiki or ?tab=wiki&project={id}) shows the vault file projects/{projectId}/WIKI.md. It is not the consumer product README.

  • Select a project (All vaults is refused). Missing WIKI.md shows an empty state; Regenerate stays available.
  • Regenerate posts POST /api/wiki/regenerate with { "projectId" } (collect β†’ fill template.md β†’ persist). Optional AI polish is off by default; set wiki.aiEnabled in vault config.json or SPEC_MEMO_WIKI_AI=1. Polish failures still save the deterministic page (aiPolished: false).
  • CLI extra (not an MCP tool): memo wiki --project <id> and memo wiki --project <id> --regenerate. Unavailable in remote mode.

HTTP routes:

Method Path Role
GET /api/wiki?project= Current markdown (exists false when missing)
GET /api/wiki/section?project=&id= One h2 section by slug
POST /api/wiki/regenerate Collect, render, persist WIKI.md

How to diagnose

memo doctor              # vault + FTS + in-repo pollution scan
memo doctor --json
memo doctor --rebuild    # rebuild SQLite FTS5 from markdown
memo doctor --fix       # delete leftover in-tree workflow residue
memo doctor --check-capture <path>  # verify CAPTURED vs IGNORED exclusion boundary

Also useful: memo rank (trap recurrence), memo wiki --regenerate (vault project page), memo gc --dry-run, and the status page live log while the SSE daemon is up.

Autoboot: run memo serve --sse as a service

Use this so the MCP SSE daemon (and status monitor) start on boot. Prefer a durable vault directory (not a login-user ~/.spec-memo unless intentional).

Linux β€” systemd

sudo mkdir -p /var/lib/spec-memo
# Install Node 22+ + clone/build to /opt/spec-memo (or npm i -g spec-memo and point ExecStart at `memo`)

/etc/systemd/system/spec-memo.service:

[Unit]
Description=spec-memo MCP SSE
After=network.target

[Service]
Type=simple
WorkingDirectory=/opt/spec-memo
Environment=SPEC_MEMO_ROOT=/var/lib/spec-memo
# Auth token (SPEC_MEMO_AUTH_TOKEN or SPEC_MEMO_SSE_TOKEN)
Environment=SPEC_MEMO_AUTH_TOKEN=replace-me
ExecStart=/usr/bin/node /opt/spec-memo/dist/cli.js serve --sse --host 0.0.0.0 --port 3000
Restart=on-failure

[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload
sudo systemctl enable --now spec-memo.service
sudo systemctl status spec-memo.service
curl -s -H "Authorization: Bearer replace-me" http://127.0.0.1:3000/health
# Status UI: http://<host>:3001/  (also requires the bearer when a token is set)

# Inspect configured environment variables on service:
systemctl show spec-memo.service --property=Environment

# Or inspect live environment variables of the running process:
sudo cat /proc/$(pgrep -f "spec-memo" | head -n 1)/environ | tr '\0' '\n' | grep SPEC_MEMO

Windows β€” Task Scheduler (autoboot at logon)

  1. Install Node 22+ and npm install -g github:jpolvora/spec-memo (or build this repo and use the full path to node + dist\cli.js).
  2. Create a vault dir, e.g. C:\spec-memo-vault.
  3. Task Scheduler β†’ Create Task:
    • Trigger: At log on (or At startup with a service account).
    • Action: Start a program
      • Program: node (full path if needed)
      • Arguments: "C:\Users\<you>\AppData\Roaming\npm\node_modules\spec-memo\dist\cli.js" serve --sse --host 127.0.0.1 --port 3000
        (or memo.cmd serve --sse … if memo is on PATH)
    • Start in: vault-friendly working directory.
  4. Add environment variables on the task (or a wrapper .cmd): SPEC_MEMO_ROOT=C:\spec-memo-vault, and SPEC_MEMO_SSE_TOKEN=… if binding off loopback.
  5. Optional: NSSM / WinSW to wrap the same command as a Windows Service with restart-on-failure.

Verify: open http://127.0.0.1:3001/ and curl http://127.0.0.1:3000/health.

Shared-lab note: project identity comes from the git remote of the tool cwd / projectId. Laptop paths do not exist on the server β€” pass a stable projectId (e.g. github.com-jpolvora-spec-memo) or a server-side clone path as cwd. One bearer token = shared vault (no per-user ACL).


3. Enable in Consumer Repositories & Agents

Zero setup required in product repos. spec-memo requires no configuration files, no .spec-memo directory, and no committed pointers in your project.

  1. Automatic Project Identity: When an agent works in any project directory, spec-memo detects the git remote origin (e.g. github.com/org/repo) and maps all memory to that project's external vault. All clones of the same repository automatically share the exact same working memory.
  2. Prevent Accidental In-Repo Memory Commits: Install the pre-commit write-block hook in any consumer repository:
    cd /path/to/your-product-repo
    memo hook install
    (Blocks accidental commits of .agents/plans/, MEMORY.md, memory/*.md, and .state.md)

4. Basic Workflow

               β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
               β”‚              AI Agent Session                β”‚
               β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                      β”‚
           1. Session Start           β”‚ 2. During Work
           β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
           β–Ό                                                     β–Ό
    memo bootstrap                                        memo upsert / append
  (Returns token-budgeted brief:                         (Saves traps, decisions,
   Traps, Decisions, Live Slug, Drift)                   specs, plans, logs to vault)
                                      β”‚
                                      β”‚ 3. Query on Demand
                                      β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Ί memo search / get
                                      β”‚
                                      β–Ό 4. Session Finish / Housekeeping
                                 memo gc
                        (Purges expired scratch,
                         compacts completed plans)
  1. Session Start (bootstrap): At the start of a prompt or task, the agent invokes bootstrap:

    memo bootstrap

    Returns a token-budgeted brief (default 8 KB; raise via ~/.spec-memo/config.json bootstrap.maxBytes or --maxBytes) containing top ranked anti-regression traps for relevant files, open architecture decisions, active spec/plan slice, and code drift alerts.

  2. During Work (upsert & append):

    • Record newly discovered bug traps or anti-regression lessons:
      memo upsert --kind trap --title "SQLite WAL Lock on Windows" --severity high --path-patterns "src/db/*.ts" --body "Always close statements before closing connection."
    • Record an architectural decision:
      memo upsert --kind decision --title "Use SQLite FTS5 for Search" --body "ADR: FTS5 provides fast local indexing with zero external daemons."
    • Append an audit or task event:
      memo append --event "Refactored vault locking mechanism and passed all 178 tests"
  3. Query Memory (search & get):

    • Filtered full-text search:
      memo search "database lock" --kind trap
    • Fetch a specific record by ID or slug:
      memo get --id trap-sqlite-wal-lock-on-windows
  4. Finishing & Housekeeping (gc & promote):

    • Run garbage collection to apply TTL retention (purges 7-day scratch, 14-day review records, and compacts completed plans):
      memo gc
    • If a human explicitly wants a decision or spec recorded in product documentation, promote it into the product repository:
      memo promote trap-sqlite-wal-lock-on-windows --to docs/adr/002-sqlite-locking.md

πŸ” Detailed Architecture & How It Works

The Vault Outside Git

All memory is stored in $SPEC_MEMO_ROOT (defaults to ~/.spec-memo/):

~/.spec-memo/
β”œβ”€β”€ config.json                 # Global vault configuration (TTL, budget, enableTelemetry, git sync)
β”œβ”€β”€ memo.sqlite                 # Disposable SQLite FTS5 search index
β”œβ”€β”€ telemetry/                  # Append-only daily rolling usage logs (telemetry-YYYY-MM-DD.part-N.jsonl)
└── projects/
    └── <projectId>/            # Hash derived from git remote origin
        β”œβ”€β”€ project.json        # Project metadata, remote URL, display name
        β”œβ”€β”€ TRAPS.md            # Auto-compiled markdown view of active traps
        β”œβ”€β”€ DECISIONS.md        # Auto-compiled markdown view of architecture decisions
        β”œβ”€β”€ INDEX.md            # Auto-compiled markdown view of all project specs & plans
        β”œβ”€β”€ traps/              # Individual *.md records with YAML frontmatter
        β”œβ”€β”€ decisions/          # Architecture decisions (ADRs)
        β”œβ”€β”€ specs/              # Feature specifications
        β”œβ”€β”€ plans/              # Implementation plans and execution state
        β”œβ”€β”€ logs/               # Append-only chronological run logs & roll-ups
        β”œβ”€β”€ reviews/            # Code review and audit notes (14-day TTL)
        └── scratch/            # Temporary scratchpad notes (7-day TTL)

Core Architecture Highlights

  • Markdown Source of Truth: Every record is a human-readable Markdown file with structured YAML frontmatter.
  • Disposable SQLite FTS5 Index: memo.sqlite provides instant Porter-stemmed search, tag filtering, and path pattern globbing. If deleted or corrupted, it is automatically rebuilt from the Markdown files.
  • Automatic Project Identity: Repositories are identified by normalized remote URL (git@github.com:org/repo.git β†’ github.com/org/repo). Multiple clones on the same machine share the same memory without conflicts.
  • Operational Telemetry & Usage Analytics: Built-in rolling JSONL telemetry records tool latencies, endpoints, duration, and error codes under ~/.spec-memo/telemetry/ (enableTelemetry: true). Asynchronously batched with zero disk blockages and secret redaction.
  • Secret Redaction & Safety: Built-in pattern filters automatically redact API keys, JWTs, private keys, and bearer tokens from memory records before writing. Writes directed to the product repository root are rejected by default.
  • Automatic Trap Deduplication: When saving a new trap, spec-memo checks token overlap against existing traps with matching path patterns. If overlap exceeds 70%, the older trap is automatically marked as superseded.
  • Spec Code Drift Detection: When specifications declare linkedPaths and verifiedAtSha, bootstrap compares git status and file contents against the verified commit SHA, warning the agent if the product code drifted from the specification.

πŸ› οΈ Advanced Workflows & Utility Commands

1. Operational Status & Configuration Inspection (status)

Inspect running daemons, deployment mode, socket reachability, project bindings, and storage metrics with a single read-only command. memo status never creates or rewrites vault files (config.json, projects/, telemetry/). Malformed config.json reports CONFIG_ERROR. Remote /health 401/403 fails --check (exit 1).

# Display colorized status dashboard (aliases: memo info, memo state)
memo status

# Health check mode for CI/CD or scripts (exits 0 if healthy, 1 if issues exist)
memo status --check

# Machine-readable JSON output
memo status --json

2. Health Diagnostics & Repository Cleaning (doctor)

Inspect vault integrity, SQLite FTS index status, and detect leftover in-repo workflow pollution. (Also see Run, serve, status monitor & autoboot for live SSE status checks.)

# Check vault health and scan product repository for residue
memo doctor

# Check and automatically clean up in-tree workflow pollution files
memo doctor --fix

# Rebuild the SQLite FTS5 index from vault markdown records
memo doctor --rebuild

3. Import Legacy Workflow Trees (import)

One-shot migration of existing .agents/specs/, memory/*.md, MEMORY.md, .agents/plans/, and CHANGELOG.md files into the external vault:

memo import --from /path/to/legacy-repo

3. Full Vault Backup, Restore & Reset (backups, restore, reset)

Manage backups, restore full ZIP archives, or reset the memory store with automatic safety snapshots:

# List available timestamped backups
memo backups

# Restore the most recent backup
memo restore --latest

# Restore from a specific backup archive (.zip or .json)
memo restore --backup ~/.spec-memo/backups/2026-08-31-14-30-45-backup.zip

# Reset vault records and SQLite databases with a mandatory pre-wipe backup
memo reset --all --force

# Export encrypted vault archive
memo export-vault --password "my-secure-password" -o ~/spec-memo-backup.json

# Restore encrypted vault archive on another machine
memo restore ~/spec-memo-backup.json --password "my-secure-password"

4. Optional Private Git Remote Sync (vault-git)

Enable automatic private git remote backup on the vault root (~/.spec-memo/):

In ~/.spec-memo/config.json:

{
  "bootstrap": {
    "maxBytes": 8192
  },
  "vaultGit": {
    "enabled": true,
    "atomic": false,
    "remoteUrl": "git@github.com:my-user/my-private-memory-vault.git",
    "branch": "main"
  }
}

bootstrap.maxBytes is the default UTF-8 session brief budget (8192). Increase it to return a larger memo bootstrap payload; per-call --maxBytes / MCP maxBytes still overrides this value.

vaultGit.atomic defaults to false (batched): mutations write markdown only; git commit + remote pull/push run on memo sync, MCP/CLI session_end, or graceful memo serve shutdown. Set "atomic": true for per-mutation commit and push (fail-open; errors go to error.logs).

When both mode: hybrid and vaultGit.enabled are set, memo sync dispatches hybrid HTTP and vault-git in parallel. Either channel can fail without crashing the MCP/SSE server. CLI one-shot memo upsert in batched mode does not flush git on process exit; run memo sync.

5. Promoting Records to Product Documentation (promote)

Vault records can be selectively promoted into the product repository with ADR templates:

memo promote decision-sqlite-fts5 --to docs/adr/001-sqlite-fts5.md --format adr

6. Vault Conflict Reconciliation & Automated Resilience (reconcile)

Resolve synchronization differences between local and remote vaults with automatic semantic auto-merging:

# Preview reconciliation changes (dry-run)
memo reconcile --dry-run

# Reconcile preferring local vault as the authoritative source of truth
memo reconcile --prefer local

# Reconcile preferring remote daemon
memo reconcile --prefer remote

# Automatic cleanup of identical conflict sidecars
memo reconcile --clean-sidecars
  • Smart Auto-Merge (smart-merge): When record bodies match, divergent retrieval counts (hits, lastHit, occurrences, tags, linkedPaths) merge cleanly in place with zero conflict files generated.
  • Single Sidecar Cap: If true body conflicts exist under --strategy sidecar, a single deterministic ${slug}.conflict.md sidecar is maintained rather than proliferating timestamped files.
  • Doctor Cleanup: memo doctor --fix automatically cleans obsolete sidecars whose bodies match the base record.
  • Transactional Rollback: Multi-record changeset applications use copy-on-write staging rollback journals; errors cleanly revert state without partial writes.

πŸ“‹ Command & Tool Reference

Command / Tool Role Key Options
status Query read-only operational dashboard, daemon reachability, configuration, and storage statistics (aliases: info, state, setup --check) --check, --cwd, --vaultRoot, --json
setup Configure deployment mode & agent host MCP wiring --mode, --url, --host, --print-mcp, --write-mcp, --json
bootstrap Compile token-budgeted session brief --maxBytes (overrides config.json bootstrap.maxBytes, default 8192), --query, --path, --slug, --session-id, --explain
search Filtered FTS5 retrieval across records --kind, --tags, --path, --all, --sort (relevance|occurrences|updated|hits), --hit-ids, --session-id, --explain, --include-expired, --as-of
get Read one record by id or kind+slug (eligible kinds bump hits) --id or --kind+--slug, --session-id
upsert Create or update typed memory record --kind, --title, --severity, --path-patterns, --body
append Append chronological event log --event, --kind
forget Archive or permanently delete record --id, --purge
gc Apply TTL retention and compact plans --dry-run, --project, --purge
promote Safe export of record to product repo --id, --to, --format (raw/adr/madr/skill), --force, --limit
check_version / check-version Compare running version to npm latest --json
install_skills / install-skills Install ws-memo / ws-session-tracking into a consumer repo or global skills roots --product-root, --global, --skill, --force, --json
install_hooks / install-hooks Optional agent lifecycle hooks for Antigravity, OpenCode, Cursor, Claude (CLI-only) --host, --global, --apply, --dry-run, --force, --remove, --json
prompt / prompts Ingest & query prompt history; derive rules; export stories; record memory feedback record/list/search/show/session/export/derive-rules/feedback
session Start/end/inspect work sessions (alias into prompt) start/end/handoff/show/export, --summary, --pr, --handoff-steps, --shared, --objective
activity Timesheet / invoicing activity report --since, --until, --client, --json
feedback Submit helpful/stale/wrong feedback on a memory record (CLI extra) <id>, --helpful/--stale/--wrong, --comment
rank List traps by recurrence (CLI-only) --layer, --limit, --backfill, --json
doctor Diagnose health, mode, conflict sidecars, semantic contradictions, stale traps, and fix repo pollution --fix, --rebuild, --json
sync Synchronize vault records (hybrid HTTP, vault-git, or both in parallel) --all, --dry-run, --prefer (local|remote), --strategy, --clean-sidecars, --force, --json
reconcile Reconcile sync conflicts, apply smart semantic auto-merge, and clean conflict sidecars --prefer (local|remote), --strategy (smart-merge|local-wins|remote-wins|sidecar), --clean-sidecars, --dry-run, --all, --json
import Import legacy .agents tree to vault --from, --vaultRoot
export-vault Export encrypted portable archive --password, --output, --project
import-vault / restore Restore portable archive (.zip or .json) into vault <file>, --backup, --latest, --password
backups List available timestamped backups in $SPEC_MEMO_ROOT/backups/ --vaultRoot, --json
reset Reset vault database and clear files with mandatory pre-wipe backup --all, --project, --force, --password
hook install Install pre-commit write-block hook --productRoot
wiki Print or regenerate vault projects/{id}/WIKI.md (CLI extra; not an MCP tool) --project, --regenerate, --json
vault Manage vault projects (alias redirect, merge, CRUD; CLI extra; not an MCP tool) list, alias --from --to, unalias --from, merge --source --target [--copy-records], create, update, delete --confirm
serve Run stdio or SSE MCP server for agent hosts (SSE co-starts status on :3124; stdio opt-in via --status) --sse, --port, --status, --status-port, --no-status, --auth-token

Operator Q&A

How do I check if I am on the latest spec-memo?

memo check-version --json

Compare current to latest. When the registry is unreachable, updateAvailable is "unknown" and latest is null.

How do I install the ws-memo skill into a consumer project?

memo install-skills --product-root /path/to/consumer
# Global (Cursor/agents + Antigravity if ~/.gemini/config exists):
memo install-skills --global --force

Use --force only when overwriting a diverged destination. MCP hosts can call install_skills with the same arguments (global: true for global roots).

How do I make the memo command available on my PATH (Windows / Linux / macOS)?

Run npm link inside your spec-memo clone directory. This links the package bin ("memo": "./dist/cli.js") to your npm global directory (e.g. %AppData%\Roaming\npm on Windows or /usr/local/bin on Linux). After running npm run build, memo is immediately accessible in any new terminal session without re-linking. See Making memo Available Globally on PATH for manual shim alternatives and PATH troubleshooting.


πŸ“„ License

MIT

About

Curated working memory for coding agents, stored outside the product git repository.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages