Skills: how we do things here
Rules say what must be true. A skill says how to do something: how to run the integration test harness, how to deploy to staging, how your team builds a new UI component. The one-line distinction: constraint = rule, procedure = skill.
Skills are what you write when you catch yourself repeating an instruction. If you've typed "start the mock API with make mock-api before running e2e tests" into three prompts, that's a skill waiting to be written.
A skill is a SKILL.md file with three parts:
- Name: what you call it, like
run-e2e-tests. - Description: one or two sentences on what the skill does and when to use it. This is the most important line in the file.
- Body: the step-by-step instructions Devin follows once the skill is active.
---
name: run-e2e-tests
description: Run the Playwright e2e suite against the mock API.
Use before opening a PR that touches src/checkout.
---
# Run the e2e tests
1. Start the mock API with `make mock-api` and wait until it's ready.
2. Run `npx playwright test $ARGUMENTS` (no arguments runs them all).
3. If a test fails, open its trace with `npx playwright show-trace`
and fix the cause before rerunning.
4. Stop the mock API when you're done.
At the start of every session, Devin sees the name and description of every skill available to it, not the bodies. That keeps context lean: a skill costs almost nothing until it's needed. There are two ways a skill gets used:
- Devin picks it. When a task matches a skill's description, Devin loads it automatically. This is why the description matters: "Testing" rarely matches anything; "Run the Playwright e2e suite against the mock API before opening a PR that touches
src/checkout" does. - You invoke it. Name the skill in your prompt with
/skill-nameor@skills:skill-name, and add arguments if the skill takes them:/deploy staging. A skill can use$1or$ARGUMENTSin its body to fill in what you pass, which makes one skill reusable across every package, environment, or ticket. Settriggers: ["user"]in a skill's frontmatter if it should only run when someone asks for it.

You rarely have to start from a blank file. Skills build up through use:
- Devin suggests one. When Devin learns something about your setup mid-session, it proposes a skill in the session timeline. Review it and approve.
- You ask for one. After a session that went well, tell Devin: "Save what you just did as a skill. Take the package name as an argument."
- You write one. Commit it to
.agents/skills/<skill-name>/SKILL.mdin your repo.
Treat skills as living documents. Keep one workflow per skill, keep descriptions specific, and when a run goes sideways because of a missing step, fix the skill instead of patching your prompt, so the next session doesn't hit the same pothole. Devin's competence in your codebase compounds: session 10 is meaningfully better than session 1 because the how-to now travels with every session.