# lore
lore (noun) — a body of traditions and knowledge on a subject, passed from person to person. — Oxford English Dictionary
简体中文 · English (this page)
> Framework-agnostic project memory for AI coding agents.
A long-term knowledge base for software projects, maintained by AI agents. Captures the kind of context that normally lives only in the original developer's head — architecture, decisions, conventions — and persists it as plain Markdown files that any agent can consume.
> **lore is a SKILL, not a CLI tool.** It is a Markdown spec ([`SKILL.md`](SKILL.md)) that AI coding agents — Claude Code, Cursor, OpenCode, Cline, Aider, GitHub Copilot — read to gain long-term project memory. You do not `npm install` or `pip install` lore; you give your agent the URL and ask it to install the skill. From then on, phrases like `lore init` and `lore sync` are commands you say to your agent, **not** commands you type in a terminal. There is no `lore` binary on your `PATH`.
## Installation
```bash
git clone https://github.com/TheaDust/lore.git
```
Or, simpler — tell your agent:
> Install https://github.com/TheaDust/lore as a skill.
Each agent host loads skills from its own directory (`~/.claude/skills/` for Claude Code, `/.claude/skills/` for project-scoped, etc.). Your agent knows its own skills directory and can clone the repo into the right place.
> Looking for a specific doc? Jump to: [Quick start](#quick-start) · [What it looks like](#what-this-looks-like) · [What lives in `.lore/`](#what-lives-in-lore) · [Seven workflows](#seven-workflows) · [Platform mirrors](#platform-mirrors) · [Configuration](#configuration) · [Upgrading](#upgrading) · [FAQ](#faq). Full reference docs live in [`references/`](references/). **Want plain-language "when to use each workflow"?** See [`WORKFLOWS.md`](WORKFLOWS.md) (also in [中文](WORKFLOWS.zh-CN.md)).
## What it solves
When you work on a project across multiple AI tools (Claude Code, Cursor, Cline, GitHub Copilot, Aider, LangGraph agents, DeepAgents) and across many sessions, context gets lost:
- **Every new session re-explains the project.** "We're using Next.js App Router, not Pages. Use Zustand, not Redux. Don't commit secrets."
- **Decisions are forgotten.** "Why did we pick X over Y?" → "I don't remember, let me ask the team."
- **Agents disagree with each other.** Cursor follows `.cursorrules`, Claude Code follows `CLAUDE.md`, but the two files drift apart.
- **Onboarding takes weeks.** New members / new agents need to learn the conventions from scratch.
lore maintains a single source of truth (`.lore/`) and projects it into whatever config files your agents already read. It tracks *why* decisions were made, not just *what* the code does, and keeps that history across sessions and tools.
## Quick start
The commands below are **phrases you say to your agent** — there is no `lore` binary. With this skill loaded, your agent runs each phrase through the workflow defined in [`SKILL.md`](SKILL.md). Anything you'd normally type into a terminal goes to the agent instead.
```bash
# 1. Initialize (run once per project)
lore init
# Walks the project, drafts entries, asks for confirmation, creates .lore/
# 2. After a non-trivial change
lore sync
# Detects code diffs, proposes [NEW]/[STALE]/[REFINED] entries, waits for your call
# 3. After many changes, refresh the agent-facing summary
lore compress
# Regenerates SUMMARY.md and updates CLAUDE.md / .cursorrules / etc.
# 4. Force a mirror refresh (e.g. after hand-editing .lore/)
lore mirror
# Rewrites CLAUDE.md and other platform files from current state
```
Three read-only commands round out the toolkit:
```bash
lore query # Answer a question from memory, cite entry IDs
lore audit # Check memory vs. reality, write report to .lore/audit/
lore history DEC-2026-02-03-7c19 # Show git commits that touched an entry's code
lore history frontend/src/store.ts # ...or a file
lore history --scope=frontend # ...or every lore file in a scope
lore history --json # machine-readable
```
## What this looks like
### Querying memory
> You: "How does this project authenticate API requests?"
> Agent (uses `lore query auth`):
```
Found 6 entries matching 'auth':
[_global/DECISIONS.md#DEC-2026-07-10-6d9c]
Opaque base64 tokens over JWT; reason: simpler revocation, no library dep.
[scopes/backend/ARCHITECTURE.md#ARCH-2026-07-10-59ac]
Auth helpers in backend/app/auth.py:
hash_password, issue_token, login_required decorator.
[scopes/backend/CONVENTIONS.md#CONV-2026-07-10-84e3]
Missing/invalid token returns 401; resource not found returns 404.
[scopes/frontend/ARCHITECTURE.md#ARCH-2026-07-10-6de2]
Auth token stored in localStorage under todo.auth.token key.
[scopes/frontend/DECISIONS.md#DEC-2026-07-10-c1ea]
Axios over raw fetch; reason: interceptors for auth header injection.
```
Every answer cites the exact `[file#ID]` so you can `cat` the entry or run `lore history ` to see why the decision exists.
### What `CLAUDE.md` looks like
`lore` keeps per-session cost flat by emitting a small index, not the full memory:
```markdown
## Lore (auto-managed)
Project memory. Read deeper on demand.
**Structure**:
- Digest: `.lore/SUMMARY.md` (top-level overview)
- Global: `.lore/_global/` (architecture, decisions, conventions)
- Scopes: `.lore/scopes/`
- `.lore/scopes/backend/` (Flask 3 + SQLAlchemy 2 + pytest; Python 3.11+)
- `.lore/scopes/frontend/` (React 18 + TypeScript + Vite + Zustand + Axios)
- `.lore/scopes/shared/` (TypeScript types mirrored as Python dataclasses)
**Query**: `lore query ` or `lore query :`
**Update**: see the `lore` skill (init / sync / query / audit / compress / mirror)
---
## My notes (free edit)
- Anything you write here is preserved verbatim across every sync.
```
### Git traceability with `lore history`
> `lore history DEC-2026-07-10-e45d` (asking "why did we choose bcrypt?")
```
# history: [DEC-2026-07-10-e45d]
> Entry: scopes\backend\DECISIONS.md
> Since: 2026-07-10 (entry #added date)
> File: backend
> Commits: 2 (showing all)
## 9f264f4 (2026-07-10, Lore Tester)
feat(backend): add alembic migrations and switch password hashing to bcrypt
## ed2b288 (2026-07-10, Lore Tester)
feat(backend): password hashing and JWT-style auth tokens
## Suggested next step
Run `lore sync` to check whether any of these commits
introduce a [REFINED] candidate for this entry.
```
The agent reads the commit messages and tells you *why* — without you having to manually dig through `git log`.
## What lives in `.lore/`
```
.lore/
├── SUMMARY.md # Top-level digest; new agents read this first
├── _global/ # Cross-scope facts
│ ├── ARCHITECTURE.md
│ ├── DECISIONS.md
│ └── CONVENTIONS.md
├── scopes/ # Per-scope facts (frontend / backend / shared)
│ └── /
│ ├── ARCHITECTURE.md
│ ├── DECISIONS.md
│ └── CONVENTIONS.md
├── draft/ # Used by `init` for proposals pending confirmation
├── audit/ # Used by `audit` for reports
└── archive/ # Old/superseded entries
```
Each entry is a single Markdown bullet (≤ 2 lines) with a deterministic ID and inline status tags:
```markdown
- [ARCH-2026-07-09-a3f2] Use Next.js App Router; reason: streaming + RSC. #added:2026-07-09
- [DEC-2026-02-03-7c19] Chose Zustand over Redux; reason: 60% less boilerplate. #added:2026-02-03 #verified:2026-06-15
- [CONV-2026-01-20-b1e8] Never commit secrets; use `dotenv` + `.env.local` (gitignored). #added:2026-01-20
```
For the full format spec (ID generation, tags, splitting rules), see [`references/entry-format.md`](references/entry-format.md).
## Seven workflows
| Command | What it does | Writes | Reference |
|---|---|---|---|
| `init` | First-time project scan; drafts entries; user confirms | `.lore/*` + platform mirrors | [SKILL.md](SKILL.md#init--initialize-the-memory-bank) |
| `sync` | Detects code changes; proposes updates; user approves | `.lore/*` only (not mirrors) | [SKILL.md](SKILL.md#sync--update-after-a-change) |
| `query` | Read-only; answers from memory with entry IDs | nothing | [SKILL.md](SKILL.md#query--answer-from-memory) |
| `audit` | Read-only; checks memory vs. current code; writes report | `.lore/audit/*` only | [`references/audit-template.md`](references/audit-template.md) |
| `compress` | Generates `SUMMARY.md` from current entries | `SUMMARY.md` + platform mirrors | [`references/summary-template.md`](references/summary-template.md) |
| `mirror` | Force-regenerate platform mirrors (with content dedup) | `CLAUDE.md`, `.cursorrules`, etc. | [`references/platform-mirrors.md`](references/platform-mirrors.md) |
| `history` | Read-only; lists git commits related to an entry / file / scope | nothing | [`references/history-command.md`](references/history-command.md) |
For a plain-language explanation of each workflow (when you'd actually use each one, with real scenarios), see [`WORKFLOWS.md`](WORKFLOWS.md) (中文版: [`WORKFLOWS.zh-CN.md`](WORKFLOWS.zh-CN.md)).
`sync` deliberately does **not** update platform mirrors. Mirror files are agent-facing entry points, not per-change logs. Regenerating them on every `sync` would clutter `git log` and dilute the "human-merged" signal they're supposed to provide. Run `lore mirror` (or `compress`) when you want the agent-facing view to catch up.
To restore old behavior (mirror updates on every `sync`), set `"sync_updates_mirror": true` in `.lore/.config.json`.
## Sync trust levels
`sync` can auto-apply or require confirmation depending on the change type and the configured trust level:
| Change type | `high` | `medium` (default) | `low` |
|---|---|---|---|
| De-duplicate hit | auto | auto | confirm |
| Equivalent REFINED | auto | auto | confirm |
| `NEW` entry | auto | confirm | confirm |
| `STALE` mark | auto | confirm | confirm |
| `ALERT` | confirm | confirm | confirm |
The default `medium` is a balance: low-risk changes apply silently, real additions or contradictions still get your sign-off. Switch to `high` for high-confidence projects (you trust the agent fully) or `low` if you want to review every change.
## Platform mirrors
lore's canonical store is `.lore/*`, but it projects into the config files agents already read. Targets are resolved by scanning the repo root for existing platform files (auto-detect). When none are present, `lore init` asks via multi-select which agents to write for. Setting `mirror_targets` in `.lore/.config.json` overrides this with an explicit list (Replace semantics).
| Platform | File | Auto-detected? |
|---|---|---|
| Claude Code | `CLAUDE.md` | ✅ |
| Cursor | `.cursorrules` (or `.cursor/rules/*.mdc`) | ✅ |
| Cline | `.clinerules` | ✅ |
| Aider / Codex / OpenCode | `AGENTS.md` (or `CONVENTIONS.md`) | ✅ |
| Windsurf | `.windsurfrules` | ✅ |
| GitHub Copilot | `.github/copilot-instructions.md` | ✅ |
| Continue.dev | `.continue/rules/lore.md` | ✅ |
| LangGraph / DeepAgents | (no file — read `.lore/*.md` directly) | n/a |
Each mirror file is split into two sections by a `---` separator:
```markdown
## Lore (auto-managed)
... Skill-managed content from .lore/ ...
---
## My notes (free edit)
... your hand-written notes, preserved verbatim across syncs ...
```
The Skill only writes inside the `## Lore` section. Everything under `## My notes` is yours to edit freely. The Skill preserves it verbatim across every `sync` and `compress`.
## Token cost
lore's token model has five components. Only the mirror file is per-session; everything else is on-demand or per-invocation.
| Component | Loaded when | Typical size | Per-session? |
|---|---|---|---|
| **Mirror file** (CLAUDE.md, AGENTS.md, etc.) | Every session start | ~500 bytes (index mode) | yes |
| **SKILL.md** (the lore spec itself) | Every `lore ` invocation | ~10 KB | no, per-invocation |
| **`.lore/SUMMARY.md`** | Agent reads on demand as the table of contents | 1–30 KB | no, on demand |
| **`scopes//{ARCH,DEC,CON}.md`** | Agent reads only the relevant scope | 1–5 KB each | no, on demand |
| **`lore query `** result | Agent runs a query | bounded by matches | no, per query |
### The mirror is constant-cost
`CLAUDE.md` and equivalent platform files are loaded by your agent on **every session**. lore keeps this cost flat by emitting an index (~500 bytes) rather than the project digest content. This is the only line item that scales with session count.
| Project size | Mirror size | Per-session context cost |
|---|---|---|
| Empty / new | ~200 bytes | negligible |
| Small (~30 entries) | ~500 bytes | negligible |
| Medium (~120 entries) | ~500 bytes | negligible |
| Large (~250 entries) | ~500 bytes | negligible |
### Memory is on-demand
`.lore/*.md` files are **not** pre-loaded. The agent reads `SUMMARY.md` as a table of contents, then drills into the specific scope or entry it needs (`cat [file#ID]`). A 250-entry project costs the agent ~500 bytes at session start, plus only the entries it actively reads.
### SKILL.md is per-invocation
Every time you say `lore sync` or `lore query`, the agent loads `SKILL.md` (~10 KB) to follow the workflow. Outside of lore invocations, no lore content sits in the agent's context.
### Queries are bounded
`lore query ` returns matched entries with stable IDs and one-line summaries, not the full text of `.lore/`. A single query is bounded by the number of matches regardless of total project size.
### Ambient vs on-demand knowledge
**Ambient** knowledge is already in the agent's context at session start — no fetch needed. **On-demand** knowledge is read only when the agent asks (`cat [file#ID]`, `lore query `).
lore's mirror file (`CLAUDE.md`, `AGENTS.md`, etc.) is ambient — the agent sees it every session. Everything under `.lore/` is on-demand: `SUMMARY.md` is the table of contents, and entries are fetched when the agent actually needs them.
Default is on-demand. If you'd rather dump the full `SUMMARY.md` into `CLAUDE.md` every session (true ambient), that works but isn't recommended — it trades session-start cost for zero fetch. See [`references/platform-mirrors.md`](references/platform-mirrors.md) for the index template.
## Scripts
Helper scripts in `scripts/` reduce repetitive mechanical work:
```bash
python scripts/id_hash.py "Use Next.js App Router" # → a3f2 (4-char ID hash)
python scripts/list_entries.py # List all entries (text)
python scripts/list_entries.py --scope=frontend --json # Filtered JSON
python scripts/find_duplicates.py # Find potential duplicates
python scripts/find_stale.py --days=90 # Find stale entries
python scripts/history.py DEC-2026-02-03-7c19 # Show git history for an entry
```
All scripts are cross-platform Python 3.6+ with no third-party dependencies. See [`scripts/README.md`](scripts/README.md) (English) or [`scripts/README.zh-CN.md`](scripts/README.zh-CN.md) (Chinese) for details.
## Configuration
`.lore/.config.json` is optional. The defaults work for most projects.
```json
{
"schema_version": 1,
"auto_mirror": false,
"sync_updates_mirror": false,
"sync_trust": "medium",
"mirror_targets": ["CLAUDE.md"], // optional — auto-detected if absent
"mirror_mode": "index",
"compress_thresholds": { "max_entries": 500, "max_days_since_compress": 30 },
"sync_thresholds": { "min_lines_changed": 50, "min_directories_changed": 2 }
}
```
Field semantics: see [`references/config.md`](references/config.md). New configs include `schema_version: 1`; old configs without it still work but trigger a warning. See [`references/compatibility.md`](references/compatibility.md) for the compatibility policy.
## Upgrading
`git pull` (or re-clone) is the normal upgrade path; your `.lore/` is preserved verbatim across upgrades. If a future release ships a breaking config change, that release will include `scripts/migrate.py`; run it once after pulling. The current schema is `schema_version: 1`; no migration has shipped yet, so you don't need to run anything today. See [`references/compatibility.md`](references/compatibility.md) for the versioning policy and deprecation workflow.
## When NOT to use lore
lore is built for long-term projects. It's overkill for:
- **Short-lived scripts / one-off demos.** The maintenance overhead exceeds the value.
- **Rapid prototyping** where decisions change weekly. The decision-tracking machinery gets in the way.
- **Tiny single-file projects.** Just use a `README.md`.
- **Projects where you never want AI to make decisions.** If you want a pure read-only agent, lore adds no value.
- **Massive monorepos with 50+ packages.** The scope tree becomes unwieldy; consider splitting per-package or using a sub-skill per cluster.
## FAQ
**Q: Does lore work without git?**
A: Partially. Most of lore is **agent workflow** described in `SKILL.md` — the agent reads your files, drafts entries, edits `.lore/*.md`, and (when asked) regenerates mirrors. Without git, the agent can still do `init` / `query` / `audit` / `compress` / `mirror` by reading files directly. What you lose: `sync` uses `git diff` to detect changes (no diff → the agent asks you what changed), and `lore history` requires a git repo (it runs `git log`). The helper scripts (`list_entries.py`, `find_stale.py`, etc.) work either way.
**Q: Can I hand-edit `.lore/*.md` directly?**
A: Yes. The files are plain Markdown. Use `id_hash.py` if you're adding new entries (to keep IDs deterministic). After hand-editing, run `lore mirror` to update agent-facing files.
**Q: What if I don't want a mirror file at all (just `.lore/`)?**
A: Set `mirror_targets: []` in `.config.json`. The `compress` and `mirror` commands will be no-ops on the file system; only `SUMMARY.md` and the entry files matter.
**Q: How is this different from Cursor's `.cursorrules` or Aider's `AGENTS.md`?**
A: Those are flat lists of rules. lore is structured (architecture / decisions / conventions), atomic (one fact per entry), and historical (every entry has `#added` and `#verified` tags). It also produces those files for you.
**Q: Does lore talk to the agent's API?**
A: No. lore is pure file I/O. The agent invoking lore does the semantic work (scanning code, deciding what to extract, classifying changes); lore provides the file layout, the ID scheme, the markers, and the verification scripts.
**Q: What about the agent's native `/init` or `/compact` commands?**
A: They serve different purposes. `/init` is a one-shot project scan → `CLAUDE.md`. `/compact` compresses conversation context. lore `init` and `compress` manage long-term project knowledge, not session context. If you run `lore init` on a project that already has a non-lore `CLAUDE.md`, the takeover check (init step 0) handles integration.
**Q: What's the difference between `sync` and `mirror`?**
A: `sync` updates `.lore/` from code changes (run after a feature or refactor). `mirror` updates agent-facing files (`CLAUDE.md`, `.cursorrules`, etc.) from current `.lore/`. `sync` deliberately does **not** update mirrors — mirror files should be human-merged, not regenerated on every commit, so `git log` stays readable. Run `mirror` (or `compress`) explicitly when you want agent-facing files to catch up.
**Q: How is lore different from ADRs (Architecture Decision Records)?**
A: ADRs are documents — one markdown file per decision. lore is structured project memory: one fact per entry, with a stable ID and `#added` / `#verified` / `#stale` markers. The `DEC` layer can replace `docs/adr/` (one DEC entry per decision), but lore also covers `ARCH` (architecture) and `CON` (conventions) in the same store, plus generates agent-facing summaries via `compress` / `mirror`. Use lore **instead of** ADRs, or **alongside** them (one DEC entry pointing to the existing ADR document).
**Q: What if I disagree with an entry the agent wrote?**
A: Edit `.lore/*.md` directly — it's plain Markdown. The next `mirror` / `compress` will reflect your edit, and the helper scripts keep the ID stable as long as the entry text is unchanged. To revert to pre-AI state, `git checkout .lore/` like any tracked file.
**Q: Can I sync `.lore/` across multiple machines without git?**
A: Git is the recommended transport (`.lore/` is plain text in your repo; `git push` / `git pull` carry it). Other transports (Dropbox, OneDrive, Syncthing) work as long as you trust their text-file conflict resolution — they won't understand lore's ID scheme or `#added` markers. **Don't run two agents on the same `.lore/` simultaneously**; last-writer-wins, and IDs aren't protected by a remote lock.
## License
[MIT](./LICENSE) — use, modify, redistribute, sublicense, and sell, including commercially. No warranty.
---
SKILL.md ·
entry-format ·
summary-template ·
audit-template ·
monorepo-detection ·
stale-new-markers ·
platform-mirrors ·
config ·
history-command ·
compatibility ·
scripts