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
Doctor reads skills-lock.json and exempts names listed there.
Downgrade unmanaged from FAIL to WARN for directories that contain a SKILL.md.
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.
## 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_
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.
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_
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Problem
bin/doctor --quiet(SessionStart hook,skills@mathias0.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 showsSessionStart:startup hook erroron every session start.Reproduced 2026-10-08 after
npx skills add remotion-dev/skills: 12FAIL unmanaged: ~/.agents/skills/remotion-* is not a link into any sourcefindings (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 inskills-lock.json(sourceremotion-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
skills-lock.jsonand exempts names listed there.unmanagedfrom FAIL to WARN for directories that contain aSKILL.md.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/skillsholds 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
Update 2026-10-08, after investigating on koala:
FAIL legacysymlinks in~/.claude/skillswere not pre-plugin wiring. They were the Remotion links (remotion-* -> ../../.agents/skills/remotion-*) from the same globalnpx skills add. Doctor'slegacycheck cannot tell those from real legacy links.FAIL drift(45 vs 44) had a separate cause: the host checkout~/.local/share/skillswas 13 commits behind origin, so it lackeddocument-to-markdown, which the plugin already served. Agit pull --ff-onlyplusinstall.shcleared it. The doctor message does not say to update the checkout.Still open: a global third-party install (
npx skills add -g) will fail the SessionStart hook again, andlegacywill misreport its links. Suggest (a) exempting names listed in a lock file, and (b) making thelegacycheck 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