# AI-Rulez > The standards-compliant lifecycle tool for agent knowledge and capabilities: author, generate, bundle, validate, govern, publish ## Home Source: https://goldziher.github.io/ai-rulez/
`, never rendered.
- **Content-Security-Policy.** Each page carries `default-src 'none'; img-src 'self' data:; style-src 'self';
script-src 'self'; base-uri 'none'; form-action 'none'` in a meta tag, and no inline script or style. A host
should send the same as response headers plus `frame-ancestors 'none'`, which a meta tag cannot set.
- **Output directory.** It must be new, empty or contain the marker `.ai-rulez-catalog` (written by an earlier run,
listing each file it wrote with its SHA-256). `--clean` removes only a listed file that has the shape of a
site file (`index.html`, `items/`, `roles/`, `assets/`, `catalog.json`, ...) and still holds the recorded bytes;
without the marker the run is refused, so `--html .` cannot overwrite a project, and a directory with a `.git` or
`.ai-rulez` folder is always refused. The marker is written before the files, so an interrupted run leaves the
directory marked. Writes never follow a symlink out of the directory.
- **Secrets.** The run is refused when the secret scanner (`AR001`) flagged an item and the site would publish its
excerpt or description; remove the secret, or pass `--allow-findings AR001` (discouraged). The published description and excerpt are also scanned
directly, so a lint that did not run, a baselined finding or an inline ignore does not let a secret through.
##### Configuration and pages
```toml
[catalog]
title = "Acme catalog" # site title (--base-title)
include_excerpt = true # body excerpts (--include-excerpt); default on, off when indexable
exclude_owners = false # leave owner names out of the JSON and the site (--no-owners)
indexable = false # let search engines in (--indexable)
max_items_per_page = 200 # overview rows per page (--max-items-per-page); 0 means 200
render_markdown = false # render excerpts as sanitized Markdown (--render-markdown)
```
Every key is optional and a flag that is given wins. `include_excerpt` and `exclude_owners` also apply to
`--format json --schema-version 2`. The `[catalog]` table can be overridden in the machine-local config.
The overview lists `max_items_per_page` rows per page. All rows are in the one `index.html` (one `` per page),
so browsing, find-in-page and the no-JavaScript view show everything; the script shows one page at a time with
Previous/Next buttons and shows every page while a filter is active. The page size does not change `catalog.json`.
##### Markdown excerpts
`--render-markdown` (or `render_markdown = true`) shows each item's excerpt as formatted Markdown instead of plain
text. The renderer is a sanitizer by construction, not by filtering: the text is parsed as CommonMark and turned into
a tree whose nodes are only paragraphs, headings (shifted to `h3`-`h6`, below the page's own headings), lists, quotes,
code blocks, emphasis, code spans, line breaks and rules. The tree has no field that holds markup, and the page is
built from it by `html/template`, so every character of the body is escaped.
- Raw HTML (block or inline, comments included) is shown as literal text, never interpreted.
- Links are not anchors: the label is kept and the destination is shown as text after it, so a `javascript:`,
`data:` or remote URL never becomes an `href`. Images show their alt text and the destination as text; nothing is
loaded.
- Depth is capped at 12 levels and the tree at 4,000 nodes (a notice says so), so a hostile body cannot recurse or
inflate the page.
- The Content-Security-Policy stays as strict as before; the Markdown view needs no script and no new source.
The excerpt is still the first 2 KiB of the body, so a long document is cut mid-structure. Excerpts are off with
`--indexable` unless asked for.
##### Freshness check
```bash
ai-rulez catalog --html site/ --check
```
Renders the site in memory and compares it with the directory without writing anything. Exit `0` when every file
matches and nothing else is there, `2` when a file is changed, missing or unexpected (the differences are listed),
`1` when the check could not run. A directory that does not exist is drift. Because the output is reproducible, the
same gate detects a tampered hosted copy. Use it in CI to keep a committed site current; `--check` and `--clean` do
not combine. Files are read through the directory only: a symlink in it is reported, never followed.
Flags: `--role R` (items role `R` keeps), `--include-excerpt` (default on), `--indexable` (no `robots.txt`, no
`noindex`; excerpts default off), `--clean`, `--base-title T`, `--allow-findings`, `--render-markdown`, `--max-items-per-page`, `--no-owners`, `--check`, `--with-eval[=FILE]`, `--with-usage[=FILE]`.
A published catalog exposes names, descriptions, owners, token costs and lint findings: treat it like the
configuration directory it describes.
#### Browser tests
`go test ./internal/catalogsite` also runs the site in a real headless Chrome or Chromium when one is installed
(`AI_RULEZ_CHROME` names the executable; `-short` skips them; they skip on their own when no browser is found or it
does not start). The harness speaks the DevTools protocol over `--remote-debugging-pipe`, so it needs no module and no
WebSocket. It opens every page of a rich and of a hostile fixture site from `file://` and requires zero
Content-Security-Policy violations (recorded by a `securitypolicyviolation` listener the protocol injects), no console
error or warning, no uncaught exception, no JavaScript dialog, no inline script or style, and no request outside the
file system. It then filters, pages and navigates (overview, item, graph, MCP pages), and a control test injects an
inline script to prove the policy blocks it, so a zero count is not vacuous. The client itself is also tested against a
fake browser on every machine.
#### Design decisions
- **Builder stays in `internal/govview`.** The issue names `internal/catalog`; the builder already lives in
`internal/govview` next to the roles and lock views that the CLI and the MCP tools share, and renaming would touch
every caller for no behaviour change. The renderer is a separate package, `internal/catalogsite`.
- **Dual emit.** Version 1 is the default and `--schema-version 2` opts in (the issue's proposed answer). The HTML
command always builds version 2.
- **Excerpt default.** On locally, off with `--indexable` (the issue's proposal); `--include-excerpt` overrides.
- **Secret check reuses `AR001`.** No new rule code.
- **Lint at the configured level.** Findings come from the in-process lint engine with the project's `[lint]`
settings, not the strict level.
- **No `catalog-data.js`.** The pages are server-rendered and the filter reads the table rows, so a second copy of the
data is not needed; `catalog.json` is the machine contract.
- **Approval.** The overview has an Approval column (the status, or `not required`); the item page shows the status with
`(required)`, the reviewers, their assurance level and the expiry, escaped like every other value.
- **Pagination is presentational.** All rows are in `index.html` in groups of `max_items_per_page`; the script pages them. Real per-page files would break filtering across pages and find-in-page.
#### Not yet built
`--no-lint-messages`, `--link-sources`, `--single-file`, a `catalog diff` page and approval or signature attestations
in the diff remain from the design.
## Monorepo
Source: https://goldziher.github.io/ai-rulez/monorepo/
For large projects with multiple teams, organize your `.ai-rulez/` configuration using domains and profiles to provide relevant context while avoiding overwhelming AI assistants with irrelevant information.
This guide outlines best practices for managing AI context at scale.
---
#### The Core Strategy: Domain-Based Organization
The most effective strategy for large projects is to organize related rules, context, and skills into domains. Each domain represents a team, service, or feature area.
!!! success "The Goal: High-Relevance, Low-Token Context"
By organizing into domains and using profiles, you provide your AI assistant with only the context it needs for the task at hand. A developer working on the frontend gets frontend-specific rules and context, while the backend developer gets API patterns and database standards. This results in faster, more accurate, and more relevant AI responses.
!!! info "Domains and Profiles"
- **Domains** organize content by team, service, or feature (`backend`, `frontend`, `mobile`)
- **Profiles** select which domains are included in generation (`full`, `backend-team`, etc.)
A typical layout might look like this:
```text
my-project/
└── .ai-rulez/
├── config.toml # ⬅️ Main config: presets, profiles, domains
├── rules/ # ⬅️ Shared rules (all teams)
├── context/ # ⬅️ Shared context (all teams)
├── skills/ # ⬅️ Shared skills (all teams)
└── domains/
├── backend/ # ⬅️ Backend team content
│ ├── rules/
│ ├── context/
│ └── skills/
├── frontend/ # ⬅️ Frontend team content
│ ├── rules/
│ ├── context/
│ └── skills/
└── qa/ # ⬅️ QA team content
└── rules/
```
When you run `ai-rulez generate --profile backend`, it includes root content plus backend-specific content.
---
#### Best Practice: Root Configuration
Your root `.ai-rulez/` should contain high-level, cross-cutting concerns that apply to all teams.
!!! tip "What to put in Root Content"
- **System Architecture:** High-level overview of the tech stack and service interactions
- **Cross-Cutting Concerns:** Rules that apply everywhere (security, logging, error handling)
- **General Standards:** Code quality, testing, git workflow, deployment processes
- **Base Skills:** Shared AI skills used by all teams
**`.ai-rulez/config.toml`:**
```toml
version = "5.0"
name = "My Full-Stack Project"
description = "Microservices project with React frontend and Go backend"
presets = ["claude", "cursor", "gemini"]
default = "full"
gitignore = true
[profiles]
full = ["backend", "frontend", "qa"]
backend = ["backend", "qa"]
frontend = ["frontend", "qa"]
qa = ["qa"]
```
**`.ai-rulez/context/architecture.md`:**
```markdown
# System Architecture
This is a microservices project with:
- Go backend services
- React web frontend
- PostgreSQL databases
- Kubernetes orchestration
```
**`.ai-rulez/rules/security.md`:**
```markdown
---
priority: critical
---
# Security Standards
- All secrets use environment variables
- Validate all user input
- Use HTTPS for external APIs
```
**`.ai-rulez/rules/git-workflow.md`:**
```markdown
---
priority: high
---
# Git Workflow
- Feature branches from main
- Squash commits before merge
- All PRs require code review
```
#### Best Practice: Domain-Specific Content
Domain directories contain specific, detailed context for that team or service.
!!! tip "What to put in Domain Content"
- **Technology Patterns:** Concrete examples for frameworks and libraries
- **Domain Logic:** Business rules specific to that service or feature
- **Domain Skills:** Specialized AI prompts for that team's expertise
**`.ai-rulez/domains/backend/rules/database.md`:**
```markdown
---
priority: critical
---
# Database Standards
- Use prepared statements to prevent SQL injection
- Always add migrations for schema changes
- Index foreign keys
```
**`.ai-rulez/domains/backend/rules/api-design.md`:**
```markdown
---
priority: high
---
# API Design
- Follow RESTful principles
- Use consistent error responses
- Version APIs from the start
```
**`.ai-rulez/domains/backend/context/architecture.md`:**
```markdown
# Backend Architecture
## Services
- API Gateway (Go, port 8000)
- User Service (Go, port 8001)
- Product Service (Go, port 8002)
- Order Service (Go, port 8003)
## Database
- PostgreSQL 14+
- Replication enabled
- Automated daily backups
```
**`.ai-rulez/domains/backend/skills/database-expert/SKILL.md`:**
```markdown
---
priority: high
description: "Database design and optimization specialist"
---
# Database Expert
You are an expert in PostgreSQL with knowledge of:
- Schema design and normalization
- Query optimization
- Performance tuning
```
**`.ai-rulez/domains/frontend/rules/components.md`:**
```markdown
---
priority: high
---
# Component Guidelines
- One component per file
- Use TypeScript for type safety
- Write unit tests for all components
- Use composition over inheritance
```
**`.ai-rulez/domains/frontend/context/design-system.md`:**
```markdown
# Design System
## Color Palette
- Primary: #3B82F6
- Secondary: #8B5CF6
- Neutral: #6B7280
## Typography
- Headings: Inter Bold
- Body: Inter Regular
```
#### Best Practice: Profile Selection
Design profiles to match your team structure and workflows.
```toml
[profiles]
# Full platform: all content
full = ["backend", "frontend", "qa", "devops"]
# Team-specific
backend-team = ["backend", "qa"]
frontend-team = ["frontend", "qa"]
qa-team = ["qa"]
devops-team = ["devops"]
# Full-stack developers
full-stack = ["backend", "frontend", "qa"]
# CI/QA environment
ci-cd = ["backend", "frontend", "qa", "devops"]
```
#### Best Practice: For Monorepos
If using multiple `.ai-rulez/` directories in a monorepo, use the `--recursive` flag:
```bash
# Process all .ai-rulez/ directories recursively
ai-rulez generate --recursive
```
**Root configuration** (`/.ai-rulez/config.toml`):
```toml
version = "5.0"
name = "Monorepo Platform"
presets = ["claude", "cursor"]
default = "full"
[profiles]
full = ["shared"]
```
**Service-specific** (`/backend/.ai-rulez/config.toml`):
```toml
version = "5.0"
name = "Backend Service"
presets = ["claude"]
default = "backend"
[profiles]
backend = ["api", "database"]
```
By combining domain organization with thoughtful profile design, you can create scalable, maintainable configurations that grow with your project.
---
#### Scoped Rule Files
For `[[scopes]]` (see [Configuration](configuration.md#scopes)), root files such as `CLAUDE.md` stay in the scope directory, but native rule files are written to the **root** rules folder, because tools read rules folders at the workspace root only. Each scope's files get the scope path as a qualifier and as a glob prefix:
| Preset | Scoped rule file for `packages/api`, rule `style` |
| --- | --- |
| Claude | `.claude/rules/packages-api/style.md` |
| Cursor | `.cursor/rules/packages-api/style.mdc` |
| Copilot | `.github/instructions/packages-api/style.instructions.md` |
| Devin, Cline, Junie | `/packages-api--style.md` |
| Antigravity | `.agents/rules/packages-api--style.md` |
Globs in a scope's rules are relative to the scope root: a rule with `paths: ["**/*.go"]` gets `packages/api/**/*.go`, and a rule without globs applies to `packages/api/**`. A rule with only negated globs also gets `packages/api/**`. A glob that climbs out of the scope with `..` (also inside braces) skips that rule for the scope with a warning. `auto` and `manual` rules keep their mode. With `[rules] mode = "inline"` only path-scoped items move to the root folder; everything else stays in the scope's root file. Two files that map to the same path (names compare case-insensitively) do not fail: the source that sorts later is written as `-<6 hex>` with a warning (see [File names](rules.md#file-names)). Generation fails only when two scopes produce the same qualifier (for example `packages/api` and `packages-api`); rename one of the scope paths.
Limitations:
- Root files left in a scope (`CLAUDE.md`, `AGENTS.md`, `GEMINI.md`, ...) are read by tools that load nested files. Copilot (`.github/copilot-instructions.md`) reads its instructions at the repository root only, so rules or context that stay inline in a scope's copy are never loaded; generation warns and names them. Use path-scoped rules or `[rules] mode = "split"` for that preset.
- Domains the root run already renders are not repeated in a scope.
- Presets without split rule files (custom provider specs with a non-split `outputs.rules`) keep a scope's rules in the scope directory; generation warns.
## Examples
Source: https://goldziher.github.io/ai-rulez/examples/
ai-rulez uses a file-based directory structure (`.ai-rulez/`) with TOML configuration. These examples show how to organize your configuration across multiple markdown files and a `config.toml` file.
---
#### 1. Minimal Configuration (Single Team)
The simplest setup for a single team with basic rules.
**`.ai-rulez/config.toml`:**
```toml
version = "5.0"
name = "My Project"
presets = ["claude", "cursor"]
gitignore = true
```
**`.ai-rulez/rules/code-quality.md`:**
```markdown
---
priority: high
---
# Code Quality
- Use meaningful variable names
- Comment complex logic
- All tests must pass before merge
```
**`.ai-rulez/context/architecture.md`:**
```markdown
# Architecture
This is a monolithic application with:
- PostgreSQL database
- REST API backend
- React frontend
```
##### Generated Output
```bash
ai-rulez generate
# Creates:
# - CLAUDE.md (context and agent roster)
# - .claude/rules/code-quality.md (the rule, under the default split mode)
# - .cursor/rules/ (one .mdc file per rule and context item)
```
---
#### 2. Multi-Team Configuration with Domains
For projects with multiple teams, use domains to organize team-specific content.
**`.ai-rulez/config.toml`:**
```toml
version = "5.0"
name = "Platform"
presets = ["claude", "cursor", "gemini"]
default = "full"
gitignore = true
[profiles]
full = ["backend", "frontend", "qa"]
backend = ["backend", "qa"]
frontend = ["frontend", "qa"]
qa = ["qa"]
```
**`.ai-rulez/rules/security.md`:**
```markdown
---
priority: critical
---
# Security
- All secrets must use environment variables
- Validate all user input
- Use HTTPS for all external API calls
```
**`.ai-rulez/domains/backend/rules/database.md`:**
```markdown
---
priority: critical
---
# Database Standards
- Use prepared statements to prevent SQL injection
- Always add database migrations
- Index foreign keys for performance
```
**`.ai-rulez/domains/frontend/rules/components.md`:**
```markdown
---
priority: high
---
# Component Guidelines
- One component per file
- Use TypeScript for type safety
- Write unit tests for all components
```
##### Generated Output
```bash
# Generate for backend team
ai-rulez generate --profile backend
# Includes: root rules + backend-specific rules
# Generate for frontend team
ai-rulez generate --profile frontend
# Includes: root rules + frontend-specific rules
# Generate for QA
ai-rulez generate --profile qa
# Includes: root rules + QA-specific rules
```
---
#### 3. Using Skills for Specialized Roles
Create AI skill definitions for specialized tasks.
**`.ai-rulez/skills/code-reviewer/SKILL.md`:**
```markdown
---
priority: high
description: "Code reviewer for quality assurance"
---
# Code Reviewer
You are an expert code reviewer with deep knowledge of:
- Code quality and maintainability
- Testing best practices
- Performance optimization
## Your Responsibilities
1. Review pull requests for correctness
2. Suggest improvements and refactoring
3. Verify test coverage
```
**`.ai-rulez/skills/architecture-expert/SKILL.md`:**
```markdown
---
priority: high
description: "System architecture specialist"
---
# Architecture Expert
You are a system architect specializing in:
- Microservices design
- Scalability patterns
- System reliability
## Your Responsibilities
1. Review architectural decisions
2. Suggest performance improvements
3. Identify technical debt
```
##### Usage in Generated Files
Each skill is written as its own file, for example `.claude/skills/code-reviewer/SKILL.md` and
`.claude/skills/architecture-expert/SKILL.md`. The assistant reads the skill's `description` and loads
the body when the task matches; nothing is added to `CLAUDE.md` for it.
---
#### 4. Complex Project with Multiple Presets
For projects that need different output formats for different tools.
**`.ai-rulez/config.toml`:**
```toml
version = "5.0"
name = "ML Research Platform"
description = "Machine learning platform with team separation"
presets = [
"claude",
"cursor",
"gemini",
"devin",
{ name = "internal-guide", type = "markdown", path = "docs/AI_DEVELOPMENT_GUIDE.md" },
]
default = "full"
gitignore = true
[profiles]
full = ["research", "infrastructure"]
research = ["research"]
infrastructure = ["infrastructure"]
```
**`.ai-rulez/domains/research/rules/ml-standards.md`:**
```markdown
---
priority: critical
targets: ["CLAUDE.md", "GEMINI.md"]
---
# ML Development Standards
- Use type hints for all functions
- Document mathematical assumptions
- Include reproducibility seeds
```
**`.ai-rulez/domains/infrastructure/rules/deployment.md`:**
```markdown
---
priority: high
targets: ["CLAUDE.md", ".cursor/rules/"]
---
# Deployment Standards
- All changes require review
- Run tests before deployment
- Keep infrastructure as code
```
---
#### 5. Project with Frontmatter and Custom Fields
Markdown files can include YAML frontmatter with custom fields.
**`.ai-rulez/rules/testing.md`:**
```markdown
---
priority: critical
author: qa-team
tags: [testing, quality, ci-cd]
review_date: 2025-01-15
targets:
- "CLAUDE.md"
- ".cursor/rules/"
---
# Testing Standards
## Unit Tests
All code changes must include corresponding unit tests.
- Aim for 80%+ code coverage
- Use table-driven tests for Go
- Test both happy path and error cases
## Integration Tests
Test service interactions:
- Database operations
- API endpoints
- External service calls
```
---
#### 6. Monorepo with Shared Rules
For larger projects, reuse configurations across subdirectories.
**`/.ai-rulez/config.toml`** (Root config):
```toml
version = "5.0"
name = "Platform"
presets = ["claude", "cursor"]
default = "full"
[profiles]
full = ["shared"]
```
**`/backend/.ai-rulez/config.toml`** (Backend-specific):
```toml
version = "5.0"
name = "Backend Service"
presets = ["claude", "cursor"]
default = "backend"
[profiles]
backend = ["api", "database"]
```
**`/backend/.ai-rulez/domains/api/rules/endpoints.md`:**
```markdown
---
priority: high
---
# API Endpoint Guidelines
- Use consistent path structure
- Version APIs from the start
- Return consistent error responses
```
##### Generation
```bash
# From root, processes all .ai-rulez/ directories recursively
ai-rulez generate --recursive
```
---
#### 7. Environment-Specific Profiles
Use profiles for different deployment environments.
**`.ai-rulez/config.toml`:**
```toml
version = "5.0"
name = "Web Application"
presets = ["claude"]
[profiles]
development = ["dev-guidelines"]
staging = ["staging-checks", "security-checks"]
production = ["production-critical", "security-hardened", "compliance"]
```
**`.ai-rulez/domains/dev-guidelines/rules/debugging.md`:**
```markdown
---
priority: medium
---
# Development Guidelines
- Enable verbose logging in dev
- Use debug endpoints for testing
- Performance is less critical than clarity
```
**`.ai-rulez/domains/production-critical/rules/reliability.md`:**
```markdown
---
priority: critical
---
# Production Standards
- All deployments require approval
- Monitor error rates in production
- Implement circuit breakers for external services
```
##### Usage
```bash
# Generate for development
ai-rulez generate --profile development
# Generate for production
ai-rulez generate --profile production
```
## Supported Harnesses
Source: https://goldziher.github.io/ai-rulez/harnesses/
ai-rulez ships 52 built-in presets, one per AI coding harness. The table below lists them; `ai-rulez init` also writes the list into a comment in the new `config.toml`. Each preset
writes the harness's own layout: file names, frontmatter, directories and settings documents. For a harness that
is not listed, use a [provider-backed custom preset](configuration.md#provider-backed-presets-full-parity).
The shared `mcp` preset (the root `.mcp.json`) is not a harness and is not in the table.
#### Feature matrix
`yes` means the preset writes that output at project level. `-` means it does not; the reason is under
[Skipped features](#skipped-features). Terms:
- **Rules**: a native rules folder. `-` means rules are inlined into the root instructions file.
- **Commands**: slash commands. A command is written as a skill where the harness has no command folder
(`codex`, `antigravity`, `devin`, `warp`) and as a prompt or workflow file for `copilot`, `pi`, `cline` and
`kiro` (`.kiro/prompts`). `claude` still reads `.claude/commands`, but ai-rulez writes commands there as
user-invocable skills, because Claude Code merges the two.
- **Hooks** and **Perms** (permissions): `yes` renders into a project file, `user` renders only with
[`generate --user`](user-scope.md) because the vendor reads them from the user configuration only.
See [Hooks, permissions and settings keys](settings.md) and [Permissions](permissions.md).
- **Checks**: [code-review guidelines](checks.md).
- **User**: supported by `generate --user`; see [User-level configuration](user-scope.md) for the paths.
| Preset | Harness | Rules | Skills | Agents | Commands | MCP | Hooks | Perms | Checks | User |
| ------ | ------- | ----- | ------ | ------ | -------- | --- | ----- | ----- | ------ | ---- |
| `aiassistant` | [JetBrains AI Assistant](https://www.jetbrains.com/help/ai-assistant/) | yes | yes | - | - | yes | - | - | - | - |
| `amp` | [Sourcegraph Amp](https://ampcode.com) | - | yes | - | - | yes | yes | - | yes | yes |
| `antigravity` | [Google Antigravity](https://antigravity.google/docs) | yes | yes | yes | yes | yes | yes | - | - | yes |
| `augment` | [Augment Code](https://docs.augmentcode.com) | yes | yes | yes | yes | yes | yes | yes | yes | yes |
| `baz` | [Baz](https://baz.ai/docs/agents/skills-and-instructions) | - | yes | yes | - | - | - | - | - | - |
| `bob` | [IBM Bob](https://bob.ibm.com/docs) | yes | yes | - | yes | yes | yes | - | - | yes |
| `claude` | [Claude Code](https://code.claude.com/docs) | yes | yes | yes | yes | yes | yes | yes | - | yes |
| `cline` | [Cline](https://docs.cline.bot) | yes | yes | yes | yes | - | yes | - | - | yes |
| `codebuddy` | [CodeBuddy Code](https://www.codebuddy.ai/docs/cli) | yes | yes | yes | yes | yes | yes | yes | - | yes |
| `codebuff` | [Codebuff](https://www.codebuff.com/docs) | - | yes | - | - | yes | - | - | - | - |
| `codewhale` | [Codewhale](https://github.com/codewhale-hq/Codewhale) | yes | yes | - | yes | yes | - | - | - | yes |
| `codex` | [OpenAI Codex](https://developers.openai.com/codex) | - | yes | yes | yes | yes | yes | yes | - | yes |
| `commandcode` | [Command Code](https://commandcode.ai/docs) | - | yes | yes | yes | yes | yes | yes | - | yes |
| `copilot` | [GitHub Copilot](https://docs.github.com/en/copilot) | yes | yes | yes | yes | yes | yes | yes | - | yes |
| `copilot-cli` | [GitHub Copilot CLI](https://docs.github.com/en/copilot/how-tos/copilot-cli) | yes | yes | yes | - | yes | yes | yes | - | yes |
| `cortex` | [Snowflake Cortex Code](https://docs.snowflake.com/en/user-guide/cortex-code/extensibility) | - | yes | yes | - | - | yes | - | - | yes |
| `crush` | [Crush](https://github.com/charmbracelet/crush) | - | yes | - | - | yes | yes | - | - | yes |
| `cursor` | [Cursor](https://cursor.com/docs) | yes | yes | yes | yes | yes | yes | yes | yes | yes |
| `deepagents` | [Deep Agents Code](https://docs.langchain.com/oss/deepagents/code) | - | yes | yes | - | yes | yes | - | - | yes |
| `devin` | [Devin CLI](https://docs.devin.ai/cli) | yes | yes | yes | yes | yes | yes | yes | - | yes |
| `dsh` | [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness) | - | yes | - | - | - | - | - | - | yes |
| `factory` | [Factory Droid](https://docs.factory.ai) | - | yes | yes | yes | yes | yes | - | yes | yes |
| `gemini` | [Gemini CLI](https://geminicli.com/docs/) | - | yes | yes | - | yes | yes | yes | - | yes |
| `gitlab-duo` | [GitLab Duo CLI](https://docs.gitlab.com/user/gitlab_duo_cli/customize/) | - | - | - | yes | yes | yes | - | yes | yes |
| `goose` | [goose](https://goose-docs.ai) | - | yes | yes | - | yes | yes | - | - | yes |
| `grok` | [Grok Build CLI](https://docs.x.ai/build/overview) | yes | yes | yes | yes | yes | yes | yes | - | yes |
| `hermes` | [Hermes Agent](https://hermes-agent.nousresearch.com/docs) | - | `agents_md` | - | - | - | user | user | - | yes |
| `junie` | [JetBrains Junie](https://junie.jetbrains.com) | yes | yes | yes | yes | yes | user | - | - | yes |
| `kilo` | [Kilo Code](https://kilo.ai/docs) | yes | yes | yes | yes | yes | yes | yes | yes | yes |
| `kimi` | [Kimi Code](https://moonshotai.github.io/kimi-code/) | - | yes | yes | - | yes | user | user | - | yes |
| `kiro` | [Kiro](https://kiro.dev/docs) | yes | yes | yes | yes | yes | yes | - | - | yes |
| `letta` | [Letta Code](https://docs.letta.com) | - | yes | yes | yes | - | yes | yes | - | yes |
| `mimocode` | [MiMo Code](https://mimo.xiaomi.com/mimocode) | - | yes | yes | yes | yes | yes | yes | - | yes |
| `muse` | [Meta Muse Code](https://dev.meta.ai/docs/muse-code) | - | yes | - | - | - | - | - | - | yes |
| `omp` | [oh-my-pi](https://github.com/can1357/oh-my-pi) | yes | yes | yes | yes | yes | - | yes | - | yes |
| `openclaw` | [OpenClaw](https://docs.openclaw.ai) | - | - | - | - | - | - | - | - | yes |
| `opencode` | [OpenCode](https://opencode.ai/docs) | - | yes | yes | yes | yes | yes | yes | - | yes |
| `pi` | [pi](https://pi.dev/docs/latest) | - | yes | yes | yes | yes | yes | - | - | yes |
| `poolside` | [Poolside Pool](https://docs.poolside.ai) | - | yes | - | - | yes | yes | yes | - | yes |
| `qoder` | [Qoder](https://docs.qoder.com/cli/quickstart) | yes | yes | yes | yes | yes | yes | yes | - | yes |
| `qwen` | [Qwen Code](https://qwenlm.github.io/qwen-code-docs/en/) | yes | yes | yes | yes | yes | yes | yes | yes | yes |
| `reasonix` | [Reasonix](https://github.com/esengine/DeepSeek-Reasonix) | - | yes | yes | yes | yes | yes | - | - | yes |
| `replit` | [Replit Agent](https://docs.replit.com/features/agent/overview) | - | yes | - | - | - | - | - | - | - |
| `rovodev` | [Atlassian Rovo Dev](https://www.atlassian.com/software/rovo-dev) | - | yes | yes | - | - | - | - | yes | yes |
| `takt` | [Takt](https://github.com/nrslib/takt) | yes | yes | yes | yes | - | - | - | - | yes |
| `trae` | [Trae](https://docs.trae.ai/ide/rules) | yes | yes | - | - | yes | - | - | - | yes |
| `vibe` | [Mistral Vibe](https://docs.mistral.ai/vibe) | - | yes | - | - | yes | yes | yes | - | yes |
| `warp` | [Warp](https://docs.warp.dev) | - | yes | - | yes | yes | - | - | - | yes |
| `xum` | [Xum](https://xum.coder.com) | - | yes | yes | - | yes | - | - | - | - |
| `zcode` | [ZCode](https://zcode.z.ai/en/docs) | - | yes | yes | yes | yes | user | - | - | yes |
| `zed` | [Zed](https://zed.dev/docs/ai) | - | yes | - | - | yes | - | user | - | yes |
| `zoocode` | [Zoo Code](https://docs.zoocode.dev) | - | yes | - | yes | yes | - | yes | - | yes |
Where each output lands (file names, merged documents, user-level paths) is in the preset's provider spec under
`internal/generator/providers/builtin/.toml` and, for the Go presets (`antigravity`, `baz`, `cline`,
`codex`, `copilot`, `cursor`, `devin`, `gemini`, `opencode`, `xum`), in `internal/generator/presets/`. The
user-level table is in [User-level configuration](user-scope.md#where-things-go).
#### Cross-cutting behavior
- **Shared outputs.** Presets that write the same path (`AGENTS.md`, `.agents/skills/`, the root `.mcp.json`)
must render identical bytes. `generate` fails and names the presets when they diverge, except for an
`AGENTS.md` that omits rules because its harness reads them from a rules folder; the complete file is kept
with a warning. See [AGENTS.md and .agents/skills](agents-md.md).
- **Merged documents.** Settings files that hold your own keys (`.claude/settings.json`, `opencode.json`,
`.codex/config.toml`, `.qwen/settings.json`, ...) are merged, not replaced. ai-rulez owns the keys, array
elements and map members it writes, and comments in JSONC, TOML and YAML survive. See
[Settings document merge behavior](configuration.md#settings-document-merge-behavior).
- **Native MCP environment references.** Where the harness expands `${VAR}`-style references itself, the
reference is written instead of the secret. See
[Environment references](configuration.md#mcp_servers).
- **Native tool and model names.** Frontmatter is translated to each harness's own tool names, and bare Claude
model aliases (`sonnet`, `opus`, `haiku`) are dropped where the harness has no such model.
#### Skipped features
A missing feature is a deliberate skip, with the reason taken from the provider spec or the settings and
permissions docs. Nothing is approximated.
##### Instructions, rules, skills and agents
| Preset | Skipped | Reason |
| ------ | ------- | ------ |
| `aiassistant` | root file | AI Assistant has no root instructions file, so every rule and context item becomes a `.aiassistant/rules/*.md` file |
| `amp` | agents | `.agents/agents` is an Antigravity format Amp does not read; agents are only listed in `AGENTS.md` |
| `baz` | rules folder, commands, MCP | Baz has no repository config file and reads only instruction files from the default branch; it ignores `.claude/commands` and does not read `.claude/rules`. See [Baz](baz.md) |
| `bob` | agents | Bob has no file-based subagents; its modes live in a Roo-style `custom_modes.yaml` aggregate |
| `codebuff` | rules, agents, commands | Codebuff documents only a knowledge file (`AGENTS.md`), skills and MCP |
| `codewhale` | agents | Subagents are TOML profiles with a deny-unknown-fields schema the provider DSL cannot express |
| `crush` | rules folder, agents, commands | Crush has inline guidance (`CRUSH.md`), skills and MCP only |
| `cline` | MCP | Cline has no project MCP file |
| `cortex` | rules folder, MCP | Cortex reads only `AGENTS.md`; project MCP is not documented (servers live in `~/.snowflake/cortex/mcp.json`) |
| `dsh` | MCP | Servers live in the home-level `cordis.patch.yml`, which a project preset cannot express |
| `gemini` | rules folder, commands | Rules stay in the root file (`AGENTS.md`, or `GEMINI.md` with `agents_md = false`); project commands are not generated (see the [plugin runtime](plugins.md) for `commands/.toml`) |
| `gitlab-duo` | skills, rules folder | GitLab documents skills only inside plugins; Duo CLI reads one rules file, `.gitlab/duo/chat-rules.md` |
| `goose` | rules folder, commands | goose has no rules folder; recipes are not slash commands |
| `hermes` | skills | With `agents_md = false` only project context is written (`.hermes.md`); skills come from the shared `.agents/skills`, which `agents_md` (the default) writes |
| `kimi`, `deepagents`, `factory`, `zcode`, `mimocode`, `zoocode`, `warp` | rules folder | No rules folder (or one the harness does not auto-load): rules are inlined into the root file. `kilo` keeps `.kilo/rules` and registers it in `kilo.jsonc` |
| `letta` | rules, MCP | No rules or MCP file the tool documents |
| `muse` | MCP | MCP servers live only in the user `settings.json` |
| `openclaw` | everything but the root file | Only the shared root `AGENTS.md` is written; no rules folder or skills layout can be targeted |
| `poolside` | agents | Subagents are entries of the settings file, which the preset does not generate |
| `replit` | rules, agents, commands, MCP | Replit has `replit.md` and `.agents/skills` only |
| `rovodev` | commands, MCP | Saved prompts need a `prompts.yml` manifest; `.rovodev/mcp.json` is inert until `config.yml` points at it |
| `takt` | MCP | Takt keeps MCP definitions inside workflow YAML. Rules, skills, agents and commands map to facets under `.takt/facets/` |
| `trae` | root file | Trae has no root instructions file; the preset writes rule files, skills and MCP |
| `vibe` | agents | A Vibe agent is a TOML profile whose prompt is a second file, which one output cannot produce |
| `xum` | commands | The tool documents no slash-command file |
| `amp`, `codex`, `commandcode`, `dsh`, `hermes`, `muse`, `opencode`, `pi`, `poolside`, `reasonix`, `rovodev`, `vibe`, `xum` | rules folder | The tool documents no rules folder: rules are inlined into the root instructions file (`AGENTS.md`, `.hermes.md` for `hermes`, `REASONIX.md` for `reasonix`) |
| `aiassistant`, `dsh`, `gitlab-duo`, `hermes`, `muse`, `trae`, `warp` | agents | The tool documents no such file |
| `zoocode` | agents | Custom modes are an aggregated `.roomodes` YAML file, which the provider DSL cannot produce |
| `aiassistant`, `amp`, `copilot-cli`, `cortex`, `deepagents`, `dsh`, `hermes`, `kimi`, `muse`, `poolside`, `trae`, `vibe` | commands | The tool documents no such file |
| `hermes` | MCP | The tool documents no project MCP file |
| `zed` | agents, commands, rules folder | Zed has no rules folder, subagent or command file format; rules go to the root `.rules` file |
##### Hooks
Sixteen presets generate no `[[hooks]]`: `aiassistant`, `baz`, `codebuff`, `codewhale`, `dsh`, `muse`, `omp`,
`openclaw`, `replit`, `rovodev`, `takt`, `trae`, `warp`, `xum`, `zed` and `zoocode`. A preset without hook
support is named in one `generate` warning; ai-rulez emits no hook it could not read from the vendor's
documentation.
`user` in the matrix marks harnesses whose vendor reads hooks (or permissions) only from the user configuration:
`junie` ("ignores project hooks"), `zcode` (ignores project hooks), `hermes`, `kimi` (user `config.toml`
only) and, for permissions, `zed`. They render with `generate --user`. Per-harness event, matcher and timeout
details are in [Hooks, permissions and settings keys](settings.md#more-settings-file-harnesses).
##### Permissions
These harnesses have no documented, committable permission file that can express `[permissions]`, so they get
nothing from it and `generate` names them in a warning (from [Permissions](permissions.md#not-translated)):
| Preset | Reason |
| ------ | ------ |
| `amp` | Current Amp docs removed `amp.permissions`; only whole-tool `amp.tools.disable` remains |
| `pi` | No permission mechanism; `defaultTools` only enables or disables whole tools |
| `cline` | Command permissions are documented only as the `CLINE_COMMAND_PERMISSIONS` environment variable |
| `kiro` | Conflicting documented shapes in `.kiro/agents/*.json`; the workspace permissions file lives outside the repository |
| `factory` | The project settings path is documented as `settings.local.json`, and `commandDenylist` means "ask", not "deny" |
| `crush` | `crush.json` is deprecated for `crushrc`; its schema has `allowed_tools` and no deny |
| `rovodev` | The bash rules location differs between Atlassian's pages and their match order is undocumented |
| `takt` | Only a coarse permission mode (`readonly`, `edit`, `full`), no rules |
| `antigravity` | Only the user-level CLI file is documented; the project path is not |
| `goose`, `junie`, `deepagents`, `warp` | User-level files with whole-tool, allow-only, exact-command or regex semantics that cannot hold the rules without widening them |
Every other preset without a `yes` or `user` in the Perms column has no permission surface in its provider spec.
##### Checks
Only eight harnesses read code-review guidelines from a repository file: `amp`, `augment`, `cursor`,
`factory`, `gitlab-duo`, `kilo`, `qwen` and `rovodev`. Not generated: Augment area grouping and per-area globs,
GitLab `fileFilters`, Takt quality gates, Hermes pre-verify specs, and JetBrains AI Assistant (its self-review
path is a per-user IDE setting). See [Checks](checks.md#where-they-are-written).
##### User scope
`aiassistant`, `baz`, `codebuff`, `replit` and `xum` have no documented user-level location for anything
`generate --user` writes and are reported and skipped. `codebuff` has only an MCP file, which user scope does not
generate. User-level MCP servers are never generated.
## AGENTS.md and .agents/skills
Source: https://goldziher.github.io/ai-rulez/agents-md/
`AGENTS.md` and `.agents/skills/` are the closest thing to a cross-tool convention for project instructions and
Agent Skills. With `agents_md = true`, ai-rulez renders them once and every preset that reads them stops writing its
own copy. The flag is on by default: `AGENTS.md` is the canonical instruction file and `CLAUDE.md` imports
`@AGENTS.md`. Set `agents_md = false` to get the per-tool files of earlier releases (`migrate v5` pins that value for
a 4.x project so its output does not move).
```toml
agents_md = true # the default
# agents_md = false # per-tool files
```
What changes:
- Always-on rules and context go into one `AGENTS.md` (plus a nested `/AGENTS.md` per `[[scopes]]` entry).
- Skills without `targets` go into one `.agents/skills//SKILL.md` tree.
- Presets that read these files stop writing their root file (`GEMINI.md`, `.hermes.md`, ...), their copy of
`AGENTS.md` and their own skills directory.
- Everything the tool cannot read from the shared files stays per-preset: scoped rules folders, agents, commands,
MCP files and settings. A rules folder is created only when at least one rule file is written into it.
With `agents_md = false`, `codex`, `opencode`, `xum`, `pi`, `amp` and `baz` already write the same `AGENTS.md`, while `claude`, `gemini`,
`cursor` and the rest each repeat the same content in their own file.
#### Tool support
Research as of 2026-10-03. `V` verified against official docs or source, `P` partial or experimental, `N` not
supported, `?` not verified. Tools are listed in the order of the presets that read the shared files, followed by two
tools that only matter because they can shadow `AGENTS.md`.
| Tool | Root `AGENTS.md` | Nested `AGENTS.md` | Precedence and double-loading | `.agents/rules` | `.agents/skills` | Agents, commands |
| -------------------------- | ----------------------------------------------------------------- | ----------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------- | -------------------------------------------------------------------- | -------------------------------------------------- |
| Claude Code | V, only when no `CLAUDE.md`, `.claude/CLAUDE.md` or `CLAUDE.local.md` exists in cwd or an ancestor (v2.1.277+; all sessions v2.1.281+) | V lazily, when a file in a subdirectory without any `CLAUDE.md` is read | `@AGENTS.md` import in `CLAUDE.md` never loads twice. `CLAUDE.local.md` suppresses `AGENTS.md` unless the user-level `instructionFiles` setting is `claude-md-and-agents-md`. Reads `.claude/AGENTS.md`, not `AGENTS.local.md` | N | N (`.claude/skills`) | N (`.claude/agents`, `.claude/commands`) |
| Codex CLI | V | V project root down to cwd only; no lazy loading below cwd | Per directory first of `AGENTS.override.md`, `AGENTS.md`, fallback names; concatenated root-down; `project_doc_max_bytes` 32 KiB | N | V repo-local, cwd up to repo root; `~/.agents/skills` | ? (`.codex/agents/*.toml`) |
| Cursor | V | V any subdirectory, more specific wins | ? Docs call `AGENTS.md` an alternative to `.cursor/rules`; co-presence and deduplication not documented | N | V `.agents/skills`, `.cursor/skills`, nested ones anywhere | V `.cursor/agents`, `.claude/agents`, `.codex/agents`; no `.agents/agents` |
| Copilot cloud agent, CLI | V | V nearest file in the tree takes precedence | Cloud agent: all relevant instruction sets are provided, no deduplication. CLI: removes duplicate copies of identical instructions, defines no general precedence | N | V `.github/skills`, `.claude/skills`, `.agents/skills` | ? (`.github/agents`) |
| Copilot in VS Code | V chat and agent | P experimental `chat.useNestedAgentsMdFiles` | Additive. `CLAUDE.md` needs `chat.useClaudeMdFile` | N | V same three locations | ? |
| Devin | V always-on rule; `agents.md` also recognized | V subdirectory file is a glob rule `/**` | Same rules engine as `.devin/rules` | N | V `.agents/skills`, native `.devin/skills` | ? workflows |
| Gemini CLI | N by default: reads only `GEMINI.md` unless `context.fileName` lists more | V for configured names, hierarchical and on file access | Only names in `context.fileName` load (`.gemini/settings.json`); `@file.md` imports work in `GEMINI.md` | N | V `.agents/skills` beats `.gemini/skills` within a tier | N (`.gemini/agents`, `.gemini/commands` only) |
| Antigravity | V | V `AGENTS.md`, `GEMINI.md` or `.agents/rules/` in any subdirectory | Cumulative; directory level wins on conflict. 24 KB per file, 20k tokens in aggregate | V any directory level, immediate `.md` children only, `trigger` frontmatter | V `/.agents/skills`; legacy `.agent/skills` | ? workflows are being superseded by skills |
| Junie | V | ? not in the fetched docs | `.junie/AGENTS.md` first; else `AGENTS.md` + `.junie/rules/*.md`; else legacy `.junie/guidelines.md`; identical content deduplicated | N | V `.junie/skills`, `.agents/skills` | ? |
| Cline | V | ? shipped code reads the root file only | Listed beside `.clinerules`, `.cursorrules`; per-file toggles | N | V in code (`.agents/skills`); docs list only `.cline/skills` and others | N |
| opencode | V | V lazily, nearest file per read | Finds the first existing of `AGENTS.md`, `CLAUDE.md`, `CONTEXT.md` and stacks every ancestor copy of it | N | V `.agents/skills`, `.claude/skills`, `.opencode/skills` | N (`.opencode`) |
| Amp | V | V when the agent reads a file in the subtree | Per directory `AGENTS.md`, else `AGENT.md`, else `CLAUDE.md` | N | V `.agents/skills` in project and parents | ? |
| xum | V | V | `AGENTS.md` > `AGENT.md` > `CLAUDE.md`; also `AGENTS.local.md` | N | ? | ? |
| pi | V | V | Reads `AGENTS.md`; skills from `.agents/skills` (preferred) or `.pi/skills`; MCP in `.pi/mcp.json` | N | V `.agents/skills` beats `.pi/skills` | ? (`.pi/agents` subagents extension) |
| Hermes | V git root to cwd | V | One context type only: `.hermes.md` shadows `AGENTS.md` entirely | N | V `.hermes/skills`, `.agents/skills` | ? |
| Zed | V | N | One file per worktree root: the first existing of `.rules`, `.cursorrules`, `.devin/rules`, `.clinerules`, `.github/copilot-instructions.md`, `AGENT.md`, `AGENTS.md`, `CLAUDE.md`, `GEMINI.md`. Earlier entries shadow `AGENTS.md` | N | V `.agents/skills` | N |
| Warp | V file name must be upper case | V root and current directory | `WARP.md` beats `AGENTS.md` in the same directory | N | V `.agents/skills` (recommended) | ? |
Only Antigravity reads `.agents/rules`; ai-rulez uses it for that tool alone. Other tools covered in the research
(Kilo Code, Roo Code, Factory, Kimi CLI, Aider) are not ai-rulez presets and are omitted.
Sources, all fetched 2026-10-03: Claude Code memory docs (`agents-md` section) and release notes for v2.1.277;
Cursor docs (`cursor.com/docs/context/rules`, `cursor.com/docs/context/skills`); GitHub docs on repository
instructions and agent skills; the VS Code custom-instructions matrix; Devin docs (`docs.devin.ai`, AGENTS.md and
skills); Gemini CLI docs and source (`settingsSchema.ts`, `memoryTool.ts`); the Antigravity rules and skills pages;
Junie guidelines and agent-skills docs; Cline rules docs and extension source; Amp docs
(`ampcode.com/docs/customize/agents-md`); and source reads of Codex (`agents_md.rs`, skills host roots), opencode
(`instruction.ts`), Hermes (`prompt_builder.py`) and Zed (`prompts.rs`, `agent.rs`). Tools change quickly; re-check a
cell before relying on it.
#### What each preset does
Rules mode is the default `split` unless noted. "Shared" means the one `AGENTS.md` or `.agents/skills` tree.
Paths below are what a project with an always-on rule, an overview context file, a glob rule, auto and manual
rules, a glob-scoped context file, two skills, one agent and one MCP server writes (taken from the test fixtures).
| Preset | Reads AGENTS.md | Root file | Skills | Written beside the shared files |
| ------------------------------ | ------------------------------------ | ------------------------------------------- | ---------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------- |
| `codex`, `opencode`, `xum`, `pi` | natively | shared `AGENTS.md` | shared; `.opencode/skills`, `.xum/skills` dropped (`pi` never writes skills under `.pi`) | their own agents, commands and MCP files |
| `amp` | natively | shared `AGENTS.md` | shared | unchanged |
| `claude` | through `CLAUDE.md` containing `@AGENTS.md` | `CLAUDE.md` is a banner plus `@AGENTS.md` | `.claude/skills` kept (Claude ignores `.agents/skills`) | `.claude/rules/*.md` for non-always-on items, `.claude/agents`, `.mcp.json` (MCP servers), `.claude/settings.json` (only hooks, permissions and managed keys) |
| `gemini` | through `context.fileName` in `.gemini/settings.json` | `GEMINI.md` not written | shared | `.gemini/settings.json`, `.gemini/agents/.md`, `.mcp.json` |
| `antigravity` | natively | `GEMINI.md` not written | shared | `.agents/rules/*.md` for non-always-on items, `.agents/agents/.md`, `.agents/mcp_config.json`, `.mcp.json` |
| `hermes` | natively | `.hermes.md` not written | shared | `.mcp.json` |
| `cursor` | natively | none | shared | `.cursor/rules/*.mdc` for non-always-on items and glob context, `.cursor/agents/.md`, `.mcp.json` |
| `copilot` | natively | `.github/copilot-instructions.md` not written | shared; `.github/skills` dropped | `.github/instructions/*.instructions.md` for `applyTo`-scoped items, `.github/agents/.agent.md` |
| `devin` | natively | none | shared; `.devin/skills` dropped | `.devin/rules/*.md` for non-always-on items and glob context, `.devin/agents/.md` |
| `cline` | natively | none | shared; `.cline/skills` dropped | `.clinerules/*.md` for non-always-on items and glob context, `.cline/agents/.yaml` |
| `junie` | natively | shared `AGENTS.md` | shared; `.junie/skills` dropped | `.junie/rules/*.md` for non-always-on items, `.junie/agents/.md` |
Every preset above still writes its MCP file where it did before. Declarative providers (`amp`, `hermes`, `claude`,
`junie`, ...) honor the flag as well. Custom presets and provider specs that are not in the table take no part, and
their `AGENTS.md` or `.agents/skills` output is dropped in favor of the shared copy (see
[Overlapping writers](#overlapping-writers)).
##### How each tool finds AGENTS.md
- **Native readers** (`codex`, `opencode`, `xum`, `amp`, `pi`, `hermes`, `cursor`, `copilot`, `devin`, `cline`,
`junie`, `antigravity`): nothing to configure.
- **Claude Code** reads `CLAUDE.md`, and only reads `AGENTS.md` itself from v2.1.277 and in every session from
v2.1.281. ai-rulez therefore keeps `CLAUDE.md` as a generated shim: the generated-file banner followed by
`@AGENTS.md`. The import works on every version and never loads the file twice.
- **Gemini CLI** loads only the names in `context.fileName`. With the flag on, ai-rulez merges `"AGENTS.md"` (and
`"GEMINI.local.md"`) into `context.fileName` in `.gemini/settings.json`, keeping existing names and other keys (a
single-string value becomes a list), and writes the file even when there are no `[[mcp_servers]]`. Gemini replaces its default
`GEMINI.md` with whatever is configured, which is why `GEMINI.md` is not written.
##### Why copilot-instructions.md, .hermes.md and friends are dropped
Some tools load a single instruction file and pick it by order, so a preset's own root file would hide `AGENTS.md`:
- **Zed** takes the first existing of `.rules`, `.cursorrules`, `.devin/rules`, `.clinerules`,
`.github/copilot-instructions.md`, `AGENT.md`, `AGENTS.md`, `CLAUDE.md`, `GEMINI.md`. A generated
`.github/copilot-instructions.md` would hide `AGENTS.md` from Zed, so the `copilot` preset does not write it.
`CLAUDE.md` and `GEMINI.md` come later and do not shadow it. `.clinerules` is a directory here, which Zed does not
treat as a rules file.
- **Hermes** loads one context type, and `.hermes.md` shadows the whole `AGENTS.md` chain; the `hermes` preset does
not write it.
- **Warp** prefers `WARP.md` in the same directory. No preset writes it; do not add one by hand.
- **Junie** prefers `.junie/AGENTS.md`; otherwise it reads the project-root `AGENTS.md` together with `.junie/rules`
and `.junie/playbook.md`. The legacy `.junie/guidelines.md` layout is no longer written; the root `AGENTS.md` is the
open-standard file Junie reads.
##### Overlapping writers
If another preset (including a custom provider) also writes `AGENTS.md` or a file under `.agents/skills`, the shared
output wins and the other copy is not written. Without this, the last preset in name order would overwrite the
shared file.
#### Where rules and context go
The shared `AGENTS.md` always carries always-on rules and context, and anything scoped only by negated globs
(`!gen/**`), which no rules folder can express. What else it carries depends on the presets that rely on it.
| Kind | Rules folder presets (`cursor`, `devin`, `cline`, `claude` and `antigravity` in split mode, `junie` in split mode) | Presets without a folder (`codex`, `opencode`, `amp`, `xum`, `pi`, `hermes`, `gemini`) |
| ----------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------- |
| Always-on rule or context | `AGENTS.md` only | `AGENTS.md` |
| Glob-scoped rule or context | the preset's folder | `AGENTS.md` with an `_Applies to_` line |
| Auto rule | the folder | `AGENTS.md` with a `_When relevant_` line |
| Manual rule | the folder | `AGENTS.md` |
| Only negated globs (`!gen/**`) | `AGENTS.md` only | `AGENTS.md` |
The decision is made once for the whole file, from the configured built-in presets that rely on it:
| Configured preset (rules mode) | Scoped items (glob rules, glob context) in `AGENTS.md` | Auto and manual items in `AGENTS.md` |
| ------------------------------------------------------ | ------------------------------------------------------ | ------------------------------------ |
| `codex`, `opencode`, `amp`, `xum`, `pi`, `hermes`, `gemini` | yes | yes |
| `claude`, `antigravity` (split) | no | no |
| `claude`, `antigravity` (inline) | no | yes |
| `cursor`, `devin`, `cline` (either) | no | no |
| `copilot` (either) | no | yes, its folder only holds `applyTo` items |
| `junie` (split) | no | no |
| `junie` (inline) | yes, it writes no rule files | yes |
The most inclusive row among the configured presets wins. In `inline` mode `claude` and `antigravity` still write
glob-scoped files, so only auto and manual items move into `AGENTS.md`. `cursor` ignores the mode: it always writes
files. Scoped context is inlined together with scoped rules.
##### Duplication trade-off
The inlining is decided for the file, not per reader. When a preset without a folder is enabled next to a preset
with one, the scoped items appear in `AGENTS.md` and in the folder, so the tool with the folder loads them twice.
Examples: `claude` + `codex`, `cursor` + `codex`, `cursor` + `gemini`, `cursor` + `amp`, `cursor` + `hermes`, and
(auto and manual items only) `claude` in `inline` mode + `cursor`. The research found no cross-file deduplication for
Cursor or Claude Code, and none for the Copilot cloud agent. A mixed setup that wants no duplication should keep to
presets that all have folders, accept the overlap, or leave `agents_md` off.
Machine-local rules are never part of the shared `AGENTS.md`. They keep their per-preset files (for example
`.github/instructions/.local.instructions.md`, `CLAUDE.local.md`, `AGENTS.override.md`). See
[Local Configuration](local-overrides.md#generated-output) for the file each tool loads.
#### Skills
- Skills without `targets` are written once to `.agents/skills//SKILL.md`, with bundled resources, in the
generic Agent Skills format (`name`, `description`). Codex's `metadata.short-description` is not emitted there.
- **Claude Code** reads `.claude/skills`, not `.agents/skills`, so the `claude` preset keeps writing its own copy.
- Skills that set `targets` stay out of the shared tree: they are written to the per-preset skills directories of the
presets the targets allow, exactly as without the flag. A skill targeting `codex` goes to Codex's own skills directory (`.agents/skills`, or `codex_skills_dir`), the only
place Codex reads, so other `.agents/skills` readers see it too; an untargeted skill goes to the shared tree; a skill targeting a preset that is not configured is written nowhere.
- `.agents/skills` is read by Codex, Cursor, Copilot, Devin, Gemini CLI, Antigravity, Junie, Cline, opencode, Amp,
Hermes, pi, Zed, Warp and others, per the table above.
#### targets
Frontmatter `targets` select the presets or files an item is written for. The shared file changes who an item can
reach:
- A rule or context item is included in `AGENTS.md` when its `targets` name a preset that relies on the file
(`claude`, `gemini`, `cursor`, `codex`, ...), the root file such a preset replaced (`CLAUDE.md`, `GEMINI.md`,
`.hermes.md`, `.github/copilot-instructions.md`, by path or base name), or any default
owner of `AGENTS.md` (`codex`, `opencode`, `xum`, `amp`, `pi`, `junie`), configured or not.
- A target naming an unconfigured preset's root file (for example `GEMINI.md` with only `codex` configured) does not
select the item for `AGENTS.md`.
- **Widening:** the file is shared, so an always-on rule targeted at a single preset now reaches every tool that reads
`AGENTS.md`.
- **Folder-only targets:** an always-on rule or context item whose `targets` match only a rules folder or rule file
path (`.cursor/rules/`, `.claude/rules/`, `.github/instructions/`, `.devin/rules/`, ...) and no `AGENTS.md`
owner or root file is not in `AGENTS.md`. The preset writes it as a rule file in that folder, exactly as without
the flag. To limit an always-on item to one tool, target its rules folder path rather than its preset name.
- Skills with `targets` are covered under [Skills](#skills).
#### Scopes, local files and hashes
**Scopes.** Each `[[scopes]]` entry gets a nested `