---
name: lean-project-instructions
description: >
  Use whenever a user wants to set up AI coding assistant instructions for their project.
  Triggers: "add a CLAUDE.md", "set up Copilot instructions", "configure Cursor rules",
  "write Windsurf rules", "add AI instructions to my repo", "configure Claude for this
  codebase", or any mention of .cursorrules, copilot-instructions.md, .windsurfrules,
  or CLAUDE.md. Also trigger when creating or updating any project rules file for AI
  coding tools, even if the user doesn't name the file format. Generates lean,
  caveman-compressed instruction files for one or more platforms. Only durable,
  non-inferable rules get written down.
---

# Lean Project Instructions

Generate lean instruction files for AI coding assistants. One canonical rule set, written
to whichever platform files the user needs. Caveman-compress everything before writing.

> **If the AI can read the codebase and figure it out, don't write it down.**

---

## Platform Files

| Platform | File path | Notes |
|---|---|---|
| Claude Code | `CLAUDE.md` | Root of repo; markdown sections |
| GitHub Copilot | `.github/copilot-instructions.md` | Injected into every request; keep short |
| Cursor | `.cursor/rules/project.mdc` | MDC format; supports frontmatter filters |
| Windsurf | `.windsurfrules` | Plain markdown; same constraints as Copilot |
| Aider | `CONVENTIONS.md` + `.aider.conf.yml` read entry | Or pass via `--read` flag |

Ask which platforms the user wants. Default to `CLAUDE.md` only if unspecified.

---

## Step 1 — Gather context

Ask only what you can't read from the codebase:

1. Which platforms? (CLAUDE.md, Copilot, Cursor, Windsurf, Aider — or all?)
2. Existing instruction files? Read them first; treat this as a revision if so.
3. Branching / PR / code review rules the team follows?
4. Sensitive areas — files or modules needing explicit approval to touch?
5. Architectural decisions made for non-obvious reasons?
6. Team conventions not enforced by linters or formatters?

Don't ask about tech stack, commands, or file structure — read those from the repo.

---

## Step 2 — Draft the canonical rule set

Apply the core filter before writing any rule:

**Keep if**: non-obvious OR high-consequence if missed.  
**Drop if**: inferable from files AND low-consequence.

### Always omit
- Stack, language, framework (visible in package.json, pyproject.toml, etc.)
- File structure and naming (visible by listing repo)
- Lint/format rules (visible in config files)
- Build/install/run commands (visible in Makefile, package.json scripts, CI)
- Absence of tools ("no test runner" — the AI sees the absence)

### Always include
- Runtime footguns: `"mixing zod/v4 and zod imports in one file breaks at runtime"`
- Intentional config that looks wrong: `` `strictFunctionTypes: false` is intentional ``
- Generated files: `"never edit generated/; change spec, re-run codegen"`
- Env asymmetry: `"CI auto-migrates; local does not — run db:push after schema pull"`
- Security decisions: `"access token in memory only; never localStorage"`
- Domain invariants: `"tenantId=null = system user; all queries must scope by tenant"`
- Conventions not in tooling: `"tests live next to source, not in __tests__/"`
- Branching / PR policy not documented elsewhere
- Scope limits: `"don't refactor adjacent code without asking"`

### Anti-patterns — reject politely and explain why
| If user wants to add... | Because... |
|---|---|
| "We use TypeScript" | Visible from tsconfig.json |
| "Run npm install" | Standard; visible from package.json |
| "Files go in src/" | Visible from repo structure |
| "We use Prettier" | Visible from .prettierrc |
| "No test runner configured" | AI sees the absence; don't narrate it |

---

## Step 3 — Caveman compress

Apply to all content before writing any file. Strip to signal — the AI needs rules, not backstory.

**Drop:**
- Articles: a / an / the
- Filler: just / really / basically / actually / simply / essentially
- Hedging: "try to", "ideally", "where possible" — unless behavior is genuinely optional
- Motivational framing: "Please remember to...", "It's important that...", "Make sure to..."
- Org justifications: "This is a KPI", "this builds trust", consequence explanations that
  don't narrow the rule's scope

**Keep but compress — never drop:**
- Rules: "always X", "never Y", "must Z"
- Scope qualifiers that prevent misapplication
- Definitions of vague terms in a rule

**Rewrite rules:**
- Fragments OK: `"Run tests before push"` not `"You should always make sure to run tests before pushing"`
- Short synonyms: big not extensive, fix not "implement a solution for", use not utilize
- Pattern: `[thing] [action] [qualifier].`
- Merge bullets that say the same thing two ways

**Never touch:**
- Code blocks, inline code, URLs, file paths, commands, env vars, library/API names

---

## Step 4 — Write platform files

Content is the same compressed rule set across all platforms — only path and wrapper differ.

**Cursor MDC format** (`.cursor/rules/project.mdc`) — wrap in frontmatter:

```
---
description: Project coding rules
alwaysApply: true
---
[compressed content]
```

**Aider** — write `CONVENTIONS.md` with compressed content, then add to `.aider.conf.yml`:

```yaml
read:
  - CONVENTIONS.md
```

All other platforms: plain markdown, no wrapper.

---

## Output structure

Use only sections with real content. Omit empty ones.

```markdown
## Working Style
## Sensitive Areas
## Conventions Not Enforced by Tooling
## Architecture Decisions
## Runtime Gotchas
## Workflow Rules
```

- Short imperative sentences. "Avoid X." not "You should try to avoid X if possible."
- Max 5 bullets per section — split or cut if more.
- Target under 40 lines total. One screen beats two.
- No "Tech Stack" or "Project Overview" section.

---

## Example output (post-compression)

```markdown
## Working Style
- Scope to task. No adjacent refactors unless asked.
- Small focused PRs. Flag creep before continuing.

## Sensitive Areas
- `src/billing/` — audited. No edits without explicit approval.
- `migrations/` — never edit existing; always create new.

## Conventions Not Enforced by Tooling
- Dep versions in `pnpm-workspace.yaml` catalog. Not in individual package.json.
- Tests next to source. Not in `__tests__/`.

## Architecture Decisions
- No ORM. Raw SQL in `src/db/`. Intentional for query transparency.
- `generated/` = codegen output. Never hand-edit; change spec, re-run codegen.
- `strictFunctionTypes: false` intentional. Don't change.
- Access token in memory only; refresh in `sessionStorage`. Not localStorage.

## Runtime Gotchas
- Mixed `zod/v4` + `zod` imports in one file = runtime break. Keep consistent per package.
- Local dev: schema changes not auto-applied. After pull: `pnpm --filter @workspace/db run push`.
```
