The Foundation
Projects rarely die from bad code. They die from missing structure: a leaked key, a decision nobody remembers making, a new session that starts blind and rebuilds what already existed. This is how Fable 5 starts a project so that none of that happens. Do these steps in order, before feature code.
Step 0: Five answers before any code
Ask these in ONE short message (not five separate messages):
- What does this do, in one sentence?
- Who uses it? (Just you? Clients? The public?)
- What data does it store, and is any of it sensitive?
- Where will it live? (Local script, Vercel, a phone, a server)
- What already exists? (Repo, accounts, API keys, old versions)
If the user says "just build it", proceed with sensible defaults, but WRITE THE DEFAULTS DOWN as decisions (see the decisions log below). A default nobody recorded becomes a mystery in three weeks.
Step 1: Skeleton before features (exact order)
git init
.gitignore FIRST, before any secret exists. Minimum: .env*, node_modules/, dist/, .next/, .DS_Store, plus anything stack-specific. The order matters: an ignore file created after a secret is committed is a bandage on a wound that already happened.
.env.example with placeholder names only. Real values go in .env, which is never committed. Every variable the app needs appears in the example file, so setup on a new machine is fill-in-the-blanks.
README.md: what this is and how to run it, in under ten lines. Written for a stranger.
CLAUDE.md: the project's own manual. This is the most important file in the repo.
The CLAUDE.md template
Every future session, human or model, starts by reading this file. Keep it current or the project goes senile.
# [Project name]
## What this is
One paragraph. What it does, who it's for.
## Stack
Each major pick and WHY. "Next.js because it deploys to Vercel in one command."
## Structure
The folders that matter and what lives in each. Skip the obvious.
## Commands
dev: ...
test: ...
deploy: ...
## Decisions log
- 2026-07-06: Chose X over Y because Z.
(One line per decision. Append, never rewrite.)
## Gotchas
Things that bit us once and will bite again if forgotten.
Step 2: Boring beats clever
Pick the most common tool for the job, not the most interesting one. Common tools have common answers; every error message has been solved publicly a thousand times.
- Web app: Next.js, deployed on Vercel.
- Database and auth: Supabase or Postgres.
- One-off automation: a single script file. It does not get a framework until it hurts.
- Styling, state, everything else: the default choice of the stack you picked.
Anything new or shiny requires one written line in the decisions log explaining what it buys you. If the line is hard to write, that's the answer.
Step 3: Habits that keep it alive
- Commit after every working change. The message says why, not what: "limit signups to 3 per email to stop the duplicate bug", not "update api.ts".
- Env validation at boot. The app checks its required variables on startup and fails loudly, naming the missing one. A named failure at boot beats
undefined at runtime in front of a user.
- One error-handling pattern, decided now, used everywhere. Errors are logged with context server-side; users see something calm.
- Append to the decisions log the moment a choice is made. Future sessions inherit reasons, not just results.
The month test
The foundation is done when a brand-new session with zero conversation history can answer all four of these from the repo files alone:
- What is this project?
- How do I run it right now?
- Why is it built the way it's built?
- What should I not touch, and why?
If any answer requires "you had to be there", the foundation is not done. Fix CLAUDE.md until it is.
Definition of done for setup
Only after this list is checked does feature work begin.
1---2name: foundation3description: Project setup playbook written by Claude Fable 5. Use whenever a new project, app, tool, script, or build starts. Triggers on "new project", "build me", "let's start", "create an app", "set this up", or the first working session in an empty folder. Establishes the questions, files, and habits that keep a project alive and understandable a month later, before any feature code is written.4---56# The Foundation78Projects rarely die from bad code. They die from missing structure: a leaked key, a decision nobody remembers making, a new session that starts blind and rebuilds what already existed. This is how Fable 5 starts a project so that none of that happens. Do these steps in order, before feature code.910## Step 0: Five answers before any code1112Ask these in ONE short message (not five separate messages):13141. What does this do, in one sentence?152. Who uses it? (Just you? Clients? The public?)163. What data does it store, and is any of it sensitive?174. Where will it live? (Local script, Vercel, a phone, a server)185. What already exists? (Repo, accounts, API keys, old versions)1920If the user says "just build it", proceed with sensible defaults, but WRITE THE DEFAULTS DOWN as decisions (see the decisions log below). A default nobody recorded becomes a mystery in three weeks.2122## Step 1: Skeleton before features (exact order)23241. `git init`252. `.gitignore` FIRST, before any secret exists. Minimum: `.env*`, `node_modules/`, `dist/`, `.next/`, `.DS_Store`, plus anything stack-specific. The order matters: an ignore file created after a secret is committed is a bandage on a wound that already happened.263. `.env.example` with placeholder names only. Real values go in `.env`, which is never committed. Every variable the app needs appears in the example file, so setup on a new machine is fill-in-the-blanks.274. `README.md`: what this is and how to run it, in under ten lines. Written for a stranger.285. `CLAUDE.md`: the project's own manual. This is the most important file in the repo.2930## The CLAUDE.md template3132Every future session, human or model, starts by reading this file. Keep it current or the project goes senile.3334```markdown35# [Project name]3637## What this is38One paragraph. What it does, who it's for.3940## Stack41Each major pick and WHY. "Next.js because it deploys to Vercel in one command."4243## Structure44The folders that matter and what lives in each. Skip the obvious.4546## Commands47dev: ...48test: ...49deploy: ...5051## Decisions log52- 2026-07-06: Chose X over Y because Z.53(One line per decision. Append, never rewrite.)5455## Gotchas56Things that bit us once and will bite again if forgotten.57```5859## Step 2: Boring beats clever6061Pick the most common tool for the job, not the most interesting one. Common tools have common answers; every error message has been solved publicly a thousand times.6263- Web app: Next.js, deployed on Vercel.64- Database and auth: Supabase or Postgres.65- One-off automation: a single script file. It does not get a framework until it hurts.66- Styling, state, everything else: the default choice of the stack you picked.6768Anything new or shiny requires one written line in the decisions log explaining what it buys you. If the line is hard to write, that's the answer.6970## Step 3: Habits that keep it alive7172- **Commit after every working change.** The message says why, not what: "limit signups to 3 per email to stop the duplicate bug", not "update api.ts".73- **Env validation at boot.** The app checks its required variables on startup and fails loudly, naming the missing one. A named failure at boot beats `undefined` at runtime in front of a user.74- **One error-handling pattern**, decided now, used everywhere. Errors are logged with context server-side; users see something calm.75- **Append to the decisions log** the moment a choice is made. Future sessions inherit reasons, not just results.7677## The month test7879The foundation is done when a brand-new session with zero conversation history can answer all four of these from the repo files alone:80811. What is this project?822. How do I run it right now?833. Why is it built the way it's built?844. What should I not touch, and why?8586If any answer requires "you had to be there", the foundation is not done. Fix CLAUDE.md until it is.8788## Definition of done for setup8990- [ ] git initialized, first commit made91- [ ] .gitignore in place before any secret existed92- [ ] .env.example lists every variable; .env untracked93- [ ] README says what + how to run94- [ ] CLAUDE.md filled in, including at least one decisions-log entry95- [ ] Stack choices are boring, or their reasons are written down96- [ ] App fails loudly on missing env vars9798Only after this list is checked does feature work begin.