One agent's skill catalog is easy; a fleet's is not
A single agent loading skills from a local .claude/skills/ directory has no consistency problem to solve -- there is one process, one filesystem, one catalog. The moment a second agent joins the picture, running as its own process, possibly on its own host, possibly built by a different team, the catalog stops being a filesystem detail and becomes a piece of shared state that two independent runtimes both need to agree on.
This matters specifically in multi-agent fleets: a supervisor agent that delegates to worker agents, a pipeline of specialist agents handing a task off in sequence, or a set of peer agents that discover each other over a protocol like A2A. In every one of those topologies, "which skills exist and what do their descriptions say" is a question more than one process needs the same answer to, and the registry pattern is the architecture for keeping that answer consistent.
Central registry versus local copies
There are exactly two honest designs. A central registry is a service (or a shared, versioned store) that every agent in the fleet queries or subscribes to; no agent holds its own permanent copy of the catalog, only a cache with a known freshness bound. A local-copy design has each agent carry its own directory of skill files, kept in sync with the source of truth through whatever deployment mechanism ships that agent's code.
Local copies are simpler to reason about per-agent -- there's no runtime dependency on a registry service being up -- but they push the consistency problem into deployment: every agent's copy has to be redeployed together for a skill change to take effect fleet-wide, which is exactly the kind of coordinated rollout that's easy to get wrong under time pressure. A central registry inverts that: one place to update, but now every agent has a runtime dependency on that registry, and its availability becomes part of the fleet's own availability story.
The practical split that holds up: local copies for skills that are stable and rarely change (the equivalent of vendoring a dependency at a pinned version), a central registry for skills that change often enough that redeploying every agent per change is the actual bottleneck. Most fleets end up with both -- a small core of always-available local skills and a larger, more volatile set fetched from a registry with a fallback to the last-known-good local cache.
Advertising capability, not just holding it
A registry that only agents query is half the pattern. The other half is agents advertising what they can do, so a supervisor or a peer can decide whether to hand work to them without already knowing their internals. This is precisely the role an agent-to-agent protocol's capability declaration plays -- see A2A's agent card for the concrete shape of that advertisement, which is functionally a skill catalog exposed outward rather than consumed inward.
The distinction matters architecturally: a registry an agent reads from is a dependency; a card an agent publishes is an interface contract with everyone who might route work to it. Getting the two conflated is how a fleet ends up with an agent whose advertised capabilities have drifted from what its actual loaded skill set can do -- it claims a capability via its card, but the registry entry backing that skill was updated (or removed) out from under it.
Supervisor Worker agent A Worker agent B
| | |
|-- query capabilities ---->| |
|<-- advertises: {code-review, test-writer} ------------|
|-- query capabilities --------------------------------->|
|<-- advertises: {code-review, deploy-check} ------------|
|
| route "review this diff" to whichever advertises code-review
| (both do -- pick by load, or by which catalog version is fresher)Cache invalidation, the part everyone underestimates
Every agent that isn't querying the registry synchronously on every single request holds a cache, even if nobody called it that. The cache has a TTL, explicit or implicit, and the fleet-wide question is: what happens in the window between the registry updating and every agent's cache catching up?
Three strategies, in increasing order of operational cost and decreasing order of staleness risk. Poll on an interval -- cheapest, but every agent can be running against a different catalog snapshot for up to one interval, which is fine for low-stakes skills and dangerous for anything safety-relevant (a guardrail skill that was just tightened should not still be running the old version anywhere). Push invalidation -- the registry notifies subscribed agents when an entry changes, cutting the staleness window to network latency, at the cost of a pub/sub dependency the fleet now also has to keep healthy. Version-pinned requests -- every task carries the catalog version it was planned against, and an agent refuses (or explicitly re-plans) if its local cache doesn't match; this is the only one of the three that turns staleness from a silent risk into a loud, catchable error.
The version-pinned approach is the one worth defaulting to for anything where a stale skill produces a wrong answer rather than a merely suboptimal one. It costs a version field on every request and a rejection path, which is cheap next to the alternative of debugging why two agents in the same pipeline behaved as though they'd read different instructions.
The drift failure mode
The failure this pattern exists to prevent is concrete: agent A in a pipeline plans a multi-step task assuming skill data-export behaves one way; by the time agent B executes a later step that also invokes data-export, the registry has been updated and B is running a materially different version. Neither agent is wrong in isolation -- each correctly used its own current cache -- but the pipeline as a whole executed against two different specifications of the same skill, and nothing in either agent's local view could have detected that.
This is the same class of bug as a distributed system running mismatched code versions across nodes, and the fix is the same discipline: make the version explicit and carried through the request rather than implicit and locally cached. A supervisor that stamps a catalog version onto a plan at creation time, and workers that validate their local cache's version against that stamp before executing a step, turns silent drift into an explicit re-plan-or-reject decision -- the same shape of fix as checkpointing makes partial progress resumable instead of silently corrupted.
Skill descriptions changing is usually the more dangerous drift than skill bodies changing, because a description change can silently alter which skill matches a request without anyone touching the instructions inside either skill -- two agents can each correctly load "the skill that matches," and still disagree, because the matching step itself ran against different catalog snapshots.
A skill registry is a piece of distributed state the moment more than one agent reads it, and it inherits every problem distributed state has: staleness, cache invalidation, and version drift between readers. Pin the catalog version into the request rather than trusting each agent's local cache to be fresh -- it's the only strategy that turns silent multi-agent drift into a loud, catchable error instead of a pipeline that quietly executed against two different specifications of the same skill.