If you build with Cursor, Claude Code, Copilot or Windsurf, you've probably had at least one of these happen:
- You asked for a small fix and the agent "tidied up" four other files.
- An API key ended up hard-coded in a component, or behind a
NEXT_PUBLIC_prefix where every visitor can read it. - A new API route works perfectly, for every user, including the ones who shouldn't see that record.
- The agent tried the same broken fix five times, each one making things a bit worse.
- Tests were "fixed" by skipping them.
None of this is the model being stupid. It's the model doing exactly what it was asked, with no idea what you consider off-limits. The fix is cheap: give it a short, clear set of house rules it reads at the start of every session.
Where the rules go
Most AI coding tools now read a plain Markdown instructions file from your project:
| Tool | File it reads |
|---|---|
| Cursor, Copilot, Windsurf, Codex, Zed, Amp and others | AGENTS.md |
| Cursor (project rules) | .cursor/rules/*.mdc |
| Claude Code | CLAUDE.md |
AGENTS.md is the closest thing to a shared standard, so it makes sense to put the real rules there and have the other files point at it. That's the setup I'll walk through below. All the files are in a free, MIT-licensed repo: vibe-coding-rules-starter.
1. Give the agent a rule priority
The most useful thing you can tell an agent is what to do when instructions clash. Without that, "just make it work" quietly beats "don't commit secrets". The starter opens with this:
## Rule priority
When rules clash, follow the higher one and say which you followed:
1. **Security guardrails** (next section): never broken, even if I ask.
Explain the risk in one line and do the safe version.
2. **The task I asked for**: it's my OK for the changes it clearly needs,
within the guardrails. List them under "Needs your OK".
3. **Stack conventions** (the conventions already used in this repo).
4. **Working style.**
"Say which you followed" matters. It turns a silent decision into one you can see in the reply.
2. Make security rules specific
"Write secure code" does nothing. Rules the agent can act on look like this:
- Public prefixes (`NEXT_PUBLIC_`, `VITE_`, `EXPO_PUBLIC_`, `PUBLIC_`) ship values
to every user: never put a secret behind one. Work that needs a secret moves
to a server or edge function.
- Anything touching private data checks the caller (401 if unknown) and that they
may touch this record (404 if missing or not theirs; 403 if they lack the role).
Hiding a button isn't security.
- Admin features need sign-in plus a role stored in the database and checked on
the server, never a client flag or hard-coded emails or IDs.
The second rule is the one that prevents the most common hole in AI-built apps: an endpoint that checks you're logged in but not that the record is yours. Change the ID in the URL and you're reading someone else's data.
It also helps to list the things the agent must never do on its own:
Never, in any mode, unless I ask for that exact action
- Destructive commands (`rm -rf`, `git reset --hard`, `git push --force`, dropping
tables, database resets), changing a remote or production database, or disabling,
skipping or loosening tests, lint rules or type checks to get a pass.
- Installing new dependencies without my OK. Check a package's exact name before
installing (typo-squats are common).
3. Keep it in scope and stop the spiral
Most "the AI broke my project" stories are scope problems, not security ones. These lines do most of the work:
- Stay in scope: don't rename, reformat or tidy unrelated code.
- Make the smallest change; never rewrite a working file wholesale.
- Never invent APIs, packages or file paths. Check the installed version's docs.
- Debugging: reproduce, read the full error, state the likely cause, make the
smallest fix. After two failed attempts, stop and summarise the next two options.
The two-attempt limit is what stops the debugging spiral. Instead of a sixth guess, you get a summary and a choice.
For anything bigger than two files, the agent writes a short plan first and waits for your OK. If it's running as a background agent and can't ask, it puts the plan at the top of its summary instead of stalling.
4. Ask for a report you can check
Finally, tell the agent what "done" looks like:
Reply with: 1) what changed, 2) the files changed, 3) the commands you ran and
their results, 4) how I can test it, 5) "Needs your OK": anything I should
confirm, plus anything risky or unfinished.
Point 3 is the important one. "I ran npm test, 41 passed, lint couldn't run because…" is something you can trust. "Everything should work now" isn't.
Making Cursor and Claude Code load it every time
Cursor. AGENTS.md is picked up automatically, but a project rule with alwaysApply: true makes sure the security section is in every chat, even if AGENTS.md gets cut short:
---
description: Rule priority and security guardrails that apply to every task
alwaysApply: true
---
Claude Code. CLAUDE.md can import another file with @, so it stays short and repeats only the security essentials as a backup:
@AGENTS.md
AGENTS.md (imported above) holds the full project rules. This file repeats the
essentials so they still apply if AGENTS.md is missing or cut short; if they
ever differ, the security rules here win.
30-second setup
From the root of your project:
git clone --depth 1 https://github.com/theodorecreatesco/vibe-coding-rules-starter.git /tmp/vcrs
cp /tmp/vcrs/AGENTS.md /tmp/vcrs/CLAUDE.md .
mkdir -p .cursor/rules && cp /tmp/vcrs/.cursor/rules/security.mdc .cursor/rules/
Already have an AGENTS.md or CLAUDE.md? Don't overwrite it. Paste the block between the BEGIN and END markers at the top of yours.
Check it worked: start a new chat and ask "What are the top rules in this project?" It should mention the rule priority and the security guardrails. If it doesn't, the file isn't being loaded. Check it's in the project root, and for Cursor, that the .cursor folder (hidden by default) was copied.
Before you share your app
Rules reduce mistakes, they don't guarantee anything. The repo also includes a 10-point checklist to run before you share a link. A few of the checks:
- [ ] `.env` and `.env.*` are listed in `.gitignore` (and `.env.example` holds names only).
Check: `git check-ignore -q .env.local` should exit with code 0.
- [ ] Every API route, server action and edge function checks the user is logged in
- [ ] Every one also checks the user owns (or may access) the record
- [ ] Spending limits or alerts are set on paid APIs (OpenAI, Anthropic, etc.) and hosting
There's also a copy-paste "secret scan" prompt that gets your agent to check the repo (and git history, if it can) for keys, without printing the values.
Wrapping up
You don't need a huge rules file. A clear priority order, specific security rules, a scope limit and a "show me what you ran" report fix most of the damage AI coding tools do. Grab the files from vibe-coding-rules-starter, and if you improve on them, issues and PRs are welcome.
If you want versions tuned for a specific stack (Next.js + Supabase, Lovable, Bolt, FastAPI, Expo and others) with a one-command installer, I also sell a full Vibe Coding Rules Kit. The free starter works fine on its own.
Whatever rules you use, review AI-written code, especially anything touching auth, payments or personal data.
Top comments (0)