A skill has callers, even though nothing calls it directly

Nothing in a runtime holds a reference to a specific skill the way code holds a reference to a function. A skill is matched by description at request time and could, in principle, be rewritten completely between one request and the next with no compile step, no import to update, no caller to notify. That looks like freedom. It's actually the exact condition under which software quietly breaks its consumers without anyone finding out until later: nothing forces you to think about who depends on the current behavior before you change it.

The fix is the same one dependency management always uses: treat a skill as a versioned artifact with a contract, even though the runtime itself enforces none of that. This is the governance half of the skills architecture -- what keeps a catalog of fifty independently-owned files from becoming fifty ways to break something nobody's watching.

Advertisement

What a skill's contract actually is

A skill has two things another skill, a person, or a downstream process can reasonably depend on. The first is its trigger conditions -- the description's promise about when it fires, per the discovery mechanism. The second is its output contract -- the shape of what it produces: a code-review skill that always returns findings ordered most-severe-first with a file:line anchor has made an implicit promise that anything consuming its output (a CI step that posts the top finding as a comment, say) now relies on.

Both halves of that contract can break silently, because nothing type-checks a markdown instruction file. Narrowing a description so it stops firing on a case it used to cover is a trigger-contract break. Reordering a skill's output section, or dropping the file:line anchor for terseness, is an output-contract break. Neither shows up as an error; both show up later as something downstream quietly stops working.

What counts as breaking, concretely

ChangeBreaking?Why
Tightening a description's negative scopeYesRequests that used to match now don't
Widening a description's positive scopeUsually notNew matches, existing ones still fire -- but check for new overlap with siblings
Rewording the instruction body, same behaviorNoTrigger and output contract both unchanged
Changing the output's structure or field namesYesAnything parsing the old shape breaks
Adding a new optional output sectionNoAdditive; existing consumers ignore what they don't parse
Changing severity ordering or default verbosityYesDownstream automation often assumes the old default

The pattern in that table is the same one that governs any API: additive changes are safe, changes to an existing promise are not, and the test for "existing promise" is always "could a reasonable caller have relied on this specific behavior" -- not whether the change feels small to the person making it.

Composition: skills that reference each other, and skills that collide

Two composition patterns show up once a catalog has real structure. The first is deliberate: one skill's instructions explicitly defer to another for part of the job -- a pr-description-writer skill that says "if the diff includes a database migration, also apply the schema-migration-reviewer skill's checklist" is composing two skills by reference. This works as long as the referenced skill's name is stable; it's exactly why a rename is a breaking change even when the renamed skill's own behavior hasn't shifted at all.

The second is accidental: two unrelated skills both match the same request (the overlap case from discovery) and their instructions actively conflict -- one says "keep the response under 200 words," the other says "always include a full worked example." Deliberate composition is designed and should be documented in both skills' bodies; accidental composition is a catalog bug and the fix is the same negative-scoping discipline that fixes false-positive matches generally, not a runtime-level conflict resolver, because a conflict resolver would just be reintroducing the coupling the whole pattern exists to avoid.

A governance model that doesn't need runtime support

None of this requires the runtime to understand versions -- it's process, sitting entirely in how a team maintains the catalog as files in a repository, which is exactly what a skills catalog already is.

A catalog manifest. One file listing every skill's name, a one-line purpose, and which team or person owns it. This is the thing a human scans before adding a fifty-first skill, to check for overlap before it happens rather than discovering it in production.

A changelog convention per skill. Even a simple ## Changed section at the bottom of the skill file, dated, noting whether a change was additive or breaking per the table above. This is cheap because a skill file is already version-controlled text -- the changelog is answering a question git log can't answer on its own, which is intent: was this edit meant to be safe, or was it a known breaking change that callers need to hear about.

## Changed
- 2026-09-12: BREAKING -- narrowed trigger to exclude "explain this code"
  requests; those now route to a separate code-explainer skill.
- 2026-08-30: additive -- added an optional "Worked example" output
  section; existing consumers unaffected.

Deprecate before you delete. When a skill is being replaced, leave the old one in the catalog with its description narrowed to nothing matches, or with an explicit note in its body that it's superseded and by what -- rather than deleting the file outright. A skill referenced by name from inside another skill's composition instructions (the deliberate-composition case above) breaks that reference silently if it simply vanishes; a deprecation stub at least fails loudly, or better, keeps working while pointing whoever reads it at the replacement.

A worked deprecation, start to finish

Say a pr-description-writer skill is being split into two -- the summary-writing part stays, the test-plan part becomes its own test-plan-writer skill, because in practice the two are used independently more often than together. Walking the full sequence makes the abstract governance model concrete.

Step one: ship the new test-plan-writer skill alongside the old one, not instead of it. Nothing downstream breaks, because nothing has been removed yet -- this is the additive case from the table above.

Step two: narrow the old skill's description to drop the test-plan-writing trigger clause, and add a changelog line noting the split and pointing at the new skill by name. Any composition reference elsewhere in the catalog (per the composition section above) that expected the old skill to also produce a test plan needs updating now, while the changelog entry makes that dependency visible instead of a silent break discovered later.

Step three, only after step two has been live long enough that nothing is still relying on the old combined behavior: delete the test-plan-writing instructions from the old skill's body entirely, or delete the file outright if the split fully replaces it. The deprecation window between steps two and three is what turns a breaking change into a scheduled, visible migration instead of a surprise.

Advertisement

Nothing in the runtime enforces a skill's contract, which means the discipline has to live in how the catalog is maintained: a manifest that surfaces overlap before it ships, a changelog that records intent rather than just diffing text, and deprecation before deletion for anything another skill might reference by name.