From rcc
Guides creation of .claude/rules/ files for path-scoped project conventions using TDD workflow: RED (test gaps), GREEN (write rule), REFACTOR (optimize). Triggers on 'add rule', 'create convention', 'scope guideline'.
npx claudepluginhub wayne930242/reflexive-claude-codeThis skill uses the workspace's default tool permissions.
**Writing rules IS creating scoped, auto-injected conventions.**
Guides authoring .claude/rules/*.md files for auto-applied constraints scoped by file patterns. Use when creating or updating rules for code conventions and quality standards.
Guides authoring rule files in .claude/rules/ for project conventions including formatting, testing, commits, architecture, and referencing from CLAUDE.md.
Guides authoring .claude/rules/ files Claude follows, with golden format (imperative + consequence + mechanism), positive framing, and enforceability tests. Use when creating, improving, or reviewing project rules.
Share bugs, ideas, or general feedback.
Writing rules IS creating scoped, auto-injected conventions.
Rules auto-inject into context when files match their paths: glob. Keep them concise—every line costs tokens.
Core principle: Rules = path-scoped conventions, auto-injected when matching files are read. CLAUDE.md = broad project instructions loaded every session. Use rules when different paths need different conventions.
Violating the letter of the rules is violating the spirit of the rules.
Pattern: Skill Steps Handoff: none Next: none
Before ANY action, create task list using TaskCreate:
TaskCreate for EACH task below:
- Subject: "[writing-rules] Task N: <action>"
- ActiveForm: "<doing action>"
Tasks:
Announce: "Created 6 tasks. Starting execution..."
Execution rules:
TaskUpdate status="in_progress" BEFORE starting each taskTaskUpdate status="completed" ONLY after verification passesTaskList to confirm all completed| TDD Phase | Rule Creation | What You Do |
|---|---|---|
| RED | Test without rule | Work on matching files, note inconsistencies |
| Verify RED | Document gaps | Note where conventions were forgotten |
| GREEN | Write rule | Create .claude/rules/ file addressing gaps |
| Verify GREEN | Test injection | Verify rule activates on matching files |
| REFACTOR | Optimize scope | Tighten paths: globs, reduce line count |
Goal: Understand what convention to encode and where it applies.
Questions to answer:
Decision:
Does it apply broadly to ALL project work?
├─ Yes → Put in CLAUDE.md (loaded every session)
└─ No → Is it scoped to specific file paths?
├─ Yes → RULE with paths: glob
└─ No → Global rule (no paths:, but consider CLAUDE.md instead)
Verification: Can state the convention in one sentence and specify the glob pattern.
Goal: Work on matching files WITHOUT the rule. Note where convention is forgotten.
Process:
Verification: Documented at least 1 instance where convention was not followed.
Goal: Create rule file addressing the gaps you documented.
~/.claude/rules/ # User-level (global, all projects)
.claude/rules/ # Project-level
├── code-style.md # Global rule (no paths:)
├── api/
│ └── conventions.md # paths: ["src/api/**"]
└── testing/
└── guidelines.md # paths: ["**/*.test.ts"]
---
paths: # Omit for global rules
- "src/api/**/*.ts"
---
# Rule Title
- Constraint 1 (imperative: "MUST", "NEVER")
- Constraint 2
Rules are Markdown content injected into context (same as CLAUDE.md):
paths → loaded at session start (always active, like CLAUDE.md)paths → loaded when Claude reads a file matching the glob~/.claude/rules/ loads before project-level .claude/rules/ (project takes precedence)CRITICAL constraints:
Specific, imperative, scoped.
</Good>
<Bad>
```yaml
---
# No paths = global!
---
# Guidelines
- Try to validate input
- Consider using consistent response shapes
- It's good practice to handle errors
Vague, unscoped, passive.
Verification:
paths: (or intentionally global)Goal: Verify rule file structure is correct.
Checklist:
.claude/rules/ directorypaths: glob (or none for global)Verification: All checklist items pass.
Goal: Have rule reviewed by rule-reviewer subagent.
Agent tool:
- subagent_type: "rcc:rule-reviewer"
- prompt: "Review rule at [path]"
Outcomes:
Verification: rule-reviewer returns "Pass" rating.
Goal: Verify rule actually activates on matching files.
Process:
paths: patternVerification:
| Pattern | Matches |
|---|---|
**/*.ts | All TypeScript files |
src/api/** | All under src/api/ |
*.md | Markdown in root only |
{src,lib}/**/*.ts | Multiple directories |
**/*.{ts,tsx} | Multiple extensions |
!**/node_modules/** | Exclude pattern |
These thoughts mean you're rationalizing. STOP and reconsider:
All of these mean: You're about to create a weak rule. Follow the process.
| Excuse | Reality |
|---|---|
| "CLAUDE.md is overkill" | If it applies broadly to all work, it belongs in CLAUDE.md. |
| "Global rules are fine" | Global = always injected. Scope it properly. |
| "50 lines is arbitrary" | 50 lines × N matches = massive token cost. |
| "I can add procedures here" | Rules = what. Skills = how. Keep them separate. |
| "One comprehensive rule" | Multiple focused rules > one bloated rule. |
digraph rule_creation {
rankdir=TB;
start [label="Need rule", shape=doublecircle];
analyze [label="Task 1: Analyze\nrequirements", shape=box];
is_broad [label="Applies to\nall work?", shape=diamond];
use_claudemd [label="Put in\nCLAUDE.md", shape=box, style=filled, fillcolor="#ffcccc"];
baseline [label="Task 2: RED\nTest without rule", shape=box, style=filled, fillcolor="#ffcccc"];
write [label="Task 3: GREEN\nWrite rule", shape=box, style=filled, fillcolor="#ccffcc"];
validate [label="Task 4: Validate\nstructure", shape=box];
review [label="Task 5: REFACTOR\nQuality review", shape=box, style=filled, fillcolor="#ccccff"];
review_pass [label="Review\npassed?", shape=diamond];
test [label="Task 6: Test\nactivation", shape=box];
done [label="Rule complete", shape=doublecircle];
start -> analyze;
analyze -> is_broad;
is_broad -> use_claudemd [label="yes"];
is_broad -> baseline [label="no"];
baseline -> write;
write -> validate;
validate -> review;
review -> review_pass;
review_pass -> test [label="pass"];
review_pass -> write [label="fail"];
test -> done;
}