Skip to content
Back to skills

Audit File Names

ASecurity

Read-only audit of a docs tree's file names against a configured casing rule: proposes a name per offender, classifies every reference to it, refuses case-only collisions, and writes the plan realign-file-names applies. Use when: 'audit file names', 'are our doc filenames consistent', 'plan a docs rename', 'which files break the naming rule', 'find every reference to this doc', 'rename the docs tree', 'lower-kebab the docs folder', 'what would a docs rename touch'. Renames nothing.

  • 13 stars
  • 0 votes
  • 0 copies
  • 2 views
  • Added September 12, 2026
ai-agentsgoshellbashgitdocumentation

Works with

  • cli

Security analysis

A100/100

Pro scans all 20 files and shows the line behind each finding

Scanned October 4, 2026

npx -y skills add melodic-software/claude-code-plugins --skill audit-file-names --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Audit File Names?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Audit File Names
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/melodic-software-audit-file-names/badge)](https://www.skillsdirectory.com/skills/melodic-software-audit-file-names)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
description: "Read-only audit of a docs tree's file names against a configured casing rule: proposes a name per offender, classifies every reference to it, refuses case-only collisions, and writes the plan realign-file-names applies. Use when: 'audit file names', 'are our doc filenames consistent', 'plan a docs rename', 'which files break the naming rule', 'find every reference to this doc', 'rename the docs tree', 'lower-kebab the docs folder', 'what would a docs rename touch'. Renames nothing."
argument-hint: "[audit] [root ...]"
user-invocable: true
disable-model-invocation: false
allowed-tools: ["Bash(${CLAUDE_SKILL_DIR}/scripts/inventory.sh:*)", "Bash(${CLAUDE_SKILL_DIR}/scripts/sweep.sh:*)", "Bash(${CLAUDE_SKILL_DIR}/scripts/emit-findings.sh:*)", "Bash(git branch --show-current:*)", "Bash(git rev-parse:*)", "Bash(git check-ignore:*)", "Read", "Write", "Grep"]
shell: bash
metadata:
  workflow-stage: anytime
  summary: Inventory a doc tree's file names and plan the renames with their references
---

## Repository context. Gather first

Collect these with **individual** Bash calls, one command per call, never
combined into a single invocation:

- Current branch, `git branch --show-current`
- Working tree status (empty = clean), `git status --porcelain | head -20`
- Repository root, `git rev-parse --show-toplevel`

The pipe is the bound and belongs in the command. A read-time cap bounds
nothing: the Bash tool returns the command's complete output into context before
there is anything to decide about.

Treat a failure as an unknown value and carry on.

## Purpose

A documentation tree drifts one file at a time, and by the time anyone notices,
the cost of fixing it is not the renames. It is finding every citation of every
renamed file, deciding which of them may be rewritten, and not corrupting a
generated record or a released changelog entry on the way through.

This skill does the finding and the deciding, and writes the result down. It
renames nothing. `/docs-naming:realign-file-names` executes the plan, one
acceptance at a time.

## Read these before presenting anything

| Read | For |
|---|---|
| [`context/tiers.md`](context/tiers.md) | the form table to print before any plan, and why a historical tier keeps its links while a released tier is frozen |
| [`../../context/file-name-findings.md`](../../context/file-name-findings.md) | where the artifact goes, its shape, its stable ids, its status arcs, and the re-audit merge |
| [`../../reference/config.md`](../../reference/config.md) | every configuration key, its default, and which layer may supply it |

## Facts before judgment

Three scripts produce the facts. Run them in order and build the plan on what
they emit.

1. **Inventory** the tree:

   ```bash
   ${CLAUDE_SKILL_DIR}/scripts/inventory.sh --root <repo>
   ```

   It emits `OFFENDER`, `COLLISION`, `EXEMPT`, and `SCANNED` rows. A `COLLISION`
   row means the plan would put two paths differing only by case into one tree.
   **Stop there.** Report the pair and the reason, and propose nothing: on a
   case-insensitive checkout the second file overwrites the first, so this is a
   corrupted tree rather than a plan to review.
   A `SCANNED 0` row, with its stderr warning, means nothing is tracked under
   the roots. Report that and stop: it is an empty root, not a clean tree.
   *Done when:* a `SCANNED` row with a nonzero count is present and the
   `COLLISION` count is zero, or the run reported an empty root and stopped.

2. **Sweep** for references, feeding it the offender pairs:

   ```bash
   ${CLAUDE_SKILL_DIR}/scripts/sweep.sh --root <repo> --pairs <pairs.tsv>
   ```

   Each `REF` row carries the citing file, the line, the form, the tier, the
   action, and an excerpt. The actions are `edit`, `report`, `review`, `skip`,
   and `regenerate`; `context/tiers.md` owns what each means.
   *Done when:* a `SITES` row is present and every offender pair appears in at
   least one `REF` row or is reported as having no site at all.

3. **Compose** the plan into the resolved home:

   ```bash
   ${CLAUDE_SKILL_DIR}/scripts/emit-findings.sh --root <repo> \
     --inventory <inv.tsv> --sweep <sweep.tsv> --out <resolved>/file-names.md
   ```

   A zero-offender run over a non-empty root still runs the sweep with an empty
   pairs file and the emit, and leaves a `findings: 0` plan.
   *Done when:* the script reports the path it wrote and a finding count equal
   to the inventory's offender count.

**Cite the scripts' rows verbatim.** The realign applies the action each site
carries, so a form or a tier you inferred by reading is a guess that edits the
wrong shape. If a site does not correspond to a `REF` row, say so rather than
inventing one.

## Where the artifact goes

Write under the home `../../context/file-name-findings.md` "Where it lives"
defines. A plan written anywhere else is one the realign never finds, and that
failure reads exactly like "no audit has been run".

If a plan already exists at the resolved home, the emitter merges into it by
finding id and carries every decision forward. Do not delete it to get a clean
run; a declined finding that reappears as pending is a decision the operator
made being asked again.

## Present the result

1. The form table for every tier the plan touched, from `context/tiers.md`.
2. One line per finding, most-cited first: the old and new path, the site count,
   the tier breakdown, and whether a generated file is involved.
3. Every `review` site, individually, with its line and excerpt. These are the
   ambiguous bare stems, and no script can settle them.
4. The artifact's path, and the next step: `/docs-naming:realign-file-names`
   with the ids to accept.

Say the count of `report` sites plainly. A maintainer who expected a frozen tier
to change needs to see that it did not.

## Completion criteria

The run is done when the artifact exists at the resolved home, its finding count
equals the inventory's offender count, the tree is byte-identical to how it
started (`git status --porcelain` unchanged), and every `review` site has been
surfaced to the operator rather than folded into a total.

## What this skill does NOT do

- Rename anything, edit any reference, or run any regenerator. It is read-only
  on every file it inspects.
- Re-judge a plan it already wrote. A stale plan is re-audited, not patched.
- Decide whether a `review` site names the file. It escalates them.
- Bump a version, write a changelog entry, or commit.
- Sweep a tree the configuration excludes, or a file a tier freezes.

## Next

`/docs-naming:realign-file-names`

## Gotchas

- **A collision refuses the plan, not just one finding.** Two paths differing
  only by case cannot coexist on macOS or Windows checkouts. The whole run stops
  so nobody applies half of it.
- **`SCANNED 0` is an empty root, not a clean tree.** A `roots` entry that
  matches no tracked file inventories nothing and finds nothing. The emitter
  exits 3 rather than overwrite an existing plan that holds findings with an
  empty one; pass `--replace` only when the plan is meant to be discarded.
- **Existence is asked of the git index, never the filesystem.** On a
  case-insensitive checkout a filesystem test answers for the wrong spelling,
  which would refuse every case-only rename on exactly the platforms the rule
  protects.
- **A `review` site is not a smaller `edit`.** It is a bare stem that is also an
  ordinary word. Rewriting one on a text match is how a rename edits a sentence
  that had nothing to do with the file.
- **A generated record is never text-edited.** Its sites are marked
  `regenerate`, because a substitution that looks right leaves a stale derived
  value no reader would notice.
- **The plan is checkout-local.** It lives in the memory tier, keyed by branch,
  and a sibling worktree never sees it. A decision that must outlive the branch
  goes into the tracked concern file, which the realign offers and never takes.
- **Run it from the tree you mean.** Every script takes `--root`; inside a second
  worktree, pass it, or run from that worktree.

Files in this skill

  • SKILL.md7.7 KB
  • context/tiers.md3.2 KB
  • evals/evals.json3.9 KB
  • scripts/emit-findings.sh8.2 KB
  • scripts/emit-findings.test.sh7.5 KB
  • scripts/fixtures/build-fixture.sh1.6 KB
  • scripts/fixtures/config.json984 B
  • scripts/fixtures/tree/CHANGELOG.md189 B
  • scripts/fixtures/tree/README.md516 B
  • scripts/fixtures/tree/build/out.json87 B
  • scripts/fixtures/tree/docs/Alpha-One.md343 B
  • scripts/fixtures/tree/docs/BETA.md268 B
  • scripts/fixtures/tree/docs/Gamma_Three.md111 B
  • scripts/fixtures/tree/docs/README.md122 B
  • scripts/fixtures/tree/docs/adr/0001-historical.md373 B
  • scripts/fixtures/tree/docs/tool.py105 B
  • scripts/fixtures/tree/docs/topics/t/PLAN.md149 B
  • scripts/fixtures/tree/docs/v1.2.schema.json68 B
  • scripts/fixtures/tree/tools/gen.sh466 B
  • scripts/inventory.sh8.4 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…