# Audit

> Read-only sweep for instruction content on the wrong surface. Conventions in an always-loaded CLAUDE.md/AGENTS.md really scoped to one file type or subtree (demote), and normative conventions stranded in ordinary docs Claude never loads (promote). Proposes a destination per candidate: a path-scoped `.claude/rules/` file whose `paths:` glob is machine-checked first, a nested AGENTS.md plus its CLAUDE.md shim, a skill, a linter, or deletion. Safety rails covering irreversible actions, secrets, data, publication, compliance, and agent authority are hard-denied from demotion and held back. Every proposal is priced: deferred content is invisible to subagents and absent after compaction until re-triggered. Use when: 'my CLAUDE.md is too long', 'convert this to rules', 'what should be a path-scoped rule', 'move conventions to .claude/rules', 'find conventions in our docs', 'nested CLAUDE.md candidates', 'audit instruction placement'. Emits a findings artifact; the sibling realign skill applies what you accept.

- Skill: `melodic-software/audit-15` (Agent Skill, multi-file: 6 files)
- Install (CLI): `npx skillmds@latest add melodic-software/audit-15`
- Raw SKILL.md: https://api.skillmd.com/api/skills/melodic-software/audit-15/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: AI & ML
- Author: melodic-software (https://skillmd.com/u/melodic-software)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/melodic-software/audit-15

---


## Pre-computed context

!`"${CLAUDE_PLUGIN_ROOT}/scripts/precompute.sh" audit 2>/dev/null || echo "- Orientation unavailable"`

## Purpose

Instruction content has a load cost set by the surface it sits on, and most repositories put
everything on the most expensive one. A convention that only matters when someone edits a `.cs` file
is paid for in every session, in every conversation, whether or not any C# is touched.

**The saving is context, not obedience.** Official guidance warns that bloated instruction files
cause Claude to ignore the instructions inside them. This plugin's own adherence measurement
([`../../evals/adherence-results.md`](../../evals/adherence-results.md)) does not reproduce that
effect for a clear, non-conflicting convention; the figures live in that file, and it is re-run
when the model tier changes. So propose moves on context cost and on reaching content Claude
never loads, never by promising the operator their instructions will be followed better
afterwards.

This skill finds content whose scope is narrower than the surface carrying it, and content whose
surface Claude never reads at all, and proposes where each should go.

**It is read-only.** Every finding is a proposal; the operator decides, and `realign` executes.

## Read these before adjudicating anything

The judgment lives in the plugin's context files, not in this hub. Do not re-derive them.

| Read | For |
|---|---|
| [`../../context/routing-rubric.md`](../../context/routing-rubric.md) | The hard-deny gate, the decision ladder, glob derivation, the promote lane |
| [`../../context/corpus.md`](../../context/corpus.md) | What is swept, in what order, and what is never touched |
| [`../../context/verified-mechanics.md`](../../context/verified-mechanics.md) | When each surface loads, and the three gaps that constrain every proposal |
| [`../../context/findings-artifact.md`](../../context/findings-artifact.md) | The artifact's shape, location, and re-run merge semantics |

A proposal that contradicts `verified-mechanics.md` is wrong even if it looks like a saving. The
common one: moving a section into `.claude/rules/` *without* a `paths:` glob, which costs exactly
what it cost before.

## The two lanes

**Demote**. Content already in the instruction layer, sitting higher than its scope warrants. The
saving is real but so is the trade: what defers is invisible to subagents and absent after
compaction until re-triggered. Price it, every time.

**Promote**. Normative content in ordinary documentation that Claude loads *never*. There is no
presence to lose, so the gaps do not apply and any working destination is a strict improvement. The
live risk here is duplication, not context: resolve single-source-of-truth per candidate using the
rubric's table rather than reflexively copying.

## Facts before judgment

Run the detector first and build every finding on what it emits:

```bash
"${CLAUDE_PLUGIN_ROOT}/scripts/detect.sh" [--tier core]
```

It emits deterministic TSV and adjudicates nothing:

| Record | Carries | Used for |
|---|---|---|
| `FILE` | path, corpus tier, line count | Corpus accounting, and the coverage report |
| `SECTION` | path, **start**, **end**, level, heading | Candidate boundaries and their line ranges |
| `SIGNAL` | path, section start, normative hit count, markers | The promote lane's normative bar |
| `HINT` | path, section start, `ext`/`dir`/`lang`, value | Raw material for glob derivation |
| `RULE` | path, `scoped`/`unscoped`, globs | Existing rule inventory, and re-scope candidates |
| `SKIP` | path, reason | The honest coverage report |

**Cite the detector's line ranges verbatim.** `realign` excises by the range the finding carries, so
a range you inferred by reading is a guess that removes the wrong text. If a candidate does not
correspond to a `SECTION` record, say so rather than inventing a boundary.

**A `HINT` is raw material, not a decision.** The detector reports what the text literally says; it
does not know whether `.ts` is the candidate's real scope. Derive the glob from the hints, then
validate it. An unvalidated hint is not a proposal.

## Workflow

1. **Run the detector** and read its `FILE`/`SKIP` records as the corpus of record. Core tier
   always; expanded tier unless the operator passed `core`.
2. **Take candidates from `SECTION` records.** A candidate is one section with its emitted line
   range. Never a lone line pulled from a section; never a whole file when one section is the
   problem; never a boundary the detector did not report.
3. **Run the hard-deny gate first.** Anything matching a Gate 0 class leaves the candidate set and
   goes to the held-back section with its class and location. No destination, ever.
4. **Walk the ladder** for what survives. First match wins. Stop there.
5. **Derive and validate the glob** for every path-scoped proposal:

   ```bash
   "${CLAUDE_PLUGIN_ROOT}/scripts/glob-tools.sh" validate --glob '<derived>'
   ```

   A glob that comes back `zero-match`, `bad-bracket`, or `over-budget` **must not be proposed**.
   Re-derive, or drop the candidate to the subtree destination, or leave it where it is. Record the
   validation facts, match count and breadth, in the finding, because that is the evidence the
   operator gates on. An `over-broad` result is proposable but must be surfaced as such.
6. **Price each proposal**: what leaves the always-loaded budget, subagent invisibility, and
   post-compaction behavior for that specific destination.
7. **Rank**, highest value first: always-loaded lines released × confidence, with promote-lane
   findings ranked on value alone since they carry no downside.
8. **Write the artifact**, then summarize inline. The artifact is the record; the summary is a view
   of it.

## Where the artifact goes

Resolve the home through the plugin's topic-docs binding
([`${CLAUDE_PLUGIN_ROOT}/reference/topic-docs.md`](${CLAUDE_PLUGIN_ROOT}/reference/topic-docs.md))
and write under it. That document owns the rung order, the constant slug, the branch axis, and the
memory root's self-ignore guard; `findings-artifact.md` owns what the file contains.

**Resolve the home; never hardcode the default's shape.** A skill that composes the documented
default itself writes where the consumer's configured root is not, and the reader's failure mode is
a missing-artifact stop indistinguishable from "the audit was never run". If a prior artifact exists
at the resolved home, merge per the contract's re-run semantics rather than overwriting. An
operator's `declined` decision must survive a re-audit.

## The suppression surface

Before ranking, resolve the tracked suppression surface `.claude/instruction-placement.md` across
its three layers ([`${CLAUDE_PLUGIN_ROOT}/reference/consumer-config.md`](${CLAUDE_PLUGIN_ROOT}/reference/consumer-config.md))
and suppress every candidate whose `finding_id` it carries. That file is how a decline reaches a
checkout the findings artifact never does, so a sweep that ignores it re-proposes decisions the
operator already made somewhere else.

Three obligations, none optional. **Read, never write**: `realign` composes an entry behind its
per-item gate and nothing here does. **Report the suppressions**, each with its reason, date, and
contributing layer, and every entry that did *not* suppress: personal-only, malformed, or outside
this run's scope. **Exclude the surface and its layers**, because auditing the file that records the
decisions would make recording one perturb the next run. That exclusion is applied to the candidate
set after the detector has run, not to the corpus: the corpus document above stays the one owner of
what is swept, and the detector's coverage numbers keep counting every file it read.

## Routing out

A candidate can raise a question placement does not answer: whether the model still needs the
instruction, whether it is duplicated, whether the whole file should exist. Those belong to sibling
plugins, and each route is presence-gated with a documented fallback.

Read [`context/routing-out.md`](context/routing-out.md) when a candidate raises one, for the route
table and the two rules that keep routing from becoming silent dropping.

## Reporting honestly

- **Say what was not swept.** The detector's `SKIP` records and `SUMMARY` are the source. Report
  them rather than recounting by hand. A run that covered 200 of 2,000 files while reading like a
  full audit is the failure this rule exists to prevent.
- **Show the held-back list.** An operator who cannot see what the hard-deny gate excluded cannot
  tell a careful sweep from a shallow one.
- **Never report a saving without its cost.** Both belong in the same sentence.
- **Zero findings is a real result.** A repository whose instructions are already well-placed gets
  told so, not handed marginal proposals to justify the run.

## Hard rules

- **Read-only.** The only file this skill writes is its own findings artifact, outside the
  repository. No edit to any instruction file, ever, not even an obviously correct one.
- **Never propose a glob that failed validation.** The check is mechanical and cheap; a guessed glob
  produces a rule that silently never fires, which is strictly worse than leaving the content alone.
- **Never propose demoting a hard-deny candidate**, under any argument, including an operator
  asking for it. Say what the class is and offer compression in place instead.
- **Never move content across the user/project boundary.** User-scope surfaces are read for
  duplicate detection only.
- **Never edit another tool's instruction files.** Cursor, Copilot, Windsurf, and Cline configs are
  read-only sources for the promote lane.
- **Deterministic output.** Files sort lexically, findings sort by rank then identifier, no
  timestamps outside frontmatter.

## Gotchas

Observed failure modes, each producing a finding that survives review by eye: the saving that is
not a saving, globs that look right and match nothing, safety rails that look path-local, and line
ranges that were read rather than measured. Read [`context/gotchas.md`](context/gotchas.md) before
finalizing a finding set.

