agentleFS
broneqbroneq/bdk/skills/refine-rules/SKILL.md

refine-rules

Skill1 starsChanged 48 days agoMITView on GitHub

Compact and verify .claude/rules/*.md against real code — admission test, relocation into doc comments, budgets, uniform format. Use on "clean up rules", "refine .claude/rules", or stale/bloated rule files.

The file

We split this skill into the rules it gives an agent

6 rules. About 0 are common, 3 are distinctive, and 3 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈3

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 3

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    Treat every existing sentence as an unverified claim, not a fact.

    line 22
  2. Distinctive:

    Run the discovery script instead of parsing the files by hand:

    line 29
  3. Very specific:

    Read references/rule-admission.md (the prime directive, the admission test - durability / decision / visibility / derivability) and …

    line 57
  4. Very specific:

    When several destinations fit, prefer in this order: narrow glob > wide glob > skill > doc comment > nothing.

    line 78
  5. Very specific:

    Use references/uniform-rule-format.md as the template for every file: same bullet shape (bold falsifiable claim.

    line 129
  6. Distinctive:

    Only proceed to Step 6 after approval.

    line 171

≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

Refine Rules

Relies on BDK foundation (STARTUP_INSTRUCTIONS.md). Assumes environment discovery has already run (language, test runner, build tool are known).

Rewrite .claude/rules/ (or the directory at $ARGUMENTS) into rule files that describe only the current, verified state of the code — no history, no changelog, no guesses — in one uniform voice across every file.

The core problem this solves: rule files in a long-lived project were written by whichever agent or engineer was in the seat on a given day, across many sessions, often under time pressure. Wording accumulates — some of it stays true, some goes stale the moment the code it described changed, and some was never verified in the first place. Treat every existing sentence as an unverified claim, not a fact. Prior wording earns no trust just by being there; it earns trust by matching the code you actually read.

Workflow

1. Discover Rule Files

Run the discovery script instead of parsing the files by hand:

python3 ${CLAUDE_SKILL_DIR}/scripts/list_rule_files.py $ARGUMENTS

Defaults to .claude/rules when no argument is given. Returns, per file: frontmatter_paths (the paths: glob list, if any), headings, line_count, char_count.

Then run the mechanical linter for a budget/narrative baseline (same argument handling):

python3 ${CLAUDE_SKILL_DIR}/scripts/lint_rules.py $ARGUMENTS

Its findings (over-budget files, narrative-marker lines, code-mirror and ticket-only-rationale bullets) tell you where the worst accretion is before you read a single file. _inbox.md is exempt by design - it stages uncurated candidates.

Health heuristic: a rule file that changes more often than roughly once a quarter is a code-mirror suspect - rules churn with decisions, not with code. Use it to decide where to look hardest, not as a metric to compute.

Skip any file whose frontmatter or header explicitly marks it as auto-generated — treat those like CHANGELOG.md, never rewrite them.

2. Classify Content: Verdict per Bullet

Read references/rule-admission.md (the prime directive, the admission test - durability / decision / visibility / derivability) and references/uniform-rule-format.md (the "What is a rule vs. what is noise" table with worked examples). For each file, go bullet-by-bullet (or paragraph-by-paragraph for prose sections) and tag each with one of six verdicts:

  • RULE - a present-tense, falsifiable claim that passes all four admission tests
  • NARROW-GLOB - a true rule, but relevant only to a subset of this file's paths:. Move it to (or create) a file whose paths: names just that subset
  • SKILL - procedural how-to behind an intent trigger no glob expresses, with a deterministic backstop that catches a missed invocation. Extract to a project skill; skills fail open, rules fail closed, so never route an ambient constraint here
  • SIGNPOST - a true constraint a test/lint already enforces, compressed to one line naming the enforcer
  • RELOCATE - true and valuable but pull-based (the trap is visible at the code site): API/protocol description, single-file subtleties, design rationale worth keeping. Belongs in a doc comment at the code site, with at most a one-line pointer left in the rule file
  • NOISE - changelog/history/narration/hedged guess/TODO. Drop these outright, no matter how confidently the original file phrased them

When several destinations fit, prefer in this order: narrow glob > wide glob > skill > doc comment > nothing. Never park content in docs/: content that fails admission is relocated to a code site or deleted. Deleting is a successful outcome; a shorter directory that instructs better is the goal.

This is a fast text-judgment pass — do it in main context, no code access needed yet.

3. Verify Every Surviving RULE Claim Against Real Code

This is the step that makes the output trustworthy. Do not skip it because a claim "sounds right" — that's exactly the failure mode this skill exists to catch.

3.1 — Split checkable vs. non-checkable claims.

  • Checkable (has ground truth in the repo): file/dir locations, exports, config settings, exclusion lists, banned/required API patterns, index names, version pins, "X calls Y" relationships.
  • Non-checkable (process/preference statements): "ask before assuming", "prefer composition over inheritance", team workflow conventions. A code search can't confirm or refute a preference — don't force verification on these, just sanity-check they still make sense given what step 1–2 surfaced.

3.2 — Dispatch verification.

For each rule file with paths: frontmatter, scope the search to those globs — that's the surface the rule claims to govern. For files with many checkable claims or broad path scope, dispatch to one or more Explore-type subagents rather than verifying serially in the main context — verification means reading real source across potentially many files, and doing that inline for every rule file burns context fast. Small rule sets (a handful of files, a few claims each) can be verified inline instead.

Brief each subagent explicitly to default to skepticism: a claim is CONFIRMED only with positive evidence found in code. Otherwise it's CONTRADICTED (found evidence it's false) or UNVERIFIED (no evidence either way — e.g. the code is too dynamic to grep, or the claim describes intent rather than a checkable artifact).

3.3 — Resolve each verdict.

VerdictAction
CONFIRMEDKeep, rewrite into uniform format (Step 4)
CONTRADICTEDDrop — or correct, only if you have positive evidence of the replacement; never invent one
UNVERIFIEDKeep, but flag it in the plan (Step 5) for the user to confirm
NOISE (from Step 2)Drop, regardless of verdict — noise doesn't get verified, it gets removed

RELOCATE and SIGNPOST candidates from Step 2 go through the same verification (a claim must be true before it earns a doc comment; an "Enforced by" clause must name a test that exists).

4. Rewrite Into Uniform Format

Use references/uniform-rule-format.md as the template for every file: same bullet shape (**bold falsifiable claim.** why it matters), same tone, paths: frontmatter preserved verbatim. Converge ALL files onto this one shape — including files that were already reasonably well-written — so the whole directory reads as one voice instead of one style per author.

Apply the structure and budgets from references/rule-admission.md:

  • Each file opens with ## Critical Invariants — the 3–6 constraints whose violation means data loss, divergence, or silent corruption.
  • File budget 150 lines / 8 KB, bullet budget ~5 lines. If genuinely all RULE-grade content still exceeds the budget, plan a split into narrower paths: scopes rather than accepting the overage.
  • For each RELOCATE item, draft the doc comment (target file, insertion point, text) alongside the rule-file rewrite — relocation happens in the SAME change set, move first, cut second. Match the target file's existing comment style.

5. Present the Plan, Get Approval

Rewriting hand-maintained docs is destructive to whatever the user or prior agents wrote — confirm before touching disk. Use a single AskUserQuestion call listing, per file:

<file>: KEEP unchanged / COMPACTED (N noise lines removed) /
        NARROWED (paths: tightened to N globs, or split into <new-file>) /
        EXTRACTED-TO-SKILL (N items → <skill>, with its backstop named) /
        RELOCATED (N items → doc comments, with target files) /
        SIGNPOSTED (N bullets compressed to enforcer pointers) /
        CONTRADICTED (N claims removed, with evidence) /
        FLAGGED (N unverified claims to confirm) / REFORMATTED (structure only)

RELOCATED, NARROWED, and EXTRACTED-TO-SKILL items all change more than the rule file - source files, paths: scoping, or a new skill. List every target in the plan so the user sees the full blast radius before approving.

Options: "Approve" / "Approve with changes" / "Cancel". For CONTRADICTED items, show the evidence (file:line or a short quote from the source) so the user can check your verdict rather than just trust it — the whole point of this skill is not asking anyone to trust unverified claims, including yours.

Only proceed to Step 6 after approval. On "Approve with changes", incorporate the feedback before writing.

6. Write

Order matters: write the RELOCATE doc comments into their target source files first, then overwrite the rule files — cutting before relocating destroys knowledge if the run is interrupted. Preserve paths: frontmatter exactly — it's functional metadata read by the drift-detection hook, not prose. Before writing, check git status on the target directory; if it's not clean or not tracked, tell the user and suggest committing first so the rewrite stays trivially reversible.

7. Lint Gate & Report

Re-run the linter over the rewritten directory:

python3 ${CLAUDE_SKILL_DIR}/scripts/lint_rules.py $ARGUMENTS

Zero errors is the exit criterion — a remaining budget error means Step 4 under-planned a split; a remaining narrative marker means a NOISE item slipped through. Fix and re-lint; never ship a rewrite that fails its own contract.

Then summarize: files touched, total noise lines removed, items relocated (target file each), claims contradicted (one-line evidence each), claims flagged unverified for follow-up, final lint status.

Resources

references/rule-admission.md

What belongs in a rule file at all: the prime directive, push vs. pull, the four-part admission test, the six verdicts (RULE/NARROW-GLOB/SKILL/SIGNPOST/RELOCATE/NOISE), the destination priority order, the duplication policy, where each kind of knowledge lives, and the file/bullet budgets. Read before Step 2.

references/uniform-rule-format.md

Template, the rule-vs-noise table, and a full before/after worked example. Skim it before Step 2 for noise calibration; use it directly while rewriting in Step 4.

scripts/lint_rules.py

Mechanical enforcement of the admission contract: budgets, paths: frontmatter, ## Critical Invariants presence, narrative markers, plus admission:code-mirror (a bullet enumerating 3+ paths from one directory with no pinning test) and admission:ticket-only-rationale. Run at discovery (Step 1 baseline) and as the exit gate (Step 7). Also used standalone by /bdk:add-rule.

Quick Reference

Checklist

  • Ran discovery script + linter, got file list, budgets, narrative baseline
  • Classified every bullet/paragraph as RULE / NARROW-GLOB / SKILL / SIGNPOST / RELOCATE / NOISE, preferring the narrowest destination that fits
  • Split checkable vs. non-checkable claims
  • Verified checkable claims against real code (subagents for large scope), skeptical default
  • Rewrote all files: uniform bullets, Critical Invariants section, budgets, frontmatter preserved
  • Drafted doc comments for every RELOCATE item (move first, cut second)
  • Reduced every duplicated fact to one home + one-line pointers elsewhere
  • Presented plan via single AskUserQuestion - including relocation, narrowing, and skill-extraction targets - got approval
  • Checked git status / suggested a commit before writing if uncommitted
  • Wrote doc comments, then rule files; linter exit gate passes with zero errors
  • Reported noise/relocation/contradiction/flag counts + lint status

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.