Skip to content

disk-hygiene: kill switch (disk_hygiene_enabled) cannot reach a skill-frontmatter guard hook — audit-only degrades to prompt-gated #1019

Description

@kyle-sexton

Summary

The disk-hygiene clean skill's disk_hygiene_enabled userConfig kill switch (false = audit-only
mode, which should deny every deletion lane) cannot be delivered to the skill-frontmatter guard
hook by any channel
, so the guard defaults to enabled and audit-only mode degrades from
deny-outright to human-prompt-gated.

Surfaced while fixing #983 (the guard's fail-open on the ${CLAUDE_PLUGIN_DATA} skill-hook launch
refusal, PR #1014). That PR removes the un-launchable ${user_config.*} token from the hook args to
guarantee the guard launches; this issue tracks the capability that removal gives up.

Why no channel reaches the guard

A skill-frontmatter hook has only two ways to receive a userConfig value, and neither works:

  1. ${user_config.disk_hygiene_enabled} arg substitution — Claude Code substitutes only
    ${CLAUDE_PLUGIN_ROOT} into skill-hook args (${CLAUDE_PLUGIN_DATA} is plugin-only and refuses
    the launch; ${user_config.*} is, on the evidence, not substituted for skill hooks). Passing it
    would reintroduce the disk-hygiene: guard hook fails to launch on skill-frontmatter hooks referencing ${CLAUDE_PLUGIN_DATA} — live fail-open on 0.4.6 #983 launch-refusal fail-open.
  2. CLAUDE_PLUGIN_OPTION_DISK_HYGIENE_ENABLED environment variable — not injected into a
    skill-frontmatter hook's process environment (the disk-hygiene: skill-frontmatter guard reads CLAUDE_PLUGIN_DATA from env but never receives it -> engine lane fails closed on all platforms #376 finding for CLAUDE_PLUGIN_DATA; the
    CLAUDE_PLUGIN_OPTION_* class is likewise absent).

Impact

Candidate resolutions (needs a design pass)

  • Platform: Claude Code adds ${user_config.*} substitution (or CLAUDE_PLUGIN_OPTION_* env
    injection) for skill-frontmatter hooks. Cleanest, but not in the plugin's control.
  • Plugin-scoped delivery: a plugin-level hooks.json SessionStart hook (plugin hooks do get
    ${user_config.*}) writes the resolved value to a file under ${CLAUDE_PLUGIN_DATA} that the skill
    guard reads. Works today but adds a per-session component and a file-trust surface — evaluate
    before building.

References

Metadata

Metadata

Assignees

No one assigned

    Labels

    needs-humanHuman-in-the-loop required; autonomous sessions must not resolve items carrying this.priority: mediumReal value, no hard deadline; normal backlog flow.wayfind: designWayfind decision item: design-space or domain-model decision; human in the loop.

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions