Designing Procedure Portability
The tools decide where reusable procedures may live. Compatibility between tools is usually one-way — one tool reading another's directory does not make the reverse true.
Problem
When work repeats, you want to write the procedure once and reuse it. Its location is not your choice: an agent product reads only the places it specifies.
With one tool, that is no problem. Put it where the tool says. The problem begins with two or more tools: the same procedure must be placed in each product's location.
The straightforward response is copying, but every copy adds a question. Which is current? Which was changed on one side only? Is a difference intentional or a forgotten update? Eventually nobody can name the authoritative copy.
There is another failure besides copying. A procedure intended for sharing can contain wording meaningful only to one product. With one product, the author may not notice. Taking it to the second tool shows that wording is ignored or cannot be interpreted.
Most easily overlooked is asymmetric compatibility. Once people learn “product X also reads product Y's directory,” they assume it can be shared. That is only a one-way fact. Nothing guarantees the reverse.
Context
Apply when:
- You use two or more agent products (or multiple surfaces of one product) — with one, follow its placement convention
- You want the same procedure from both — a procedure used on only one side needs no portability
- The procedure will grow — a one-time procedure tolerates copying; continuing revisions make the absence of an authoritative source expensive
- The procedure is long — a few duplicated lines can be managed, but divergence in a long procedure is harder to see
Do not apply when:
- You use one tool only. Portability is insurance for the future, and its premium is paid now
- The procedure is one-time. It has not yet reached the point of extraction (see Instruction Layering and Scoping)
- You use only the direction in which compatibility already holds. As described below, one direction can require only placement. Do not add machinery where it is not needed
Boundaries with adjacent patterns:
- One Authoritative Source for Instructions is close, but handles a different failure. It handles priority divergence — not knowing which of multiple instructions wins. This pattern handles copy dispersion — not knowing which copy is authoritative. The former prevents conflicts; the latter distributes from one source
- Instruction Layering and Scoping decides whether something is resident or read when needed. This pattern decides the location of a procedure read when needed, after deciding to extract it
- Resident Context Inventory counts all resident material. Extracted procedures are not resident, so the patterns are not directly in tension
- Strong Gates for Unattended Paths decides when a procedure starts; this pattern decides only where it is placed
Solution
There is an order: first discover compatibility; then build only the mechanism that is missing.
1. Check each direction in the documentation. Do not begin with “they probably share it.” Discovery locations are product specification. Check both directions independently: reading a one-way statement as bidirectional is the common error here.
2. Add nothing to a direction that already works. If product A reads product B's directory, placing the procedure in B's location makes it available to both. Synchronization there pays cost for nothing.
3. Add distribution only to a direction that does not work. Choose one source and edit only it. Put distributed copies in each product's discovery locations and treat them as generated artifacts — do not edit them, or assume regeneration will erase edits. Keeping the source outside every product discovery location avoids giving one product special status and avoids distortion as products are added.
4. Put only wording meaningful to every product in the shared source. Keep a setting meaningful only to one product outside it. It often does not break when mixed in, but not breaking is not the same as having meaning. Other products ignore it, while its author may mistakenly believe it takes effect.
Why this order? Portability is a cost, not a goal. Sources and distributed copies create opportunities to edit the wrong place, forget distribution, and decide whether to commit generated output. Compatibility that already exists avoids all of those costs, so investigate first.
Trade-offs
Benefits
- The authoritative source is unique. You no longer ask which is current; this matters more as procedures change more often
- Adding a product costs less. Add one distribution target instead of reconciling every existing copy
- Intentional differences are distinguishable from forgotten updates. Differences live only in the distribution mechanism, never in the source
- Product-specific wording becomes visible. Moving it out of the source requires asking which product it belongs to
Costs
- The dual structure of source and distributed copies itself costs. Editing the wrong place disappears silently at the next distribution. Disappearance is not worst; failing to notice it disappeared is
- Distribution is forgotten. Manual distribution will be forgotten. The mechanism is complete only when it also detects missed distribution (see Separating Mechanical Gates from Semantic Gates)
- ⚠ Within the range checked, neither vendor recommends the configuration of keeping a source outside discovery locations and distributing it. Official material confirms where discovery locations are, not this configuration. It is this catalog's design proposal derived from the mechanism; do not read it as official guidance
- Compatibility can change. Discovery locations are product specifications and specifications change. Today's asymmetry may not be tomorrow's; record the depended-on direction and check it periodically (see Auditing Past Decisions)
- Sharing thins content. Limiting the source to wording meaningful in every product gives up strong product-specific directives. Portability and optimization trade off
GitHub Copilot in Practice
The asymmetric discovery locations are confirmed by primary material from both vendors. The following are results from retrieving raw HTML on 2026-07-26 and searching the body. Byte counts record full retrieval, not identity.
GitHub — reads three directories Official
Source: About Agent Skills (551,223 bytes).
Project skills, stored in your repository (.github/skills, .claude/skills, or .agents/skills)
Personal skills, stored in your home directory and shared across projects (
~/.copilot/skillsor~/.agents/skills)
grep -c returns 2 for .github/skills, 2 for .claude/skills, 3 for .agents/skills, and 2 for .copilot/skills.
Copilot is the side that reads directories conventionally associated with other vendors.
Anthropic — reads only under .claude/ Official
Source: Skills (953,891 bytes). grep -c for the same material is:
| Search term | Hits |
|---|---|
.claude/skills | 23 |
.github/skills | 0 |
.agents/skills | 0 |
SKILL.md | 27 |
This is where the asymmetry appears. Copilot's material lists three directories, while the Anthropic material's discovery locations are confined under .claude/ and mention other vendors' directories 0 times.
In practice, then, a procedure in .claude/skills can be read by both within the range checked; a procedure only in .github/skills can be read only by Copilot. Where choosing one location is enough, there is no reason to build distribution.
⚠ This is a fact about what today's materials say, not a permanent guarantee. If you depend on it, record that dependency.
Discovery locations differ by surface — the same is true beyond procedures Official
The same asymmetry appears for reusable units other than procedures:
- Copilot CLI custom agents — place
.agent.mdin.github/agents/or~/.copilot/agents/(Creating custom agents for Copilot CLI, 581,336 bytes;grep -creturns 2 for.github/agents, 2 for.copilot/agents, and 4 for.agent.md) - Repository custom instructions —
.github/copilot-instructions.mdand.github/instructions/NAME.instructions.md(Adding repository custom instructions) - Claude Code memory —
~/.claude/CLAUDE.md,./CLAUDE.md,./.claude/CLAUDE.md, and others (Manage Claude's memory, 616,932 bytes)
Even the same “reusable wording” has a different placement convention for each unit. Procedure compatibility does not imply instruction or agent-definition compatibility. Check each unit separately.
Absence Confirmed — no material recommends distribution
Within the full texts of the four materials above — About Agent Skills, Claude Code Skills, Copilot CLI custom agents, and Claude Code memory — no description was found that says, in effect, “keep an authoritative source outside discovery locations and synchronize it to each discovery location.” Official material says only which directories are read.
Therefore, in this page's Solution, asymmetric discovery locations are Official, while the source-and-distributed-copy configuration is this catalog's design proposal. Do not collapse that distinction.
Also Known As
| Name | Source |
|---|---|
| Designing Procedure Portability | Descriptive — this catalog's descriptive name; it has no primary-source use |
Agent Skills / SKILL.md | Primary — names a format for writing procedures, not the practice of designing portability |
| Single source of truth | [Common] — a general design term. No primary source has been confirmed in the context of distributing procedures. This catalog's One Authoritative Source for Instructions uses it as an alternative name for a different problem: instruction priority |
The format has an official name, but the design of where to put it and how to distribute it has none. Calling the practice by the format's name creates the false implication that writing in that format makes it portable. The same format can be placed where only one side reads it.
Related
- One Authoritative Source for Instructions — the goal of a single source is shared, but the breakage differs: priority divergence there, dispersion of copies here
- Instruction Layering and Scoping — whether to keep an instruction resident or extract it is that pattern. Where to put it once you have decided to extract is this one
- Strong Gates for Unattended Paths — that pattern covers when a procedure you placed starts. Placement and start condition are separate problems
- Separating Mechanical Gates from Semantic Gates — detect a missed distribution mechanically. Do not build something held together by human attention
- Auditing Past Decisions — the compatibility direction you depend on is a premise a spec revision can break. It becomes an audit target