"Verify the disk-hygiene plugin's runtime prerequisites and platform posture for this machine. Use when: 'set up disk-hygiene', 'configure disk-hygiene', 'is disk-hygiene working', a clean run reported a missing prerequisite, or before a first audit on a new machine. Actions: check (read-only verification, default) | apply (resolve what check found). Re-runnable and safe."
Resources
2Install
npx skillscat add melodic-software/claude-code-plugins/plugins-disk-hygiene-skills-setup Install via the SkillsCat registry.
Purpose
Thin check-centric setup per the uniform contract: check inspects and reports, apply
resolves. This plugin owns no consumer-project configuration — targets and modes arrive as/disk-hygiene:clean arguments, and the only tunable is the native userConfig toggle —
so apply is pure guidance and writes nothing.
Action routing: no argument or check runs the check; apply runs the check first, then
points at each remediation. Both are non-interactive — never prompt when the action is given.
check (read-only)
The clean skill and its bundled scripts (${CLAUDE_PLUGIN_ROOT}/skills/clean/) are the
single source of truth for what the plugin requires per platform. Read them first —
probe what they actually require, don't recite this file. Then run each probe via Bash and
report a PASS/FAIL/INFO table with one remediation line per FAIL.
When the plugin's toggle is disabled, every prerequisite absence downgrades from FAIL to
INFO — a deliberately disabled plugin is not broken. Report the probes informationally and
note that re-enabling restores the FAIL semantics. One exception: every step-1 and step-2 failure stays
FAIL with the toggle disabled. Audit-only mode is enforced by the guard, every guard surface
depends on a Python 3 interpreter resolving (every surface throughhooks/run-python-hook.sh, which tries python3, then python, then py -3), and a
guard that never runs can neither read nor enforce the configured false — so the fail-open
is most dangerous in exactly this
configuration. That covers an exhausted interpreter ladder — every rung absent, a stub, orindeterminate — a rung whose version probe then fails to launch at all (a corrupt or
zero-length binary outside WindowsApps, a broken shim, a permission error), and an
interpreter that starts but reports a version below the parsed floor. It does not cover a
stubbed python3 alongside a working python or py -3: the launcher skips the stub, every
guard launches, and that is a WARN (see step 2), not a failure to downgrade.
Launching the version probe proves only that something executes, not that it can run
the guard's own source: Python 3.6, for example, rejects the guard'sfrom __future__ import annotations and exits without a deny, which PreToolUse treats as
non-blocking — the same silent fail-open through a different door. Unproven guard execution
fails closed like every other guard-relevant unknown in this plugin.
Shell-form launcher registration — all three registrations (both wired hooks in
hooks/hooks.jsonand the skill-scoped belt inskills/clean/SKILL.mdfrontmatter) must namehooks/run-python-hook.shdirectly incommand, with"shell": "bash"and noargs, so
Claude Code routes them through its own Git Bash rather than aPATHlookup. FAIL if any
registration carries anargskey or setscommandto a bare interpreter name such asbash
orpython3: that is exec form, which on Windows resolvesbashto the WSL relaySystem32\bash.exeandpython3to the zero-lengthWindowsAppsApp Execution Alias stub, and
fails to launch — and a failed hook launch is non-blocking, so the guard silently enforces
nothing (#1416 for the wired hooks, #2568 for the belt). Do not report this as aPATH-ordering problem: shell form is resolved by
Claude Code, so reorderingPATHneither causes nor fixes it. Also FAIL if the launcher is
missing or not executable. Report a missing Git Bash on Windows as an environment prerequisite
(shell form falls back to PowerShell there, which cannot run a.sh), not as aPATHfix.Python floor on
PATH— the interpreter used by scanning, validation, the
guard, and cleanup. (The guard registers on two surfaces: a plugin-level engine gate
that acts only on engine-referencing commands, and the skill-frontmatter belt that
Claude Code keeps armed for the rest of the session after/disk-hygiene:cleanis
invoked. Both register unconditionally and resolve the kill switch by
readingdisk_hygiene_enabledfrom the usersettings.json.) The required version has one origin: theMIN_PYTHON
constant in${CLAUDE_PLUGIN_ROOT}/skills/clean/scripts/hygiene.py— parse it from
there (grep -m1 '^MIN_PYTHON' …) and probe the interpreter against that value; do not
recite a version number from this file or the README. FAIL if absent or older, naming
the parsed floor in the remediation; the plugin never downloads a runtime. Report the
absolute interpreter path (guarded engine calls must use the same absolute interpreter
the guard reports — Bash aliases and functions cannot substitute).On Windows, confirm the name the guard resolves is real BEFORE anything executes it —
including this floor check's own version probe.python3is the first rung of the ladderhooks/run-python-hook.shwalks for every guard surface; on stock Windows it resolves to a
zero-lengthWindowsApps\python3.exeApp Execution Alias that opens the Microsoft Store
(or hangs) instead of running an interpreter, and executing that name from setup pops the
Store instead of probing. Since #2568 the stub no longer stops any guard by itself — the
launcher skips it and falls through topython, thenpy -3. The ladder, not the first
rung, is the verdict. A host with real Python installed without "Add to PATH" but with thepylauncher has a stubbedpython3and a perfectly working guard; failing it would report a
healthy install as broken and send the operator to reinstall Python. So the alias probe is
diagnostic input — it says what the first rung is, and keeps setup from executing it —
while the verdict comes from resolving the ladder and checking the selected interpreter
against the parsed floor.
Order of operations: (a) locate the resolution without executing it (Get-Command python3
/command -v python3— locating is inspection; running is not); (b) classify it with the
bundled inspect-only probe, launched via an interpreter that is NOT the bare namepython3(py -3,python, or an absolute interpreter path — any interpreter already
proven real):"<python>" "${CLAUDE_PLUGIN_ROOT}/skills/setup/scripts/python3_alias_probe.py"; if no
such interpreter exists or the one you chose emits no JSON verdict, apply the probe's own
portable signal directly in PowerShell. Proven real is not the same as able to run the probe:
a pre-3.7 interpreter rejects itsfrom __future__ import annotationsand a legacypython
2.x fails earlier still, each before anything is classified — so a machine whose only
alternate launcher is Python 3.6 reaches the verdict through PowerShell, not by having no
launcher at all. The signal: a zero-length file under aWindowsAppspath component is the stub
((Get-Item -Force (Get-Command python3).Source)→Length0 plus aReparsePoint
attribute); (c) resolve the ladder in the launcher's own order, skipping any rung the probe
classified as a stub:python3only when its verdict isok, thenpython, thenpy -3.
The version probe may execute a rung only once that rung is not a stub — that is the whole
point of (b), and it is why the bare namepython3is never executed on astore-alias-stubverdict. Report the absolute path of the first rung that runs and meets
the floor.FAIL when the ladder is exhausted or below the floor — no rung resolves, or the one that
does reports a version under the parsedMIN_PYTHON. That is the real fail-open: the guard
cannot run, and it emits neither exit 2 nor adeny. Distinguish the two for the remediation
wording — an interpreter that starts and reports a version below the floor is a floor miss
(name the parsed floor), one that fails to launch at all is an absent-interpreter failure
(the plugin never downloads a runtime). Both keep the FAIL under a disabled toggle: a
below-floor interpreter is not proven able to execute the guard's source, so audit-only mode
is unenforceable there too.indeterminateon every rung is the same case — identity the
probe could not read anywhere on the ladder is uncertainty about whether the guard can launch
at all, and fails closed like every other guard-relevant unknown in this plugin.PASS with a WARN when the ladder resolves a supported interpreter but
python3is the
stub. Every guard launches, so nothing is failing open. State the residual plainly: the
operator's own barepython3still opens the Microsoft Store, and guarded engine calls must
use the absolute interpreter path reported above rather than that name. Offer the same
remediation as an optional tidy-up, not as a fix for a broken install — disable thepython3
App execution alias (Settings > Apps > Advanced app settings > App execution aliases), or put
real Python ahead of WindowsApps onPATH. A barecommand -v python3success is not
evidence on its own — it matches the stub too.Git —
command -v git. Conditional per the README: optional for ordinary trees,
required when a target contains or sits inside a Git worktree. Report presence as INFO
with that conditionality stated; absence is only a FAIL for worktree-containing targets.Platform posture — detect the current OS family and report its documented lane per
the README, keeping the audit and execution lanes visibly separate: Windows (full
audit —lstatreparse + Win32, never UAC; engine execution unsupported —previewreportsexecution-platform-unsupportedas a per-candidate blocker, removal is
a manual, per-path Recycle-Bin handoff only under--executeand after explicit
approval), Linux (full audit; execution when/proc/self/mountinfois readable —lsofneeded only for that optional execution
lane, absentlsofis INFO with the reduced-capability note), macOS (audit/report
only by design; manual Trash handoff only under--execute— INFO, not a defect).Execution kill switch — resolve the effective
disk_hygiene_enabledvalue
deterministically; never present an assumed value as the configured one. Run the bundled
probe with the step-2 interpreter:"<python>" "${CLAUDE_PLUGIN_ROOT}/skills/setup/scripts/kill_switch_probe.py"
and report itseffectivevalue together with itssource(configuredvsdefault).
When the probe saysdegraded: true, report that the configured value could not be read
and that defaulttrueis being assumed — an assumption, never the configured value. The
body token${user_config.disk_hygiene_enabled}is at most a cross-check: if it expanded
to a boolean that contradicts the probe, report the discrepancy instead of silently
preferring either channel (the probe sees user settings only; managed settings or a--settingsflag can carry a value the probe cannot see).Plugin registration — INFO: confirm the plugin is enabled for this project
(/plugin→ Installed) rather than parsing settings files.
apply (idempotent)
Run check, then for each FAIL point at the resolution. Every prerequisite is a system
tool or an OS capability, so apply installs nothing and writes nothing — it only points:
- missing/old Python: the platform's own install channel for the floor
checkparsed from
the engine'sMIN_PYTHON; never a plugin download. - missing git (worktree targets): platform install instructions.
- toggle off: direct to
/plugin configure disk-hygiene(interactive, any time).
Headless:--configonly applies on a fresh install (ignored once installed), so
reconfigure viaclaude plugin uninstall disk-hygiene -s <scope>thenclaude plugin install disk-hygiene@<marketplace> -s <scope> --config disk_hygiene_enabled=true;
this skill never writes user settings orpluginConfigs. Both commands default to-s user—
pass the scopeclaude plugin listreports for this plugin, and run from that project's
directory for aproject/localscope. Defaulting instead uninstalls a separate user-scope
record while the effective install stays in place, so the reinstall lands at a scope that
does not load.
Re-running apply after everything passes changes nothing and reports "already configured".
What this skill does NOT do
- Run an audit or cleanup — that is
/disk-hygiene:clean. - Write the plugin cache, Claude Code user settings, or
pluginConfigs. - Install any tool or runtime, during either
checkorapply— guidance only.