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
In this repository45 other files it gives its agents.
- AGENTS.mdAGENTS.md
- dependency-analyzerSkill
- docsSkill
- handoffSkill
- openai-reviewerSkill
- plugin-homeSkill
- schema-validatorSkill
- security-auditSkill
- session-auditSkill
- test-validatorSkill
- claude-codeSkill
- codexSkill
- opencodeSkill
- chartsSkill
- export-csvSkill
- export-excelSkill
- make-chartSkill
- make-html-reportSkill
- make-pdfSkill
- a2a-communicateSkill
- a2a-handle-inboundSkill
- codebase-inspectionSkill
- native-mcpSkill
- github-authSkill
- github-code-reviewSkill
- github-issuesSkill
- github-pr-workflowSkill
- github-repo-managementSkill
- birth-ritualSkill
- get-to-know-youSkill
- xurlSkill
- arxivSkill
- grounded-citationsSkill
- research-paper-writingSkill
- reddit-researchSkill
- code-reviewSkill
- coding-agentSkill
- planSkill
- requesting-code-reviewSkill
- spikeSkill
- subagent-driven-developmentSkill
- systematic-debuggingSkill
- tddSkill
- writing-plansSkill
- no-ai-slopSkill
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
- Very specific: line 156
Skill that lists every tool in
required_tools: Only list the ones whose absence makes the skill useless. - Very specific: line 160
Inventing tools: If the registry doesn't have it, the skill can't require it.
≈ “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.
Files
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 skillThe 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 theethos: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 isecharts@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
| Reason | Cause | Fix |
required_tools not in effective reach | A tool listed in required_tools isn't in the personality's toolset.yaml | Either drop the tool from required_tools (skill works without it) or add it to the personality |
Missing name / description | Frontmatter not parsed | YAML syntax error — most often unquoted : in description |
category is undefined | First-party skill without an ethos: block | Add the block; categories are validated against an allowlist |
tags not array | Tags written as a comma-separated string | Use YAML list: [tag1, tag2] |
| Skill not in scanner output | Directory not under a known source root | Check 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.mdapply.
Anti-patterns
- Skill that lists every tool in
required_tools. Only list the ones whose absence makes the skill useless. Optional tools go inoptional_tools(underprerequisites). - 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.mdis the only required file. Companion files (adapters/,examples/,templates/) are optional and skill-specific.- Bump
versionon every meaningful change. Patch for typo, minor for body changes, major for frontmatter contract changes. required_toolsandoptional_toolsuse 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_varslist is the operator-visible contract; if it's missing, the skill will silently fail under capability isolation.
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
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.

