OpenClaw Skill Routing Architecture: Descriptions, Manifests, and Which Skills Each Project Gets to See
Every skill you install is a candidate for every request, in every project, until you decide otherwise.
Open the CLAUDE.md at the root of the repo that builds this site and the first thing in it is a block fenced by two HTML comments, skill-routing:start and its matching end marker. Inside, it says the project's surfaces are a marketing site and content, and it lists five skills in priority order: /design-review, /delight-pass, /qa, /verify, /email-craft. Nobody typed that list into the file. A script generated it from a single routing manifest that lives outside the repo, and a note above the list tells humans not to edit it by hand.
That block is the whole subject of this article.
How a Skill Gets Picked
The mechanics are well covered elsewhere, so briefly. A skill is a folder under ~/.openclaw/skills/ with a SKILL.md inside, plus whatever scripts and examples it needs. The file opens with YAML frontmatter holding a name and a description. At boot the agent sees only those two fields for every installed skill. When a request matches a description, the full body gets read into context and the agent follows it. Community skills come from ClawHub with clawhub install, and the OpenClawKit guide walks through packaging your own.
Every guide I read stops there, at roughly the point where the trouble starts. That loading model is cheap per skill and quietly expensive in aggregate, because the matching step is the model reading a list of descriptions and making a judgment call. Ten skills, the judgment is easy. Sixty skills, several of them overlapping, written by different people (or by the agent itself, months apart), and the agent starts picking the plausible skill instead of the right one.
The Description Is the Router
I think most skill descriptions are written for the wrong reader. They read like a README summary, telling a human what the skill is. The model needs to know when to reach for it, and just as badly, when to leave it alone. I write mine with an explicit trigger phrase and an explicit exclusion:
--- name: design-review description: > Designer's-eye QA of a live page: spacing, hierarchy, components that drifted from the rest of the site. Use when: "audit the design", "does this look right", "visual QA", "polish this page". Do NOT use for broken links or failing forms (that is qa). ---
The Use when: line carries the user's own words, because those are what the request will contain. The Do NOT use line names the neighbour skill by name. That one line resolves more misroutes than anything else I have tried, since the hard cases are almost never a skill that matches nothing. They are two skills that both match.
The routing block in this repo depends on that convention. Proactive suggestion is switched on there, which means a phrase matching a skill's Use when: text surfaces the skill without anyone typing its slash-name. A vague description in that setup fires at random, and a missing one never fires at all.
One Skill Directory, Many Projects
The skills directory is global. The work is not. A content site has no use for a court-document skill, and a legal workspace should never be offered the email-template skill that writes marketing copy. If you leave the directory flat, every project gets every skill, and the only thing keeping them apart is the model's reading of sixty descriptions on every turn.
So I keep one manifest that maps projects to surfaces and surfaces to an ordered skill list. It lives at ~/.openclaw/workspace/skill-routing.yaml, and a small generator (tools/generate-skill-routing-sections.py) rewrites the marked block inside each project's CLAUDE.md. A manifest shaped like this is enough:
# skill-routing.yaml (shape only, trimmed)
projects:
openclaw-blueprint:
surfaces: [marketing-site, content]
proactive_suggest: true
skills: # priority order: first match wins a tie
- design-review
- delight-pass
- qa
- verify
- email-craftThree choices in there are deliberate, and they carry different weight.
The order matters most. /design-review and /qa genuinely overlap on a marketing site, since a broken layout is both a visual problem and a bug, and on this project I want the visual pass first. On an app with real user flows I would flip them. The list order is how one global skill directory produces different behaviour per project without forking a single SKILL.md.
Then the markers. A CLAUDE.md is a file people edit, and a generator that rewrites the whole file will eventually delete somebody's hand-written rule. Rewriting only the text between skill-routing:start and the end marker lets the generator run on every change to the manifest without anyone flinching.
Surfaces are the least important. They are labels, useful mostly when you add a new project and want to copy the skill list from a project of the same kind.
Routing to a Skill That Is Not There
A routing entry that points at a skill missing from disk is worse than no entry, because the agent believes it has a capability it cannot load.
Check the Manifest Against the Disk
I learned the shape of this failure from the model escalation work, where a working script sat unused all summer because the agent's instructions never named it. Skills fail the same way in reverse. The instructions name a skill, the skill got renamed or never finished installing, and the agent improvises something in its place. I run this before the generator, and the generator refuses to write if it fails:
#!/bin/bash
# check-skill-routing.sh: every routed skill must exist and say when to use it
manifest=~/.openclaw/workspace/skill-routing.yaml
skills_dir=~/.openclaw/skills
fail=0
for name in $(yq '.projects[].skills[]' "$manifest" | sort -u); do
f="$skills_dir/$name/SKILL.md"
if [ ! -f "$f" ]; then
echo "MISSING $name"; fail=1; continue
fi
grep -qi 'use when' "$f" || { echo "NO TRIGGER $name"; fail=1; }
done
exit $failRun it the other way too, once in a while. Any skill on disk that no project routes to is either dead weight or a gap in the manifest, and you want to know which.
Test Phrasings, Both Directions
Keep a short file of real requests per project with the skill each one should trigger, and a second file of requests that should trigger nothing. Replay both after any change to a description. The second file is the one people skip, and it is the one that catches a greedy description, like a /verify skill that starts claiming every message containing the word "check".
The manifest doubles as a security boundary, which I like more than I expected to. A skill pulled from ClawHub cannot fire inside a project until someone adds it to that project's list, so review happens at the moment of routing rather than at install. The security architecture guide covers what that review should look for.
Internal Links & Further Reading
- OpenClawKit Architecture: Building Modular Agent Kits →
How a skill folder and its SKILL.md are put together.
- OpenClaw Context Window Architecture →
Why every skill description you load is paid for on every turn.
- OpenClaw Model Escalation Architecture →
The same lesson for scripts: an agent only uses what its instructions name.
- OpenClaw Tool Layer Architecture →
The layer below skills, where the actual calls get made.
FAQ
Q: Why not give each project its own skills folder?
You can, and for a client workspace with private skills you should. For shared skills it means copies, and copies drift. A fix to /qa lands in one project and the other four keep the old version. One directory plus a manifest gives you per-project behaviour with a single copy of each skill.
Q: Should the agent be allowed to write its own skills?
Yes, into the directory. Not into the manifest. An agent that notices a repeated workflow and writes it down is doing useful work, and a person deciding which projects get to use that skill is the cheapest review step you will ever add.
The Bottom Line
Write every description with a Use when: line and a Do NOT use line that names the neighbour. Route skills per project from one manifest, in priority order, and generate the routing block between markers so nobody edits it by hand.
Then check the manifest against the disk before every regeneration, because a skill the agent thinks it has is more dangerous than one it knows it lacks.
Skip the trial and error
Get the OpenClaw Starter Kit — config templates, 5 ready-made skills, deployment checklist. Everything you need to go from zero to running in under an hour.
$14 $6.99
Get the Starter Kit →Also in the OpenClaw store
Get the free OpenClaw deployment checklist
Production-ready setup steps. Nothing you don't need.