Article · Apr 28, 2026
How I document AI-built projects: a CLAUDE.md, ISSUES.md, and prompts/ workflow
The four-part system I install on day one of every inherited Lovable, Cursor, or Claude Code project: CLAUDE.md template, ISSUES.md learning log, prompts/ folder, two-AI workflow.
If you have inherited a Lovable, Cursor, or Claude Code project and the codebase looks fine but feels haunted, this post is for you. You’re hitting bugs you don’t understand, the AI suggestions keep violating rules nobody wrote down, and the only people who could explain why a pattern exists are a stateless model in a chat window six weeks ago and a founder who pasted prompts at midnight. The fix is not more tests. The fix is the four documents that should already have been in the repo, which I’ll show you how to install, in the order I install them, on every AI-built project I take over.
Why standard developer workflows break on AI-built code
In a normal codebase, when you hit a confusing pattern you walk three streets to recover the why. You read the commit message that introduced the change. If that’s thin, you pull up the PR description. If that’s also thin, you ask the original author on Slack.
AI-built codebases break all three streets at once.
- The commits are mechanical. “Update dashboard layout.” “Add auth flow.” Generic verbs in every message because the AI tool wrote them with the same template every time.
- The PR descriptions, if they exist, restate the diff. They tell you what changed. They do not tell you why this pattern over the alternative the model considered.
- There is no author on Slack, because the author was a model, that conversation was either thrown away or buried in a tool nobody ever opens, and even if you find it, the model that wrote the code is no longer the same checkpoint that’s available today.
The fix is to reconstruct the missing context as you go, in the repo, in a form that survives the next time someone (you, a future contributor, a different AI) needs it. The four documents below are how I do that. Each one props up the next, and missing one quietly breaks the others.
1. ISSUES.md as a learning log
The first file that goes into the repo is a flat markdown file at the root: ISSUES.md. Not a Linear board. Not a GitHub Projects view. A markdown file, version-controlled with the code, grep-able from the command line.
Every bug, every weird behaviour, every “why does this happen on Tuesdays” gets an entry. Each entry has four parts:
## #017 · Webhook payload nested one level deeper
**Repro**
Trigger the form submission. Inspect the workflow run. Note that
every field arrives as `undefined`.
**Root cause**
The provider wrapped the payload. Yesterday it returned `data`.
Today it returns `{ data: { ... } }`. The downstream code reads
the top level.
**Fix reasoning**
Read from `payload.data.*`. Add a shape check at ingest so the
next provider change crashes loud, not silent.
**Related**
Surfaces #009 (similar shape mismatch on the Stripe webhook).
The format is not the point. The “fix reasoning” line is what earns the file’s keep, because three months from now when an analogous bug shows up at a different ingest point, the same reasoning applies and you can find it with grep -i 'shape mismatch' ISSUES.md.
On a real project of mine, this file holds 78 closed entries. The dependency graph between them, the “Related” lines, catches regressions automatically: if entry #017’s fix re-broke entry #009, the link is in the file, and the next person who reads the new bug walks straight to the old one. The tracker is not a status board. It is a learning log, and that is a different artifact entirely.
2. The prompts/ folder
The second thing I add is a prompts/ directory at the repo root. Every non-trivial AI instruction gets saved before I run it. One file per prompt, named <id>-<topic>.md.
What goes in each file:
- The intent. What I am trying to change, in one sentence.
- The constraints. What the AI must not break. Other features. Schema invariants. Public contracts.
- The files in scope. A short list. If the change is a refactor, the boundary is named.
- The bits the AI will probably get wrong on the first attempt. I write these before I run the prompt, because the act of writing them surfaces edge cases I would otherwise hit by accident.
What stays out: anything that would let a future reader rerun the prompt verbatim and expect the same diff. The goal is not reproducibility. The goal is traceability. When I look at a commit four months from now and ask “what was I actually trying to do here,” the prompt file is the answer.
On the project I mentioned, this folder holds 17 files covering the last six weeks of substantive work. They are short, most under 50 lines. Their value is not as documentation. Their value is as the kind of documentation that captures the half-decision, the half-spec, the moment when the work was still negotiable. That is the only window where the why is recoverable.
3. A CLAUDE.md template at the repo root
The third file is CLAUDE.md, which Claude Code reads automatically at the start of every session. (Cursor reads .cursorrules; the same content fits.) This is the file that turns a stateless model into a collaborator that knows your project.
The CLAUDE.md best-practice posts on the SERP all converge on one rule: keep it under 80 lines or Claude starts ignoring parts of it. I keep mine to four sections, in this order:
Section 1: Commands
How to run, test, lint, build. The exact strings, copy-paste ready. npm run dev, npm run build, npm run test. If there is a non-obvious env var, name it. If a deploy step requires a secret, point at where it lives. The reason this is first is that ninety percent of “the AI suggested something that broke our setup” mistakes happen because the AI guessed at the command and got it half right.
Section 2: Architecture
The handful of patterns this codebase actually uses. Naming conventions. Layering. Where data flows in and out. Three to five paragraphs. Not exhaustive. The point is to give the AI the right priors so its first guess about where to put new code is the same as yours.
Section 3: Guardrails
Hard rules. Imperative voice. No hedging.
Never write to production directly. Always use the typed client. Never bypass row-level security. Never delete data without a confirmation prompt.
These are the things that, if you violate them once, damage something real. A guardrail with the word “usually” in it is not a guardrail.
Section 4: What not to touch
The fragile corners. Migration scripts that have run once and must not run again. Payment paths that are audited. Webhook signature verification. Anything load-bearing whose blast radius is larger than the line you would change. Naming these explicitly is the cheapest insurance the project has.
Without this file, AI suggestions are plausible-looking and routinely violate project rules. With it, the hit rate on first-try prompts climbs measurably and the wasted-prompt count drops to a fraction. It is the highest-leverage two hours you will spend on any AI-assisted project.
4. The two-AI, one-referee workflow
The fourth piece is a workflow, not a file. Claude Code plans, audits, documents, and reviews. Lovable (or Cursor, or Bolt) ships the actual code edits. I approve every handoff in between.
The split matters because the two tools are good at different things:
- Claude Code is excellent at reasoning over a repo it can read end to end, comparing approaches, flagging risks, and writing the surrounding documentation. It is less good at the rapid scaffold of a new component or a UI tweak that needs to land in five minutes.
- Lovable / Cursor / Bolt are the opposite: they ship visible UI changes quickly, but they will agree to almost any change you ask for and rarely refuse on their own.
If you let either of them run alone, the failure mode is predictable. Claude Code alone will reason for ten minutes about a change that should have taken thirty seconds to scaffold. Lovable alone will happily ship something that violates a rule in your CLAUDE.md, because Lovable doesn’t read CLAUDE.md.
The referee role is not optional. The pattern is plan, approve, ship, review, document:
- Claude Code plans the change. It writes the diff in plain English, lists the files it intends to touch, and surfaces the risks (which guardrail, which fragile corner, which existing pattern).
- I read the plan and approve, push back, or rewrite it. This is the human referee step.
- Lovable ships the approved plan. The diff lands in the preview branch.
- Claude Code reviews the diff against the plan, updates the relevant docs (CLAUDE.md, ISSUES.md, the prompts folder), and writes the commit message.
- I merge.
Without the referee step, the two AIs will agree to changes neither of them should be confident about, and the result will pass tests and break in production. With it, every change has a written record of intent, a reviewer who is not the writer, and a documentation update that captures what the project just learned.
Which document are you missing?
The four pieces are not interchangeable, and they are not optional in any combination.
- A
prompts/folder without aCLAUDE.mdis a graveyard, because the prompts assume context the AI doesn’t have at session start. - A
CLAUDE.mdwithout anISSUES.mdis a file that goes silently out of date, because nothing in the workflow forces it to absorb what the project just learned. - An
ISSUES.mdwithout the two-AI referee step fills up with regressions, because there is no checkpoint that asks “is this a class of bug we have seen before?” before the diff lands.
The system works because each piece props up the next. If you are inheriting a Lovable, Cursor, or Claude Code project and the codebase looks fine but feels haunted, this is usually what is missing. Not tests. Not types. The connective tissue between the work that has happened and the work that is about to happen.
Related reading
- Real-world example of the rotation discipline this workflow enables: How to audit a Lovable app after the BOLA disclosure.
- What it looks like when an AI tool re-implements the platform’s own SDK: Migrating to Supabase publishable keys broke my Chrome extension.
If you are a SaaS founder or product team across North America, the UK and Ireland, the EU and EEA, or the ANZ region, and you have inherited an AI-built project that needs this scaffolding installed properly, let’s talk. The four-part system above is what gets installed on day one of every engagement.
Frequently asked questions
How do I document an AI-built project I just inherited?
Install four documents in the repo on day one. An ISSUES.md learning log at the root, with one entry per bug containing repro, root cause, fix reasoning, and a Related line. A prompts/ folder with one file per non-trivial AI instruction, capturing intent, constraints, files in scope, and likely first-attempt failure modes. A CLAUDE.md at the repo root with four sections: commands, architecture, guardrails, and what not to touch. A two-AI workflow where Claude Code plans and reviews, Lovable or Cursor ships the edits, and you act as the human referee on every handoff.
What should go in a CLAUDE.md file?
Keep CLAUDE.md under 80 lines or Claude starts ignoring parts of it. Use four sections in this order. Commands - the exact strings to run, test, lint, and build, copy-paste ready, plus any non-obvious env vars. Architecture - three to five paragraphs naming the patterns the codebase actually uses, the layering, and the data flow. Guardrails - hard rules in imperative voice with no hedging (never write to production directly, always use the typed client, never bypass row-level security). What not to touch - the fragile corners like migration scripts, payment paths, webhook signature verification, and anything load-bearing.
What is ISSUES.md and how is it different from a Linear board?
ISSUES.md is a flat markdown file at the root of the repo, version-controlled with the code, grep-able from the command line. Each entry has a numbered ID, a Repro section, a Root cause section, a Fix reasoning section, and a Related line linking other entries that surface the same class of bug. Unlike a Linear board, ISSUES.md travels with the code, so the next person who reads a similar bug walks straight to the dependency graph in the file. It is a learning log, not a status board, and the Fix reasoning line is what earns the file its keep months later.
Why use both Claude Code and Lovable or Cursor on the same project?
The two tools are good at different things. Claude Code reasons over a repo end-to-end, compares approaches, flags risks, and writes the surrounding documentation, but it is slow at scaffolding new UI. Lovable and Cursor ship visible UI changes quickly but rarely refuse a change on their own and will happily violate a rule in your CLAUDE.md. The pattern is plan, approve, ship, review, document. Claude Code plans and reviews. Lovable or Cursor ships. You approve every handoff. The split prevents either tool's blind spot from reaching production.