Use when someone wants to add, list, inspect, curate, refresh, or remove an external agent-skill source in Agent Compass — \"add these skills from <repo>\", \"integrate this skill pack\", \"what external sources do we track\", \"is <skill> already covered\", \"update the pinned sources\", \"drop that source\". Runs the licence gate first, registers the source as tracked-not-copied, computes its inventory, records the curation, writes the pointer document, and validates. Triggers: external ski...
Scanned 9/5/2026
Install to Claude Code
npx -y skills add me-cedric/agent-compass --skill compass-external-source --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Compass External Source?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/me-cedric-compass-external-source)More formats (shields.io, HTML) on the badges page.
---
name: compass-external-source
description: "Use when someone wants to add, list, inspect, curate, refresh, or remove an external agent-skill source in Agent Compass — \"add these skills from <repo>\", \"integrate this skill pack\", \"what external sources do we track\", \"is <skill> already covered\", \"update the pinned sources\", \"drop that source\". Runs the licence gate first, registers the source as tracked-not-copied, computes its inventory, records the curation, writes the pointer document, and validates. Triggers: external skills, third-party skills, skill pack, agent skills repo, upstream source, track a repo, vendor a skill pack, upstream-sources.json, external-skills."
risk_level: medium
writes_files: true
requires_tools: [node, git]
version: 1.0.0
---
# Adding An External Skill Source
Agent Compass stores **no** third-party skill. Every external source is a pinned
entry in [`skills/upstream-sources.json`](../../skills/upstream-sources.json)
that records what the source holds, which of it Agent Compass endorses, and how
to install it. The copy is made into a host project or a user config at install
time, never into this repository.
That is the shape any new source has to take. This playbook gets it there.
## First: is it already covered?
Two commands answer this without reading a repository:
```bash
agent-compass external-skills --list # every tracked source, count, licence
agent-compass skills --grep <term> # searches local AND tracked skills
agent-compass skills <name> # source, pin, licence, install command
```
`agent-compass skills <name>` answers for a tracked skill as readily as a local
one. If the capability already exists, say so and stop — a second source for the
same job splits the curation and doubles the refresh work.
## Step 1 — The licence gate (do this before reading the skills)
This is the step that has actually blocked work, so it comes first.
Read the repository's `LICENSE` in full. Then answer, in the handoff:
| Question | Why it decides the outcome |
| -------- | -------------------------- |
| Is it a recognised permissive licence (MIT, Apache-2.0, BSD, ISC)? | Tracking is uncontroversial; note attribution duties. |
| Does it restrict **use**, not just distribution? | A noncompete or field-of-use term (PolyForm, BUSL, SSPL, CC-BY-NC, "personal use only") changes what a host may do with an install, not only what Agent Compass may store. |
| Does it require a verbatim notice? | PolyForm's `Required Notice:` lines and Apache-2.0's `NOTICE` must travel with every copy. Record the exact string in the registry so the installer emits it. |
| Is there no licence at all? | **Refuse.** No licence means no grant. Do not register it; say so plainly. |
Tracking rather than copying removes Agent Compass's own redistribution
exposure — but it does **not** remove the host's. When a licence restricts use,
say so in the pointer document and in the notice, and let the person adopting it
decide. Do not silently absorb the question.
If the licence has a restriction you cannot resolve, stop and ask. That is a
decision for the repository owner, not for an agent.
## Step 2 — Content review
Read the source's own `SKILL.md` files, at least the ones you intend to
recommend. A skill is instruction text an agent will obey, so this is a security
review, not a taste review.
Reject or narrow anything that:
- pipes a remote script into a shell, or installs from an unpinned source;
- puts a secret in `argv`, an environment dump, or a log;
- tells the agent to skip a test, a review, or an approval;
- instructs the agent to act on production without confirmation;
- contradicts a rule in `AGENTS.md` — that is a **narrowing**, see Step 5.
Note what you rejected. A source can be worth tracking with three of its twenty
skills recommended; that is the normal outcome, not a failure.
## Step 3 — Register the source
Compute the inventory from the pinned tree rather than by hand:
```bash
node -e "
import('./scripts/lib/upstream-sources.mjs').then(m => {
// a shallow clone of the source, at the commit you reviewed
console.log(JSON.stringify(m.inventoryFromTree('<checkout>', '<commit>', '<inventoryRoot>'), null, 1))
})"
```
`inventoryRoot` is where `SKILL.md` files live upstream: `skills` for most,
`.` for a repository whose skills sit at the top level or in nested domain
folders. The slug is the frontmatter `name` when it is a usable slug and the
directory name otherwise — upstream folder names often disagree with the skill
names, and the skill name is what an agent keys on.
Add the entry to `skills/upstream-sources.json`:
```json
"<source-id>": {
"repository": "https://github.com/<owner>/<repo>",
"commit": "<40-hex commit you reviewed>",
"strategy": "reference",
"license": "<SPDX id or licence name>",
"licenseHolder": "<copyright holder>",
"requiredNotice": "<verbatim notice line, when the licence demands one>",
"licenseNote": "<one line naming a use restriction, when there is one>",
"install": "agent-compass external-skills --source <source-id> --recommended",
"vendorInstall": "<the vendor's own installer, when it ships one>",
"inventoryRoot": "skills",
"inventoryDoc": "docs/tooling/<pointer-doc>.md",
"pointers": ["skills/<router-skill>/SKILL.md"],
"recommended": ["<sorted subset you endorse>"],
"upstreamSkills": ["<the full sorted inventory>"]
}
```
Rules the verifier enforces, so get them right the first time:
- `recommended` must be a sorted subset of `upstreamSkills`.
- `upstreamSkills` must be sorted.
- No `assets` and no `skills` — a tracked source owns no local file.
- Every path in `pointers` and `inventoryDoc` must exist and must contain the
repository URL.
## Step 4 — Write the pointer document
Add the source to an existing pointer document when one fits
([operational-skills.md](../../docs/tooling/operational-skills.md),
[native-mobile-skills.md](../../docs/tooling/native-mobile-skills.md),
[style-and-design-skills.md](../../docs/tooling/style-and-design-skills.md)), or
create one. It must carry:
- the source, its licence, and any use restriction in plain words;
- what Agent Compass curates and **why** that subset — the reasoning is the
compass-authored value, and it is lost if only the list survives;
- the install commands, project and user-wide;
- which `AGENTS.md` gates survive an installed skill;
- a generated inventory block, exactly:
```markdown
<!-- BEGIN GENERATED:<source-id>-inventory -->
<!-- END GENERATED:<source-id>-inventory -->
```
Fill it, never by hand:
```bash
node -e "
import('./scripts/lib/upstream-sources.mjs').then(async m => {
const { readFileSync, writeFileSync } = await import('node:fs')
const s = m.readSourceRegistry('.').sources['<source-id>']
writeFileSync(s.inventoryDoc, m.applyGeneratedBlock(
readFileSync(s.inventoryDoc, 'utf8'),
m.inventoryBlockKey('<source-id>'),
m.renderInventory(s.upstreamSkills),
))
})"
```
## Step 5 — Narrow anything that conflicts with a compass rule
When a recommended skill contradicts `AGENTS.md`, do not drop the skill and do
not edit a copy — there is no copy. Add the correction to `LOCAL_OVERRIDES` in
[`scripts/lib/upstream-skills.mjs`](../../scripts/lib/upstream-skills.mjs) and
set `"adapter": "operational"` on the source. The installer then applies it on
every install, and an override whose upstream target was reworded **fails** the
install rather than being silently skipped.
Record each narrowing in the pointer document and in
[`THIRD_PARTY_NOTICES.md`](../../THIRD_PARTY_NOTICES.md): the upstream passage,
the replacement, and the compass rule that required it.
## Step 6 — Wire it into fit-based adoption (only if it should be automatic)
A source whose skills belong to a detected stack goes into
[`scripts/lib/profiles.mjs`](../../scripts/lib/profiles.mjs) as an `external`
entry on that stack's profile. `selectAssets` merges `external` into `skills`,
and `skills-sync --only` routes each name to the right install path — so
`recommend`, `adopt`, and `setup-wizard` pick it up with no further change.
Leave it out of the profiles when it is a user preference (a working-style skill)
or a broad opt-in corpus (operations). Those get installed on request.
## Step 7 — Index, test, validate
```bash
node scripts/upstream-skills.mjs --verify # offline: pins, pointers, inventories
node scripts/external-skills.mjs . --source <source-id> --recommended --dry
npm run check # tests + every linter
```
Index the new skill or document (`skills/README.md`, `docs/tooling/README.md`),
add the source row to `THIRD_PARTY_NOTICES.md` and
[upstream-sources.md](../../docs/tooling/upstream-sources.md), and add a
`CHANGELOG.md` entry. `npm run check` fails on a missed index.
Then install it for real into a scratch directory and read one installed file.
An inventory that verifies is not proof that an install produces usable text.
## Step 8 — If the source drives a published package, track its version
A skill that tells the agent to run `npx <pkg>@<version>` pins a version in prose.
The commit pin will not catch that going stale — the repository can move without
the package moving, and the package can move without the text noticing. Record it:
```json
"package": { "name": "@scope/pkg", "manifest": "path/to/package.json" },
"version": "<version at the pinned commit>"
```
`--verify` then fails when any local file pins a different version (including a
`tool_version` frontmatter field), and `--update` rewrites every occurrence when
the pin moves. Never hand-edit such a version; refresh the source.
## Refreshing and removing
```bash
agent-compass upstream-skills --check-updates # all sources, cached 24h
agent-compass upstream-skills --update <source-id> --dry
agent-compass upstream-skills --update <source-id>
```
A refresh moves the pin, re-reads the inventory, rewrites the generated block and
any tracked package version, and prints added and removed upstream skills. It
copies nothing. A removed upstream skill that is still in `recommended` fails
`--verify` — that is the signal to re-curate, not to force the pin.
A refresh also makes every existing install stale, because an install is a
snapshot of a pin. Say so in the handoff, and give the command:
```bash
agent-compass external-skills . --check # which installs are behind
agent-compass external-skills . --upgrade # re-install at the current pin
```
To remove a source: delete its registry entry, its pointer sections, its router
skill if nothing else uses it, its `profiles.mjs` entries, and its notice row.
Then run `npm run check`. Say in the handoff that hosts which already installed
from it keep their copies — removal stops tracking, not distribution.
## When to refuse
- **No licence.** No grant, no registration.
- **A licence you cannot read or resolve.** Ask; do not guess.
- **A source that duplicates an existing one.** Say which one covers it.
- **A single skill you could write yourself in twenty lines.** Write it as a
compass skill instead. A tracked source is a maintenance commitment: a pin to
refresh, an inventory to re-curate, and a notice to keep accurate.
## Related
- [skill-intake](../../docs/workflows/skill-intake.md) — whether a capability
belongs in Agent Compass at all, before this playbook applies.
- [upstream-sources](../../docs/tooling/upstream-sources.md) — the registry
contract and the strategies.
- [ADR 002](../../docs/decisions/002-tracked-external-reference-sources.md) — why
tracking replaced vendoring, and what moved to install time.
- [`compass-extend`](../compass-extend/SKILL.md) — adding a compass-authored
skill, instinct, template, or stack instead.
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!