Rule Extraction
This skill teaches you how to extract a structured, line-numbered list of rules from a skill directory.
What Counts as a Rule
A rule is any statement that prescribes or constrains agent behavior. Recognize rules by their form:
- Imperative directives: "Always add type annotations", "Never use
var"
- Prohibition patterns: "Do not X", "Avoid X", "禁止 X"
- Requirement patterns: "Must X", "Should X", "需要 X", "必须 X"
- Conditional behavior: "If X, then Y", "When X, do Y"
- Style/format mandates: "Use camelCase", "Limit lines to 80 characters"
- Preference statements: "Prefer X over Y", "优先使用 X"
Rules can appear as:
- Bullet list items (
- or * or +)
- Numbered list items (
1., 2.)
- Bold or emphasized sentences (
**Always do X**)
- Plain sentences within a paragraph that contain directive language
- Section headers that are themselves imperatives ("Never commit secrets")
What Does NOT Count as a Rule
Exclude the following from extraction:
- Descriptive text: Explanations of why a rule exists, background context
- Examples: Code blocks, sample outputs, "for example..." passages
- Metadata: YAML frontmatter, version info, author notes
- Headings that introduce a section (unless the heading itself is an imperative rule)
- Vague non-actionable statements: "Do good work", "Be helpful" — extract these but flag them as
vague: true
Output Format
Return a JSON array. Each rule is an object:
[
{
"id": 1,
"file": "SKILL.md",
"line": 12,
"text": "Always add type annotations to function parameters",
"source_text": "- Always add type annotations to function parameters",
"vague": false
},
{
"id": 2,
"file": "SKILL.md",
"line": 15,
"text": "Do not use var, prefer const or let",
"source_text": "**Do not use `var`** — prefer `const` or `let`",
"vague": false
},
{
"id": 3,
"file": "examples.md",
"line": 4,
"text": "Do good work",
"source_text": "- Do good work",
"vague": true
}
]
Field definitions:
id: Sequential integer starting from 1, across all files combined
file: Filename (basename only, e.g. SKILL.md, examples.md) where the rule appears
line: Line number within that file where the rule appears (1-indexed)
text: Cleaned rule text, stripped of markdown formatting
source_text: Original raw line as it appears in the file
vague: true if the rule is too broad to be actionable
Input Scope
The input is a skill directory path (e.g. ~/.claude/skills/humanizer/).
Files to read: all *.md files directly inside the skill directory — SKILL.md first, then any other *.md files in alphabetical order.
Files to skip:
- Subdirectories and any files inside them (no recursive scan)
- Non-markdown files (
.sh, .py, .js, .json, etc.)
Extraction Process
- List all
*.md files at the top level of the skill directory (non-recursive). Read SKILL.md first if present; read remaining *.md files in alphabetical order.
- For each file, read it line by line, tracking line numbers within that file.
- Skip frontmatter (everything between
--- delimiters at the top of each file)
- Skip code blocks (between
``` fences) — these are examples, not rules
- For each line, determine if it contains a rule using the criteria above
- For paragraph text: split into sentences, check each sentence independently
- Clean the extracted text: remove markdown syntax (
-, *, **, backticks) but preserve the meaning
- Assign line numbers based on where the rule text starts within its file
- Record the source filename for every rule
Handling Ambiguous Cases
- Compound bullet: "Use camelCase and limit lines to 80 chars" → split into two rules, both on the same line number
- Nested bullets: Treat each nested item as an independent rule
- Conditional rules: Keep the full conditional ("If Python, use type hints") as one rule — do not split on the condition
- Negated rules: "Don't use X" and "Never use X" are equivalent — normalize to a consistent form in
text, preserve original in source_text
Example
Input skill directory: ~/.claude/skills/code-style/
Files found at top level: SKILL.md, extra-rules.md
(Any subdirectory contents are ignored.)
SKILL.md:
---
name: Code Style
---
# Code Style Guidelines
Keep code clean and maintainable.
## Naming
- Use camelCase for variables and functions
- Use PascalCase for classes and types
- Never use single-letter variable names except for loop indices
## Comments
Always write comments in English.
Do not write comments explaining what the code does — only explain why.
## Example
\`\`\`python
# good
def calculate_total(items):
return sum(items)
\`\`\`
extra-rules.md:
- Prefer explicit returns over implicit ones
Output:
[
{
"id": 1,
"file": "SKILL.md",
"line": 10,
"text": "Use camelCase for variables and functions",
"source_text": "- Use camelCase for variables and functions",
"vague": false
},
{
"id": 2,
"file": "SKILL.md",
"line": 11,
"text": "Use PascalCase for classes and types",
"source_text": "- Use PascalCase for classes and types",
"vague": false
},
{
"id": 3,
"file": "SKILL.md",
"line": 12,
"text": "Never use single-letter variable names except for loop indices",
"source_text": "- Never use single-letter variable names except for loop indices",
"vague": false
},
{
"id": 4,
"file": "SKILL.md",
"line": 15,
"text": "Always write comments in English",
"source_text": "Always write comments in English.",
"vague": false
},
{
"id": 5,
"file": "SKILL.md",
"line": 16,
"text": "Do not write comments explaining what the code does — only explain why",
"source_text": "Do not write comments explaining what the code does — only explain why.",
"vague": false
},
{
"id": 6,
"file": "extra-rules.md",
"line": 1,
"text": "Prefer explicit returns over implicit ones",
"source_text": "- Prefer explicit returns over implicit ones",
"vague": false
}
]
Notes:
- SKILL.md lines 18–23 (the code block) are skipped entirely
id is sequential across all files; line resets to 1 for each new file
- Any subdirectories inside
~/.claude/skills/code-style/ are not scanned
1---2name: rule-extraction3description: Extract a structured list of rules from all markdown files at the top level of a skill directory. Use this skill whenever you need to parse rules out of a skill for conflict checking, merging, or diffing.4---56# Rule Extraction78This skill teaches you how to extract a structured, line-numbered list of rules from a skill directory.910## What Counts as a Rule1112A **rule** is any statement that prescribes or constrains agent behavior. Recognize rules by their form:1314- **Imperative directives**: "Always add type annotations", "Never use `var`"15- **Prohibition patterns**: "Do not X", "Avoid X", "禁止 X"16- **Requirement patterns**: "Must X", "Should X", "需要 X", "必须 X"17- **Conditional behavior**: "If X, then Y", "When X, do Y"18- **Style/format mandates**: "Use camelCase", "Limit lines to 80 characters"19- **Preference statements**: "Prefer X over Y", "优先使用 X"2021Rules can appear as:22- Bullet list items (`-` or `*` or `+`)23- Numbered list items (`1.`, `2.`)24- Bold or emphasized sentences (`**Always do X**`)25- Plain sentences within a paragraph that contain directive language26- Section headers that are themselves imperatives ("Never commit secrets")2728## What Does NOT Count as a Rule2930Exclude the following from extraction:3132- **Descriptive text**: Explanations of why a rule exists, background context33- **Examples**: Code blocks, sample outputs, "for example..." passages34- **Metadata**: YAML frontmatter, version info, author notes35- **Headings that introduce a section** (unless the heading itself is an imperative rule)36- **Vague non-actionable statements**: "Do good work", "Be helpful" — extract these but flag them as `vague: true`3738## Output Format3940Return a JSON array. Each rule is an object:4142```json43[44 {45 "id": 1,46 "file": "SKILL.md",47 "line": 12,48 "text": "Always add type annotations to function parameters",49 "source_text": "- Always add type annotations to function parameters",50 "vague": false51 },52 {53 "id": 2,54 "file": "SKILL.md",55 "line": 15,56 "text": "Do not use var, prefer const or let",57 "source_text": "**Do not use `var`** — prefer `const` or `let`",58 "vague": false59 },60 {61 "id": 3,62 "file": "examples.md",63 "line": 4,64 "text": "Do good work",65 "source_text": "- Do good work",66 "vague": true67 }68]69```7071Field definitions:72- `id`: Sequential integer starting from 1, across all files combined73- `file`: Filename (basename only, e.g. `SKILL.md`, `examples.md`) where the rule appears74- `line`: Line number within that file where the rule appears (1-indexed)75- `text`: Cleaned rule text, stripped of markdown formatting76- `source_text`: Original raw line as it appears in the file77- `vague`: `true` if the rule is too broad to be actionable7879## Input Scope8081The input is a **skill directory path** (e.g. `~/.claude/skills/humanizer/`).8283**Files to read:** all `*.md` files directly inside the skill directory — `SKILL.md` first, then any other `*.md` files in alphabetical order.8485**Files to skip:**86- Subdirectories and any files inside them (no recursive scan)87- Non-markdown files (`.sh`, `.py`, `.js`, `.json`, etc.)8889## Extraction Process90911. **List** all `*.md` files at the top level of the skill directory (non-recursive). Read `SKILL.md` first if present; read remaining `*.md` files in alphabetical order.922. **For each file**, read it line by line, tracking line numbers within that file.933. **Skip frontmatter** (everything between `---` delimiters at the top of each file)944. **Skip code blocks** (between ` ``` ` fences) — these are examples, not rules955. **For each line**, determine if it contains a rule using the criteria above966. **For paragraph text**: split into sentences, check each sentence independently977. **Clean the extracted text**: remove markdown syntax (`-`, `*`, `**`, backticks) but preserve the meaning988. **Assign line numbers** based on where the rule text starts within its file999. **Record the source filename** for every rule100101## Handling Ambiguous Cases102103- **Compound bullet**: "Use camelCase and limit lines to 80 chars" → split into two rules, both on the same line number104- **Nested bullets**: Treat each nested item as an independent rule105- **Conditional rules**: Keep the full conditional ("If Python, use type hints") as one rule — do not split on the condition106- **Negated rules**: "Don't use X" and "Never use X" are equivalent — normalize to a consistent form in `text`, preserve original in `source_text`107108## Example109110Input skill directory: `~/.claude/skills/code-style/`111Files found at top level: `SKILL.md`, `extra-rules.md`112(Any subdirectory contents are ignored.)113114**SKILL.md:**115```116---117name: Code Style118---119120# Code Style Guidelines121122Keep code clean and maintainable.123124## Naming125- Use camelCase for variables and functions126- Use PascalCase for classes and types127- Never use single-letter variable names except for loop indices128129## Comments130Always write comments in English.131Do not write comments explaining what the code does — only explain why.132133## Example134\`\`\`python135# good136def calculate_total(items):137 return sum(items)138\`\`\`139```140141**extra-rules.md:**142```143- Prefer explicit returns over implicit ones144```145146Output:147```json148[149 {150 "id": 1,151 "file": "SKILL.md",152 "line": 10,153 "text": "Use camelCase for variables and functions",154 "source_text": "- Use camelCase for variables and functions",155 "vague": false156 },157 {158 "id": 2,159 "file": "SKILL.md",160 "line": 11,161 "text": "Use PascalCase for classes and types",162 "source_text": "- Use PascalCase for classes and types",163 "vague": false164 },165 {166 "id": 3,167 "file": "SKILL.md",168 "line": 12,169 "text": "Never use single-letter variable names except for loop indices",170 "source_text": "- Never use single-letter variable names except for loop indices",171 "vague": false172 },173 {174 "id": 4,175 "file": "SKILL.md",176 "line": 15,177 "text": "Always write comments in English",178 "source_text": "Always write comments in English.",179 "vague": false180 },181 {182 "id": 5,183 "file": "SKILL.md",184 "line": 16,185 "text": "Do not write comments explaining what the code does — only explain why",186 "source_text": "Do not write comments explaining what the code does — only explain why.",187 "vague": false188 },189 {190 "id": 6,191 "file": "extra-rules.md",192 "line": 1,193 "text": "Prefer explicit returns over implicit ones",194 "source_text": "- Prefer explicit returns over implicit ones",195 "vague": false196 }197]198```199200Notes:201- SKILL.md lines 18–23 (the code block) are skipped entirely202- `id` is sequential across all files; `line` resets to 1 for each new file203- Any subdirectories inside `~/.claude/skills/code-style/` are not scanned