Ambient recall
A prompt hook matches what you typed against your notes and injects the best matches every turn — locally, instantly, with no model call. You never have to remember to look.
Claude Code & Codex plugin
The bug with the non-obvious cause. The convention no one wrote down. The footgun that cost an afternoon. Lore captures them — then quietly hands the relevant one back on your next prompt, so the same lesson is never learned twice.
you ▸ add a retry to the image upload job
↳ lore recalled 1 learning into context:
• learnings/jobs/upload-retry-idempotency.md
“Uploads aren't idempotent — retries duplicate rows.”
claude ▸ Good catch — I'll key it on a dedupe token so re-runs don't double-upload.No command to run. The relevant note just shows up.
A prompt hook matches what you typed against your notes and injects the best matches every turn — locally, instantly, with no model call. You never have to remember to look.
At the end of a turn, Claude is nudged to write down anything genuinely new and reusable — one fact per file, in plain Markdown that lives in your repo.
A deterministic linter flags notes whose code was deleted or has drifted, so your knowledge base never quietly rots into confident, wrong advice.
The loop
Most work accrues debt — every change makes the next one a little harder. Lore inverts that: the knowledge you generate is captured and fed forward.
You prompt. Relevant past learnings are pulled into context before Claude answers.
Claude solves the task with that hindsight already in hand.
If the turn produced something non-obvious and reusable, it's written down — one note.
As the code changes, drifted notes are flagged for a quick re-verify. Then repeat.
Install
Requires Claude Code or OpenAI Codex, plus Python 3 (already on macOS & Linux; on Windows, Claude Code's bundled Git Bash runs it).
# add the marketplace and install the plugin
/plugin marketplace add aoc81/lore
/plugin install lore@lore
# then, once per project you want it in:
/lore:init
# install once per machine, then trust the hooks in Codex
python3 codex/install.py
# open Codex → /hooks → trust the two hooks
# per project (optional): scaffold ./learnings
python3 codex/install.py --store
/lore:init creates a learnings/ folder (committed by default, so your
team shares it) and offers to wire an optional pre-push freshness check. Nothing is sent anywhere —
recall is a local text match.
The installer registers the recall + capture hooks under ~/.codex — trust them once
in /hooks. The same core scripts and learnings/ store are reused
unchanged. Nothing is sent anywhere — recall is a local text match.
Commands
Recall and the capture nudge run on their own. These are for when you want to drive it directly.
/lore:init
Scaffold the learnings/ store in a project and (optionally) install the pre-push freshness hook.
/lore:capture
Write a learning from the current work now — applies the gate, avoids duplicates, files it in the store.
/lore:lint
Check that every note's referenced files still exist. --report ranks drifted notes; --index rebuilds the index.
/lore:sweep
Re-verify drifted notes against the current code and update, supersede, or refresh them.
These are Claude Code slash commands. On Codex the same steps are
plain scripts: init is python3 codex/install.py, capture is the
lore skill plus the Stop hook, and lint is python3 ~/.codex/lore/verify_refs.py.
Under the hood
A UserPromptSubmit hook tokenizes your prompt and matches it against each note's
title and tags — never the body. The top few are injected as paths and titles; Claude opens a
file only if it's actually relevant. Notes marked superseded are down-ranked and flagged,
so they're never read as current truth.
# injected before Claude sees your prompt
Possibly-relevant prior learnings:
- learnings/api/pagination-cursor.md — Cursor,
not offset, above 10k rows
- learnings/ci/cache-key-lockfile.md — Cache key
must hash the lockfile [SUPERSEDED]
Each learning is a Markdown file with light frontmatter. Plain text, version-controlled,
greppable, and readable without the plugin. Tags are how recall finds it; files:
is how the linter knows what the note depends on.
---
title: Cursor pagination above 10k rows
track: knowledge
tags: [api, pagination, cursor, scale]
files: [src/api/list.ts]
status: current
verified: 2026-01-12
---
The linter checks that referenced files still exist, and a --report mode uses
git log to rank notes whose code changed since you last verified them — a cheap,
LLM-free worklist of what to re-check. An optional pre-push hook runs the existence check before
every push.
$ /lore:lint --report
Drift triage (biggest gap first):
34d learnings/api/pagination-cursor.md
verified 2026-01-12, code changed 2026-02-15
FAQ
No. Recall is a local text match over files in your repo — no network calls, no external service. Capture and the linter run locally too.
Yes — macOS, Linux, and Windows. The hooks are stdlib Python invoked through a small shell wrapper
that resolves python3/python/py. On Windows, Claude Code's
bundled Git Bash runs it. No build step, no dependencies.
Committed by default, so a whole team benefits from the same knowledge base. Want them personal
instead? Add the learnings/ folder to .gitignore.
Both Claude Code and OpenAI Codex. They share the same
UserPromptSubmit / Stop hook contract, so recall and capture work natively
on each from the same scripts and store. The notes themselves are just Markdown, useful even without
either plugin.
Every codebase has lore — the hard-won, half-remembered knowledge that lives in people's heads and chat threads. Lore writes it down where the work happens, and hands it back exactly when it's needed.
Install it once, and every task starts teaching the next.