/blueprint:derive-rules
Extract project decisions from git commit history and codify them as Claude rules. Newer commits override older decisions when conflicts exist.
Use case: Derive implicit project patterns from git history to establish consistent AI-assisted development guidelines.
Usage: /blueprint:derive-rules [--since DATE] [--scope SCOPE]
When to Use This Skill
| Use this skill when... |
Use alternative when... |
| Want to extract implicit decisions from git history |
Creating rules from requirements (use PRDs instead) |
| Project has significant commit history |
New project with little history |
| Establishing project coding standards |
Quick manual rule creation |
Context
- Git repository: !
git rev-parse --git-dir
- Blueprint initialized: !
find . -path '*/docs/blueprint/*' -maxdepth 3 -name 'manifest.json' -type f
- Total commits: !
git rev-list --count HEAD
- Conventional commits %: !
git log --format="%s"
- Existing rules in default location: !
find . -path '*/.claude/rules/*' -maxdepth 3 -name "*.md" -type f
- Existing rules in blueprint subdir: !
find . -path '*/.claude/rules/blueprint/*' -maxdepth 4 -name "*.md" -type f
Parameters
Parse $ARGUMENTS:
--since DATE: Analyze commits from specific date (e.g., --since 2024-01-01)
--scope SCOPE: Focus on specific area (e.g., --scope api, --scope testing)
Execution
Execute the complete git-to-rules derivation workflow:
Step 0: Resolve the output path
Read structure.generated_rules_path from docs/blueprint/manifest.json (default .claude/rules/):
RULES_DIR=$(jq -r '.structure.generated_rules_path // ".claude/rules/"' docs/blueprint/manifest.json)
mkdir -p "$RULES_DIR"
Use $RULES_DIR for all subsequent reads/writes and conflict checks. Hand-written files in the parent .claude/rules/ are intentionally invisible to this skill (issue #1043).
Step 1: Verify prerequisites
- If not a git repository → Error: "This directory is not a git repository"
- If Blueprint not initialized → Suggest
/blueprint:init first
- If few commits (< 20) → Warn: "Limited commit history; derived rules may be incomplete"
Step 2: Analyze git history quality
- Calculate total commits in scope
- Calculate conventional commits percentage
- Report quality: Higher % = higher confidence in extracted rules
- Parse
--since and --scope flags to determine analysis range
Step 3: Extract decision-bearing commits
Use parallel agents to analyze git history efficiently (see REFERENCE.md):
- Agent 1: Analyze
refactor: commits for code style patterns
- Agent 2: Analyze
fix: commits for repeated issue types
- Agent 3: Analyze
feat!: and BREAKING CHANGE: commits for architecture decisions
- Agent 4: Analyze
chore: and build: commits for tooling decisions
Consolidate findings by domain (code-style, testing, api-design, etc.), chronologically (newest first), and by frequency (most common wins).
Step 4: Resolve conflicts
When multiple commits address the same topic:
- Detect conflicts using pattern matching:
git log --format="%H|%ai|%s" | grep "{topic}"
- Apply resolution strategy:
- Newer overrides older: Latest decision wins
- Higher frequency wins: If 5 commits say X and 1 says Y, X wins
- Breaking changes override:
feat!: trumps regular commits
- Mark overridden decisions as "superseded" with reference to newer decision
- Confirm significant decisions with user via AskUserQuestion
Step 5: Generate rules in $RULES_DIR
For each decision, generate rule file using template from REFERENCE.md. Write each file to $RULES_DIR/<filename>.md (the configured structure.generated_rules_path):
Extract source commit, date, type
Determine confidence level (High/Medium/Low based on commit frequency and clarity)
Generate actionable rule statement
Include code examples from commit diffs
Reference any superseded earlier decisions
REQUIRED: scope every generated rule via paths: frontmatter unless the rule genuinely applies everywhere. Rules without paths: load on every session and pollute context for unrelated work. Pick paths: from the source signal:
| Signal |
Source |
paths: value |
Rule body cites a specific file via "patterns extracted from <path>" |
Step 3 / 4 conflict resolution |
Glob over that file's directory: <dir>/**/*.<ext> |
Rule was derived from chore(deps) / build: commits |
Tooling-decision agent |
Lockfiles + manifests: package.json, pyproject.toml, Cargo.toml, go.mod, *.lock, biome.json, etc. |
Rule references a language (refactor: + JS-only code blocks) |
Code-style agent |
Language Glob: **/*.{js,jsx,ts,tsx}, **/*.py, **/*.rs |
| Rule is about tests |
Test-strategy agent |
**/*.{test,spec}.*, tests/**/*, test/**/* |
| Rule is about API endpoints |
API-design agent |
src/{api,routes}/**/*, **/*controller*, **/*handler* |
| Rule is about documentation |
Docs agent |
docs/**, **/*.md |
| Rule restates global project context (already in CLAUDE.md) |
any |
Do not emit — that's CLAUDE.md's job; abort the rule |
| Rule genuinely applies to every file (e.g. universal error-handling philosophy, security mindset) |
Rare |
Omit paths: deliberately and note "global rule" in the rule body |
Default to scoping. The auto-derived starting point: take every code block in the rule body, collect the file extensions / directory roots they reference, and emit those as paths:. Verify the resulting glob set actually matches files in the working tree before writing — an empty match list means the inferred scope is wrong; re-derive.
Generate separate rule files by category (see REFERENCE.md for canonical filenames and default paths: per category):
code-style.md, testing-standards.md, api-conventions.md, error-handling.md, dependencies.md, security-practices.md
Step 6: Handle conflicts with existing rules
Check for conflicts with existing rules only under $RULES_DIR (never the parent .claude/rules/, which may contain hand-authored content unrelated to blueprint):
- If conflicts found → Ask user: Git-derived overrides existing rule, or keep existing?
- Apply user choice: Update, merge, or keep separate
- Document conflict resolution in rule file
Step 7: Update task registry
Update the task registry entry in docs/blueprint/manifest.json:
jq --arg now "$(date -u +%Y-%m-%dT%H:%M:%SZ)" \
--arg sha "$(git rev-parse HEAD 2>/dev/null)" \
--argjson processed "${COMMITS_ANALYZED:-0}" \
--argjson created "${RULES_DERIVED:-0}" \
'.task_registry["derive-rules"].last_completed_at = $now |
.task_registry["derive-rules"].last_result = "success" |
.task_registry["derive-rules"].context.commits_analyzed_up_to = $sha |
.task_registry["derive-rules"].stats.runs_total = ((.task_registry["derive-rules"].stats.runs_total // 0) + 1) |
.task_registry["derive-rules"].stats.items_processed = $processed |
.task_registry["derive-rules"].stats.items_created = $created' \
docs/blueprint/manifest.json > tmp.json && mv tmp.json docs/blueprint/manifest.json
Step 8: Update manifest and report
- Update
docs/blueprint/manifest.json with derived rules metadata: timestamp, commits analyzed, rules generated, source commits
- Generate completion report showing:
- Commits analyzed (count and date range)
- Conventional commits percentage
- Rules generated by category
- Confidence scores per rule
- Any conflicts resolved
- Prompt user for next action: Review rules, execute derived development workflow, or done
Agentic Optimizations
| Context |
Command |
| Check git status |
git rev-parse --git-dir 2>/dev/null && echo "YES" || echo "NO" |
| Count total commits |
git rev-list --count HEAD 2>/dev/null || echo "0" |
| Conventional commits % |
git log --format="%s" | grep -c "^(feat|fix|refactor)" || echo 0 |
| Extract decision commits |
git log --format="%H|%s|%b" | grep -E "(always|never|must|prefer)" |
| Fast derivation |
Use parallel agents (Explore) for multi-domain analysis |
For git analysis patterns, rule templates, conflict resolution, and detailed procedures, see REFERENCE.md.
1---
2created: 2026-01-30
3modified: 2026-06-18
4reviewed: 2026-05-22
5description: Derive Claude rules from git commit history. Use when extracting implicit decisions from commits or codifying code-style, testing, and API-design rules.
6args: "[--since DATE] [--scope SCOPE]"
7argument-hint: "--since 2024-01-01 for date range, --scope api for specific area"
8allowed-tools: Read, Write, Glob, Grep, Bash, AskUserQuestion, Task
9model: opus
10name: blueprint-derive-rules
11---
12
13# /blueprint:derive-rules
14
15Extract project decisions from git commit history and codify them as Claude rules. Newer commits override older decisions when conflicts exist.
16
17**Use case**: Derive implicit project patterns from git history to establish consistent AI-assisted development guidelines.
18
19**Usage**: `/blueprint:derive-rules [--since DATE] [--scope SCOPE]`
20
21## When to Use This Skill
22
23| Use this skill when... | Use alternative when... |
24|------------------------|-------------------------|
25| Want to extract implicit decisions from git history | Creating rules from requirements (use PRDs instead) |
26| Project has significant commit history | New project with little history |
27| Establishing project coding standards | Quick manual rule creation |
28
29## Context
30
31- Git repository: !`git rev-parse --git-dir`
32- Blueprint initialized: !`find . -path '*/docs/blueprint/*' -maxdepth 3 -name 'manifest.json' -type f`
33- Total commits: !`git rev-list --count HEAD`
34- Conventional commits %: !`git log --format="%s"`
35- Existing rules in default location: !`find . -path '*/.claude/rules/*' -maxdepth 3 -name "*.md" -type f`
36- Existing rules in blueprint subdir: !`find . -path '*/.claude/rules/blueprint/*' -maxdepth 4 -name "*.md" -type f`
37
38## Parameters
39
40Parse `$ARGUMENTS`:
41
42- `--since DATE`: Analyze commits from specific date (e.g., `--since 2024-01-01`)
43- `--scope SCOPE`: Focus on specific area (e.g., `--scope api`, `--scope testing`)
44
45## Execution
46
47Execute the complete git-to-rules derivation workflow:
48
49### Step 0: Resolve the output path
50
51Read `structure.generated_rules_path` from `docs/blueprint/manifest.json` (default `.claude/rules/`):
52
53```bash
54RULES_DIR=$(jq -r '.structure.generated_rules_path // ".claude/rules/"' docs/blueprint/manifest.json)
55mkdir -p "$RULES_DIR"
56```
57
58Use `$RULES_DIR` for all subsequent reads/writes and conflict checks. Hand-written files in the parent `.claude/rules/` are intentionally invisible to this skill (issue #1043).
59
60### Step 1: Verify prerequisites
61
621. If not a git repository → Error: "This directory is not a git repository"
632. If Blueprint not initialized → Suggest `/blueprint:init` first
643. If few commits (< 20) → Warn: "Limited commit history; derived rules may be incomplete"
65
66### Step 2: Analyze git history quality
67
681. Calculate total commits in scope
692. Calculate conventional commits percentage
703. Report quality: Higher % = higher confidence in extracted rules
714. Parse `--since` and `--scope` flags to determine analysis range
72
73### Step 3: Extract decision-bearing commits
74
75Use parallel agents to analyze git history efficiently (see [REFERENCE.md](REFERENCE.md#git-analysis)):
76
77- **Agent 1**: Analyze `refactor:` commits for code style patterns
78- **Agent 2**: Analyze `fix:` commits for repeated issue types
79- **Agent 3**: Analyze `feat!:` and `BREAKING CHANGE:` commits for architecture decisions
80- **Agent 4**: Analyze `chore:` and `build:` commits for tooling decisions
81
82Consolidate findings by domain (code-style, testing, api-design, etc.), chronologically (newest first), and by frequency (most common wins).
83
84### Step 4: Resolve conflicts
85
86When multiple commits address the same topic:
87
881. Detect conflicts using pattern matching: `git log --format="%H|%ai|%s" | grep "{topic}"`
892. Apply resolution strategy:
90 - **Newer overrides older**: Latest decision wins
91 - **Higher frequency wins**: If 5 commits say X and 1 says Y, X wins
92 - **Breaking changes override**: `feat!:` trumps regular commits
933. Mark overridden decisions as "superseded" with reference to newer decision
944. Confirm significant decisions with user via AskUserQuestion
95
96### Step 5: Generate rules in `$RULES_DIR`
97
98For each decision, generate rule file using template from [REFERENCE.md](REFERENCE.md#rule-template). Write each file to `$RULES_DIR/<filename>.md` (the configured `structure.generated_rules_path`):
99
1001. Extract source commit, date, type
1012. Determine confidence level (High/Medium/Low based on commit frequency and clarity)
1023. Generate actionable rule statement
1034. Include code examples from commit diffs
1045. Reference any superseded earlier decisions
1056. **REQUIRED: scope every generated rule via `paths:` frontmatter unless the rule genuinely applies everywhere.** Rules without `paths:` load on every session and pollute context for unrelated work. Pick `paths:` from the source signal:
106
107 | Signal | Source | `paths:` value |
108 |---|---|---|
109 | Rule body cites a specific file via "patterns extracted from `<path>`" | Step 3 / 4 conflict resolution | Glob over that file's directory: `<dir>/**/*.<ext>` |
110 | Rule was derived from `chore(deps)` / `build:` commits | Tooling-decision agent | Lockfiles + manifests: `package.json`, `pyproject.toml`, `Cargo.toml`, `go.mod`, `*.lock`, `biome.json`, etc. |
111 | Rule references a language (`refactor:` + JS-only code blocks) | Code-style agent | Language Glob: `**/*.{js,jsx,ts,tsx}`, `**/*.py`, `**/*.rs` |
112 | Rule is about tests | Test-strategy agent | `**/*.{test,spec}.*`, `tests/**/*`, `test/**/*` |
113 | Rule is about API endpoints | API-design agent | `src/{api,routes}/**/*`, `**/*controller*`, `**/*handler*` |
114 | Rule is about documentation | Docs agent | `docs/**`, `**/*.md` |
115 | Rule restates global project context (already in CLAUDE.md) | _any_ | **Do not emit** — that's CLAUDE.md's job; abort the rule |
116 | Rule genuinely applies to every file (e.g. universal error-handling philosophy, security mindset) | Rare | Omit `paths:` deliberately and note "global rule" in the rule body |
117
118 Default to scoping. The auto-derived starting point: take every code block in the rule body, collect the file extensions / directory roots they reference, and emit those as `paths:`. Verify the resulting glob set actually matches files in the working tree before writing — an empty match list means the inferred scope is wrong; re-derive.
119
120Generate separate rule files by category (see [REFERENCE.md](REFERENCE.md#rule-categories) for canonical filenames and default `paths:` per category):
121- `code-style.md`, `testing-standards.md`, `api-conventions.md`, `error-handling.md`, `dependencies.md`, `security-practices.md`
122
123### Step 6: Handle conflicts with existing rules
124
125Check for conflicts with existing rules **only under `$RULES_DIR`** (never the parent `.claude/rules/`, which may contain hand-authored content unrelated to blueprint):
126
1271. If conflicts found → Ask user: Git-derived overrides existing rule, or keep existing?
1282. Apply user choice: Update, merge, or keep separate
1293. Document conflict resolution in rule file
130
131### Step 7: Update task registry
132
133Update the task registry entry in `docs/blueprint/manifest.json`:
134
135```bash
136jq --arg now "$(date -u +%Y-%m-%dT%H:%M:%SZ)" \
137 --arg sha "$(git rev-parse HEAD 2>/dev/null)" \
138 --argjson processed "${COMMITS_ANALYZED:-0}" \
139 --argjson created "${RULES_DERIVED:-0}" \
140 '.task_registry["derive-rules"].last_completed_at = $now |
141 .task_registry["derive-rules"].last_result = "success" |
142 .task_registry["derive-rules"].context.commits_analyzed_up_to = $sha |
143 .task_registry["derive-rules"].stats.runs_total = ((.task_registry["derive-rules"].stats.runs_total // 0) + 1) |
144 .task_registry["derive-rules"].stats.items_processed = $processed |
145 .task_registry["derive-rules"].stats.items_created = $created' \
146 docs/blueprint/manifest.json > tmp.json && mv tmp.json docs/blueprint/manifest.json
147```
148
149### Step 8: Update manifest and report
150
1511. Update `docs/blueprint/manifest.json` with derived rules metadata: timestamp, commits analyzed, rules generated, source commits
1522. Generate completion report showing:
153 - Commits analyzed (count and date range)
154 - Conventional commits percentage
155 - Rules generated by category
156 - Confidence scores per rule
157 - Any conflicts resolved
1583. Prompt user for next action: Review rules, execute derived development workflow, or done
159
160## Agentic Optimizations
161
162| Context | Command |
163|---------|---------|
164| Check git status | `git rev-parse --git-dir 2>/dev/null && echo "YES" \|\| echo "NO"` |
165| Count total commits | `git rev-list --count HEAD 2>/dev/null \|\| echo "0"` |
166| Conventional commits % | `git log --format="%s" \| grep -c "^(feat\|fix\|refactor)" \|\| echo 0` |
167| Extract decision commits | `git log --format="%H\|%s\|%b" \| grep -E "(always\|never\|must\|prefer)"` |
168| Fast derivation | Use parallel agents (Explore) for multi-domain analysis |
169
170---
171
172For git analysis patterns, rule templates, conflict resolution, and detailed procedures, see [REFERENCE.md](REFERENCE.md).