Penloom Studio · Notes
Pull the low-star reviews of any AI assistant app and one complaint outnumbers almost everything that isn't billing: the thing forgets what you just told it. Point that same failure at a coding agent — Claude Code, Cursor, Copilot, Windsurf, Codex — and it costs more than an annoying re-ask. It costs you a session that doesn't know your build command, doesn't know which files are off-limits, and confidently invents an API your codebase never had, because nothing told it otherwise.
The fix isn't a smarter model. It's a file. A model with no memory of your project isn't a bug to route around — it's the starting condition, every time, for every tool. The only lever you have is what's sitting in the repo when the session starts. Twenty minutes from now, the templates below give you three files that close that gap. Copy them straight into your repo — everything on this page is real and ready to use as written.
Most agentic coding tools read a root-level CLAUDE.md automatically, without being told to. That's the entire point of putting it there instead of in a chat message that scrolls away.
# CLAUDE.md — (project name)
## What this is
One paragraph: what the project does, who it's for, and the one constraint
that matters most (e.g. "this is a payment system — correctness over speed").
## Tech stack
- Language/runtime: (e.g. Node 20, Python 3.12)
- Framework: (e.g. Express, Django, Next.js)
- Database: (e.g. Postgres via Prisma)
- Tests: (exact command, e.g. `npm test`, `pytest -x`)
- Lint/format: (exact command, e.g. `npm run lint`, `ruff check .`)
- Build: (exact command)
## How to run it locally
(the exact commands, in order, that take a clean checkout to a running app)
## Where things live
- `/src/api/` — (what's here)
- `/src/lib/` — (what's here)
- `/tests/` — (what's here)
- (add every top-level directory a new session would otherwise have to
discover by exploring — this section is the single highest-value part
of the whole file)
## Conventions
- (naming, error handling pattern, how you structure commits — whatever is
true of this codebase specifically and not obvious from reading one file)
## Do not touch
- (files/directories that are generated, vendored, or otherwise off-limits
— an agent that doesn't know this WILL eventually "helpfully" edit one)
## Known issues / in-progress work
- (anything a fresh session needs to know is already broken or intentional,
so it doesn't "fix" something you're mid-way through changing)
## Verification
- Before calling anything done: (the actual commands that must pass —
e.g. `npm test && npm run build`)
The two sections that do the most work: "Where things live" and "Verification." Everything else is context an experienced contributor would eventually infer. Those two are the ones a fresh session cannot infer at all — it either knows the file map and the pass/fail bar, or it's guessing. Fill those two in first; the rest can wait until the next time you notice something missing.
AGENTS.md is the same idea under a tool-agnostic name — useful when your team uses more than one coding agent, or a tool that doesn't look for CLAUDE.md specifically. Keep one line at the top so nobody deletes one thinking it's a duplicate.
# AGENTS.md
> This project also keeps `CLAUDE.md` for Claude Code specifically.
> If you're editing project context, update both — or make this file
> the single source and have CLAUDE.md point here in one line:
> "See AGENTS.md — same content, read by every agent we use here."
(same sections as CLAUDE.md)
That one-line pointer solves the actual failure this causes in practice: two context files silently drifting apart because someone updated one and forgot the other existed.
CLAUDE.md answers "what is this project." SESSION-NOTES.md answers "what was I just doing" — and it's the one people skip, which is exactly why it's the highest-leverage one to add. CLAUDE.md gets written once and mostly holds steady. SESSION-NOTES.md changes every session, and it's what makes session #2 pick up in seconds instead of minutes of re-discovery.
SESSION-NOTES.md# SESSION-NOTES.md
(Update this at the END of every session, before you stop. Overwrite the
previous entry — this is a handoff note, not a changelog. Git history is
the changelog.)
## As of (date/time)
**Working on:** (the specific task, one line)
**State:** (what's done, what's half-done, what's untouched)
**Next step:** (the literal next action — not "keep working", the actual
next command or file to open)
**Watch out for:** (anything you'd tell a coworker taking over right now —
a flaky test, an unfinalised decision, a file mid-refactor)
**Verified:** (what you actually ran and confirmed passed, with the command)
Filled in, a real entry looks like this. Copy the shape, not the specifics:
## As of 2026-08-07 16:40
**Working on:** migrating the invoice total calc from float to integer cents
**State:** `src/billing/total.ts` converted and tests updated; `src/billing/
refund.ts` still uses float — NOT yet converted, will double-round if
touched before this finishes.
**Next step:** convert `refund.ts`, then run `npm test -- billing`
**Watch out for:** don't "fix" the float math in `refund.ts` as a
side-effect of an unrelated task — it's mid-migration, not broken
**Verified:** `npm test -- billing/total` passes (12/12), 2026-08-07 16:38
That single entry does what a chat transcript can't: it's the first thing the next session reads, it's five lines instead of a scroll-back search, and it names the exact trap — don't fix refund.ts — that a context-blind agent would otherwise walk straight into.
A context file that exists but isn't read is a placebo. "Read CLAUDE.md" is not, on its own, reliably enough — some sessions skim, some start mid-conversation without a fresh read. Each of these forces a checkable action rather than a promise.
Before doing anything else: read CLAUDE.md and SESSION-NOTES.md in full.
Then summarize back to me, in 3 bullet points, what you now know about
this project that you didn't know before reading them. Do not start the
actual task until you've done this.
Before creating any new file, check "Where things live" in CLAUDE.md for
where this kind of file already belongs. If it's not covered, ask me
where it should go instead of picking a location yourself.
Before editing any file, check it against the "Do not touch" list in
CLAUDE.md. If the file you're about to change is on that list, or looks
generated/vendored even if it isn't explicitly listed, stop and ask me
first.
Before ending this session, update SESSION-NOTES.md with what's actually
done vs. half-done, the literal next step, and the exact command you ran
to verify your work — not what you intended to run, what you actually
ran and what it printed.
Quote the exact line in CLAUDE.md or SESSION-NOTES.md that supports what
you just told me. If there isn't one, tell me you're inferring, not
reading — and tell me what you're inferring it from instead.
Prompt 5 is the most useful one here. An agent that has to cite its source stops silently blending "what the file said" with "what seemed plausible" — which is the exact mechanism behind an invented API or a made-up config value. Not malice. Just an unmarked guess, presented with the same confidence as a fact.
The other half of the memory problem isn't what the agent forgot — it's what you never told it precisely enough to remember. "Clean up the billing code" gives a context-blind agent nothing to verify itself against, so it verifies against nothing and calls it done. A task packet makes the request itself the memory.
Purpose: (why this needs to happen — one line)
Task: (the concrete, checkable deliverable)
Context: (only what's needed for THIS task; link to CLAUDE.md
sections rather than re-pasting them)
Boundaries: (explicit do-not list — files not to touch, patterns not
to introduce, scope not to expand into)
Verification: (the exact command that proves success, and what "pass"
looks like)
Worked example:
Purpose: refund.ts still uses float cents; a rounding bug there
caused a real $0.01 discrepancy last week.
Task: convert src/billing/refund.ts from float to integer cents,
matching the pattern already used in src/billing/total.ts.
Context: see CLAUDE.md "Conventions" for the integer-cents rule;
total.ts is the reference implementation, already converted.
Boundaries: do not touch total.ts (already correct); do not change the
public function signature of processRefund() — three
other files call it.
Verification: `npm test -- billing` must pass, and add one new test that
asserts a $19.99 refund on a $0.01-fee order nets exactly
$19.98, not $19.979999999999998.
This isn't process for its own sake. It's the same five lines whether you type them or the agent drafts them from your one-sentence request and shows them back before starting. Either way the task now has a definition of done that doesn't live only in your head — which means the next session can pick up an unfinished packet and know exactly what "unfinished" means.
CLAUDE.md at the project root automatically. Put SESSION-NOTES.md at the root too, and reference it from CLAUDE.md's Verification section or a new "Session handoff" line so it isn't missed..cursorrules or a .windsurf/ config in addition to a root markdown file. Keep CLAUDE.md/AGENTS.md canonical and point tool-specific config at it in one line, rather than duplicating content that will drift.Three failure modes, all the same root cause — nothing persisted between the last session and this one.
None of these are the model reasoning badly. They're the model reasoning correctly from an incomplete picture, because nothing gave it a complete one. That distinction is the whole reason this is three files instead of a plea to be more careful.
A context file that's wrong is worse than none — because it's wrong with confidence. Two habits keep it honest:
That's the kit — three files and five prompts, all above, free to copy. If you want the interactive version with a progress tracker and one-click copy buttons, it's also up at Penloom Studio. Nothing to download either way — a PDF of copy-paste templates is a worse version of the same thing.