Skip to content

Rules

Rules encode durable guidance (style, testing, domain constraints). Declare them under rules, then run capa install. capa writes Cursor-style rule files where the provider has a rules directory, and folds content into the provider’s instructions file elsewhere.

TypeFields
inlinecontent
localpath (relative to the capabilities file; re-read on each install)
remoteurl
github / gitlabdef.repo (@basename or ::exact/path, with optional :tag / #sha)
FieldPurpose
idFilename stem and capa marker id
providersOptional allow-list of provider ids; omit for all active providers
appliesToGlob patterns (maps to Cursor globs, Claude Code paths, Copilot applyTo; nested instruction files for folded providers; see below)
alwaysApplyWhen true, always load the rule
descriptionFrontmatter description where supported
visibilitystrict (default) or best-effort: accept that other readers of a shared instructions file see this rule
scopestrict (default) or best-effort: accept a project-wide fold when appliesTo can’t be scoped natively
rules:
- id: code-style
type: inline
alwaysApply: true
description: Project code style guidelines
content: |
Use TypeScript strict mode. Prefer const over let.
- id: test-patterns
type: inline
appliesTo:
- '**/*.test.ts'
- '**/*.spec.ts'
description: Testing conventions
content: |
Use describe/it blocks. Prefer toBe over toEqual for primitives.
- id: typescript-standards
type: github
def:
repo: my-org/standards::rules/typescript.md
providers:
- cursor

Prefer :: for rules when you know the file path: installs fail loudly if the file moves. Use @basename only when the basename is unique in the repo.

Provider shapeWhat capa writes
Rules directory (e.g. Cursor → .cursor/rules/)Separate rule file with YAML frontmatter (description, globs, alwaysApply): Cursor uses .mdc
No rules directory (e.g. Codex, Gemini CLI, OpenCode)Rule body folded into the provider’s instructions file as a capa-managed marker block

capa clean removes capa-installed rules. Hand-authored provider rules are left alone.

Several providers read the same instructions file: Codex, Cursor, OpenCode, Gemini CLI, and many others read AGENTS.md. A folded rule in that file is visible to every provider that reads it, whatever its providers list says. Which file each provider reads depends only on the active providers, so capa plans placement up front:

  • Gemini CLI reads AGENTS.md when it is the only active provider that does. When another active provider also reads AGENTS.md, capa moves Gemini onto a generated GEMINI.md (agent snippets plus the rules Gemini may see), so rules targeted at other providers don’t reach it.
  • capa adds that file to .gemini/settings.json → context.fileName, keeping Gemini’s GEMINI.md default and any entries you added. What capa added is recorded in capabilities.lock, and capa clean (or dropping gemini-cli from providers) removes only those values.
  • Any other provider-restricted rule that would still be read by an excluded provider through a shared file (for example a Codex-only rule while Cursor also reads AGENTS.md) is a visibility conflict.

Providers without a rules directory can’t attach a rule to globs, so capa maps appliesTo onto instruction files:

appliesToWhat capa does
Omitted, alwaysApply: true, or match-all (**, **/*)Folds the rule into the root instructions file
Directory glob (src/**, packages/api/**/*)Writes the rule into a nested file (src/AGENTS.md, src/GEMINI.md) for providers that read nested instruction files (Codex, Gemini CLI). The directory must already exist.
Any other glob (**/*.py), or a directory glob when a targeted folding provider doesn’t read nested filesFolds the rule at the root with an > Applies to: note: a scope conflict
Glob outside the project (absolute path or ..)Ignored and reported

capa install reports visibility and scope conflicts before it prunes or writes any rule files. options.rules.conflicts decides what happens next:

ValueBehavior
warnInstalls the rule and prints a warning
errorSkips the rule for every provider (rules directories included) and records an install failure; under onInstallError: stop the install aborts

When conflicts is unset, it defaults to warn, or error when options.onInstallError is stop. In error mode the message says the rule was skipped.

To accept a conflict for one rule, opt in on the rule itself:

options:
rules:
conflicts: error
rules:
- id: codex-review
type: inline
providers: [codex]
visibility: best-effort # OK if other AGENTS.md readers see it too
content: |
Run the review checklist before proposing a patch.
- id: python-style
type: inline
appliesTo: ['**/*.py']
scope: best-effort # fold at the root with an "Applies to" note
content: |
Follow PEP 8. Use type hints on public functions.