| name | shape-rule-review |
| description | Review the condition of an "AI rules" file (CLAUDE.md, AGENTS.md, .cursor/rules/*.mdc, .github/copilot-instructions.md, .windsurfrules, nested per-area rule files, or any other rule-for-AI markdown) and produce a 5-point scorecard with concrete, actionable fixes. Use when the user invokes /shape-rule-review with a path to a rules file, or asks to "review AI rules", "audit AGENTS.md", "check my CLAUDE.md", "score my agent instructions", "is this rules file healthy", or similar. The skill is agnostic to which tool the rules file targets โ it scores the file as a rule-for-AI artifact, not as a project document.
|
| allowed-tools | ["Read","Glob","Grep","Edit","AskUserQuestion"] |
Shape Rule Review
Score an AI rules file on five axes and return concrete fixes. The file under review is whatever rule-for-AI markdown the user passes in โ this skill does not assume CLAUDE.md, AGENTS.md, or any specific tool.
The skill never edits the file. It produces a scorecard. The user decides what to act on.
Input resolution
$ARGUMENTS should be a path to a single markdown file (absolute, repo-relative, or @-prefixed). Examples:
@CLAUDE.md
AGENTS.md
.cursor/rules/api.mdc
src/api/AGENTS.md
.github/copilot-instructions.md
~/.claude/CLAUDE.md
If $ARGUMENTS is empty, ask the user once for the path. Do not guess.
If the path resolves to a directory, ask which file to review. If it resolves to multiple files (e.g. **/AGENTS.md), score them one at a time and report each scorecard separately โ do not merge.
If the file does not exist, stop and report the path. Do not invent content.
What this skill does NOT do
- Does not edit the rules file unless the user explicitly approves the reorder proposed by Check 5. The default output is read-only.
- Does not generate a full "fixed version" of the file. At most, Check 5 may move/regroup sections; it never rewrites rule content.
- Does not assume the file's tool target. CLAUDE.md, AGENTS.md,
.mdc, .windsurfrules, custom names โ all treated as "a rules-for-AI file".
- Does not score project content (architecture, tech choices, conventions). It scores the rule artifact's condition โ the same way a code review scores code, not the product.
Procedure
Pre-step โ Resolve CONTEXT_ROOT and exclude context/ from git
Before reading or writing anything under context/, apply the context-root protocol documented in ../shape-init/references/context-root-protocol.md (or invoke /shape-init via the Skill tool, which runs the same protocol as its Step 0). The protocol does two things in one block:
- Resolves
CONTEXT_ROOT โ the directory context/ lives in. Inside a git repo, that's the parent of git rev-parse --git-common-dir (the main working tree of the repo, even when invoked from a worktree). Outside a git repo, it's the cwd. Anywhere this skill's instructions say context/foo/bar.md, treat it as $CONTEXT_ROOT/context/foo/bar.md.
- Excludes
context/ from git โ appends one line to <git-common-dir>/info/exclude (repo-local, untracked, never committed, shared by every worktree of the same repo). Idempotent: skipped if context/ is already excluded.
Why this skill cares about the worktree case: if the user has a layout like ~/Projects/kibana (main) plus ~/Projects/kibana.worktrees/feature-a, ~/Projects/kibana.worktrees/feature-b, etc., they don't want to re-init each worktree. The protocol resolves CONTEXT_ROOT to ~/Projects/kibana from any of those locations โ so /shape-prd writes the same prd.md regardless of which worktree it ran from, and the git-exclude line is set once for the whole repo.
Why this skill cares about the exclude case: when the user is running this command from inside a shared repository they don't own (kibana, an upstream monorepo), the artifact this skill writes under context/ is a personal working note. It must never be staged, committed, or pushed by accident. The exclusion lives only in the user's clone (in info/exclude, never in .gitignore) and cannot leak upstream.
The protocol is idempotent and safe โ if context/ is already excluded, this is a no-op. If you are not inside a git repo at all, CONTEXT_ROOT is just the cwd and there is no exclude to write. Surface a one-line git-exclude: <state> in this skill's final summary, plus a context-root: <path> line when CONTEXT_ROOT differs from cwd (so the user knows their notes are in the shared, worktree-spanning location).
Do not edit .gitignore. /shape-init mode=gitignore is the only path that touches the tracked .gitignore, and only when the user explicitly opted in.
- Read the file in full (use
Read once; if it's > 2000 lines, read in chunks until complete).
- Compute Checks 1โ4.
- Run Check 5 in its own multi-step flow (5a list โ 5b comment โ 5c propose โ 5d ask via
AskUserQuestion โ 5e atomic-change reminder). The reorder edit, if any, happens here and only with explicit user approval.
- Print the scorecard in the exact format under "Output format". Include the reorder-proposal summary and the user's decision in the Check 5 findings.
- Stop. Do not propose further follow-up actions unless the user asks.
The 5 checks
Check 1 โ Length
Count non-empty lines (ignore blank lines and pure separator lines like ---).
| Lines | Verdict | Symbol |
|---|
| 0โ200 | fine | OK |
| 201โ500 | watch out | WARN |
| 501+ | warn | FAIL |
Why it matters: long rule files crowd out the user's prompt in the context window, and middle-of-file rules get the weakest attention from the model. Length is a proxy for "you're paying context for things the agent doesn't need every session."
For WARN/FAIL, suggest:
- Split per-area rules into nested files closer to their code (e.g.
src/api/AGENTS.md).
- Replace duplicated docs with
@-references to the canonical file.
- Drop rules that aren't tied to a recurring agent failure mode.
Check 2 โ Direct code/config snippets
Scan for fenced code blocks (```) and inline code blocks longer than ~3 lines.
Flag any block that looks like:
- An example component, endpoint, migration, schema, query, bash script or test.
- A configuration file (
tsconfig.json, eslintrc, package.json, wrangler.toml).
- A migration template or boilerplate that lives elsewhere in the repo.
Do not flag:
- Short structural snippets used to define a format the agent must produce (e.g. a 2โ4 line error-shape template).
- Command examples (
npm run dev, git rebase, etc.).
- Mermaid/diagram blocks.
For each flagged block, suggest:
- Move the snippet to a real file in the repo.
- Replace the block with a one-line
@-reference, e.g. @src/features/users/user.service.ts, @docs/api-errors.md.
- Reason: the example will be wrong in two places at the next refactor; a reference can't drift.
Verdict: OK if 0 flagged blocks ยท WARN if 1โ2 ยท FAIL if 3+.
Check 3 โ Precise language
Scan for vague intent that cannot be checked against a diff. Common offenders:
- "Write clean code"
- "Follow best practices"
- "Care about quality"
- "Be consistent"
- "Use modern patterns"
- "Make it readable / maintainable / robust"
- "Handle errors properly"
- "Keep things simple"
For every match, always propose at least one concrete, testable alternative grounded in this project's context. Never suggest "just delete it" โ the author put the line there for a reason; your job is to translate the intent into something a reviewer can check against a diff.
To ground the suggestion, pull signal from:
- the file under review (stack mentioned, naming conventions stated elsewhere, hard rules in other sections),
- nearby paragraphs around the vague phrase (what was the author about to say?),
- visible repo context if available (
package.json, tsconfig.json, framework choice, lint config, sibling rule files).
If the project context truly doesn't suggest anything specific, propose a sensible default for the detected stack and label it (assumed) so the author knows to confirm.
Examples (note how each replacement borrows project-specific names/conventions, not generic advice):
| Vague phrase in file | Project context signal | Grounded testable replacement |
|---|
| "Write clean code" | TypeScript + ESLint mentioned in same file | "Avoid any. Functions over 40 lines must be split. Run pnpm lint before committing." |
| "Handle errors properly" | Hard rule earlier: API returns { error: {...} } shape | "API handlers must return { error: { code, message, context } } per the shape defined above. Never throw raw." |
| "Be consistent with naming" | File mentions feature.handler.ts elsewhere | "Use <feature>.handler.ts (matching the existing handlers in src/api/), not featureHandler.ts." |
| "Use modern patterns" | Project uses native JS, no lodash in package.json | "Use native Array/Object methods. Do not add lodash โ it's not in package.json and we keep it that way." |
| "Make components readable" | React + Tailwind project | "Components over 150 lines must be split. Tailwind classes go through cn() for conditionals (assumed โ confirm if a different helper is used)." |
| "Keep things simple" | Python FastAPI service | "Prefer one Pydantic model per request/response. No nested decorators beyond @router.post + @requires_auth." |
Verdict: OK if 0 vague phrases ยท WARN if 1โ3 ยท FAIL if 4+.
Verdict: OK if 0 vague phrases ยท WARN if 1โ3 ยท FAIL if 4+.
Check 4 โ Redundant knowledge
You are the actor agent reviewing this file. Read it the way you'd read it at the start of a session and ask one question after each paragraph:
"Did I already know this before I opened the file?"
If the answer is "yes, this is in my training data" or "yes, this is the framework's documented default" or "yes, the README/lint config already says this" โ flag it. The author paid context for something you didn't need explained.
Use these self-checks while scanning:
- The "no surprise" test. Could you have produced this paragraph yourself if asked, with no project access? If yes โ redundant.
- The "framework default" test. Is the rule restating something the framework, the lint config, the type checker, or the test runner already enforces (e.g. "use TypeScript strict mode", "use
useEffect cleanup", "FastAPI uses Pydantic for validation", "PostgreSQL supports JSONB")? If yes โ redundant. The tool will catch the violation; the prose won't add anything.
- The "definition" test. Does the paragraph define a generic engineering term ("what is a service layer", "what REST is", "what hooks are", "what JSX is", "what is
Decimal")? You know these. Flag and delete.
- The "could be a link" test. Does it duplicate
README.md, package.json scripts, the project layout, or .eslintrc settings? If yes โ replace with @README.md / @package.json / @.eslintrc.json. A reference doesn't drift; copied prose does.
- The "tutorial smell" test. If the paragraph reads like a section from the framework's "Getting Started" page or a Medium article โ it's tutorial content, not project knowledge. You read those during training.
What is not redundant (don't flag):
- Project-specific conventions that contradict the framework default ("we use
useEffect only for non-data side effects").
- Local pitfalls and historical workarounds you couldn't infer from the code ("the
events table is partitioned by month โ bulk inserts to the wrong partition fail silently").
- Internal naming, layout, or workflow rules ("postings live in
<verb>_<noun>.posting.ts").
- Rules that look generic but are tied to a real incident (the file should mention the incident or link to a failure-modes register).
For each flagged paragraph, suggest one of:
- Delete it โ you already knew it.
- Replace with
@-reference โ @README.md, @tsconfig.json, @docs/....
- Keep only if backed by an incident โ and if so, ask the author to add the incident note inline so the rule survives future audits.
Verdict: OK if 0 redundant paragraphs ยท WARN if 1โ3 ยท FAIL if 4+.
Check 5 โ Rule ordering
Models pay more attention to the start and end of long contexts ("U-shaped attention"). Critical rules buried in the middle of a long file are statistically less likely to be followed. This check has its own multi-step flow because reordering a file is a meaningful edit, not a one-line fix.
Run the steps in order. The result of this check goes into the scorecard and may trigger an interactive reorder.
Step 5a โ List the current high-level order
Walk the file and print the current top-level structure as a numbered list. Use H1/H2 headings (and H3s only if there are no H2s). Include the line number of each heading. Do not comment yet โ just lay out what's there.
Example:
Current order:
1. # Welcome to OrderFlow (line 1)
2. ## About the team (line 5)
3. ## Project mission (line 9)
4. ## Our values (line 13)
5. ## Tech stack (line 22)
6. ## Setup (line 36)
7. ## TypeScript (line 78)
...
N. ## Project conventions (line 312)
If the file has no headings, say so explicitly: "No section headings โ file is one undifferentiated block."
Step 5b โ Comment on the order
Now annotate the list. For each section, give it a short tag and a one-line note. Use these tags:
- CRITICAL โ load-bearing rule (security, money, irreversibility, project-specific "never do X").
- USEFUL โ real project knowledge that helps but isn't a tripwire.
- INTRO โ welcome/mission/team โ lowers signal density at the top.
- REDUNDANT โ already flagged in Check 4 (framework defaults, definitions, tutorial content).
- VAGUE โ already flagged in Check 3.
- REFERENCE โ points to other files via
@-syntax (cheap, fine anywhere).
Then state the structural problem in one paragraph. Examples:
"Critical security and tenancy rules are at the bottom (line 312). The first 35 lines are INTRO/values/marketing, which the model will weight heavily but which contain no actionable rules. Risk: the agent reads the bloat fully and skims past the rules that actually matter."
"Order is roughly correct โ hard rules at top, conventions in the middle, references at the bottom. One INTRO paragraph at line 1 could be tightened, but no structural reshuffle needed."
Step 5c โ Propose a better order (only if needed)
If the comment in 5b identified a real problem, propose a target order. Frame it as "sections moved to top / kept / moved to bottom / removed", not as a full rewrite of every line.
Example:
Proposed order:
1. ## Hard rules (was: line 312) โ moved to top
2. ## Project conventions (was: line 312, split) โ moved up
3. ## Tech stack (was: line 22) โ kept
4. ## Setup (was: line 36) โ kept, replace with @README.md if possible
5. ## Failure modes (new section) โ collect incident-driven rules here
โ ## About the team / Mission / Values โ remove (Check 3/4 already flagged these)
If 5b found no problem, skip 5c entirely โ say "Order is sound; no reshuffle needed."
Step 5d โ Ask before reordering
If 5c produced a proposal, ask the user via AskUserQuestion before touching the file. Phrase the question concretely. Example options:
- Yes, reorder the file now โ apply the proposed structure, preserve all rule content, only move/regroup sections.
- Only move the critical rules to the top โ minimal change: lift hard rules to the top, leave the rest alone.
- No, just leave the suggestion in the report โ don't edit the file; the scorecard stands.
- Show me the diff first โ produce the reordered file as a preview block in chat, no write.
If the user picks an editing option, apply it with care: preserve every byte of rule content (only headings and section blocks move), and write a single edit. If the user picks "leave the suggestion", do nothing.
Step 5e โ Atomic-change reminder
Always end Check 5 with this reminder, regardless of whether a reorder happened:
Test each change in your next agent session. Reordering a rules file is a context-shape change โ its effect on agent behavior only shows up the next time you run a real task. Apply changes one at a time (atomic): reorder, then run a representative task, then move on to the next change (split, dedupe, rewrite). Bundling multiple structural changes makes it impossible to attribute a behavior shift to a specific edit.
Verdict
Score the file before any reorder happens, based on the original order:
- OK โ top of file is dense with CRITICAL/USEFUL rules, clear headings, no INTRO bloat at the start.
- WARN โ structure is mixed: some critical rules at top, others buried; or non-trivial INTRO at the start.
- FAIL โ critical rules appear after line 200, or the file has no headings at all, or the top 30+ lines are pure INTRO/marketing.
Output format
Print exactly this, in this order. Use Polish or English matching the user's prompt language. Reference path:line for every concrete finding so the user can jump straight to it.
# Rule Review โ <path>
**Overall:** <one-line summary, e.g. "Healthy file with two redundancy hotspots" or "Long, vague, and bottom-heavy โ needs a split">
## Scorecard
| # | Check | Verdict | Score |
|---|----------------------|---------|-------|
| 1 | Length | OK/WARN/FAIL | <n> non-blank lines |
| 2 | Direct snippets | OK/WARN/FAIL | <n> flagged blocks |
| 3 | Precise language | OK/WARN/FAIL | <n> vague phrases |
| 4 | Redundant knowledge | OK/WARN/FAIL | <n> redundant rules |
| 5 | Rule ordering | OK/WARN/FAIL | <one-line reason> |
## Findings
### 1. Length โ <verdict>
- <n> non-blank lines.
- <suggestion if WARN/FAIL, otherwise omit>
### 2. Direct snippets โ <verdict>
- `path:line-range` โ <what kind of snippet> โ suggest `@<file>` reference.
- ...
### 3. Precise language โ <verdict>
- `path:line` โ "<vague phrase>" โ "<testable rewrite>"
- ...
### 4. Redundant knowledge โ <verdict>
- `path:line` โ <what's redundant> โ <delete | replace with @reference | keep only if backed by an incident>
- ...
### 5. Rule ordering โ <verdict>
- <structural observation, e.g. "Critical security rule at line 287, intro fluff lines 1โ42">
- <suggestion>
## Top 3 actions
1. <highest-leverage fix>
2. <second>
3. <third>
If a check is OK, still list it in the table but skip the "Findings" subsection (write ### N. <name> โ OK and one short line, nothing more).
The "Top 3 actions" must be ordered by leverage, not by check number. Pick from across all five checks.
Edge cases
- File under 50 lines: still run all five checks. Short files often fail Check 3 (vague) and Check 4 (redundant) the most.
- File is mostly references (
@โฆ) and few inline rules: that's a good sign for Checks 2 and 4. Don't penalize it.
- File is a
.mdc with frontmatter (globs:, alwaysApply:): count rule lines from after the frontmatter. The frontmatter itself is configuration, not rule content.
- File is a generated stub from
/init and untouched: still review it. Often Check 4 (redundant) will dominate โ that's the signal to clean it.
- Multiple rule files in the project: review the one passed in. Mention sibling files in "Top 3 actions" only if relevant (e.g. duplication between root
AGENTS.md and a nested one).