agentleFS
ethosagentethosagent/ethos/skills/framework/ethos-skill-authoring/SKILL.md

ethos-skill-authoring

Skill22 starsChanged 9 days agoMITView on GitHub

Write a SKILL.md that the Ethos universal scanner will accept. Covers the frontmatter contract (name, description, version, tags, required_tools, ethos extension block), the body shape (When to use / Workflow / Anti-patterns), and the common rejection reasons (missing fields, unreachable tools, category drift).

  • Commits and pushes

The file

We split this skill into the rules it gives an agent

2 rules. About 0 are common, 0 are distinctive, and 2 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈0

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 2

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Very specific:

    Skill that lists every tool in required_tools: Only list the ones whose absence makes the skill useless.

    line 156
  2. Very specific:

    Inventing tools: If the registry doesn't have it, the skill can't require it.

    line 160

≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

Ethos Skill Authoring

Skills are prose. The Ethos universal scanner discovers them, the ingest filter prunes them per personality, and the agent loop injects the surviving ones into the system prompt. This skill is the contract.

When to use this skill

  • User asks "how do I write a skill?" or "add a skill for <X>".
  • A skill the user wrote isn't loading — diagnose the rejection.
  • You're authoring a personality and want it to ship with a skill.

When NOT to use this skill

  • The thing the user wants is actually a tool (it executes something). Tools live in extensions/tools-* packages; skills are prose.
  • The thing is a personality, not a skill. Personalities answer "who am I"; skills answer "how do I do X well".

File layout

~/.ethos/skills/<skill-id>/SKILL.md       # user-level (any personality can ingest)
~/.ethos/personalities/<p>/skills/<id>/SKILL.md  # personality-scoped
skills/data/<category>/<id>/SKILL.md             # first-party bundle (repo-level)
.agents/skills/<id>/SKILL.md                     # repo-level community skill

The file must be named SKILL.md exactly. The directory name becomes the skill id (kebab-case). One skill = one directory.

Under a personality's default fs_reach, write_file cannot create either ~/.ethos location. ~/.ethos/skills/ is read-only (deriveFsReachPaths in packages/core/src/fs-reach.ts), and a personality's own skills/ is write-denied (PERSONALITY_DEFINITION_ENTRIES, same file). Draft the skill in the workspace (for example .ethos-work/skills/<id>/SKILL.md) and ask the user to move it into place.

Frontmatter — the required contract

---
name: <kebab-case, matches directory>
description: <one paragraph — what it does, in the same voice the agent will read it. Avoid marketing copy.>
version: <semver, start at 1.0.0>
author: <handle / org>
tags: [<lowercase, kebab-case>, ...]
required_tools: [<exact tool names from the registry>]
---

Every field is enforced. The ingest filter rejects skills with missing or malformed frontmatter. The required_tools list is the gate: if a personality's toolset doesn't include every name in the list, the skill is filtered out (logged at INFO at boot — operator can see which skills got pruned and why).

The ethos: extension block

First-party skills carry an additional block the scanner uses for routing:

