doctor: third-party skills in ~/.agents/skills fail SessionStart hook as "unmanaged" #53

Open
opened 2026-10-08 05:24:04 +00:00 by mathias · 1 comment
Owner

Problem

bin/doctor --quiet (SessionStart hook, skills@mathias 0.22.1) exits 1 whenever ~/.agents/skills/ holds a skill that is a plain directory rather than a link into a managed source. Claude Code then shows SessionStart:startup hook error on every session start.

Reproduced 2026-10-08 after npx skills add remotion-dev/skills: 12 FAIL unmanaged: ~/.agents/skills/remotion-* is not a link into any source findings (remotion-best-practices, -captions, -create, -docs, -interactivity, -maps, -markup, -multimedia, -render, -saas, -studio, -upgrade). Legitimate third-party skills, installed on purpose; the project pins them in skills-lock.json (source remotion-dev/skills, with computedHash).

Expected

Skills recorded in a skills-lock.json (project) or otherwise declared as third-party are not "unmanaged". At most a WARN; the hook must not exit non-zero for them.

Options

  1. Doctor reads skills-lock.json and exempts names listed there.
  2. Downgrade unmanaged from FAIL to WARN for directories that contain a SKILL.md.
  3. Support an explicit allowlist (e.g. SKILLS_EXTERNAL=remotion-*).

Recommendation: 1, since the lock file already records provenance and hash.

Related findings from the same run (check separately)

  • FAIL legacy: ~/.claude/skills holds 12 per-skill symlinks from the pre-plugin wiring, so skills load twice.
  • FAIL drift: Claude Code plugin serves 45 skills, other harnesses see 44. Possibly a side effect of the above; verify after the Remotion findings are exempted.

Evidence

sh $CLAUDE_PLUGIN_ROOT/bin/doctor --quiet -> skills doctor: 14 finding(s), exit 1, runtime ~0.2s (within the 5s hook timeout).
Source: plugins/cache/mathias/skills/0.22.1/bin/doctor.


Created via git-mcp on behalf of @mathias

## Problem `bin/doctor --quiet` (SessionStart hook, `skills@mathias` 0.22.1) exits 1 whenever `~/.agents/skills/` holds a skill that is a plain directory rather than a link into a managed source. Claude Code then shows `SessionStart:startup hook error` on every session start. Reproduced 2026-10-08 after `npx skills add remotion-dev/skills`: 12 `FAIL unmanaged: ~/.agents/skills/remotion-* is not a link into any source` findings (remotion-best-practices, -captions, -create, -docs, -interactivity, -maps, -markup, -multimedia, -render, -saas, -studio, -upgrade). Legitimate third-party skills, installed on purpose; the project pins them in `skills-lock.json` (source `remotion-dev/skills`, with computedHash). ## Expected Skills recorded in a `skills-lock.json` (project) or otherwise declared as third-party are not "unmanaged". At most a WARN; the hook must not exit non-zero for them. ## Options 1. Doctor reads `skills-lock.json` and exempts names listed there. 2. Downgrade `unmanaged` from FAIL to WARN for directories that contain a `SKILL.md`. 3. Support an explicit allowlist (e.g. `SKILLS_EXTERNAL=remotion-*`). Recommendation: 1, since the lock file already records provenance and hash. ## Related findings from the same run (check separately) - `FAIL legacy`: `~/.claude/skills` holds 12 per-skill symlinks from the pre-plugin wiring, so skills load twice. - `FAIL drift`: Claude Code plugin serves 45 skills, other harnesses see 44. Possibly a side effect of the above; verify after the Remotion findings are exempted. ## Evidence `sh $CLAUDE_PLUGIN_ROOT/bin/doctor --quiet` -> `skills doctor: 14 finding(s)`, exit 1, runtime ~0.2s (within the 5s hook timeout). Source: `plugins/cache/mathias/skills/0.22.1/bin/doctor`. --- _Created via git-mcp on behalf of @mathias_
Author
Owner

Update 2026-10-08, after investigating on koala:

  • The 12 FAIL legacy symlinks in ~/.claude/skills were not pre-plugin wiring. They were the Remotion links (remotion-* -> ../../.agents/skills/remotion-*) from the same global npx skills add. Doctor's legacy check cannot tell those from real legacy links.
  • The FAIL drift (45 vs 44) had a separate cause: the host checkout ~/.local/share/skills was 13 commits behind origin, so it lacked document-to-markdown, which the plugin already served. A git pull --ff-only plus install.sh cleared it. The doctor message does not say to update the checkout.
  • Remotion is now installed project-local (doodle) only; global copies removed. Doctor exits 0.

Still open: a global third-party install (npx skills add -g) will fail the SessionStart hook again, and legacy will misreport its links. Suggest (a) exempting names listed in a lock file, and (b) making the legacy check only match links that point into the checkout. Policy going forward: third-party skills are installed per project, not globally.


Created via git-mcp on behalf of @mathias

Update 2026-10-08, after investigating on koala: - The 12 `FAIL legacy` symlinks in `~/.claude/skills` were not pre-plugin wiring. They were the Remotion links (`remotion-* -> ../../.agents/skills/remotion-*`) from the same global `npx skills add`. Doctor's `legacy` check cannot tell those from real legacy links. - The `FAIL drift` (45 vs 44) had a separate cause: the host checkout `~/.local/share/skills` was 13 commits behind origin, so it lacked `document-to-markdown`, which the plugin already served. A `git pull --ff-only` plus `install.sh` cleared it. The doctor message does not say to update the checkout. - Remotion is now installed project-local (doodle) only; global copies removed. Doctor exits 0. Still open: a global third-party install (`npx skills add -g`) will fail the SessionStart hook again, and `legacy` will misreport its links. Suggest (a) exempting names listed in a lock file, and (b) making the `legacy` check only match links that point into the checkout. Policy going forward: third-party skills are installed per project, not globally. --- _Created via git-mcp on behalf of @mathias_
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: mathias/skills#53