The skills layer
Reusable agent behaviour packaged as a directory with one markdown file. Its defining property is negative — a skill reaches exactly one machine — and the fleet has three delivery layers with three different reaches.
in-flux
Sourced from the fleet's own component document for skills-layer. Called in-flux because three of its
own in-repository pointers resolve to files that are wired to nothing; because only two of the fleet's
seven agent repositories carry a skills directory at all; and because the two that do have diverged, with
nothing measuring the gap.
A skill is a directory holding one markdown file. The file's frontmatter description is what the model matches on to decide whether the skill applies — which means the description is not documentation, it is the routing key, and a vague one makes a skill that exists and never fires.
This is where the fleet's process doors live: the entry points that start a plan, continue one, or run a feedback pass. Delete the layer and no agent stops executing — but every way of starting something goes with it.
The cross-harness question — whether to write a reusable behaviour as a skill or a slash command when you run more than one agent tool — is on More than one harness. This page is about delivery: who gets a skill, and how far it actually travels.
The defining property is negative
🔴 A skill reaches exactly one machine.
The fleet ships a plugin to every box — hooks and scripts, pinned to a commit and gated on a version. It is genuinely one push and every box pulls. That is true of the plugin and of nothing else, and the sentence "one push, every machine gets it" has been applied to skills more than once by people who had read the plugin's documentation.
The plugin does not carry skills. It never has.
Three delivery layers, three reaches
PLUGIN one repository → EVERY box
pinned to a commit, gated on a version
carries: hooks, scripts
DOCTRINE each box's own clone → EVERY box, live
read through a symlink, so a rule change
lands with no version bump
🔴 but the SYMLINK is tracked in that box's own repo
SKILL one box's own repository → exactly ONE box
arrives at that box's next pullConflating any two of these is the recurring error, and the middle one is where it bites, because it is the second layer wearing the third layer's clothes.
Doctrine is symlinked live out of each machine's own clone, so a rule change reaches every box without a release. But the symlink itself is a tracked file in that machine's own repository. When the links were repointed by hand on five machines and committed on none, every subsequent checkout restored nine symlinks into a directory the rebuilt tree no longer had — and the automatic pull then skipped, because it refuses to run over uncommitted deletions. Five machines, silently pinned to a stale tree.
A repoint is not delivered until it is committed. A change made by hand on a live machine is a change that exists until the next checkout, and no longer.
What belongs in a skill, and what does not
A skill belongs to the agent that owns the folder. A machine's agent directory is that agent's; a project's own skills, commands and rules never live there. That boundary is what stops one agent's behaviour leaking into another's by proximity.
Four conventions this fleet holds its own skills to, each earned rather than chosen:
- A skill that touches more than one file loads its context and shows a status table before any write. The reader sees what is about to happen while it is still cheap to stop.
- An interactive question is never step one. A skill that opens by asking has not read anything yet, so its question is uninformed by definition.
- A skill with side effects opts out of automatic invocation. Auto-matching on a description is right for a skill that reads and wrong for one that writes.
- The verbs are fixed: audit is read-only, self-enhance is autonomous, update and fix are scoped. A skill whose name does not start with one of those is claiming a shape the fleet has no rules for.
A door is thin; the process is a frame
The skills that start things resolve which process you mean and then hand off to a frame document. The process lives in the frame, never in the door.
This matters more than it sounds. A door that contains its process cannot be shared with a second door, so the moment two entry points need the same steps, the steps get copied — and two copies of a process diverge exactly the way two copies of anything else do.
A fact a skill would assert becomes a command that reads it
🔴 In a skill file, an exclamation mark immediately followed by a backticked command runs in a shell before the content is sent to the model, and the output replaces the placeholder. Verified here both without any tool allowlist and with automatic invocation disabled.
So: a sentence stating a count, a path or a version is a sentence that rots. The live read cannot. This is the same discipline the pages on this wiki follow — state the probe, not the answer — applied one layer down, inside the instruction itself.
The executing agents have no skills at all
🔴 And that is the current design, not a gap. An agent executing a filed piece of work reads its specification and its checklist; anything it needs from a process arrives written into the issue body at filing time.
Worth sitting with, because it inverts the obvious approach. The machines doing the work carry the least process. Process lives where work is shaped, and travels to where work is done as data rather than as installed behaviour — which means the shape of a process can change without a deployment to anywhere.
Grade the population, never one machine
🔴 "The fleet has skill X" is only ever true of machines individually, and most of them are not readable from any one account. A verification that read one machine and pronounced the layer sound has already shipped here once.
Every fact about this layer is off-repository, so this page states the readings rather than the answers:
| Question | Command |
|---|---|
| What does this machine have | ls ~/.claude/skills/ |
| What does a given machine's repository carry | gh api repos/<org>/<repo>/contents/skills --jq '.[]|select(.type=="dir").name' |
| What one skill actually does | gh api repos/<org>/<repo>/contents/skills/<name>/SKILL.md --jq .content | base64 -d |
| Does the plugin carry skills (it does not) | gh api repos/<org>/<repo>/contents/plugins/<plugin> --jq '.[].name' |
| Is a machine on the current plugin payload | bash _infra/scripts/plugin-deploy-check.sh |
One trap in that table, and it costs an hour the first time: gh api writes its 404 body to standard
output, so a bare fallback prints the error JSON and the fallback text on one line. Filter for the
shape you expect rather than for non-emptiness.
Where this layer is currently weakest
- Two of seven agent repositories hold a skills directory at all. The rest return 404. So the layer's real population is two machines, and the larger set — the majority of every skill that exists here — is reachable by nobody else. Any plan that says "ship a skill to the fleet" is describing a mechanism that does not exist.
- The two sets have diverged with nothing measuring the gap. Twenty-four named skills against fifty-one. No shared manifest, no linter, no index. There is no command that answers "which skills exist in the fleet" — the probe table above is one read per machine precisely because that single command has never existed.
- A backup file sits inside the skills directory, in the same directory the loader walks. It is not a skill and nothing prunes it, against this fleet's own standing rule that git history is the archive.
- Three of this component's own in-repository pointers are wired to nothing. The assertion checker reports them present on disk and called by nobody — which is exactly what a door that was replaced but not deleted looks like.
Take it further
2 · Find the rot in the skills you already have
Reads every skill, rule and instruction file on this machine, checks each stated fact against the filesystem, and reports which ones are already false. Reads only; writes nothing.
You are going to audit the reusable instructions on this machine — skills, rules, agent instruction files — and find the statements in them that are already false.
Read the reference first:
curl -s https://docs.utopiamodels.ai/docs/structure/skills-layer.md
The claim being tested: an instruction that ASSERTS a fact rots, and one that READS it cannot. I want to know how much of what my agent is being told is already wrong.
Do not edit anything. Read, check, report.
## Step 1 — find every instruction file
Cover all of these; most machines have several layers and they disagree:
ls -la ~/.claude/skills/ ~/.claude/rules/ ~/.claude/commands/ 2>/dev/null
ls -la .claude/ .agents/ .cursor/ .github/ 2>/dev/null
find . -maxdepth 3 \( -name 'CLAUDE.md' -o -name 'AGENTS.md' -o -name 'SKILL.md' -o -name '.cursorrules' \) -not -path './node_modules/*' 2>/dev/null
Report each with its path, its size, and whether it is a real file or a symlink. A symlink matters: the reference page describes five machines that were silently pinned to a stale tree because a link was repointed by hand and never committed. Run `git status --short` on any repository containing one of these and say whether the link is committed as it currently points.
## Step 2 — extract every checkable claim
Read each file fully — do not grep. A grep returns only what its pattern already describes, so it can never surface an ABSENCE, and absences are half of what you are looking for here.
Pull out every statement that could be checked against this machine:
- a file or directory path
- a count ("the 12 services", "our three environments")
- a command that is claimed to exist
- a version, a port, a package name
- a claim about what some other file contains
## Step 3 — check every one of them
For each claim, run the check and record the command and its raw output. Not a summary — the command and what it printed, so I can reproduce any finding.
test -e <path> && echo PRESENT || echo ABSENT
command -v <tool> || echo 'not on PATH'
<the actual count command> | wc -l
For any stated count, go count the thing. This is the highest-yield check in the whole audit and it takes seconds each.
## Step 4 — check the routing descriptions
For every skill with a frontmatter description, the description is what the model matches on to decide whether to fire. Read each one and tell me:
- Is it phrased as the SITUATION a user would be in, or as a summary of what the skill does? Only the first kind fires reliably.
- Do any two skills have descriptions that overlap enough that the model could not choose between them?
- Is any description so generic it would match almost anything?
## Step 5 — report
Three sections.
**Already false** — the claim, the file and line, the command you ran, and its output. Ranked by how badly it would mislead an agent that believed it.
**Rots next** — claims that happen to be true today but are asserted rather than read, with the command that should replace each one. Give me the literal replacement text.
**Never fires** — skills whose description would not match the situation they are for, with a rewritten description for each.
Finish with one number: what fraction of the checkable claims across all these files are currently false. That number is the whole point of the audit, and it is the one I want to watch.
If something cannot be checked from this machine, say which command would settle it and where it has to run. Do not report an unreadable thing as absent — those are different results.
Then ask me which section to work through first with the `AskUserQuestion` tool, and recommend one — default to the already-false list, because those are actively misleading an agent right now rather than merely at risk of it later.The always-on agent
The fleet forbids resident processes, then permits exactly one. What earns that exception, what the exception has to declare about itself, and the three properties that keep a permanent loop from dying quietly.
Surfaces
Every hostname the fleet owns or references, each with an explicit class — LIVE, RETIRED-BY-DECISION or BROKEN. A status code on its own is not a state.