Skip to content

check-skill.sh: a cross-skill reference fails as a broken internal ref, and the error points at the wrong directory #2173

Description

@kyle-sexton

Problem

plugins/skill-quality/scripts/check-skill.sh (check 5, INTERNAL_DIRS around line 357) extracts any bare context/…, reference/…, templates/…, scripts/… (etc.) path from a SKILL.md and resolves it against the citing skill's own directory.

Two things make it misfire:

  1. It matches paths appearing in prose and inline code, not only in markdown link targets.
  2. There is no notion of a sibling skill — a legitimate cross-skill citation resolves to the wrong directory and fails.

So citing another skill's file by its natural relative name fails with:

FAIL: broken skill-internal ref: context/suppression.md (no such file under the skill dir; cited at SKILL.md:39 — hand-verify the line before fixing, may be an illustrative example)

…while the file plainly exists at plugins/<plugin>/skills/<other>/context/suppression.md. The message points at the citing skill, so the natural next move is to look for the file where it isn't.

Impact

Hit twice in a single PR (#2161) while building mutation-testing, once in each direction:

  • setup/SKILL.md citing audit/context/suppression.md
  • a later edit citing principles/reference/scaling-and-suppression.md

The working form is the plugin-root reference:

[`${CLAUDE_PLUGIN_ROOT}/skills/audit/context/suppression.md`](../audit/context/suppression.md)

That form is used elsewhere in the marketplace, but nothing states it where an author writing a cross-skill citation would meet it, and the error doesn't suggest it.

Options

  1. Docs: state the cross-skill citation form in PLUGIN-PHILOSOPHY.md and/or SKILL-CHEAT-SHEET.md, where an author meets it.
  2. Message: when the unresolved path does exist under a sibling skill of the same plugin, say so and name the ${CLAUDE_PLUGIN_ROOT} form. Cheap to detect — the checker already knows the plugin root.
  3. Extractor precision: only extract from link targets, not prose/inline code. Riskier — prose refs are presumably intentional coverage.

(2) alone would have saved both incidents. (1) and (2) together are complementary.

Source

Found by using the gate, not by reading it. Recorded during the gate doc-currency audit (PR #2169).

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions