Skills
Procedural memory as markdown files. A skill is a note about how to do something, loaded when its trigger fires, delivered as context the agent read rather than as instructions you gave.
Where they live
~/.crv/skills/*.md. One file per skill, YAML frontmatter plus a markdown body.
Format
---
name: deploy-staging
description: How this project ships to staging
triggers:
- deploy
- staging
- "ship it"
tools:
- name: stage_deploy
description: Run the staging deploy playbook
command: ansible-playbook deploy.yml -l staging
schema:
type: object
properties: {}
---
The staging box is behind the tailnet. Always run the smoke test after,
and never deploy on a Friday afternoon.
| Field | Required | Notes |
|---|---|---|
name | yes | Unique. Shown in the panel and in GET /api/skills. |
description | yes | One line. This is what the model sees when deciding relevance. |
triggers | no | Strings that load the skill when they appear. No triggers means it is available but never auto-loads. |
tools | no | Tools the skill contributes: name, description, command and JSON schema. |
| body | yes | Everything after the frontmatter. The actual knowledge. |
Loading
When a trigger matches, the skill's body is injected for that turn. It does not stay in the window forever — a skill that loaded three turns ago and is no longer relevant is subject to the same demotion as anything else. See Context window.
The system-reminder envelope
Skills and recalled memory both re-enter the conversation the same way: as user-role text wrapped in <system-reminder> tags, not as a system message.
<system-reminder>
## Loaded skill: deploy-staging
The staging box is behind the tailnet…
</system-reminder>
Why not a system message
Strict chat templates — Qwen3.8's among them — raise on any system message that is not first:
jinja2.exceptions.TemplateError: System message must be at the beginning.
Cerveau emits recall and skill notes after the system prompt, and the window manager can trim the turns in front of them, which leaves them sitting mid-conversation. That returned a 502 on every multi-turn task on vLLM and forced a patched chat template. Neither of the reference harnesses emits a system message after the first turn; both use this tag convention instead, and teach the model to read it in the system prompt.
Escaping
Any <system-reminder> or </system-reminder> inside the content is escaped to entities before wrapping. A skill or a stored note containing the closing tag would otherwise end the envelope early and have everything after it read as ordinary user input — the same class of problem as unescaped HTML. See Safety guard.
Skills or a reflex?
| Skill | Reflex | |
|---|---|---|
| Is | Knowledge | Capability |
| Format | Markdown + frontmatter | YAML manifest |
| Loaded | On trigger, into the window | Registered as tools |
| Use for | "Here is how this project does X" | "Here is a command that does X" |
A skill can declare tools, which blurs the line — the rule of thumb is that if the valuable part is the prose, write a skill; if it is the command, write a reflex.