I use AI coding agents a lot.
And for a while, one of the most annoying parts had nothing to do with whether they could write code.
It was that every new session felt like working with someone who had technically read the project but had absolutely no idea what had happened before.
The code tells an agent a lot.
It can see the structure, inspect the functions, trace the data flow, read the package.json, and figure out what the application does.
What it usually cannot see is everything around the code.
Why did I choose this approach instead of that one?
Did I already try that library?
Was this weird-looking piece of code deliberate?
Did another agent already spend two hours debugging this exact problem?
Did I specifically say three sessions ago that I do not want that abstraction added?
That information tends to disappear between sessions unless you deliberately give it somewhere to live.
So over time, I ended up building a little system around that problem.
And because it has been working really well for me, I cleaned it up, removed anything project-specific, made some fictional examples, and put the whole thing into a reusable repo.
It started with AGENTS.md
I already had an AGENTS.md file with the usual project rules.
Things like:
- do not touch unrelated code
- use the simplest solution first
- do not silently make architectural decisions
- preserve working prompts and logic unless they actually need to change
- do not run huge test suites after every tiny edit
- do not commit, push, deploy, or delete things unless I ask
Basically, all the stuff I got tired of repeating.
That helped a lot.
But eventually I realized I was trying to make AGENTS.md do too many jobs.
There is a difference between:
Here is how I want you to work.
and:
Here is why this project works the way it does.
And there is another difference between both of those and:
We already tried this. It exploded. Please do not make us learn this lesson again.
So I split them apart.
The four files
The system ended up with four Markdown files, each answering a different question.
| File | What it answers |
|---|---|
AGENTS.md |
How should the agent behave while working here? |
OVERVIEW.md |
How does the project work right now? |
MEMORY.md |
Why is it built this way, and what alternatives did we reject? |
ERRORS.md |
What already failed, and what worked instead? |
AGENTS.md stays at the root.
The other three live in /DOCS.
And that separation turned out to matter a lot more than I expected.
OVERVIEW.md is the project as it exists today
OVERVIEW.md is basically the technical map.
It can contain things like:
- the stack
- important directories
- the main application flow
- data models
- routes
- APIs
- authentication behavior
- testing commands
- deployment notes
- current limitations
The important part is that it describes now.
It is not a development diary.
If the project stops using one database and starts using another, I do not append:
Update: we no longer do this.
I change the documentation so it reflects what is currently true.
That gives an agent somewhere to start before it starts wandering through the codebase trying to reconstruct the entire application from scratch.
MEMORY.md is for decisions
This is where things got much more useful for me.
MEMORY.md is not a list of everything that happened.
It is specifically for decisions where the reasoning might otherwise disappear.
Something like:
We save the record before doing metadata extraction because the user's primary action should succeed even if the remote site times out.
And then I can record the alternative that was rejected and why.
Now a future agent does not look at that flow and decide:
Huh. This seems backwards. I'll clean it up.
It knows that the order is deliberate.
That is the kind of context code usually cannot give you.
A good test I use is:
Could a competent developer look at this code later and reasonably change it back because they do not know why we chose it?
If yes, it probably belongs in MEMORY.md.
If it is just:
Added the settings page.
That is a changelog entry. It does not need memory.
ERRORS.md is for the painful stuff
This one is probably self-explanatory.
But I also did not want it turning into a bug tracker.
Normal bugs happen. You find them, fix them, move on.
ERRORS.md is for the ones that cost enough time that I really do not want the next agent repeating the whole adventure.
Things like:
- an API behaving differently than expected
- a test failure caused by shared state instead of the feature being tested
- a configuration detail that only applies to one connection
- a dependency incompatibility that took multiple attempts to understand
- some incredibly stupid edge case that looks obvious only after you finally figure it out
The entry records:
- what did not work
- what worked instead
- the lesson worth remembering
Then the next time something similar happens, the agent can check that before starting from zero.
The important part is actually what doesn't get written down
At first, I think the obvious temptation with something like this is to document everything.
That would completely ruin it.
If MEMORY.md becomes a changelog, nobody wants to read it.
If ERRORS.md becomes Jira in Markdown, the useful failures disappear into hundreds of boring bugs.
If OVERVIEW.md becomes a running history of every architecture change, you no longer know which parts describe the current application.
So I ended up with a pretty high bar for adding things.
For OVERVIEW.md:
Did this change make something in the document incorrect or incomplete?
For MEMORY.md:
Was there an actual decision here that someone might reasonably reverse later without knowing the reasoning?
For ERRORS.md:
Was this painful or surprising enough that someone could waste serious time rediscovering it?
If not, nothing gets added.
That might be one of the more important parts of the whole system.
Context is only helpful while there is still a reasonable amount of it.
Why not just shove all of this into AGENTS.md?
I tried the giant-instruction-file direction.
I do not love it.
AGENTS.md is usually part of the context every session, whether all of its contents are relevant or not.
If it contains every project decision, every debugging lesson, every architecture detail, every writing rule, every release procedure, and every random preference I have accumulated over six months, it becomes a giant wall of instructions competing with the actual task.
It also mixes information that behaves differently.
Behavior rules are fairly stable.
Architecture changes.
Decision history grows.
Debugging history grows in a completely different way.
So now AGENTS.md mostly tells the agent where to look and how to behave, instead of trying to contain the entire project brain.
Then I added skills
This was the piece that made the system feel more complete.
I created a project-context skill that teaches the agent how to use these files instead of relying on the agent to guess.
It covers things like:
- when each file should be read
- how to search a large
MEMORY.mdinstead of dumping all 700 lines into context - what to do if the documentation and code disagree
- how to handle a request that conflicts with a previously recorded decision
- what qualifies for a new entry
- what should absolutely not be logged
One rule I especially like is:
The code wins as a description of what happens. The documentation wins as a description of what was intended.
If those two disagree, that is useful information.
The agent should not blindly trust stale docs, but it also should not assume the current code represents the intended design.
And if I ask for something that MEMORY.md says we already rejected, the agent should not just refuse to do it.
Reasons expire.
But it should tell me:
We previously rejected this for X reason. Do you still want to change it?
Now the reversal is deliberate instead of accidental.
I made another skill for writing too
This part is slightly separate from the context system, but it fits into how I use coding agents.
I have a clear-writing skill for documentation, READMEs, setup instructions, error messages, release notes, and other project writing.
One thing that kept bothering me was agents applying the same writing style to everything.
A setup guide should be boringly clear.
A README opening should not sound like a Boeing maintenance manual.
So the skill first determines what kind of writing it is.
Instructional writing gets stricter rules around sentence structure, terminology, and ambiguity.
Writing that is supposed to have an actual voice gets different rules so it does not turn into the usual polished-but-weird AI prose.
It is not necessary for the context system itself, but since I use both together, I included it.
The workflow now looks something like this
Before an agent changes an existing project:
- Read the relevant project documentation.
- Use
OVERVIEW.mdto understand the current system. - Check
MEMORY.mdfor decisions related to the thing being changed. - Check
ERRORS.mdif the task involves debugging or an area that has caused trouble before. - Inspect the actual implementation.
Then do the work.
Afterward:
- Fix
OVERVIEW.mdif anything in it became untrue. - Add something to
MEMORY.mdonly if a real decision was made. - Add something to
ERRORS.mdonly if the failure is actually worth remembering. - Otherwise, leave them alone.
It is basically:
Read before changing. Write after learning.
This is not some giant AI memory system
There is no vector database.
No embeddings.
No background memory agent.
No separate service.
No database at all.
It is Markdown.
That is kind of the point.
I have built RAG systems and memory layers before, and those absolutely have their uses.
But I did not need any of that for this problem.
I just needed important project knowledge to survive longer than one coding session.
Plain files are searchable, editable, version controlled, easy for humans to read, and easy for coding agents to use.
Good enough.
I turned it into a reusable repo
pinkpixel-dev
/
agent-context-kit
Durable project context for AI coding agents: an AGENTS.md template, three context files, and the skills to read and maintain them.
Agent Context Kit
A small system for giving AI coding agents the project context they cannot get from reading the code alone.
Code can tell an agent what exists. It usually cannot tell it why something was built that way, what already failed, which alternatives were rejected, or how you want the agent to behave while working in the repository.
That is what this kit is for.
It is four Markdown files with separate jobs, plus two skills that teach an agent how to actually use them. Copy the parts that make sense for your workflow, change whatever does not, and ignore the rest.
This is not an AI memory service, vector database, RAG system, or autonomous memory framework. It is just a lightweight repository convention for keeping useful project context in plain Markdown.
The problem
An agent starts a session knowing nothing about your project except what it can…
Once I realized how much I was relying on this setup, I figured it might be useful to other people too.
So I made a generic version of my AGENTS.md, removed my personal project rules, and created templates for the supporting docs.
I also made a fictional project called Lantern and filled out example versions of OVERVIEW.md, MEMORY.md, and ERRORS.md.
That seemed more useful than giving people three completely empty files and saying:
Okay, now document your architecture.
The examples show what these files can look like after a project has actually been worked on for a while.
The repo also includes the two skills and their templates/reference material.
I'm definitely not saying everybody needs this exact setup
You might only want MEMORY.md.
You might already have architecture docs and just want the debugging log.
You might hate my folder structure.
You might use a completely different agent workflow.
That is fine.
The thing I think is useful is the separation:
behavior
current state
decisions
failures
Once I stopped treating all of that as one giant blob of "context," my coding sessions got noticeably less repetitive.
Agents stopped suggesting some of the same rejected ideas.
I had to explain fewer architectural decisions again.
And when something ugly had already been debugged once, there was finally somewhere useful to put that knowledge.
Mostly, I built this because I was tired of repeating myself.
It turns out Markdown is pretty good at remembering things.
I find this much more useful than another "Agent Memory" MCP server or database.
I'd be interested to hear what you think and if you have suggestions to improve this.
Top comments (2)
nice!
The distinction between code representing what happens and documentation representing what was intended is the clearest framing I have seen for handling doc drift. When an agent spots a conflict between an implementation and an old decision, surfacing it as an explicit question rather than silently assuming one of them is wrong saves hours of accidental rewrites.
The main maintenance trap I ran into with long-lived debugging logs was scope expiration. A workaround recorded for a weird ORM bug or runtime quirk can quietly turn into permanent superstition three dependency updates later. Adding a narrow tag or version floor to the error entry keeps the agent from treating temporary patches as permanent architecture rules.