Skip to content

check-skill-refs: catch typos and orphaned catalog entries - #13

Closed
sergiobuilds wants to merge 2 commits into
LilMGenius:mainfrom
sergiobuilds:pr-b-skillref-check
Closed

check-skill-refs: catch typos and orphaned catalog entries#13
sergiobuilds wants to merge 2 commits into
LilMGenius:mainfrom
sergiobuilds:pr-b-skillref-check

Conversation

@sergiobuilds

Copy link
Copy Markdown
Contributor

New scripts/check-skill-refs.sh — applies the same drift detection ssotchk looks for, to the catalog's own cross-skill vocabulary.

Checks

1. Backticked typo guard

A backticked skill-shaped token that is near a shipped skill name but does not resolve to one is almost certainly a typo — for example, re0-git-log when only re0-git is shipped. Only near-collisions with an existing shipped name are flagged; unrelated backticked identifiers pass silently.

2. Orphan guard

Every shipped skill must be reachable from README.md, either by a backticked mention or by a link to its SKILL.md path. A skill on disk that README never links to is orphaned.

Complements validate-skills.sh

validate-skills.sh already enforces that plugin.json paths resolve to SKILL.md files. This adds the reverse direction (disk → README) plus a typo guard on incidental references, so a rename that misses README (or misspells the new name in prose) fails CI instead of drifting silently.

Verification

$ bash scripts/check-skill-refs.sh
✓ skill references resolve (17 shipped names, 30 scanned files)

Empirically clean on the current catalog.

CI wiring — one line

The script is not yet wired into CI in this PR (OAuth workflow scope). Suggested addition after Validate the skill catalog step in .github/workflows/ci.yml:

- name: Verify skill references resolve
  run: bash scripts/check-skill-refs.sh

Happy to land the wiring in a follow-up, or fold into this PR if preferred.

New scripts/check-skill-refs.sh, wired into ci.yml alongside validate-skills.sh.
Applies the same drift detection ssotchk looks for — but to the catalog's own
cross-skill vocabulary.

Two checks:

1. A backticked skill-shaped token that is near a shipped skill name but does not
   resolve to one is almost certainly a typo. Example — 're0-git-log' when only
   're0-git' is shipped. Only near-collisions with an existing shipped name are
   flagged, so unrelated backticked identifiers pass silently.

2. Every shipped skill must be reachable from README.md, either by a backticked
   mention or by a link to its SKILL.md path. A skill on disk that README never
   links to is orphaned; if it should not ship, it belongs elsewhere.

Rationale — validate-skills.sh already enforces that plugin.json paths resolve to
SKILL.md files. This adds the reverse direction (disk → README) plus a typo
guard on incidental references, so a rename that misses README (or misspells the
new name in prose) fails CI instead of drifting silently until a reader stumbles
on it.

Empirically clean on the current catalog: 17 shipped names, 30 scanned files, 0
findings.
…propagate

The previous check-1 fed the token loop through a pipe (grep | tr | sort | while
read). That put the loop body in a subshell, so `fail=1` set by `err` never
reached the final exit-code decision — the script always ended 0 even when it
had flagged typos. Switch to `while read ... done < <(...)` so the loop stays
in the current shell and `fail` propagates.

While here, guard two states that would silently misreport:
- empty `shipped` array (no SKILL.md found): fail fast instead of iterating
  an empty catalog under `set -u`.
- missing README.md at repo root: fail fast instead of reporting every skill
  as orphaned.

Verified locally: clean repo exits 0; injecting `re0-git-log` into
docs/invocation.md exits 1 with the correct token/file in the message;
removing README.md exits 1 with the missing-catalog message; restoring
returns to exit 0.
@sergiobuilds

Copy link
Copy Markdown
Contributor Author

Cold-read pointed out that check-1 was effectively dead: piping grep | tr | sort into while read ran the loop body in a subshell, so fail=1 never made it back to the final exit-code decision. Real hits were silently swallowed.

Pushed fix (e976bbd):

  • check-skill-refs.sh check-1 loop now uses while read ... done < <(...) so it runs in the current shell and fail propagates.
  • Added two guards that would otherwise misreport under the newly-working exit code: empty shipped array (no SKILL.md under skills/) and missing README.md at repo root — both now fail fast with a clear message instead of appearing green or noisy.

Local verification (from a clean checkout of this branch):

scenario expected actual
clean repo exit 0 ✓ (17 shipped, 30 files)
inject `re0-git-log` into docs/invocation.md exit 1, message names file + re0
restore exit 0
remove README.md exit 1, message says catalog missing
restore README.md exit 0

Ready for another look.

@LilMGenius

Copy link
Copy Markdown
Owner

Landed in 4b8bf9a (v0.14.0), with a follow-up scoping fix on top. Thanks @sergiobuilds! 💚

@LilMGenius LilMGenius closed this Jul 17, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants