Stop Starting From Zero: Build an AI Context Knowledge Base
Every AI session starts blind. Here's how to build a structured markdown knowledge base that gives your AI coding assistant persistent context — and starter templates to get you going in minutes.
Every new AI session starts blind.
Your assistant doesn't know your stack. It doesn't know your team's conventions. It doesn't know why you picked Supabase over Firebase, why you're avoiding Redux, or why the payments service has that weird retry loop. None of that is hard to look up — it's all sitting in your codebase, your docs, your head — but the AI has to be told fresh, every single time.
So you repeat yourself. Constantly.
Every prompt starts with some version of "we use Next.js with TypeScript and Tailwind, and in this project we..." You paste screenshots of the same files. You re-explain the same decisions. Half your context window gets eaten by re-orienting the AI before the real work can even start.
There's a better way, and it doesn't require a RAG system, a vector database, or an expensive product. Just markdown files and a convention.
I call it an AI Context Knowledge Base, and after building one for my own work, I won't go back. Here's what it is, why it matters, how to build one, and how to get started fast.
The Problem Nobody Talks About
Let's be honest about what's actually happening when you use AI coding assistants.
You open Claude Code in your project. You ask it to add a feature. It writes code that doesn't match your conventions. You correct it. It fixes that, but picks the wrong library. You correct it again. It gets there eventually, but only after you've essentially dictated your entire project context through corrections.
The next day, you open a new session. Same project. You ask for a related change.
It has no idea what your project even is. Not because it's stupid, but because that's how AI sessions work — each one is stateless, starting from whatever you put in front of it.
You're not crazy for being frustrated by this. You're watching the AI waste context on things you've explained a hundred times. Every session is Groundhog Day — same questions, same explanations, same corrections.
The core problem: AI sessions have no persistent context. Your stack, your conventions, your past decisions — these are stable facts that don't change between sessions, yet you have to re-supply them every time.
The usual workarounds all fail at scale:
- Pasting context into every prompt is tedious, error-prone, and fills your limited context window with noise
- One massive instructions file drowns the AI in irrelevant context and degrades output quality
- Hoping the AI figures it out — it won't, because it can't read your mind or your history
What you actually need is persistent, structured context that gets loaded on demand. Not everything at once. Just the right files for the current task.
What This Post Covers
This guide has two parts:
Part 1: The Context System — How to build a knowledge base that gives your AI persistent context. The architecture, the patterns, practical examples, and starter templates you can fork right now. If you just want to eliminate the blank-slate problem as fast as possible, Part 1 gets you there.
Part 2: Adding Memory — How to layer episodic memory on top of the context system. Because persistent context tells the AI what your project is, but it doesn't tell the AI what happened yesterday. Part 2 covers changelogs, decisions logs, and a pattern called prompt-as-policy that makes the AI maintain these artifacts for you. The starter templates ship with the infrastructure for this, but memory requires intentional maintenance — Part 2 explains what's included and what's left for you.
Part 1: The Context System
Build a knowledge base that eliminates the blank-slate problem.
What an AI Context Knowledge Base Is
An AI Context Knowledge Base is a folder of markdown files organized with navigation conventions that AI can follow. One line in your project tells the AI where to look. From there, it loads only what the task requires.
It is:
- Just markdown files — no runtime, no build step, no dependencies
- Version controlled — lives in git like any other code artifact
- Dynamically loaded — the AI navigates to specific files based on the task
- Portable across projects — one knowledge base can serve many repos
It is not:
- Not a RAG system or vector database
- Not an application — no install, no service to run
- Not a prompt library — it's structured context, not prompts
- Not "a giant CLAUDE.md file" — the whole point is that it isn't
The key insight is that your AI assistant is already great at following instructions and reading files. It doesn't need a fancy retrieval system. It needs a map — something that tells it where your context lives and which files to load for a given task.
The Architecture: A Router and Recursive Indexes
The whole system is just two kinds of files:
- A single router —
CONTEXT.mdat the root, the file that gets imported into every project - Index files —
_index.mdfiles that list what's in their directory and route the AI deeper
Index files can point to content files (the actual knowledge) or to more index files (navigating deeper into a sub-area). That recursion is the whole trick. The structure isn't a fixed N-layer hierarchy — it's a tree that goes as deep as you need it to and no deeper.
A solo developer with two side projects might only have two layers:
CONTEXT.md ← router
↓
projects/_index.md ← lists the projects
↓
projects/blog.md ← single content file per project
projects/portfolio.md
That's it. Two hops from the router to the actual content. Adding entity directories would be over-engineering for a setup this small.
A small business owner with a single brand has slightly more depth:
CONTEXT.md ← router
↓
brand/_index.md ← lists the brand's files
↓
brand/voice.md ← actual content
brand/audience.md
brand/visual_identity.md
Still only two hops, because there's only one entity. The brand IS the entity, so its files live directly under the domain.
A microservices engineer at a company might go four or five layers deep when they need to:
CONTEXT.md ← router
↓
services/_index.md ← lists services
↓
services/payments/_index.md ← one service entity
↓
services/payments/architecture/_index.md ← splits architecture into sub-files
↓
services/payments/architecture/api.md ← actual content
services/payments/architecture/database.md
services/payments/architecture/queues.md
Same pattern, more nesting. The router points to a domain, the domain points to an entity, the entity points to a sub-area, the sub-area points to content. Four hops, but at each step the AI is loading exactly one small file to figure out where to go next.
The depth follows the complexity, not the other way around. You don't decide upfront "I'm going to use four layers." You start flat and split a file into a directory the moment that file gets too big or starts mixing too many concerns. Each split adds one layer to that branch of the tree, but only that branch — the rest of the KB stays as shallow as it needs to be.
Why this structure works
Three things matter at every layer:
Each _index.md is a navigation aid, not content. Its job is to tell the AI "here's what's in this directory and when to load each file." It should be short — 40-80 lines, mostly tables — and contain almost no actual knowledge. If your _index.md files are getting long, you're putting content in the wrong place.
Each level halves the search space. When the AI is looking for something, it reads the router, picks a domain, reads the domain index, picks an entity (or sub-area), reads that index, and so on. Every hop eliminates everything not in that branch. By the time it reaches actual content, it's only looking at the 2-4 files that matter for the current task — never the whole knowledge base.
The router is the only file projects ever import. No matter how deep your tree gets, @import CONTEXT.md is the only line in your project's CLAUDE.md. The router contains tables and triggers that point into the tree. Everything below that is discovered dynamically by the AI as it navigates.
What lives in each kind of file
The router (CONTEXT.md) is the reception desk. It has:
- A domain router — a table mapping broad categories to their indexes
- Context triggers — keywords that tell the AI which specific files to load ("when the user mentions 'deploy,' load the runbook")
- Task recipes — multi-file loading sequences for common workflows ("to debug a service issue, load these three files in order")
- Project detection — directory-name to entity mappings so the AI knows which context applies to the current project
An _index.md file is a directory's table of contents. The pattern is consistent at every depth:
| File | Covers | Load When |
|---|---|---|
payments_api/_index.md | Payments service entry | Any payments work |
auth_service/_index.md | Auth service entry | Auth flows, token handling |
webhook_handler/_index.md | Webhook handler entry | Inbound webhook debugging |
The Load When column is the magic. It lets the AI scan the index and know — without reading the files themselves — which ones are relevant to the current task. A few extra characters per row save dozens of unnecessary file reads per session.
Content files (overview.md, voice.md, runbook.md, decisions.md) are where the actual knowledge lives. These are what the AI reads when it's done navigating. Everything above exists to help it find the right ones quickly.
The discipline is: the AI follows links, it doesn't bulk-load directories. A typical task loads 2-4 files total. Not 40.
Why Entity Isolation Matters
This deserves its own section because it's the thing people get wrong.
If you run a single service, entity isolation doesn't matter much. You have one thing. There's nothing to isolate.
But the moment you have two things with distinct identities — two services, two products, a personal project and a client project — contexts start to bleed. Loading the wrong voice file will make the AI write in the wrong tone. Loading the wrong architecture file will make it suggest the wrong patterns. Loading the wrong runbook will make it run the wrong deploy commands.
The cardinal rule: each entity's files are self-contained. No inheritance from parent entities. No shared files that blend contexts. When the AI needs the payments service's runbook, it loads services/payments_api/runbook.md — not a shared runbook with an "override" section for payments.
This is also why I recommend a flat file structure within entities. Don't do services/payments_api/architecture/database/schema.md. Do services/payments_api/architecture.md and split later if it gets too long. Fewer hops means faster navigation and less for the AI to hold in memory at once.
The @import Pattern
Here's the part that makes this practical at scale. Your projects connect to the knowledge base with one line in their CLAUDE.md:
# My Project
## Project Context
- Type: Microservice
- Stack: Node.js, PostgreSQL, Redis
@~/path/to/knowledge-base/CONTEXT.md
That's it. One line. The @ import pulls in the router, and the AI navigates from there.
Why does this work? Because the router doesn't contain the knowledge itself — it contains the map. When a task arrives, the AI reads the router, matches the task to a domain, loads the domain's index, and from there loads only the specific files it needs. No bulk loading. No guessing.
Even better: multiple projects can import the same knowledge base. If you have five service repos, each one's CLAUDE.md imports the same CONTEXT.md. Project detection rules in the router map each directory name to the right entity, so the AI automatically knows to load services/payments_api/ when you're in the payments repo, and services/auth_service/ when you're in auth.
One knowledge base, many projects. Your context compounds over time, and every session benefits from every previous session's learning.
Practical Example: A Microservices Engineer
Let me walk through what this looks like in practice for an engineer working on a microservices backend.
Imagine you own three services: a payments API, an auth service, and a webhook handler. You also share team conventions (PR review process, coding standards, on-call rotation) with the rest of your team.
Your knowledge base might look like this:
my-kb/
├── CONTEXT.md ← the router
├── CLAUDE.md ← system brain for the KB itself
├── team/
│ ├── _index.md
│ ├── charter.md ← team mission, members
│ ├── processes.md ← PR flow, sprint cadence
│ └── oncall.md ← rotation, escalation, handoff
├── services/
│ ├── _index.md
│ ├── payments_api/
│ │ ├── _index.md
│ │ ├── overview.md ← purpose, dependencies, SLA
│ │ ├── architecture.md ← stack, data flow, schema
│ │ └── runbook.md ← deploy, rollback, alerts
│ ├── auth_service/
│ │ ├── _index.md
│ │ ├── overview.md
│ │ ├── architecture.md
│ │ └── runbook.md
│ └── webhook_handler/
│ ├── _index.md
│ ├── overview.md
│ └── architecture.md
├── architecture/
│ ├── _index.md
│ ├── decisions.md ← ADRs: why we chose X
│ └── patterns.md ← error handling, logging, auth
└── tech/
├── _index.md
├── standards.md ← lint rules, naming, style
└── ci_cd.md ← pipeline, environments, rollback
Now imagine a typical workflow:
Monday morning. You open the payments API repo. Your CLAUDE.md imports CONTEXT.md. You ask the AI: "Help me debug why webhook retries are failing."
The AI reads the router, sees you mentioned "debug" and "webhook," and matches to the project detection rule for payments-api/. It loads:
services/payments_api/overview.md— to understand what the service doesservices/payments_api/architecture.md— to understand the data flowservices/payments_api/runbook.md— which has a section on common webhook issues
Three files. Targeted context. The AI immediately knows your SLA is 99.9%, that webhooks go through SQS with a dead letter queue, and that there's a known issue where retries fail if the Stripe webhook signature check runs before the body is parsed.
It suggests the right fix on the first try.
Tuesday afternoon. You switch to the auth service repo. Same CONTEXT.md import. You ask: "Add refresh token rotation."
The AI sees you're in auth-service/, loads a different entity, and gets services/auth_service/architecture.md plus architecture/patterns.md for the shared auth patterns. It suggests an implementation that matches your existing token storage approach and references the ADR that explains why you chose JWT over session cookies.
Zero contamination between services. Each task gets exactly the context it needs.
Practical Example: A Solo Developer With Side Projects
It's not just for corporate engineers. Here's what this looks like for someone managing their personal life and a few side projects.
personal-kb/
├── CONTEXT.md
├── CLAUDE.md
├── career/
│ ├── _index.md
│ ├── current_role.md ← title, responsibilities, stack at work
│ ├── skills.md ← tech and soft skills, levels
│ └── goals.md ← short and long term
├── learning/
│ ├── _index.md
│ └── current.md ← active courses, certs, progress
├── projects/
│ ├── _index.md
│ ├── my_app/
│ │ ├── _index.md
│ │ ├── overview.md
│ │ └── roadmap.md
│ └── blog/
│ ├── _index.md
│ └── overview.md
├── decisions/
│ ├── _index.md
│ └── log.md ← why I picked Supabase over Firebase, etc.
└── tech/
├── _index.md
└── preferences.md ← default stack, tools, conventions
Now when I ask AI to help me plan a weekend sprint on a side project, it knows:
- What the project is and what I've been building (from
projects/my_app/overview.md) - What's on the roadmap (from
projects/my_app/roadmap.md) - What stack I'm using and why (from
tech/preferences.mdanddecisions/log.md) - How much time I have (implied by my work situation in
career/current_role.md)
No re-explaining. No pasting context. I just say "let's plan this weekend's work" and the AI already has the map.
Adding Skills for Automation
Once you have a knowledge base, you can add local skills — markdown-based playbooks stored in .claude/skills/ that automate KB-specific workflows. These only run when you're working directly in the KB repo.
Two that I find essential:
/brief-me {entity} — Quick briefing on any entity before starting work. You type /brief-me payments and the AI reads the entity's index and key files, then presents a concise summary: what it is, current status, key facts, recent changes. Perfect for getting back up to speed on something you haven't touched in a month.
/sync-kb — Scan recent commits and suggest updates to the knowledge base. You've been adding code, making decisions, changing architecture. Run this periodically and the AI will tell you "hey, you added Redis to payments — should I update services/payments_api/architecture.md to mention it?"
Skills turn the knowledge base from passive context into an active part of your workflow. You're not just storing knowledge — you're maintaining it with help.
Start Small, Grow Over Time
Here's where people get stuck: they look at the full structure and feel overwhelmed. "I can't document everything at once."
You don't have to. The knowledge base is a living document, and the best way to build one is to grow it organically.
Start with the minimum viable version:
- Create a repo with
CONTEXT.mdandCLAUDE.mdat the root - Pick the one area you explain most often — probably your stack or your team's conventions
- Write one domain and one entity for that area
- Add the
@importto your most active project - Use it for a week
Every time you explain something to the AI that the knowledge base could have told it, that's a candidate for a new file. Add it. Next session, that context is already loaded.
Within a month, you'll have covered the 20% of context that drives 80% of your interactions. The knowledge base earns its keep by then, and it keeps getting better as you expand it.
Starter Templates — Skip the Blank Page
Writing a knowledge base from scratch is a chicken-and-egg problem: you need to understand the pattern to build one, and you need one built to understand the pattern in practice.
I solved that for you. I built four starter templates — complete, forkable directories with wired-up routing tables, placeholder content, and working local skills. Every starter also ships with a CHANGELOG.md (with the auto-update rule pre-wired in CLAUDE.md) and a decisions/ folder (with the soft "ask, never infer" rule), so the memory layer described in Part 2 below is ready to go from day one — not something you have to add later. Clone one, replace the <!-- placeholders --> with your actual context, and you're running.
- Base — Minimal standalone KB with just
tech/anddecisions/. Customize from scratch. - Personal — Career, learning, side projects, tech. For individual use.
- Business/Corporate — Team, services (with two worked examples), architecture, product, tech standards. For engineers and PMs at companies.
- Embedded — For injecting the context system directly into a code repo you already have. Content lives in
docs/split by domain (architecture, stack, conventions, decisions, runbook) with indexes for each.
The standalone starters (base, personal, business) split responsibilities between CONTEXT.md (routing) and CLAUDE.md (maintenance rules and conventions). This works because standalone KBs are their own repos with no CLAUDE.md conflict.
The embedded starter is designed to drop into a project you already have — which might already have its own CLAUDE.md. To avoid conflicts, the embedded CONTEXT.md is self-sufficient: it carries routing tables, maintenance rules, changelog and decisions automation, conventions, and skill references all in one file. If you already have a CLAUDE.md, just add @CONTEXT.md to it and you're done — no merging, no replacing.
The embedded template is the one I'd recommend if you just want to make this project smarter without maintaining a separate knowledge base. Everything lives inside the repo, version controlled with the code, and ships to anyone who clones it. Great for open source projects or onboarding new contributors.
All four templates are on GitHub:
github.com/holdenmonroe/ai-context-system-starters
Clone, fork, adapt. Or read the guides in the repo to understand the pattern before building your own.
Quick Start
-
Clone the starter templates repo:
bashgit clone https://github.com/holdenmonroe/ai-context-system-startersThen copy the template closest to your use case into your project (or wherever you want it):
bashcp -r ai-context-system-starters/starters/embedded my-project/Replace
embeddedwithbase,personal, orbusinessdepending on what fits. -
If you already have a
CLAUDE.md: add@CONTEXT.md(for embedded) or@~/path/to/kb/CONTEXT.md(for standalone) to your existing file. The embedded starter'sCONTEXT.mdis self-sufficient — no merging needed. If you don't have aCLAUDE.md: the starter includes one ready to use. -
Read
CONTEXT.md— it's the router. It contains the domain routing tables, context triggers, task recipes, and maintenance rules that tell the AI how the system works. -
Fill in one file — the one that covers what you repeat most often to AI.
-
Let the AI help you build it out. The starters ship with enough structure and rules that the AI understands the system from its first session. Ask it to help you document your architecture, capture your conventions, or draft your first decision entry — it knows the file formats, the
_index.mdcontract, and where everything should go. You're not filling in templates alone; you're pair-building the knowledge base with an AI that already understands the pattern. -
Expand over the next few weeks — every time you notice yourself re-explaining something, add it as a new context file. The changelog auto-updates, the AI prompts you when it notices a decision worth logging, and the
/sync-kbskill catches drift between your code and your context.
That's the whole loop. Start small, let the AI help you grow it, never look back.
If the context system is all you need right now, stop here — you have everything to get started. But if you want your AI to remember what happened, not just what your project is, keep reading.
Part 2: Adding Memory
The context system tells the AI what your project is. Memory tells it what happened.
The knowledge base you just built in Part 1 solves the context problem: stable, structural facts about your project that should be true session after session. Stack, conventions, brand, audience, architecture. Stuff that doesn't change between Monday and Tuesday. The KB makes that information persistent and loadable on demand, so the AI never has to be re-told the things that don't change.
But there's a second problem the context system doesn't solve by default: memory. The AI doesn't automatically know that yesterday you tried implementing payments with webhook polling and it broke under load, so you switched to SQS. That's not stable context — that's a moment in time. Pure context loading won't capture it, no matter how good your _index.md files are.
Here's the thing though: you can solve the memory problem too, with the same system. You just have to be intentional about it. There are three patterns I use:
1. A decisions log
Every entity has a decisions.md file (or, in larger setups, a decisions/ folder with one ADR per file). When you make a meaningful technical choice — especially one where you tried something and it didn't work — you log it. Format something like:
### 2026-03-12: Switched payments from webhook polling to SQS
**Context**: Polling was hitting rate limits during peak load and dropping
events. Tried doubling the poll interval first; just delayed the issue.
**Decision**: Move to SQS with a dead letter queue. Webhook handler now
just enqueues, processing happens async.
**Alternatives**: Increased polling frequency (failed), Redis pub/sub
(more infra to manage), AWS Kinesis (overkill for our volume).
**Rationale**: SQS is already in our stack for other queues. DLQ gives
us easy replay for failed events.
The next time you (or the AI) work on payments, the decisions file gets loaded. The AI sees you already tried polling and why it failed, and won't suggest going back. Episodic memory becomes searchable structured context, just by writing it down once.
2. A changelog the AI maintains for you
The KB itself can have a CHANGELOG.md at its root that tracks meaningful changes to the knowledge base over time. Not commit-level detail — semantic changes. "Added Redis to payments stack." "Changed deploy process to require manual prod approval." "Onboarded new team member, added their service ownership to team/charter.md." It's a one-line journal of what's true now versus what was true a month ago.
But here's the thing: nobody actually maintains a changelog by hand. They start strong, miss a few entries, fall behind, and abandon it. The trick is making the AI maintain it for you — and you can do that with nothing but a rule written in plain English.
Add a section to your KB's CLAUDE.md (the file Claude Code auto-loads at the start of every session in the repo). Here's what mine looks like, simplified:
## Changelog
This knowledge base has a CHANGELOG.md that tracks semantic changes —
what changed and why it matters, not commit-level detail.
### When to update
After any session that changes KB files, add an entry to CHANGELOG.md:
- New files or directories
- Significant content updates
- Structural changes (moved files, new domains, new entities)
- Skip typo fixes and formatting tweaks
### Format
1. Add entries under today's date heading (## YYYY-MM-DD)
2. Tag each entry by domain: [business], [tech], [system], [decisions]
3. One line per change, focused on what matters to a future session
### Auto-update rule
**This is mandatory.** At the end of any session that modifies KB files,
update CHANGELOG.md before finishing. If you're unsure whether a change
warrants a log entry, err on the side of logging it.
That's it. No hooks, no scripts, no automation framework. The reason it works is that CLAUDE.md is loaded by Claude Code at the start of every session in the repo. Any rule you write in there, the AI reads before doing any work. So when a session ends with file changes, the AI encounters the "mandatory" rule and updates CHANGELOG.md as part of wrapping up — without you ever having to remember to ask.
I call this prompt-as-policy: a behavior rule that's enforced by writing it in the file the AI reads first, every session. It's the same mechanism that makes the rest of the KB system work — the router (CONTEXT.md) is enforced this way too. The AI follows the routing tables because it loads them every session, not because anything is hooked into the runtime.
Once this is in place, the changelog starts maintaining itself. You finish a session refactoring auth — the AI logs it. You add a new client to the KB — the AI logs it. Next time you sit down, you can scan the changelog and know what's recent without crawling git.
Here's what an actively-maintained CHANGELOG.md looks like after a few weeks:
# Changelog
Semantic log of what changed in this knowledge base and when. Not a commit
log — focuses on what matters for someone picking up context in a future
session.
## 2026-04-09
- [services] Added Redis to payments stack — `payments_api/stack.md` updated
- [decisions] Logged decision to migrate webhook handling from polling to SQS
- [system] Added prompt-as-policy rule for auto-updating this changelog
## 2026-04-08
- [services] New `auth_service/` entity with full overview, architecture,
and runbook
- [team] Updated on-call rotation — new schedule effective next sprint
- [tech] Added `tech/standards.md` covering naming and PR conventions
## 2026-04-05
- [system] Major restructure: `services/` is now top-level domain
- [services] Migrated payments and auth into per-service entity directories
- [system] Wrote CONTEXT.md router with domain tables and project detection
A few things to notice. The entries are semantic, not commit-level — "migrated webhook handling from polling to SQS" tells you what mattered, not which files were touched. Each entry is one line, scannable in a few seconds. The domain tags in brackets ([services], [system], [decisions]) let you filter mentally — if you're about to work on auth, the [services] and [decisions] entries are what you care about; you can skip [tech] and [team]. And entries land under date headings, newest first, so the most recent state of the KB is always at the top.
When the AI is asked "what's changed recently in the payments service?" it can scan this file in a single read, find the two relevant entries from April 9, and answer concretely — without crawling git history or grepping the codebase.
The same prompt-as-policy pattern works for anything you want enforced consistently:
- "Always update
decisions.mdwhen making technical choices in this conversation" - "Always run
/sync-kbbefore ending a session that touched code" - "Always ask before deleting files in any client directory under
clients/" - "Always announce when loading a new context file so the user can see what's happening"
Write the rule once in CLAUDE.md, and it becomes baseline behavior for every future session. No code, no automation, just a sentence the AI reads before it starts working.
Cross-project enforcement
The CLAUDE.md trick has one limitation: it only fires when you're working inside the KB repo. If you spend Tuesday in your payments-api repo making a big architectural change, the KB doesn't automatically hear about it. You'd have to remember to switch over to the KB and run a sync.
The fix is simple: put the maintenance rules in CONTEXT.md instead of (or in addition to) CLAUDE.md. Since every connected project imports CONTEXT.md via @, the rules load at the start of every session in every project that uses the KB. The AI sees the changelog rule, the decisions rule, and the "proactively suggest updates" table every time it starts working — not just when you're in the KB repo.
This is still prompt-as-policy, just at a different scope:
| Rule lives in... | Triggers when... | Use for... |
|---|---|---|
CLAUDE.md (in the KB repo) | Working inside that repo | Behaviors specific to the KB itself (conventions, adding domains, system maintenance) |
CONTEXT.md (imported by every project) | Any session in any connected project | Cross-project policies: changelog updates, decision logging, proactive KB maintenance suggestions |
Together they cover both directions. Inside the KB, CLAUDE.md governs how the system is maintained. In every connected project, CONTEXT.md carries the maintenance rules so the AI knows to suggest KB updates when your work changes something the KB describes.
The starter templates ship with the maintenance rules already in CONTEXT.md, so this cross-project coverage works from day one.
What to automate, and what to leave manual
One important nuance before moving on. Prompt-as-policy works beautifully for descriptive automation but is risky for prescriptive automation, and knowing the difference matters.
A changelog is descriptive — it records what happened. The AI saw what it did this session, so it can write a faithful entry. There's no judgment involved, no missing context, no risk of being wrong. Automating it is safe. A decision log is prescriptive — it records what you chose and why. And the why is the part you can't safely automate. You picked Supabase because of its RLS support, your ops budget, and a bad experience with Firebase auth two years ago. The AI saw none of that. If you tell it to auto-log decisions, it'll fabricate plausible-sounding rationale that's wrong — and future sessions will trust it as gospel. A wrong decision entry is worse than a missing one because it calcifies into false canonical history.
The fix is to use prompt-as-policy in a softer mode. Instead of "always log decisions," the rule becomes:
If you notice a decision being made in conversation, ask the user if it should be logged to
decisions.md. Never infer the rationale — get it from the user.
That keeps the AI watching for moments worth capturing, but puts the human in the loop for the part where AI judgment can't be trusted. The general principle: automate the descriptive, semi-automate the prescriptive, and never let AI write canonical reasoning.
A specific warning: "let AI populate my decisions log from git history"
There's one variation of this idea that's especially tempting and especially dangerous, so it deserves its own callout.
When you set up a knowledge base on an existing project, you face an immediate gap: your decisions.md is empty, but your codebase is full of historical decisions baked into the architecture. The natural impulse is to ask AI to mine the git history and PR descriptions and just fill the file in for you. "Read the last two years of commits and write me a decisions log." It feels like a perfect job for AI — there's clearly information in there, and the AI can read fast.
Don't do this without strict guardrails. Git history shows you what changed, not why. A commit that says feat: switch from REST to GraphQL tells the AI nothing about the rationale. If you let it write a decision entry from that, it'll invent something plausible: "We adopted GraphQL for better client flexibility and reduced over-fetching." That may or may not match the real reason, but it'll get added to decisions.md and from that point on, every future session will treat it as canonical. You've just taught your AI assistant a fact about your project that nobody on your team actually believes.
If you do want to retroactively populate decisions, build the workflow with these constraints:
- Only surface candidates where the rationale is visible in the source. If a commit message or PR description explicitly explains the why, that's a real candidate. If it just says
WIPorrefactor auth, skip it. Never infer rationale from code diffs alone. - Always cite the source. Every suggested entry includes a commit hash, PR number, or file:line citation. The user can verify the cited source actually says what the AI claims it does, and reject anything where the rationale is invented.
- Tag retroactive entries differently. Mark them as
[retroactive, derived from commit a3f8b2]or similar. Future sessions should know this entry was reconstructed from history, not logged at the moment the decision was made — it's "best guess from sources," not ground truth. - Force the user to supply missing rationale. When the AI finds a meaningful change but the source doesn't explain why, it should NOT suggest a decision entry. It should ask: "I see this change happened — do you remember why? If you tell me the reason, I'll log it." The AI becomes a prompter, not a fabricator.
- Scope the queries narrowly. Don't run "find all decisions in the entire repo history." Run "find decisions about the auth flow" or "find decisions made in the last six months." Small batches the user can actually review one by one.
The pattern here is the same as the broader rule: AI is good at noticing things, bad at inventing rationale. Use it to surface candidates from history and prompt you for the reasoning. Don't use it as a one-shot "write me my missing decisions log" command, because what you'll get is a beautifully formatted file of false canon that will mislead every session that touches it.
3. The /sync-kb skill
The two patterns above are great for passive maintenance — they fire on a session boundary and ask the right question at the right moment. But sometimes you want to actively reconcile the KB with reality on demand: "I just spent two weeks in the auth service repo, what does the KB need to know?"
That's what /sync-kb is for. It's a local skill that lives in .claude/skills/ inside the KB repo. You invoke it explicitly when you want a deeper diff than the Stop hook can do in a few sentences.
The skill scans your recent commits and uncommitted changes, compares them against the KB, and surfaces a list of things that look like they should be reflected: "You added Redis as a dependency — update services/payments_api/stack.md?" "You deleted the webhook-poller service — should I remove services/webhook_poller/ from the KB?" "This commit message mentions a decision about migrating off Firebase — should we add it to decisions.md?"
You confirm or skip each one. The KB stays in sync with reality. Yesterday's session becomes today's context, deliberately.
What the starters include (and what's left for you)
The starter templates from Part 1 already ship with the infrastructure for everything described above:
What's included out of the box:
CHANGELOG.mdwith the mandatory auto-update rule pre-wired inCONTEXT.md— the AI starts maintaining the changelog from your first session, in every connected projectdecisions/folder with a log file, decision template, and the soft "ask before logging, never infer rationale" rule inCONTEXT.md/sync-kband/brief-melocal skills for on-demand KB maintenance- Cross-project enforcement via the maintenance rules in
CONTEXT.md— works in every project that imports it, not just the KB repo
What you'd add yourself to complete the memory layer:
- The discipline of confirming decisions when the AI asks — the prompt-as-policy rule surfaces opportunities, but you have to actually say "yes, log it" and provide the rationale. The memory layer accumulates at the speed of your engagement with it.
- Retroactive population of past decisions if you want historical coverage — the starters ship with an empty decisions log. If you want to fill it from existing history, follow the guardrails above (only log candidates with visible rationale, always cite sources, tag entries as retroactive).
The starters give you the context system fully assembled and the memory infrastructure ready to go. Memory itself accumulates as you use it — the more sessions you run, the more decisions get logged, the more the changelog fills in, and the richer the AI's understanding of your project's history becomes.
Why this distinction matters
Without these patterns, you'll feel let down. You'll set up a beautiful knowledge base, and then a week later you'll catch the AI suggesting an approach you already shot down — and you'll think "wait, didn't I tell it about this?" The answer is no, you told yesterday's session about it. Yesterday's session is gone.
With these patterns, you build a deliberate memory layer on top of the context layer. The KB gives you persistent context for free; persistent memory costs you the discipline of logging decisions and running sync at the end of meaningful sessions.
That's a small price for an AI assistant that actually remembers your project's history.
Rules That Keep This Working
A few hard rules I've learned the hard way:
Load minimum context, never bulk-load. The whole value of this system is targeted loading. If you find yourself thinking "let me just have the AI read the whole services/ directory," the router isn't doing its job. Fix the router.
Never blend entities. If two things have distinct identities, they get separate directories with zero shared files. This is the rule I see people violate most often, and it's the one that causes the worst output quality issues.
When uncertain, ask. Don't let the AI guess which entity applies to an ambiguous task. Have it ask the user. One wrong brand or voice file can poison an entire output.
Update the KB proactively. When your work changes something the KB describes, update the relevant files. Don't wait for the AI to get confused. The /sync-kb skill makes this cheap.
Store context, not secrets. This is version controlled markdown. No API keys, no credentials, no PII, no customer data. Use references to where those things live, not the things themselves.
Automate the descriptive, semi-automate the prescriptive. Changelogs can be fully automated. Decisions can't — never let AI write canonical reasoning without human confirmation.
What This Actually Feels Like
I want to be concrete about the transformation, because the architecture sections above might make this sound like a lot of setup for theoretical benefit. It's not. Here's what actually changed in my daily workflow:
Before the knowledge base, every AI session started with five minutes of context-loading. "We use Next.js with App Router and Tailwind. The project is a React Native app deployed as a PWA. Auth is through Supabase with RLS. The client is a photographer who speaks three languages. The gallery uses Vercel Blob Storage." And that's just one project. Switch to a different project and do it all again. Switch back the next day and do it again. I was spending more time orienting the AI than actually building.
After the knowledge base, I open Claude Code in any project, type what I want to build, and start. The AI already knows the stack, the conventions, the client's brand voice, the past decisions, the deployment process. It doesn't ask "what framework are you using?" It doesn't suggest libraries I've already rejected. It doesn't write code that violates my patterns. The first response is useful — not the third one after two rounds of corrections.
The compound effect is what really matters. Every decision I log, every convention I document, every architecture note I capture — they all pay dividends across every future session. A decision I logged three months ago about why we chose SQS over polling saves me from re-explaining that choice every time the AI touches the webhook system. A convention I wrote once about how we handle errors means the AI writes error handling correctly the first time, in every project that imports my KB.
There's also a cost you don't see until it's gone: the exploration tax. Without a knowledge base, every time you ask the AI to do something non-trivial, it has to spend tokens exploring your codebase first. It spins up agents to read your directory structure, opens files trying to understand your patterns, scans your package.json to figure out your stack. That exploration eats context window and burns time — and it happens every session, because the AI doesn't retain what it learned yesterday.
With a knowledge base, the AI skips almost all of that. The architecture is documented. The conventions are written down. The stack is in preferences.md. The AI doesn't need to reverse-engineer your project — it reads the map and goes straight to the relevant files. Fewer exploration agents, less token waste, faster responses, more of your context window available for the actual work.
This is also why a knowledge base beats relying on agents to "understand" your project. Agents are reactive — they explore your codebase after you ask a question, re-deriving understanding from scratch every session. A KB is proactive — the understanding is already structured and waiting. Your tenth session on a project loads just as fast as your first, because the AI reads the map instead of re-exploring the territory.
More importantly, agents can only find what's in the code. They can read your files, your directory structure, your package.json. But they can't find the decisions you made and why. They can't find the approaches you tried and rejected. They can't find the unwritten conventions your team follows, or the business context that shaped the architecture. A knowledge base has all of that — if you documented it. The AI goes from "I can see what the code does" to "I understand why it was built this way and what you're trying to achieve."
The KB doesn't eliminate agents. The AI still uses them for targeted code-level work — finding a specific function, tracing a call chain, reading a file it hasn't seen before. But the structural understanding, the historical context, and the decision rationale are already loaded before the agent even spins up. The agent becomes a scalpel instead of a machete.
And critically, the knowledge base isn't a context dump. It doesn't shove your entire project history into the prompt and hope the AI figures out what matters. It's a router that teaches the AI how to find what it needs. The AI reads a 50-line routing table, picks the right domain, reads a 40-line index, and loads the 2-3 specific files that matter for the current task. The rest of the KB stays unloaded. This is why it scales — a knowledge base with 50 files works exactly the same as one with 5, because the AI never reads more than it needs.
There's one more benefit that surprised me: the knowledge base doubles as documentation for humans too. The same architecture overview that tells the AI how your code is organized is the same document a new team member reads on day one. The same brand voice file that keeps the AI writing in the right tone is the same brief a freelancer follows. The same decisions log that prevents the AI from suggesting rejected approaches is the same history a new hire reads to understand why things were built this way.
This applies whether you're running a codebase, a business, or just your own life. An engineering team gets onboarding docs and ADRs. A business owner gets SOPs and brand guidelines ready for the next contractor. A solo developer gets a personal reference that future-them can actually use — not scattered notes that made sense at the time but are useless six months later.
You're not maintaining two things — documentation for humans and context for AI. You're maintaining one set of files that serves both audiences. Every time you improve the KB for better AI output, you're improving it for the next person (or future you) who needs the same information. And every time someone reads the KB and asks "why isn't X documented?" — that's a signal the AI is also missing that context.
It's the difference between an AI that's a capable stranger and an AI that's a colleague who's been on the project for months. The capability is the same — the context makes the difference.
Why This Matters More Every Day
AI coding assistants are getting better fast, but they're still bounded by context. A better model with no context is worse than a worse model with the right context. The ceiling on how much AI can help you is set by how effectively you can give it the right information at the right time.
Context engineering isn't going away. If anything, it's becoming the actual skill of working with AI — more important than prompt engineering, more important than model selection, more important than tool choice. The people who figure out how to give their AI assistants persistent, structured, on-demand context are the ones who will pull ahead.
The knowledge base is just one way to do this. Mine isn't the only shape this can take. But the pattern — structured markdown, layered navigation, entity isolation, dynamic loading — works, and it works today, with tools you already have.
You don't need permission. You don't need a new tool. You don't need to wait for the next model release.
You just need to start.
If you build your own knowledge base after reading this, I'd love to see what you come up with. Find me on LinkedIn.
Context is the new prompt. Get good at it early.