Skip to content

devin-skill-valid

Devin-native SKILL.md frontmatter must use Devin's documented field shapes

Severity error (auto)
Autofix -
Since v0.20.0
Repo Types devin
Category Devin

Why

Skills in .devin/skills/ use Devin's native dialect. Unlike portable Agent Skills under .agents/skills/ and .windsurf/skills/, their frontmatter is optional and the directory name supplies the default name. When frontmatter is present, however, values with the wrong shape can keep tools, permissions, activation, or delegation settings from taking effect.

This rule validates Devin's documented fields while tolerating unknown keys for forward compatibility. The skill body still receives skillsaw's shared content-quality and security checks.

A known field may appear only once, even when its value is null. This also applies to permissions.allow, permissions.deny, and permissions.ask. Duplicate unknown extension keys remain accepted. The finding points to the repeated key; remove the duplicate and keep the intended value.

Severity

Malformed YAML and invalid field types are errors. Empty trigger lists and lists with no recognized trigger are activation-policy errors: the skill may load, but no supported invocation route is declared. Unknown strings alongside user or model are warnings because the recognized route still works. An explicit rule severity overrides these primary findings. Setting both a named agent and subagent: true is informational: Devin uses the named agent, so the finding explains the precedence without treating a documented combination as invalid.

Examples

Bad — tool permissions and triggers have the wrong shapes:

---
allowed-tools: 4
permissions:
  allow: Read(src/**)
triggers:
  - autonomous
---

Good — a configured native skill:

---
argument-hint: "[path]"
model: sonnet
allowed-tools: Bash(openspec:*)
permissions:
  allow:
    - Read(src/**)
triggers:
  - user
  - model
---

Review the selected path and report actionable findings.

A native skill with no frontmatter, an empty header, or a comment-only header is also valid. An explicit null document between the delimiters is invalid. Optional string fields, allowed-tools, permissions, and triggers may be omitted or null to use Devin's defaults. The nested permissions.allow, permissions.deny, and permissions.ask lists may also be null. subagent still requires a boolean when present; subagent: null prevents the skill from loading.

Native string fields retain scalar text such as yes, dates, and numbers. String lists also accept scalar items, including null as the literal pattern null. A scalar allowed-tools value still must be a string: numbers and booleans only work as list items. Use true or false for subagent; YAML 1.1 spellings such as yes, no, on, and off do not load, nor does a quoted "true". These decoding rules apply only to Devin-native frontmatter. Devin ignores YAML merge keys (<<); declare native fields explicitly instead.

How to fix

  • Use strings for name, description, argument-hint, model, and agent, and a boolean for subagent.
  • Make allowed-tools a string or a list of strings.
  • Make permissions an object; its allow, deny, and ask values must be lists of strings.
  • Make triggers a non-empty list containing only user and/or model.
  • When both delegation fields are present, remove subagent: true if the named agent already expresses the intended behavior.

Configuration

rules:
  devin-skill-valid:
    enabled: auto  # true | false | auto
    severity: error

Run skillsaw explain devin-skill-valid to see this documentation and the rule's effective configuration in your terminal.