Skip to content
Back to skills

Audit

ASecurity

Read-only, audit-only scan of one directory tree for orphaned, temporary, stale-lock, failed-write, partial-download, and empty leftovers, reported as an evidence snapshot. Removes nothing; any removal is a separate /disk-hygiene:clean run that a person invokes. Use when: 'delegate a disk-hygiene audit', 'orchestrator scan of a directory for leftovers', 'subagent scan of this directory for leftovers', 'disk-hygiene audit report'. Skip when: the ask is to clean up or reclaim space (that is /di...

  • 13 stars
  • 0 votes
  • 0 copies
  • 3 views
  • Added September 2, 2026
ai-agentspythongoshellbashgit

Works with

  • claude code

Security analysis

A100/100

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

Scanned October 4, 2026

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

Installs into .claude/skills of the current project.

Are you the author of Audit?

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

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

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-only scan of one directory tree for orphaned, temporary, stale-lock, failed-write, partial-download, and empty leftovers, reported as an evidence snapshot. Removes nothing; any removal is a separate /disk-hygiene:clean run that a person invokes. Use when: 'delegate a disk-hygiene audit', 'orchestrator scan of a directory for leftovers', 'subagent scan of this directory for leftovers', 'disk-hygiene audit report'. Skip when: the ask is to clean up or reclaim space (that is /disk-hygiene:clean), one repository's caches or build output (repo-hygiene), or an OS-managed root."
argument-hint: "[--max-depth <N>] [--sizes-only] [--policy <file>] <target-directory>"
user-invocable: true
disable-model-invocation: false
metadata:
  workflow-stage: anytime
  summary: Scan a directory tree for stale leftovers and report the evidence, read-only
---

**Arguments.** `[--max-depth <N>] [--sizes-only] [--policy <file>] <target-directory>`. Full form: `[--max-depth <N>] [--sizes-only] [--quiet] [--policy <file>] [--root-children [--root-child <name>]...] <target-directory>`

# Disk hygiene audit

Scan one directory tree and report what the snapshot shows. This skill runs the engine's `scan`
subcommand and nothing else, and it changes nothing in the target. A filename pattern is a
discovery hint, never proof that an entry is junk.

This skill carries no hooks of its own. Safety rests on the plugin-level engine-gate in
`hooks/hooks.json`, which checks every Bash or PowerShell call that names `hygiene.py`. Run no
engine subcommand other than `scan`, no shell command that writes, moves, or deletes under the
target, and no compound shell around an engine call. A subagent follows that contract itself, from
the worker brief in step 2.

## 1. Bootstrap

Run the argument-free probe first, before any engine call:

```text
"<hook-python>" "${CLAUDE_PLUGIN_ROOT}/skills/setup/scripts/kill_switch_probe.py"
```

Take `hook_python` and `data_root` from its one-line JSON. Every engine call needs the absolute
`<hook-python>` and `--data-root`; a bare `python3` is rejected. When `hook_python` is not yet
known, submit the probe once with bare `python`. The probe reports `hook_python` as the interpreter
it ran under, so that value is the guard's only if the guard's own interpreter ran it. The scan is
admitted only under the guard's interpreter: if it is denied for that reason, the denial names the
interpreter and ran nothing, so rerun the scan with the interpreter it names.

- `data_root` is `null`: the install layout proved no data root and the guard denies every engine
  call. Report the audit as not run, submit no engine call, and stop.
- The probe call is denied or left waiting for a person: report the audit as not run and stop. Do
  not scan without it.
- The guard's interpreter is older than `MIN_PYTHON` in
  [`hygiene.py`](../clean/scripts/hygiene.py): stop with that declared prerequisite. An older
  `hook_python` from a bare-`python` probe is not that finding; the scan's admission settles it.
- `effective` is `false` (audit-only): the scan still runs. State the configured value, and leave
  out the removal handoff in step 4. On `degraded: true`, say the configured value could not be read.

## 2. Scan

Pick a unique run directory under `<data_root>/runs/`; the snapshot lives there, never in the
target. With no target, ask the person who invoked you once. Reject an OS-managed root, a missing
directory, a symlink, or a Windows reparse point.

```text
"<hook-python>" "${CLAUDE_PLUGIN_ROOT}/skills/clean/scripts/hygiene.py" scan \
  --target "<target>" --output "<run-dir>/snapshot.json" \
  --data-root "<data_root>" [--project-dir "<project-dir>"] \
  [--policy "<policy.json>"] [--max-depth <N>] [--sizes-only] [--quiet] \
  [--root-children [--root-child <name>]...]
```

`--project-dir` is optional; pass it, as a literal absolute path, when the consumer project has
standing policy files. Pass literal values only: the guard rejects shell expansion, so never pass
an environment-variable reference. What each flag does, including the large-target and volume-root rules, is in
[scan-flags.md](../clean/reference/scan-flags.md). For a home directory or another large target,
start with `--max-depth 1`, then scan the subtrees the evidence justifies. Never pass
`--confirmed-large-scan` on your own: an unbounded walk needs a person's answer.

For a subtree worker, the brief to paste into the spawn prompt is
[fan-out-worker-brief.md](../clean/reference/fan-out-worker-brief.md). Before spawning, replace every
`${...}` token and `<placeholder>` in it with the literal absolute value you hold from the probe
(`hook_python`, `data_root`) or from step 2: a worker cannot expand `${...}` tokens, and its data
root is the probe's `data_root`. A worker returns scan evidence only.

## 3. Read and report the snapshot

Report from the snapshot and the scan's stdout, and nothing the run did not observe.

- Lead with `children_rollup`. `walked: true` rows carry exact totals; `walked: false` rows carry
  `null` aggregates and `unwalked_reasons`, so report them as coverage gaps, never as small or clean.
- Rank on `reclaimable_local_bytes`, not `logical_bytes`. An entry whose `size_qualifiers` is
  non-empty stays out of any reclaimable total; state its bytes and reasons separately.
- Report `truncated_paths` (a count under `--quiet`, the list in the snapshot) and every scan error
  as coverage gaps. A `large-target-confirmation-required` or `root-children-selection-required`
  status names the next step, not a failure.
- Quote hint coverage as a rate: `hinted_entries` of `entries`, never "N findings".
- List protected entries separately, and surface an `os_autoclean` recommendation as the engine
  states it. A scan does not assess live handles or elevation, so it yields no locked,
  needs-elevation, or unverified entries: say those were not assessed, never that there are none.
- Give each hinted entry the evidence the snapshot holds (path, hint, `protected_reasons`,
  `size_qualifiers`). A hint has no owner check behind it, so label the list hints for a person to
  judge, not verdicts, and rank nothing for deletion. Empty directories stay visible.
- A non-zero exit is a real failure: 2 for an invalid or blocked target, 3 when elevation is needed
  or filesystem state could not be verified. Report it and stop.

## 4. Hand off

Removal is `/disk-hygiene:clean`, which a person invokes. Close the report with the snapshot path
and that one line. Do not start a removal run and do not propose exact paths for one. When
`effective` was `false`, say instead that removal is disabled by the plugin's configuration.

## Next

/disk-hygiene:clean <target-directory>

Run by a person when the findings warrant removal; it takes the same target, not this snapshot.

## Gotchas

- The argument-free probe is not one of the calls the engine-gate adjudicates, so a session in a
  permission mode that asks may hold it for a person. That is the "waiting for a person" stop in
  step 1, not a reason to skip the probe. **Claim:** a headless session in the default permission
  mode denies the probe and a `--bg` session parks it, because no hook adjudicates it.
  **Basis:** the three probe lanes on
  [#5516](https://github.com/melodic-software/claude-code-plugins/issues/5516) (headless default
  denied, `--bg` default parked, headless `bypassPermissions` denied), run on Claude Code 2.1.285;
  upstream behavior is in the
  [permission modes doc](https://code.claude.com/docs/en/permission-modes) and the
  [hooks doc](https://code.claude.com/docs/en/hooks). **As of:** 2026-09-30. **Recheck:** a Claude
  Code release changes how permission modes treat Bash calls no hook adjudicates.
- Under an inline `--plugin-dir` load the probe can report `data_root` as `null` even though the
  plugin data directory exists. Stop as step 1 says; do not substitute a guessed path. **Claim:** the
  guard derives `data_root` only from the `<plugins>/cache/<marketplace>/<name>` install layout or a
  registered directory marketplace, so a checkout loaded inline reports `null`. **Basis:** the probe
  run from a checkout with neither reported `hook_python` resolved and `data_root: null` on Claude Code
  2.1.285 (Linux); the derivation rule is in
  [safety-model.md](../clean/reference/safety-model.md), "Local-directory marketplace installs".
  **As of:** 2026-09-30. **Recheck:** the guard's data-root derivation changes, or a Claude Code
  release documents a plugin data path for `--plugin-dir` loads.
- A hint match is discovery evidence only. Reporting "N hinted entries" as "N safe deletions" is the
  failure this skill exists to avoid.

Files in this skill

  • SKILL.md9.9 KB
  • context/audit.md8 KB
  • context/fix.md4.4 KB
  • context/update.md3.1 KB
  • evals/evals.json15.2 KB
  • evals/fixtures/init-bloated-claude-md.md14.7 KB
  • reference/criteria.md25.5 KB
  • reference/official-guidance.md14.3 KB
  • scripts/discover-instruction-surfaces.sh7.7 KB
  • scripts/discover-instruction-surfaces.test.sh11.3 KB
  • scripts/memory-dir-stats.sh10.6 KB
  • scripts/memory-dir-stats.test.sh15.8 KB
  • scripts/memory-index-refs-check.sh3.6 KB
  • scripts/memory-index-refs-check.test.sh4.5 KB
  • scripts/orphan-rule-check.sh4.6 KB
  • scripts/orphan-rule-check.test.sh6.6 KB
  • scripts/parse-concern-value.sh6.3 KB
  • scripts/resolve-memory-dir.sh4.3 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…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.