ethos:
  category: <one of the validated categories>
  renders: [<renderer@specVersion>, ...]   # optional — see below
  default_personalities: [<personality ids this skill complements>]
  prerequisites:
    external_cli: [<binaries the skill assumes exist>]
    auth: [<one-line auth steps>]
    env_vars: [<names>]
    optional_tools: [<tool names that enhance but aren't required>]
  integrates_with:
    - skill: <other-skill-id>
      role: <companion / prereq / shares-logic-with>
    - tool: <tool-name>
      role: <what the tool adds>
  surface_metadata:
    invocation_trigger: "<plain-language description of when this skill should fire>"
    estimated_turns: "<small range, e.g. 1-3>"

Valid category values today: planning-and-process, quality-and-testing, github-workflow, delegation-and-orchestration, framework-usage. Adding a new category requires updating the bundle-test allowlist in lockstep.

ethos.renders — declaring an output renderer

A skill that teaches a fenced output format declares it here. skills/document/charts/SKILL.md is the reference example: renders: ['echarts@1'] teaches the ```echarts fence AND unlocks the chart renderer for any personality whose skill set includes it. One declaration, both effects — what a personality is taught and what it may draw cannot drift apart.

  • It goes under ethos:, not at top level. Top level is the shared agentskills.io namespace (name, description, tags, required_tools); every Ethos-specific contract field lives in the ethos: block.
  • The grammar is <renderer-name>@<integer> — /^[a-z][a-z0-9-]*@\d+$/. Entries that do not match are dropped silently.
  • Semver is rejected on purpose. The integer is our spec version — a documented option subset owned by the skill — not the renderer library's npm version. There is no echarts@1.1: a changed subset is echarts@2. During a migration a skill declares both (renders: ['echarts@1', 'echarts@2']).
  • Declaring a renderer no surface maps is harmless. It is an inert capability claim. Surfaces keep their own curated, first-party registry and simply do not draw what they do not map; the fence falls back to a code block. This is also why a skill can never ship renderer code — it declares, the surface provides.

Body — the standard shape

The body is markdown. Order matters because the agent reads top-down.

# <Skill Name>

<One paragraph: what this skill is, in a sentence the model can recall.>

## When to use this skill
<Bulleted list of triggers. Specific over abstract.>

## When NOT to use this skill
<Bulleted list of explicit non-triggers. Cheaper than letting the model guess.>

## <Workflow / Steps>
<Numbered or stepped procedure. Use code blocks for actual commands the agent will run.>

## Anti-patterns
<Bulleted list — the failure modes you want the model to avoid.>

## Hard rules
<Non-negotiable constraints. The most senior content in the skill.>

## Setup the user needs to do once   (optional)
<For skills that depend on external CLIs or auth. Mirrors the `prerequisites:` frontmatter.>

The "When to use / When NOT to use" pair is the most load-bearing section — the model relies on it to decide whether the skill applies at all. Spend time on it.

Common rejection reasons

ReasonCauseFix
required_tools not in effective reachA tool listed in required_tools isn't in the personality's toolset.yamlEither drop the tool from required_tools (skill works without it) or add it to the personality
Missing name / descriptionFrontmatter not parsedYAML syntax error — most often unquoted : in description
category is undefinedFirst-party skill without an ethos: blockAdd the block; categories are validated against an allowlist
tags not arrayTags written as a comma-separated stringUse YAML list: [tag1, tag2]
Skill not in scanner outputDirectory not under a known source rootCheck the scanner sources list in apps/ethos/src/wiring.ts

Writing well — voice and density

  • Imperative second person: "Run gh auth status." Not "the user runs gh auth status".
  • Concrete identifiers: real file paths, real tool names, real config keys.
  • No marketing copy: skills are read by an LLM that uses them; not by a prospect.
  • Tables for ≥3 parallel items. Prose for 1-2.
  • Code blocks for actual commands. Inline backticks for tool / file / flag references.
  • No emoji. Voice rules from DESIGN.md apply.

Anti-patterns

  • Skill that lists every tool in required_tools. Only list the ones whose absence makes the skill useless. Optional tools go in optional_tools (under prerequisites).
  • Skill body that recapitulates the description. The description is the gate; the body is the operating manual.
  • No "When NOT to use" section. The model will over-trigger.
  • Vague triggers. "Use this when reviewing code" is too broad; "Use after staged edits when the next action is git push" is right.
  • Inventing tools. If the registry doesn't have it, the skill can't require it. Check ethos personality show <id> for the actual tool list.

Hard rules

  • SKILL.md is the only required file. Companion files (adapters/, examples/, templates/) are optional and skill-specific.
  • Bump version on every meaningful change. Patch for typo, minor for body changes, major for frontmatter contract changes.
  • required_tools and optional_tools use the exact names the registry exposes. No aliases, no abbreviations.
  • First-party skills must declare a category in the validated set. New categories require the bundle-test update in the same commit.
  • Don't ship skills that load secrets via env-var without documenting it. The prerequisites.env_vars list is the operator-visible contract; if it's missing, the skill will silently fail under capability isolation.

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.