|
| 1 | +--- |
| 2 | +name: lore |
| 3 | +description: Lore harness — status, update, memory, repair |
| 4 | +type: command |
| 5 | +user-invocable: true |
| 6 | +allowed-tools: Read, Write, Edit, Bash, Glob, Grep, TaskCreate, TaskUpdate |
| 7 | +--- |
| 8 | + |
| 9 | +# Lore |
| 10 | + |
| 11 | +Unified entry point for Lore harness commands. Parse the first argument to route to the correct subcommand. |
| 12 | + |
| 13 | +## Routing |
| 14 | + |
| 15 | +Parse arguments from the user's invocation: |
| 16 | + |
| 17 | +| Input | Route | |
| 18 | +|-------|-------| |
| 19 | +| `/lore` (no args) | → **Help** | |
| 20 | +| `/lore status` | → **Status** | |
| 21 | +| `/lore update` | → **Update** | |
| 22 | +| `/lore repair` | → **Repair** | |
| 23 | +| `/lore memory` | → **Memory › Sidecar** (default: start) | |
| 24 | +| `/lore memory start` | → **Memory › Sidecar** (start) | |
| 25 | +| `/lore memory stop` | → **Memory › Sidecar** (stop) | |
| 26 | +| `/lore memory status` | → **Memory › Sidecar** (status) | |
| 27 | +| `/lore memory burn` | → **Memory › Burn** | |
| 28 | +| `/lore memory rem` | → **Memory › Defrag** | |
| 29 | + |
| 30 | +Unrecognized arguments → show Help with a note that the subcommand wasn't recognized. |
| 31 | + |
| 32 | +## Help |
| 33 | + |
| 34 | +Display this table when invoked with no arguments: |
| 35 | + |
| 36 | +``` |
| 37 | +/lore Show this help |
| 38 | +/lore status Instance health — version, hooks, skills, fieldnotes |
| 39 | +/lore update Update harness to latest version |
| 40 | +/lore repair Diagnose and fix a harness bug |
| 41 | +/lore memory Start the sidecar (semantic search + hot memory) |
| 42 | +/lore memory stop Stop the sidecar |
| 43 | +/lore memory status Sidecar health check |
| 44 | +/lore memory burn Promote hot facts to the knowledge base |
| 45 | +/lore memory rem Knowledge defrag — restructure the KB |
| 46 | +``` |
| 47 | + |
| 48 | +--- |
| 49 | + |
| 50 | +## Status |
| 51 | + |
| 52 | +Operator-facing diagnostic. Shows whether Lore is loaded and healthy. |
| 53 | + |
| 54 | +### Process |
| 55 | + |
| 56 | +Run these checks and present a formatted summary to the operator: |
| 57 | + |
| 58 | +1. **Version** — read `version` from `.lore/config.json`. If missing, report "no version (pre-update-lore)". |
| 59 | + |
| 60 | +2. **Hooks** — check each platform that has config present: |
| 61 | + |
| 62 | + **Claude Code** (`.claude/settings.json`): |
| 63 | + - `SessionStart` → `session-init.js` |
| 64 | + - `UserPromptSubmit` → `prompt-preamble.js` |
| 65 | + - `PreToolUse` → `protect-memory.js`, `harness-guard.js`, `search-guard.js` |
| 66 | + - `PostToolUse` → `memory-nudge.js` |
| 67 | + - `PostToolUseFailure` → `memory-nudge.js` |
| 68 | + |
| 69 | + **Gemini CLI** (`.gemini/settings.json`): |
| 70 | + - `SessionStart` → `session-init.js` |
| 71 | + - `BeforeAgent` → `prompt-preamble.js` |
| 72 | + - `BeforeTool` → `protect-memory.js`, `harness-guard.js`, `search-guard.js` |
| 73 | + - `AfterTool` → `memory-nudge.js` |
| 74 | + |
| 75 | + Report each platform as OK, PARTIAL, or MISSING. |
| 76 | + |
| 77 | +3. **Counts** — count and report: |
| 78 | + - Harness skills: number of directories in `.lore/harness/skills/` |
| 79 | + - Operator skills: number of directories in `.lore/skills/` |
| 80 | + - Agents: number of `.md` files in `.lore/agents/` |
| 81 | + - Fieldnotes: number of directories in `~/.lore/knowledge-base/fieldnotes/` |
| 82 | + - Runbooks: number of `.md` files under `~/.lore/knowledge-base/runbooks/` |
| 83 | + |
| 84 | +4. **Active work** — scan `~/.lore/knowledge-base/work-items/` for items with `status: active` or `status: on-hold` in frontmatter. List titles. |
| 85 | + |
| 86 | +5. **Format** — present as a clean block the operator can read at a glance: |
| 87 | + ``` |
| 88 | + Lore v<version> |
| 89 | +
|
| 90 | + Hooks: |
| 91 | + Claude Code OK |
| 92 | + Cursor OK |
| 93 | + Cursor MCP OK |
| 94 | + OpenCode OK |
| 95 | +
|
| 96 | + Harness skills: 8 | Operator skills: 4 | Agents: 3 |
| 97 | + Fieldnotes: 19 | Runbooks: 5 |
| 98 | +
|
| 99 | + Active work: (none) |
| 100 | + ``` |
| 101 | + |
| 102 | +--- |
| 103 | + |
| 104 | +## Update |
| 105 | + |
| 106 | +Pull the latest Lore harness files without touching operator content. |
| 107 | + |
| 108 | +### Process |
| 109 | + |
| 110 | +1. Read current version from `.lore/config.json` |
| 111 | +2. Clone the latest Lore template to a temp directory: |
| 112 | + ```bash |
| 113 | + tmp=$(mktemp -d) && [ -d "$tmp" ] || { echo "mktemp failed"; exit 1; } |
| 114 | + git clone --depth 1 https://github.com/lorehq/lore.git "$tmp" |
| 115 | + ``` |
| 116 | + **Critical**: always pass `"$tmp"` as the target — omitting it clones into the working directory as `lore/`. |
| 117 | +3. Read the source version from the cloned `.lore/config.json` |
| 118 | +4. Show the operator: current version, new version, what will be synced |
| 119 | +5. On approval, run **from the instance directory** (cwd), passing the harness repo clone as the argument: |
| 120 | + ```bash |
| 121 | + bash "$tmp/.lore/harness/scripts/sync-harness.sh" "$tmp" |
| 122 | + ``` |
| 123 | + **Direction: cwd = target instance, argument = source harness repo.** Getting this backwards overwrites the harness repo with stale instance files. |
| 124 | +6. Update the `version` field in `.lore/config.json` to match the source |
| 125 | +7. **Migrate global directory** — bring `~/.lore/` up to date: |
| 126 | + ```bash |
| 127 | + node -e "const{ensureGlobalDir}=require('./.lore/harness/lib/global');const r=ensureGlobalDir('./.lore/harness/migrations');console.log(r.ran?'Migrated to v'+r.version:'Global dir up to date (v'+r.version+')');" |
| 128 | + ``` |
| 129 | + This creates `~/.lore/` if missing and applies pending structural migrations. |
| 130 | +8. **Seed review** — compare `.lore/harness/templates/seeds/rules/` to operator rule files in `.lore/rules/`. For each seed template where the operator file exists and differs: |
| 131 | + - Show the diff (seed template vs operator file) |
| 132 | + - Ask the operator whether to adopt the updated seed or keep their version |
| 133 | + - Only overwrite operator files the operator explicitly approves |
| 134 | + Note: seed filenames may map differently (e.g., seed `docs.md` → operator `documentation.md`). Compare by content purpose, not filename. |
| 135 | +9. Clean up: `rm -rf "$tmp"` |
| 136 | +10. Report what changed |
| 137 | + |
| 138 | +### What Gets Synced |
| 139 | + |
| 140 | +**Overwritten (harness-owned):** |
| 141 | +- `.lore/harness/hooks/`, `.lore/harness/lib/`, `.lore/harness/scripts/`, `.opencode/` |
| 142 | +- `.claude/settings.json`, `.lore/skills/<built-in>/` |
| 143 | +- `.lore/instructions.md`, `.gitignore`, `opencode.json` |
| 144 | +- Generated copies (`CLAUDE.md`, `.cursor/rules/lore-*.mdc`) are also regenerated via `sync-platform-skills.sh` |
| 145 | + |
| 146 | +**Seed files (opt-in update):** |
| 147 | +- `.lore/harness/templates/seeds/rules/` — default rule content. Created on first install if missing. On update, diffs shown for operator review. |
| 148 | + |
| 149 | +**Never touched (operator-owned):** |
| 150 | +- `.lore/agents/` |
| 151 | +- `.lore/config.json`, `.lore/memory.local.md`, `.lore/operator.gitignore` |
| 152 | + |
| 153 | +### Snags |
| 154 | + |
| 155 | +- Always show the version diff and file list before syncing — never auto-update |
| 156 | +- The sync script uses rsync semantics: overwrite existing, never delete operator files |
| 157 | +- If the operator has modified a harness-owned file (e.g., edited CLAUDE.md), the update will overwrite it — warn about this |
| 158 | +- Operator-specific ignores go in `.lore/operator.gitignore` (never overwritten). The sync script appends them after harness rules automatically — no manual re-adding needed |
| 159 | +- Always clean up the temp clone (`rm -rf "$tmp"`) even if sync fails — otherwise a `lore/` directory persists in the project root |
| 160 | + |
| 161 | +--- |
| 162 | + |
| 163 | +## Repair |
| 164 | + |
| 165 | +Diagnose and fix a harness bug using the field repair workflow. |
| 166 | + |
| 167 | +### Process |
| 168 | + |
| 169 | +1. Load the field-repair rule: `.lore/rules/field-repair.md` |
| 170 | +2. Ask the operator: |
| 171 | + - **What's broken?** (hook error, skill failure, script crash, bad behavior) |
| 172 | + - **How to reproduce?** (exact trigger — slash command, tool call, event) |
| 173 | + - **Which repo likely owns this?** (lore, create-lore, lore-memory, lore-docs) |
| 174 | +3. Follow the rule steps in order: |
| 175 | + - Reproduce → Isolate → Fix in source → Test → Push and sync → Report → Capture |
| 176 | +4. Use TaskCreate to track each step if the repair spans multiple turns |
| 177 | + |
| 178 | +### Snags |
| 179 | + |
| 180 | +- Debug output goes to `/tmp`, never stderr — stderr corrupts hook responses |
| 181 | +- Copy fixed files into the instance for testing, but revert before syncing |
| 182 | +- Always fix in the source repo, never patch the instance directly |
| 183 | +- Run `/lore update` from the instance after pushing — never run sync scripts ad-hoc |
| 184 | +- The operator is your eyes — ask them to confirm behavior you can't observe |
| 185 | + |
| 186 | +--- |
| 187 | + |
| 188 | +## Memory |
| 189 | + |
| 190 | +### Sidecar |
| 191 | + |
| 192 | +Manage the local Lore sidecar lifecycle. |
| 193 | + |
| 194 | +The sidecar provides semantic search over the knowledge base and hot memory (Redis) for agent sessions. It runs from `~/.lore/docker-compose.yml` — one sidecar per machine, shared across all projects. |
| 195 | + |
| 196 | +#### Platform detection |
| 197 | + |
| 198 | +Detect the OS for process queries: |
| 199 | +- `uname -s` → `Linux` or `Darwin` = Unix, `MINGW*` or `MSYS*` or `CYGWIN*` = Windows |
| 200 | + |
| 201 | +#### Process |
| 202 | + |
| 203 | +Interpret intent from user input: |
| 204 | +- default or `start` -> start sidecar |
| 205 | +- `stop` -> stop sidecar |
| 206 | +- `status` -> report current state |
| 207 | + |
| 208 | +**Start:** |
| 209 | + |
| 210 | +1. Check Docker daemon: `docker info > /dev/null 2>&1` |
| 211 | +2. Pull image: `docker pull lorehq/lore-memory:latest` |
| 212 | +3. Start services: |
| 213 | + ```bash |
| 214 | + docker compose -f ~/.lore/docker-compose.yml up -d |
| 215 | + ``` |
| 216 | +4. Wait for port 9185 to respond. |
| 217 | +5. Verify health: `curl -s http://localhost:9185/health` |
| 218 | + |
| 219 | +**Stop:** |
| 220 | + |
| 221 | +1. Stop services: |
| 222 | + ```bash |
| 223 | + docker compose -f ~/.lore/docker-compose.yml down |
| 224 | + ``` |
| 225 | + |
| 226 | +**Status:** |
| 227 | + |
| 228 | +1. Check container state and verify HTTP response at `localhost:9185/health`. |
| 229 | + |
| 230 | +#### Snags |
| 231 | + |
| 232 | +- Semantic search model loading can take 30-60 seconds on first start. Poll `/health` until `ok: true`. |
| 233 | +- The compose file lives at `~/.lore/docker-compose.yml`. Users customize ports and settings by editing it directly. |
| 234 | +- If the port is changed from the default 9185, also set `sidecarPort` in `~/.lore/config.json`. |
| 235 | + |
| 236 | +### Burn |
| 237 | + |
| 238 | +Burn "hot" session experiences into the permanent knowledge base. |
| 239 | + |
| 240 | +Lore uses heat-based tiering to manage context. Facts and draft fieldnotes start in Hot Memory (Redis) and promote to the Persistent KB (Markdown files) after operator approval. Burn is the promotion gate. |
| 241 | + |
| 242 | +#### Process |
| 243 | + |
| 244 | +**1. Scan Hot Memory** |
| 245 | + |
| 246 | +Retrieve active facts using the `lore_hot_recall` MCP tool: |
| 247 | + |
| 248 | +``` |
| 249 | +lore_hot_recall(limit: 20) |
| 250 | +``` |
| 251 | + |
| 252 | +If MCP is unavailable, fall back to curl: |
| 253 | +```bash |
| 254 | +curl -s "http://localhost:9185/memory/hot?limit=20" |
| 255 | +``` |
| 256 | + |
| 257 | +If the sidecar is down, fall back to `.lore/memory.local.md`. |
| 258 | + |
| 259 | +**2. Heat Filter** |
| 260 | + |
| 261 | +Score each fact by recency and frequency. Present only facts above the heat threshold (default: score > 1.0) to the operator. Show key, content, hit count, and current score. |
| 262 | + |
| 263 | +**3. Present for Approval** |
| 264 | + |
| 265 | +Show the operator a numbered list of print-ready facts. For each: |
| 266 | +- **Key**: the hot memory identifier |
| 267 | +- **Score**: current heat score |
| 268 | +- **Content**: the fact or draft fieldnote body |
| 269 | +- **Proposed location**: where it would land in the KB |
| 270 | + |
| 271 | +The operator selects which facts to promote, skip, or discard. |
| 272 | + |
| 273 | +**4. Commit** |
| 274 | + |
| 275 | +For each approved fact: |
| 276 | +1. Read the source content from hot memory. |
| 277 | +2. Write to the appropriate KB location: |
| 278 | + - Draft fieldnotes (key starts with `fieldnote:`) → `~/.lore/knowledge-base/fieldnotes/{name}/FIELDNOTE.md` |
| 279 | + - Environment facts → `~/.lore/knowledge-base/environment/` |
| 280 | + - Operator preferences → `~/.lore/knowledge-base/operator-profile.md` |
| 281 | + - Procedural knowledge → `~/.lore/knowledge-base/runbooks/` |
| 282 | + - Project-specific → project `.lore/` directory |
| 283 | +3. Add frontmatter (`name`, `description`, `tags`) per KB structure rules. |
| 284 | +4. Verify the file was written and is valid markdown. |
| 285 | + |
| 286 | +**5. Cleanup** |
| 287 | + |
| 288 | +After successful promotion, the hot cache entry remains (it decays naturally). Do not delete hot cache entries — they continue to track access frequency. |
| 289 | + |
| 290 | +#### Routing Rules |
| 291 | + |
| 292 | +| Fact Type | Destination | |
| 293 | +|-----------|-------------| |
| 294 | +| Draft fieldnote (`fieldnote:*`) | `~/.lore/knowledge-base/fieldnotes/` | |
| 295 | +| Machine/infra detail | `~/.lore/knowledge-base/environment/` | |
| 296 | +| Operator preference | `~/.lore/knowledge-base/operator-profile.md` | |
| 297 | +| Recurring snag | `~/.lore/knowledge-base/fieldnotes/` via `/lore-create-fieldnote` | |
| 298 | +| Procedural knowledge | `~/.lore/knowledge-base/runbooks/` | |
| 299 | +| Project convention | `.lore/` in the project repo | |
| 300 | + |
| 301 | +### Defrag |
| 302 | + |
| 303 | +Knowledge defrag — restructure the global knowledge base by content rather than creation order. |
| 304 | + |
| 305 | +**Run after the environment is substantially documented — not before.** |
| 306 | + |
| 307 | +#### Process |
| 308 | + |
| 309 | +1. Check that semantic search is available (sidecar running). |
| 310 | +2. Scan `~/.lore/knowledge-base/` for structural issues: |
| 311 | + - Duplicate or overlapping fieldnotes |
| 312 | + - Environment docs that should be merged or split |
| 313 | + - Misrouted content (e.g., environment facts in fieldnotes) |
| 314 | +3. Present proposed changes to the operator for approval. |
| 315 | +4. Execute approved restructuring on a branch: |
| 316 | + ```bash |
| 317 | + cd ~/.lore && git checkout -b knowledge-defrag-$(date +%Y%m%d) |
| 318 | + ``` |
| 319 | +5. After operator review, merge the branch. |
| 320 | + |
| 321 | +See `~/.lore/knowledge-base/runbooks/system/knowledge-defrag.md` for the full procedure. |
0 commit comments