---
title: "Rules"
description: "Defines portable rule source, path scoping, provider destination behavior, ownership, and target-native command-policy boundaries."
---

> Documentation Index
> Fetch the complete documentation index at: https://nimbus.focal.host/llms.txt
> Use this file to discover all available pages before exploring further.

# Rules

<a id="rules"></a>

Rules are durable repository guidance authored as [source units](/skillset/glossary/#source-unit) under `.skillset/rules/**/*.md`. They are not invokable skills. Skillset keeps the source hierarchy and [renders](/skillset/glossary/#render) each enabled provider's supported guidance form.

For the current field set and override shape, use the generated [rule frontmatter schema](/skillset/reference/schemas/0.1.0/rule-frontmatter.schema.json) and [example](/skillset/reference/examples/rule-frontmatter.yaml). The [rules feature page](/skillset/reference/features/rules/) owns the current support summary.

## Authoring

A rule is Markdown with optional frontmatter and a body. This one lives at `.skillset/rules/docs/guidance.md`:

```markdown
---
paths:
  - "*.md"
  - "guides/**/*.md"
---

# Documentation guidance

- Keep public behavior aligned with its canonical contract.
```

## Scope

Where a rule sits under `.skillset/rules/` is its scope. `rules/<topic>.md` is unscoped and applies to the whole repository. `rules/<dir>/<topic>.md` governs `<dir>/`, so the rule above governs `docs/`. The filename is the topic and may not contain `[` or `]`.

`paths` narrows files within that scope and is relative to the rule's directory: in `rules/docs/`, `"*.md"` means `docs/*.md`. A `paths` entry that starts with its own scope directory, such as `docs/**` inside `rules/docs/`, warns with `rule-scope-path-double-prefix`, because it now means `docs/docs/**`.

Directory names are literal except for two reserved segments: `[.]` matches one level and `[...]` matches any depth. `app/[slug]/` and `app/(marketing)/` are ordinary directories. A rule under a wildcard scope such as `rules/apps/[.]/src/` renders nothing yet and records an `unsupported` render result (`rule-wildcard-scope-pending`) until wildcard expansion lands; it never falls back to the root `AGENTS.md`.

A scope directory that does not exist yet still gets its `AGENTS.md`, with a `rule-scope-directory-missing` warning in case the name is a typo. A rule cannot scope to a directory inside the `.skillset/` source root, because its generated `AGENTS.md` would be read back as rule source.

Rule frontmatter can also carry shared metadata, explicit provider blocks, and provider toggles. For example, set `codex: false` when a rule is intentionally unavailable to Codex. [Target](/skillset/glossary/#target)-specific fields override shared intent only for that target; they do not create a second portable meaning.

Use `skillset new rule <name>` to preview a normalized source file under `.skillset/rules/`. `--in <plugin>` selects an existing plugin container, and `--yes` confirms the write. The command refuses collisions and does not run a [build](/skillset/glossary/#build). See the generated [`new` command reference](/skillset/reference/cli/new/) for the complete CLI contract.

Rule bodies support [preprocessing](/skillset/reference/source/preprocessing/). Set `skillset.preprocess: false` when recognized Skillset expressions must remain literal.

Write a rule's relative Markdown links as seen from the directory the rule applies to: the repository root for `RULES.md`, and `apps/` for `rules/apps/*.md`. That is where the rule's `AGENTS.md` lands, so that file keeps the links unchanged. Every other destination, such as `.claude/CLAUDE.md`, `.claude/rules/`, and `.cursor/rules/`, gets each link rebased to its own depth. This covers inline links (with or without a title), reference definitions, and links inside included partials. URLs, `#` anchors, absolute paths, `<...>` targets, preprocessing expressions, and links inside code are left as written.

## Destination behavior

Claude and Cursor [destinations](/skillset/glossary/#destination) follow the enabled targets. Root and scoped `AGENTS.md` files are the Agent Instructions baseline: Skillset writes them whenever rules apply, even when Codex is not a target, and Codex reads them.

| Authored source | Destination | Behavior |
| --- | --- | --- |
| `.skillset/RULES.md` | `.claude/CLAUDE.md` (default) or root `CLAUDE.md` | Renders the front page in its authored dialect under a generated-by header. `compile.instruction_front_page` selects `claude-dir` or `repo-root`. |
| `.skillset/RULES.md` | root `AGENTS.md` (Agent Instructions baseline) | Becomes the bare first section of the root `AGENTS.md`, with no section tag, ahead of unscoped rules. |
| `.skillset/RULES.md` | none for Cursor | Unsupported for Cursor (`cursor-agents-md-root`); Cursor receives only `.skillset/rules/**`. |
| `.skillset/rules/**/*.md` | `.claude/rules/**/*.md` | Mirrors the source path. Frontmatter `paths` is the scope joined with each `paths` entry, sorted, or `<dir>/**` for a scoped rule without `paths`. Glob characters in the literal scope directory (`[`, `]`, `*`, `?`, `{`, `}`) are escaped (`app/\[slug\]/**`) so the glob matches only that directory; Claude treats an unescaped `[` as a bracket expression. Unscoped rules without `paths` render without frontmatter. |
| `.skillset/rules/**/*.md` | `.cursor/rules/**/*.mdc` | Mirrors the source path and writes the same derived globs, unescaped. A glob containing `[`, `]`, `(` or `)` records a `degraded` render result (`cursor-rule-glob-escaping-unverified`) because Cursor documents no escape. |
| `.skillset/rules/**/*.md` | `<dir>/AGENTS.md` for a rule under `rules/<dir>/`, root `AGENTS.md` when unscoped (Agent Instructions baseline) | Strips source-only frontmatter and combines contributing rules deterministically. |

A rule's `AGENTS.md` is always its scope directory's, whatever files exist in the working tree. Codex reads one instruction file per directory and cannot narrow below it, so a rule with `paths` still reaches all of its scope in the generated `AGENTS.md`; the narrowing is recorded as a `degraded` render result (`codex-rule-paths-not-enforceable`) that `skillset explain <dir>/AGENTS.md` shows.

Generated paths mirror the literal source path, so quote them in a shell: brackets and parentheses are glob characters. Use `cat 'app/[slug]/AGENTS.md'`; zsh otherwise answers "no matches found", and PowerShell needs `-LiteralPath`.

When multiple rules reach one Codex destination, Skillset concatenates them in source-path order, after the `RULES.md` front page in the root `AGENTS.md`. Skillset does not use `.codex/AGENTS.md` as a default Codex destination.

A generated `AGENTS.md` wraps each rule in an XML section when it combines more than one contribution, or when its one rule narrows with `paths` that would otherwise be invisible. A lone rule without `paths` and the `RULES.md` front page stay bare. XML survives every provider's processing, while Claude strips HTML comments. The tag is the rule's frontmatter `name` or filename stem, lowercased, with each run of other characters replaced by `_`, a leading `_` before a digit, and `rule` when nothing is left; two sections may share a tag because `source` tells them apart. `source` is the authored path, and `applies_to` is the derived scope: `<dir>/**`, `**` when unscoped, or each `paths` entry joined onto the scope, sorted and comma-separated, with literal brackets unescaped. Both attribute values escape `&`, `<`, `>` and `"` as XML entities:

```markdown
<coding_guidance
  source=".skillset/rules/engineering/coding-guidance.md"
  applies_to="engineering/**/*.ts" >

# Coding guidance
...

</coding_guidance>
```

Source-only frontmatter never reaches the section. When two contributions to one `AGENTS.md` both carry a `## Code Review Rules` heading, the build warns with `codex-code-review-rules-duplicate`, naming both sources, and renders both sections unmerged.

Codex may silently truncate an `AGENTS.md` beyond its configured project-document byte limit. Build and output checks warn when generated guidance exceeds the default 32 KiB limit. Move rules into directories under `rules/` so they land in nested `AGENTS.md` files, or deliberately adjust the provider's own configuration.

## Ownership and collisions

Generated rule files are recorded in the root `skillset.lock`. If a confirmed build must replace an unmanaged `AGENTS.md`, Skillset first creates recovery evidence and reports the restore identifier. Move hand-written guidance into `.skillset/rules/` only when you intend Skillset to own that destination; otherwise change the source scope or target selection.

Claude loads both `CLAUDE.md` and `.claude/CLAUDE.md` and concatenates them, so Skillset renders only the placement `compile.instruction_front_page` names. When an unmanaged file sits at the other placement, build and output checks emit a `claude-instructions-duplicate-root` warning naming both paths and leave the unmanaged file untouched. Fold its content into `.skillset/RULES.md` or delete it.

Skillset never writes `AGENTS.override.md`. Codex reads only the first instruction file in a directory, so an unmanaged `AGENTS.override.md` beside a generated `AGENTS.md` hides it; build and output checks warn with `codex-agents-override-shadow`, naming both paths.

`codex: symlink` is not supported. A symlink to a Claude rule would expose Claude-specific frontmatter as Codex guidance and would bypass normal generated ownership.

## Rules are not command policy

Codex `.rules` files describe target-native command execution policy, not Markdown rule prose. Author those files explicitly under `.skillset/_codex/rules/**/*.rules` when that native surface is required. They mirror to `.codex/rules/**/*.rules`; portable rules continue to render through `AGENTS.md`.

The same boundary applies to plugin-native companions: provider-specific plugin `rules/` content is an explicit island, not another location for workspace rule source. Use the [workspace layout](/skillset/reference/source/workspace-layout/#provider-native-islands) to choose the correct owner.

Source: https://nimbus.focal.host/skillset/reference/source/rules/index.mdx
