ASK KNOX
beta
LESSON 666

Installing a Memory Brain

A skill without memory starts from zero every run — give it a store it reads at the start and writes to at the end, and it stops repeating its own mistakes across sessions.

9 min read·Skill Engineering Mastery

Why Skills Forget

By default, every skill run is an amnesiac. It starts with an empty slate, does its work, and when the session ends, everything it learned evaporates with the context window. The next run repeats the same investigation, rediscovers the same gotcha, makes the same mistake. The compound-learning loop — the thing that makes a human operator better at a task the tenth time than the first — never closes.

Installing a memory brain fixes this. The pattern is two-sided and simple to state: the skill reads a memory store at the start and writes back to it at the end. Read, so the run begins informed by everything past runs discovered. Write, so this run's hard-won lessons survive for the next one. Miss either half and the loop stays open — a write-only skill accumulates lessons it never reads; a read-only skill reads a store nothing ever fills.

The Memory Brain: Three Tiers

Not everything wants the same store. The mastery skill is choosing the right tier per fact, because using a heavyweight semantic store for a counter is as wrong as trying to do semantic recall against a flat file.

  • Ephemeral (the context window). The current conversation, this run's tool outputs, scratch reasoning. It dies at session end. This is working memory — never a place to persist anything you need next time.
  • File-based memory. A JSON file the skill owns, e.g. ~/.claude/skills/<name>/memory.json. Fast, transparent, git-diffable, retrieved by key. This is the right default for small structured state: counters, the last run's decisions, a short list of known-bad inputs. When in doubt, start here.
  • Semantic memory layer. A vector-backed store behind the memory_remember / memory_recall interface. You write a note with tags; you recall by meaning, not by key — "what went wrong the last time we deployed?" returns the relevant incident even if it was filed under different words. This is where cross-session lessons, past incidents, and searchable knowledge belong. It scales to thousands of notes where a flat file would not.

The dividing question is the access pattern. Retrieved by key, small, structured? File. Retrieved by meaning, accumulates over time, searched fuzzily? Semantic layer. Needed only this run? Leave it ephemeral.

What to Persist — and What Not To

The fastest way to ruin a memory store is to write too much. A store full of transcripts and "started run" markers makes recall return noise, which trains everyone to ignore it. Persist the durable signal, drop the rest.

Persist: the lesson from a failure (what broke, why, the rule to prevent it), a decision and its rationale, a stable fact discovered at cost (an API's real rate limit, a config that only works one way), a counter or piece of state the next run needs.

Do not persist: the raw conversation, tool outputs verbatim, anything trivially re-derivable, secrets or credentials of any kind, and — critically — anything from a run that didn't finish. A half-completed run's "lessons" are usually wrong.

The Write Lifecycle

Reading is cheap, so you do it unconditionally at the start. Writing is consequential, so you gate it on success at the end. That asymmetry is the whole discipline.

In practice, the skill's body looks like this. Recall first, do the work, then write only if the run verifiably succeeded:

# START — pull what past runs learned about this task
hits = memory_recall(query="deploy backend to production", limit=5)
# inject `hits` into the working context so the run starts informed

# ACT — do the real work. Hold candidate lessons, but DO NOT write yet.
result = run_deploy_steps()

# GATE + END — only a verified success earns a durable write
if result.verified:
    memory_remember(
        text=(
            "Deploy gate: a 'built' container is not a 'running' one. "
            "Always confirm the service is actually serving the new "
            "response shape before declaring the deploy done."
        ),
        tags=["deploy", "production", "verification", "lesson"],
    )

Two details carry the weight. The tags are the recall handle — the next run's memory_recall finds this note by searching on the same topic, so tag for how it will be looked up, not how it was produced. And the write sits behind the success gate: a failed or abandoned run writes nothing, because the lessons of a broken run are usually the wrong lessons.

This is the same loop a good operator runs by hand. After a correction, you write down what went wrong, why, and the rule to prevent it — so the next session reads it and doesn't repeat the mistake. A memory-equipped skill automates exactly that, and the discipline compounds: after enough runs, the store is the skill's accumulated expertise.

Build It

Wire memory into a skill. At the start, call memory_recall with the task context and use the hits. Do the work. At the end, gate the write on success and call memory_remember with a durable, well-tagged lesson — never on a half-finished run, never with a transcript. Choose the right tier for each thing you store.

What's Next

You can now gate before an action, verify after it, and give a skill memory that survives the session. That trio — deterministic enforcement plus persistent recall — is what separates a clever one-shot script from a skill that genuinely gets better at its job every time it runs. Take it into your own skills and watch the compound-learning loop finally close.