run-skill-generator: step-0 probe cannot see an existing skill in the target unit, silently rewrites it

Status Open
Reported on v2.1.220
Maintainer reply None cached
Activity 1 comment · opened Jul 28, 2026

What happened

Step 0 of the bundled run-skill-generator skill tells the agent to find any existing run-skill before writing one, using this probe:

d=$PWD; while :; do
  grep -Hm1 '^description:' "$d"/.claude/skills/*/SKILL.md 2>/dev/null
  [ -e "$d/.git" ] || [ "$d" = / ] && break
  d=$(dirname "$d")
done

The probe only ever walks upward from $PWD. But the next section of the same skill tells the agent the unit is often a subdirectory:

Large repo with many apps: one per app, colocated — apps/billing/.claude/skills/run-billing/, apps/desktop/.claude/skills/run-desktop/

So whenever the chosen unit is below the invocation directory — the normal case in a monorepo, and the case the skill explicitly instructs you to handle by asking the user which app to target — an existing skill inside that unit is invisible to the probe. The agent concludes "no skill exists", takes the create branch, and overwrites SKILL.md wholesale.

This directly contradicts the skill's own instruction:

If one is about launching/driving this app — whatever it's named — refine, don't rewrite: verify its claims, fix what's wrong, add what's missing, preserve what works.

The shipped probe cannot satisfy that instruction in exactly the repo layout the skill recommends.

Steps to reproduce

  1. A repo foo/ with a committed skill at foo/apps/bar/.claude/skills/run-bar/SKILL.md.
  2. cd foo, invoke /run-skill-generator.
  3. The generator asks which unit to target; answer apps/bar.
  4. Run the step-0 probe from foo: it checks foo/.claude/skills/*/SKILL.md, then walks up to /. It never looks under apps/bar/.
  5. Output is empty → the agent creates rather than refines, replacing the existing skill and its driver.

Observed

Invoked from a workspace directory; the operator selected a nested unit one level down. The probe returned nothing, but a skill was already committed in that unit, with a working driver script alongside it.

It was caught only by accident — an unrelated git worktree add checked the tracked files out, and a Write to SKILL.md then failed with "File has not been read yet". Without that guard the existing skill and its driver would have been silently replaced.

Worth noting: in that repo .claude/ is gitignored with the skill force-added, so git status gave no hint either. Any check based on working-tree dirtiness would also have missed it.

Suggested fixes

Any one closes it; the first two are cheap.

  1. Re-run the probe after entering the unit. Add to the discovery step: "once the unit is chosen, re-run the step-0 probe from inside it before deciding create-vs-refine."
  2. Search downward too. Replace the upward walk with a repo-wide lookup that also finds nested units, e.g.

``bash
git ls-files '*/.claude/skills/*/SKILL.md' '.claude/skills/*/SKILL.md'
`
This also catches force-added skills under a gitignored
.claude/`.

  1. Make the create path non-destructive — refuse to overwrite an existing SKILL.md without an explicit read-and-merge step.

Environment

  • Claude Code 2.1.220
  • macOS (arm64)
  • Bundled skill path: bundled-skills/2.1.220/<hash>/run-skill-generator

View original on GitHub ↗

This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