plugins/build/skills/build-rule/SKILL.md
Create a Claude Code rule under `.claude/rules/` — a markdown instruction file with optional `paths:` frontmatter for path-scoping. Use when the user wants to "create a rule", "capture this convention", or "enforce this pattern".
npx skillsauth add bcbeidel/wos build-ruleInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Create a Claude Code rule. Rules are markdown files in .claude/rules/
that Claude reads automatically — globally at session start (no frontmatter)
or on demand when a matching file is opened (with paths: frontmatter).
See Anthropic's .claude/rules/ reference.
Authoring principles — what makes a rule load-bearing, the anatomy template, patterns that work — live in rule-best-practices.md. This skill is the workflow; the principles doc is the rubric.
Also fires when the user phrases the request as:
Before proceeding, confirm a rule is the right mechanism. Full decision matrix: primitive-routing.md.
A rule is right when:
Redirect when:
/build:build-skill/build:build-hook.claude/CLAUDE.md instead — rules
are right when the topic justifies its own fileRead $ARGUMENTS and decide: does the input describe one convention or
several?
Signals that the input is multi-concern:
If single-concern: proceed to Step 2 with one rule in scope.
If multi-concern: propose a split. Present the candidate rule list (one line per rule, with a proposed filename) and ask the user to confirm, merge, or re-split. On approval, subsequent steps iterate per rule.
Example fork:
"I see three conventions here. Proposed split:
api-validation.md— API endpoints must validate inputtest-path-mirroring.md— test files mirror source paths with.test.tssuffixcommit-messages.md— commit messages follow Conventional CommitsAccept, merge any, or re-split?"
This enforces one claim per file (from rule-best-practices.md) at intake rather than after drafting.
Each rule becomes <topic>.md under .claude/rules/. Use a descriptive,
single-word or hyphenated name like testing.md, api-design.md,
security.md, code-style.md. Subdirectories are allowed (e.g.,
.claude/rules/frontend/components.md).
If the intake didn't settle filenames, propose 2–3 candidates per rule and let the user pick.
Two choices:
| Scope | Frontmatter | When to use |
|-------|-------------|-------------|
| Always-on | none | Project-wide standards (e.g., naming conventions, commit message format) |
| Path-scoped | paths: glob list | Rules that only apply when Claude works with specific files (e.g., backend rules in a monorepo) |
Path-scope example:
---
paths:
- "src/api/**/*.ts"
---
Globs follow standard syntax; brace expansion works
("src/**/*.{ts,tsx}"). Multiple patterns live under one paths: key.
Prefer narrow, directory-rooted patterns. An unscoped rule is a context
tax on every unrelated task — justify paths: omission explicitly.
Read existing rules in .claude/rules/ (and ~/.claude/rules/ if the
user maintains personal rules). Anthropic warns explicitly:
"if two rules contradict each other, Claude may pick one arbitrarily"
Check for:
paths: globs (or both global) covering the
same conventionIf overlap found, ask: "This overlaps with [existing rule]. Merge,
replace, or keep both with explicit boundaries?"
Sibling-conflict check (multi-rule invocations): when drafting multiple rules in one invocation, after each sibling is drafted at Step 5, compare the new draft against earlier siblings in the batch for the same kinds of overlap. Resolve inline before moving that draft into Step 6 approval.
Follow the anatomy template from rule-best-practices.md:
---
paths:
- "path/glob/**/*.ext"
---
<One-line imperative rule statement, framed as an action to take.>
**Why:** <the reason — incident, constraint, strong preference>
**How to apply:** <when/where this kicks in, including edge cases>
<Optional: one concrete example. When the rule requires judgment and
the boundary is non-obvious, show a contrasting non-compliant example.>
For judgment-based rules, **How to apply:** can be replaced by
contrasting example pairs — the examples themselves convey the
when/where without a separate prose line. Simple directive rules
("Use snake_case for table names") benefit from the inline
**How to apply:**; judgment-heavy rules lean on the example pair.
Apply the principles without restating them here — the rubric is the principles doc. Key things to get right:
foo/barFor judgment-heavy rules (Claude evaluates a file against the rule), the why becomes longer and an example pair makes the boundary visible. For simple directive rules ("use snake_case"), a one-line rule + inline Why is enough.
Before writing, narrate the design choices in 2–4 bullets per rule:
.claude/rules/<name>.mdShow the complete file. Iterate on feedback. Hold the write until the user approves.
When multiple rules are in flight, present each rule's draft and gate separately. Do not batch approvals.
.claude/rules/ (and any subdirectory) if it doesn't exist.claude/rules/<name>.mdClaude Code picks up the new rules on the next session (always-on rules)
or the next time it reads a file matching paths: (scoped rules).
Single-concern intake — one rule. Filename staging-model-purity.md.
Path-scoped to models/staging/**/*.sql. Judgment-based — boundary
between "pure" and "has business logic" benefits from a contrasting
example pair.
Drafts:
---
paths:
- "models/staging/**/*.sql"
---
Keep staging models to casts, renames, and deduplication only.
**Why:** Business logic in staging (revenue calculations, tier
classifications) couples source schema changes to business definitions.
When either changes, both layers need coordinated updates, which
produces silent divergence between the staging contract and downstream
assumptions.
**Exception:** pure data-type normalization (parsing a date string to
a date type) is permitted.
## Compliant
```sql
-- models/staging/stg_orders.sql
select
id as order_id,
cast(order_date as date) as order_date,
cast(quantity as integer) as quantity
from {{ source('raw', 'orders') }}
qualify row_number() over (partition by id order by _loaded_at desc) = 1
-- models/staging/stg_orders.sql
-- revenue calculation and tier classification are business logic
select id, quantity * unit_price as revenue,
case when lifetime_value > 1000 then 'high' else 'standard' end as tier
from {{ source('raw', 'orders') }}
Narrates design (path-scoped, ~30 lines, example pair because the
boundary is subtle). On approval, writes to
`.claude/rules/staging-model-purity.md`.
</example>
**On heading names:** the `## Compliant` / `## Non-compliant` headings
in the example above are one convention. Any heading or code-block
arrangement works — `check-rule` audits example content (real code
vs. synthetic), not heading names.
## Key Instructions
- Run the Step 0 primitive check before drafting — if the ask fits a hook or linter better, redirect and stop
- At Step 1, detect multi-concern input and propose a split before any drafting — one claim per file is a principle; enforce it at intake
- Run the Step 4 conflict check before drafting — Anthropic warns that contradicting rules cause Claude to pick one arbitrarily
- Draft against the anatomy template and principles from [rule-best-practices.md](../../_shared/references/rule-best-practices.md); don't invent new frontmatter fields or required sections
- Hold each write until the user approves that rule's draft (Step 6 gate) — gate per rule, not per batch
- Keep rules short; split when they approach the audit's 200-line warn threshold (check-rule fails at 500)
## Anti-Pattern Guards
1. **Rule outside `.claude/rules/`** — Claude Code only auto-loads rules from `.claude/rules/` (and `~/.claude/rules/`); files elsewhere are inert. Refuse to write to `docs/rules/` or other invented paths.
2. **Multi-concern rule written as one file** — if Step 1 missed a split opportunity and the draft covers multiple topics, fork back to Step 1 and re-split before writing.
3. **Conflict check skipped** — run Step 4 before drafting; contradicting rules produce arbitrary behavior.
4. **Always-on rule that should be path-scoped** — flag rules whose content names a specific directory or file type but that omit `paths:`; the unscoped rule consumes context every session for content that only applies sometimes.
## Handoff
**Chainable to:** `/build:check-rule` (verify new rules fit the existing library without conflicts)
tools
Use when the user wants to "audit a help skill", "review my plugin index", or "verify my help-skill is up to date". Audits a plugins/<plugin>/skills/help/SKILL.md against the help-skill rubric — coverage, freshness, frontmatter fidelity, plus five judgment dimensions and a trigger-collision check.
tools
Use when the user wants to "scaffold a help skill", "add a /<plugin>:help command", or "build a plugin index skill", or wants to give a plugin an orientation surface that lists its skills and common workflows. Produces a SKILL.md at plugins/<plugin>/skills/help/SKILL.md.
tools
Audits pair-level integrity of a primitive-pair (the artifact `/build:build-skill-pair` produces) by walking the four required artifact slots — principles doc, `build-<primitive>/SKILL.md`, `check-<primitive>/SKILL.md`, and the `primitive-routing.md` registration — and reports cross-artifact issues a per-SKILL.md checker cannot see: missing principles doc, divergent principles paths between halves, absent routing registration, missing build→check handoff. Per-half structural compliance with the unified pattern (`check-skill-pattern.md`) is delegated to `plugins/build/_shared/scripts/check_skill_pattern.py`. Use when the user wants to "audit a skill pair", "review a primitive pair", or "validate the skill pair for X". Not for auditing a single SKILL.md — route to `/build:check-skill`. Not for re-distilling a stale principles doc — route to `/build:build-skill-pair`.
testing
Audit a root-level resolver — verify AGENTS.md pointer, managed-region integrity, filing-table coverage against disk, context-table actionability, and trigger-eval pass rate. Use when the user wants to "audit a resolver", "validate routing table", or "find dark capabilities".