Half of every SKILL.md on GitHub is a verbatim copy of another one. That
single number is the whole problem: a skill runs with your user's
permissions, it can execute shell commands and reach the network, and it
arrives by being copy-pasted out of a repository somebody found.
Within ten months of the format appearing, skills existed in 259,596 repositories — 1,612,846 distinct ones. But copying leaves no dependency edge. There is no registry recording where a skill came from, no version you can pin, no channel that carries a fix downstream. Package managers answer "which of my dependencies are affected?" from a dependency graph. Skills have no such graph.
You cannot reconstruct it from a snapshot either. A census of which repositories hold which skill records the nodes of the network and nothing about the edges — not who copied from whom, not which copy came first, not when. Those edges exist in one place only: git history.
The approach that works is to treat the commit log as the edge source. A
lineage joins the versions of one skill that are linked by edits; its first
adoption is the origin. A commit that adds ten or more SKILL.md files is a
copy event, and the source is the earlier adopter already holding at
least half of the adopter's existing lineages. The cascade of one skill
through the ecosystem is its constellation.
# The earliest known adoption of a skill is the commit that added it
git log --follow --diff-filter=A --format='%H %aI' -- SKILL.md
# A commit adding ten or more SKILL.md files is a copy event
git log --diff-filter=A --name-only --format='%H' \
| awk '/^[0-9a-f]{40}$/{sha=$0; next} /SKILL\.md$/{c[sha]++}
END{for(s in c) if(c[s]>=10) print s, c[s]}' \
| sort -k2 -nr
Applied across every SKILL.md path on the default branch, this yields a
dated, directed network of 2,193,119 adoptions. The reconstruction is
checkable against an independent record: in 1,534 folders whose skill
installer logged where and when it copied from, the reconstructed date lands
within seven days in 94.6% of cases.
One skill makes the shape visible. web-design-guidelines reached 972
adopters across 12 generations of copies. That is a dependency graph in
everything but declaration — and nobody had it.
Most of GitHub is peripheral. 64.2% of repositories share no skill with any other repository at all; the remainder form 50 communities of at least 100 repositories each, organised by topic.
The growth mechanism is not the one you would guess. Individual adoption is rare — repositories copy whole catalogs, in bundles of up to a hundred files, far more often than they take a single skill. Preferential attachment therefore operates on catalogs, not on skills. A conditional logit fitted to the source-choice data puts a coefficient of 1.64 on the logarithm of past copies: a bundle copy strongly prefers a source that has itself already been copied.
Transmission is wildly overdispersed (negative binomial dispersion k = 0.086). Most adopters transmit nothing onward; a handful of repositories account for almost the entire spread. If you are trying to understand where skills come from, that is the first thing to model.
GitHub stars are nearly uninformative about out-degree in the dated copy network. Ranked before a fixed cut-off, current copy out-degree identifies 4.0 times as many later transmissions as stars do. PageRank and the raw number of skills held perform comparably to out-degree.
Dating also corrects attribution. Of the 20 repositories with the highest static out-degree, only 7 stay in the top 20 once each is credited only for skills it actually held first — the rest are late adopters that inherited a large catalogue. And fake-star campaigns make stars a manipulable signal outright.
The top sources, it turns out, are mostly unremarkable projects rather than the aggregators you would expect. Which is the point: you cannot find the sources by looking for hubs.
This is where the copy network stops being a curiosity and becomes an operational problem. A clone group is the set of repositories holding one exact version of a skill in a given week; a genealogy follows a group through time; a change is consistent when every member moves to the same next version.
Only 11.1% of changes to a group are consistent, at every observation window. Consistency collapses once a group spans several owners. A single owner raises the odds of a consistent change 3.32-fold, and only 4.0% of genealogies ever change consistently.
Compare that with copied code files, which adopt upstream security fixes in 47% to 84% of cases. For skills, only 20.9% of copies follow a later edit of their source. A security fix at the origin of a constellation reaches a minority of the copies, and the copies have no version reference that would tell them a newer version exists.
The inverse also holds. Modified copies gain command execution more often than they lose it — and the gain comes not from the owners' own edits, which add and remove capabilities at similar rates, but from adopting a different version of the skill. A third of copies now cross agent platforms, and skills sitting in one agent's folder routinely name tools that only another agent provides.
Here the network pays for itself. Fit a model of which repositories others copy from, rank repositories by that score, and audit the top 100. On a held-out period after a temporal split, that prevents 14.9% of later adoptions of high-risk skills — against 0.5% for auditing the 100 most starred repositories. A quarter of the prevented adoptions are indirect copies, which a source-level audit would otherwise miss.
Three things follow. The ordering survives moving the split to 1 March or 1 May. A ranking chosen in hindsight prevents only about a quarter as much, because roughly half of the harm arrives as new skills rather than as copies of known ones. And a new skill reaches few of its eventual adopters in its first week, so reviewers have weeks, not hours — but they have to act inside that window.
The whole analysis reduces to a directed graph and an out-degree ranking. Once the copy edges are in Neo4j, the audit list is a query:
// Rank repositories by dated copy out-degree — the audit shortlist
MATCH (source:Repository)-[copy:COPIED]->(target:Repository)
WITH source, count(copy) AS outDegree
RETURN source.fullName AS repository, outDegree, source.stars AS stars
ORDER BY outDegree DESC
LIMIT 100;
Add the stars column deliberately. The gap between the two orderings is the finding: it measures how much of your audit effort a popularity signal would have wasted.
The practical guidance is unchanged by the method. If you run agents that load skills, you are running code you cannot version-pin, from a supply chain with no dependency graph. Build the graph yourself from commit history, rank by copy out-degree rather than stars, and act in the first weeks — because the copies will never do it for you.