Ambient, hook-driven memory · Claude Code & Codex

Every codebase has lore.

The bug with the non-obvious cause. The convention no one wrote down. The footgun that cost an afternoon. Lore captures them — then your agent recalls the relevant one automatically on your next prompt, no slash command required, so the same lesson is never learned twice.

Open source · MIT · zero recurring cost · install once, works everywhere · no runtime dependencies

claude code — lore
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.

Ambient recall

A hook matches what you typed against your notes and injects the best matches every turn — locally, instantly, with no model call. Matching is word-boundary, not substring, with a score threshold that keeps weak overlaps out. It even fires when the agent is about to edit a file, so the gotcha surfaces exactly when you touch the code. You never have to remember to look.

Frictionless capture

At the end of a working turn, Claude is nudged to write down anything genuinely new and reusable — one fact per file, in plain Markdown that lives in your repo. The nudge is smart by default, skipping conversational turns, and an overlap check updates a related note instead of spawning a duplicate.

Stays fresh

A deterministic linter flags notes whose code was deleted or has drifted, and every recalled note carries a freshness flag — so a stale entry is never trusted blindly, and your knowledge base never rots into confident, wrong advice.

Ambient by design

Memory that doesn't wait to be asked

Most agent memory is manual — you have to remember to look, run a command, or paste context into a workflow. Lore is ambient: it lives in hooks, so the relevant learning is already in context before the agent answers, and the capture nudge fires on its own at the end of a working turn. No slash command in the loop, no model call, no recurring cost.

That makes it a light layer, not another framework to adopt. Install it once and it works in every project — on its own, or quietly alongside whatever heavier workflow suite you already run.

The loop

Each task leaves the next one easier

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.

  1. 1

    Recall

    You prompt. Relevant past learnings are pulled into context before Claude answers.

  2. 2

    Work

    Claude solves the task with that hindsight already in hand.

  3. 3

    Capture

    If the turn produced something non-obvious and reusable, it's written down — one note.

  4. 4

    Keep fresh

    As the code changes, drifted notes are flagged for a quick re-verify. Then repeat.

Install

Three lines, then it's working

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

/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.

Commands

Seven commands, mostly invisible

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 hook.

/lore:capture

Write a learning from the current work now — applies the gate, avoids duplicates, files it in the store.

/lore:search

Search the store by title and tags from the CLI — the same scorer the recall hook runs on every prompt.

/lore:lint

Check that every note's referenced files still exist. --report ranks drifted notes; --dupes finds near-duplicate pairs; --index rebuilds the index.

/lore:stats

Store-health snapshot: counts by status and category, the drift backlog, recall activity, near-duplicates, and dangling links.

/lore:sweep

Re-verify drifted notes against the current code and update, supersede, or refresh them.

/lore:scan

Scan the store for committed secrets — the same blocking check the pre-push hook runs, on demand.

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

How the trick works

Recall is a hook, not a model call

A UserPromptSubmit hook tokenizes your prompt and matches it against each note's title and tags — never the body. Matching is word-boundary (auth never hits author) with a score threshold that filters noise; the top few are injected as paths and titles, and 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. Every surfaced note is logged locally so /lore:stats can show what actually gets used.

# 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]

One fact per file, in your repo

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
---

Freshness is deterministic

The linter checks that referenced files still exist, and a --report mode uses a single streaming git log pass to rank notes whose code changed since you last verified them — a cheap, LLM-free worklist of what to re-check. A --dupes mode flags near-duplicate notes before they pile up, and 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

Shared by default, guarded at the push

The store is committed so a whole team benefits — which means a note is effectively published the moment it's written. A blocking pre-push secret scan reads the store and aborts the push if it finds a key, token, or credential. Recall itself only ever emits paths and titles — never the body — so a shared store has a small injection surface. Run the scan any time with /lore:scan.

$ git push

# pre-push hook runs scan_secrets.py
lore: secret scan — 14 learnings
 aws-keys.md:7  AWS access key id
push aborted — remove the secret or allowlist it

FAQ

Questions

Does it send my code or notes anywhere?

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. The only thing that ever leaves your machine is what you push — which is exactly what the secret scan guards.

Does it cost anything per prompt?

No. Recall is a deterministic text match run in a hook — no model call, no tokens, no API spend on each turn. You install it once and it runs for free in every project, however many prompts you send.

Does it work on Windows?

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.

Are my learnings private or shared?

Committed by default, so a whole team benefits from the same knowledge base. Want them personal instead? Add the learnings/ folder to .gitignore. Because a shared store is effectively published, a blocking pre-push secret scan aborts the push if a note ever contains a key, token, or credential.

How is it different from other agent-memory tools?

Most are manual — you invoke recall inside a workflow or run a command to look things up. Lore is ambient: recall and capture live in hooks, so they happen on their own, with no command in the loop and no per-prompt cost. It's a light, standalone layer rather than a framework — install it once and it works in every project, on its own or alongside whatever heavier workflow suite you already use.

Which agents does it work with?

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.

Where does the name come from?

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.

Your codebase, with a memory.

Install it once, and every task starts teaching the next.