Rules
Rules (opens in a new tab) are short Markdown files Claude loads into its context. A rule’s frontmatter paths: field decides when it loads: when Claude reads or edits a file matching one of those file patterns, the rule loads. A rule with no paths: field loads at the start of every session.
Rules are guidance Claude reads; nothing forces Claude to follow them. Anything that must always hold, whatever Claude decides, is enforced by hooks, the commit hooks, and the merge audit.
GAIA ships rules in two places:
.claude/rules/at the root: rules for the whole repository. Their file patterns are relative to the repository root.frontend/.claude/rules/: rules for the React app. They load when the work is underfrontend/, and their file patterns are relative tofrontend/.
Always loaded (root)
Section titled “Always loaded (root)”| Rule | What it enforces |
|---|---|
coding-guidelines | Kebab-case files and folders. Keep code simple: no handling for situations that cannot happen, but real failures are handled with limits. Change only what the task needs. Use TDD. Leave formatting and auto-fixable lint to pnpm lint. React file layout lives in coding-guidelines-react. |
context-discipline | Keep the main session’s context small by handing reading-heavy work to sub-agents. Choose models from GAIA’s model table. Research goes in .notebook/research/<date>-<topic>/. Long work resumes from one STATE.md file. |
fenced-copy-paste-blocks | Anything meant for you to paste goes, whole, in its own plain three-backtick fence, never in prose or a blockquote, so Claude Code shows it with a copy button. A handoff prompt carries its own context instead of pointing back at the session. |
issue-claim | Before work that closes a GitHub issue, check for the in-progress label and add it. Release it when Claude closes the pull request unmerged or you drop the work. Follow the work lifecycle. Claim tech-debt issues only through /gaia-debt. |
pr-merge | Before any gh pr merge, run the audit and post GAIA-Audit as the last step. The audit loop runs on its own until it reaches the branch checkpoint, which only you can answer. |
quality-gate | Run the Quality Gate before any commit that touches source, unless nothing in the gate’s scope is staged. |
shell-cwd | No cd in Bash calls; use absolute paths. Each hook finds its script from the checkout the shell is in, so a cd into another checkout can switch the guards off without any warning. See Hooks. |
subagent-dispatch | Claude re-runs a sub-agent that returned nothing, instead of reading silence as “found nothing”. |
Path-scoped (root)
Section titled “Path-scoped (root)”| Rule | What it enforces | Loads on |
|---|---|---|
ambient-context-resolution | Applies when Claude writes shell scripts or GitHub workflows: a script gets the repository root, base branch, and commit from its input, not from the current folder or HEAD. The last two patterns match files a GAIA project does not ship (TypeScript under .gaia/ and bats test suites), so they apply only if you add such files. | .gaia/scripts/**/*.sh, .claude/hooks/**/*.sh, .github/workflows/**/*.yml, .gaia/**/*.ts, **/*.bats |
code-comments | A comment says something the code itself does not; the merge audit checks comments by the same standard. | app, test, Playwright (opens in a new tab), and Storybook (opens in a new tab) source under frontend/, .gaia/**/*.ts and .sh, .claude/hooks/**/*.sh, .github/**/*.sh, and **/*.bats |
file-placement | New hooks go at the root of .claude/hooks/, and how to register one so it keeps working. Project scripts go outside .gaia/, never in .gaia/scripts/. | .claude/hooks/**, .gaia/scripts/** |
generated-files | Names the source to change for a file GAIA or pnpm generates. For frontend/.claude/settings.json: the root .claude/settings.json or the frontend overlay, then regenerate. For pnpm-lock.yaml: pnpm commands, never a hand edit. | frontend/.claude/settings.json, pnpm-lock.yaml |
guards-must-fail | A guard and its tests must be seen failing before anyone trusts them. | hooks, scripts, workflows, and Playwright specs |
no-abbreviations | Descriptive names in every language, alongside the naming-conventions skill. | code files in any language |
user-questions | Ask a choice as an AskUserQuestion menu: recommended option first, at most four options, one question per decision. A list of review findings, each with its own recommendation, is one decision: every finding prints as text, then one question asks Accept all as recommended or Revise. | skills, commands, and agents (root and frontend/), plus a few wiki pages about the merge workflow and the Quality Gate |
wiki-style | Present-tense prose; no historical phrasing or roadmap stated as current; no SPEC, PR, or commit references in body prose. | wiki/**/*.md and the Markdown files for skills, commands, agents, and rules |
working-doc-ids | No SPEC, plan, or audit IDs, no paths to one machine’s notebook or .gaia/local/ entries, and none of your own issue or PR numbers, in code or prose. Hooks also enforce most of this (gate). | app, test, and harness source |
Frontend (frontend/.claude/rules/)
Section titled “Frontend (frontend/.claude/rules/)”| Rule | What it enforces | Loads on |
|---|---|---|
accessibility | Keyboard reachability, alt text, focus management, semantic HTML over ARIA roles, color never the only indicator. | app/components/**, app/pages/** |
api-service | Points Claude to the API Service Pattern and the new-service skill. | app/services/**, test/mocks/** |
coding-guidelines-react | React file and folder layout and naming: kebab-case folders, index.tsx, use-<name>.ts hooks, tests/ folders. | app/**, test/**, .playwright/**, .storybook/** |
design-baseline | GAIA’s neutral styling is a placeholder, not a design system; confirm the design direction before extending tokens. | app/styles/**, app/components/**, app/pages/** |
i18n | Every user-facing string comes from t(); namespace and key-file conventions; which steps to follow to add a language or remove i18n. | app/routes/**, app/pages/**, app/components/**, app/languages/** |
playwright | Spec layout, semantic selectors, web-first assertions, the hydration helper, MSW (opens in a new tab) in dev. | .playwright/**, playwright.config.* |
ports | Each checkout owns its dev, Storybook, and Playwright ports. Claude reads them from GAIA’s ports script and never hardcodes 5173 or 6006. | Test, Playwright, Storybook, and server config files, and package.json |
react-router-docs | Read the React Router (opens in a new tab) docs in node_modules/react-router/docs, which match the installed version, and check remix-utils before writing a basic utility from scratch. | routes, pages, app/root.tsx, middleware |
routes | Thin route files (loader, action, meta, one-line page render); UI in app/pages/. | app/routes/**, app/pages/** |
shadcn-ui | The ui components copied in from shadcn/ui (opens in a new tab) are not edited; add components with pnpm shadcn add. | app/components/ui/** |
state-pattern | Context lives in app/state/, with Provider, useX, and useMaybeX naming. | app/state/** |
storybook | Story location and typing, titles, decorator order, layout, and Chromatic (opens in a new tab) light and dark modes. | app/**/*.stories.tsx, .storybook/** |
tailwind | Use the role-based color tokens (named for their purpose, not their color), never raw palette classes or arbitrary colors. Tailwind (opens in a new tab) v4 config lives in CSS. | app/**/*.tsx, app/**/*.css |
Adding your own
Section titled “Adding your own”Ask Claude to write the rule for you. Say what the rule should make Claude do, and which files it applies to, so Claude can scope it with a paths: pattern:
Add a Claude Code rule that <what Claude should always do>. It applies when working on <which files, for example frontend/app/services/**>. Scope it with a paths: pattern, and keep it short.A rule for the whole repository goes under .claude/rules/. A rule that only applies to the app goes under frontend/.claude/rules/, with patterns relative to frontend/. Leave out paths: only when the rule truly needs to load in every session, because an always-loaded rule uses up context in every session.
/gaia-codify writes path-scoped rules from recurring audit findings, and /gaia-cleanse and /gaia-fitness keep rules lean.