feat(skills): make skills loadable, and audit for it - #182
Merged
Conversation
The MQ convention keeps skills in <repo>/skills/, but Claude Code only discovers them under <repo>/.claude/skills/. Every repo in the stack therefore carried a full set of skills that no agent could load — 63 across the eight of them. mq-skills.py reported them all "ok, indexed", because it validates the MQ convention and knows nothing about Claude Code's search path. Relative symlinks, so a fresh clone is wired the same way. This mirrors how .agents/skills entries were already linked by hand in mq-agent and macos-scripts. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
mq-skills.py reported all 63 skills in the stack as "ok, indexed" while not one of them could be loaded. It validated the MQ convention — skills/ plus a SKILLS.md entry — and knew nothing about Claude Code's search path, which is .claude/skills/. Being indexed says a human can find the file; it says nothing about whether a tool can run it. audit now prints a third column and validate warns on two new states: not-discoverable (no entry under .claude/skills) and broken-link (an entry with no SKILL.md behind it). The fix hints name the actual remedy. The smoke test builds a scratch repo with one skill, asserts it is reported while unlinked and not reported once linked — so the check tracks reality instead of always complaining. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Step 11 passed `--repo macos-scripts`, and a bare name resolves under $HOME. On a CI runner the repo lives in $GITHUB_WORKSPACE, so the audit found no repos, printed nothing, and the grep failed against a checker that was working correctly. Step 10 already skips its listing assertions for the same reason. Reproduced by running the suite with HOME pointed at a scratch dir, which fails before this change and passes after. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Two commits: wire this repo's skills up, then stop the same gap coming back.
The gap
The MQ convention keeps skills in
<repo>/skills/and indexes them inSKILLS.md. Claude Code discovers skills somewhere else:<repo>/.claude/skills/. Nothing checked those two against each other, so the entire stack carried skills no agent could load:63 in total.
mq-skills.py auditcalled every one of themok, indexed.The one that looked wired here was a false positive:
.claude/commands/mqlaunch-command-surface.mdis a slash command whose whole body is an instruction to go readskills/mqlaunch-command-surface/SKILL.md. That works when someone types the command; automatic triggering on the description — the thing that makes a skill worth having — never happened.The fix
Relative symlinks from
.claude/skills/intoskills/and.agents/skills/, mirroring how.agents/skills/pdfwas already wired here by hand. The other seven repos get the same treatment in their own commits.The check
mq-skills.py auditprints a third column, andvalidatewarns on two new states:not-discoverable— no entry under.claude/skillsbroken-link— an entry with noSKILL.mdbehind itFix hints name the actual remedy rather than pointing at
SKILL.mdagain.Step 12 of the smoke test builds a scratch repo with one skill and asserts it is reported while unlinked and not reported once linked, so the check tracks reality instead of always complaining.
Verification
The linked skills became available in this session the moment the links existed — no restart, which is the proof that matters more than the audit column.
🤖 Generated with Claude Code