aiusage-skills: using other people's agent skills without surprises
An agent skill is a set of instructions for an agent that can already read your files. How do you use skills written by others without those instructions changing underneath you?
- Status
- Open source. The decisions described here are implemented; the gaps are listed at the end.
- My role
- Author. aiusage-skills is my own project.
- Scope
- How third-party skills get into the plugin, and how changes upstream are noticed
- Last reviewed
- 29 September 2026
aiusage-skills is a Claude Code plugin with twelve skills of my own, for planning, test-driven development and reviewing changes, plus a selection of skills from other authors. It goes together with aiusage.guide: the guide describes the working practices, the plugin puts them into the agent, and the two feed into each other.
Where it started
A skill from a marketplace isn't a library. It's a set of instructions for an agent that already has your files and your credentials. Installing it from a marketplace means the upstream author decides when those instructions change, and the change arrives without anyone reading it.
Decisions
Copy and pin instead of installing. Third-party skills are copied into vendor/, pinned to an upstream commit, together with their licence. Only the areas the plugin was missing were taken: 35 of 145 upstream skills. The rejected alternative was a marketplace install that updates itself. The decision record says what that costs:
Updates become a ritual (NOTICE.md) instead of an event. That is the point. The tree is 35 skills, not 145; absence is a decision.
From ADR-0001, "Vendor third-party skills instead of installing from marketplaces", accepted. Last changed 9 September 2026.
Scripts don't run until someone has read them. Scripts arrive in scripts.quarantine/ without execute permission. A script is only enabled through a written decision. ADR-0019 enabled 54 reviewed scripts and kept four quarantined, among them one that clones twelve third-party rule repositories at scan time without pinning. Reading the scripts also showed that several skills failed on a path error several steps in, although their descriptions said they stopped on purpose.
Freeze the whole vendor tree. Holding the vendored skills to my own lint rules would fail every one of them and drown the real findings. So CI compares the entire vendor/ tree with a SHA-256 baseline instead. Any change fails the build until someone accepts it with a deliberate --write-baseline commit after reading it.
Report upstream changes, never apply them. A nightly job compares vendor/ with each upstream source and keeps exactly one issue per source that has moved on. On the day the first full read was finished, three of the four sources were already behind.
It does not copy anything into
vendor/, does not open merge requests, and does not read upstream file contents —--name-statusneeds trees, not blobs. Fetched content is diffed, never executed. Copying and reading stay with the human, per ADR-0001; the job only says that there is something to read.
From ADR-0018, "A nightly job compares vendor/ with upstream and keeps one issue per source", accepted. Last changed 9 September 2026.
Verification
Four CI jobs enforce this:
validate:skillschecks my own skills against the rules: allowed tools, no fetching or installing at runtime, a length limit.validate:self-testruns the validator against fixtures that must fail, for example a skill that runscurl(runs-curl) or tells the agent to fetch something in prose (prose-fetch), and one that must pass because it only mentionscurl(mentions-curl).validate:vendorchecks the quarantine, the manifests and the SHA-256 baseline ofvendor/.vendor:driftis the nightly comparison with upstream.
Not done yet
- The CI images are referenced by tag, not by digest. ADR-0014 calls this "the one unpinned input in a repository whose argument is pinning".
- The validator doesn't follow skills that call other skills.
- The checks are pattern matching. Semantic attacks the patterns miss, and prompt injection in the content an agent is pointed at, are outside what this protects against. The threat model says so explicitly.
- The script that clones rule repositories unpinned stays quarantined until there is a decision on it.
Stack: Python (standard library only), GitLab CI.