
What Claude Code Skills are
A Claude Code Skill is a single Markdown file — SKILL.md — placed under .claude/skills/<persona>/ at the root of your repo. Claude Code discovers it on conversation start, indexes its YAML frontmatter, and routes prompts to the matching skill at runtime.
Where CLAUDE.md is one root file describing the whole repo, skills are many small files describing one job each: answer revenue questions, run a security review, generate a verified SQL query against the Postgres warehouse. The unit shrinks; the context grows sharper.
For SQL, the killer feature is grounding. A SKILL.md can declare a must-read on a CHION.md that contains the verified queries, schema mappings, and read-only discipline your team has already vetted — so the agent never invents a join or guesses at a column name.
The unit shrinks; the context grows sharper.
The agent file family: CLAUDE.md, AGENTS.md, SKILL.md, CHION.md
Before SKILL.md was a thing, Claude Code shipped with CLAUDE.md as the root agent file and OpenAI's Codex shipped with AGENTS.md. The skills convention narrows the unit of work. Instead of one big file describing the whole repo, a skill describes one job.
| File | Owner | Purpose |
|---|---|---|
| CLAUDE.md | Anthropic | Root agent context for Claude Code. Loaded on every conversation. |
| AGENTS.md | OpenAI | Equivalent convention used by Codex. Same role, different filename. |
| SKILL.md | Open standard | A scoped, persona-level skill. Frontmatter declares triggers, must-read, mutability. |
| CHION.md | Chion | Auto-generated mirror of the above, grounded in your verified SQL queries, not your repo prose. |
The bytes are interchangeable. Pick the filename your agent prefers. The skill behind it is the same.
Anatomy of a SQL SKILL.md
Every skill is two layers: a YAML frontmatter block the agent parses, and a Markdown body the agent reads as context. The frontmatter is what makes routing work. Below is the exact shape Chion emits for a finance-analyst skill.
--- name: finance-analyst description: Use when answering revenue, MRR, ARR, churn, or cohort questions on the production Postgres warehouse. triggers: [revenue, mrr, arr, churn, cohort, ltv, billing] must-read: - CHION.md - personas/finance-analyst/_INDEX.md mutability: layer_1: locked layer_2: overwrite-on-refresh persona: pass-A rules: pass-B profiles: portable: true claude_code: true metadata: tags: [postgres, finance, verified-sql] ---
Five fields do all the work. name is the persona slug. description always starts with "Use when" so the agent's routing layer can match prompts to skills. triggers are the high-signal vocabulary that pulls a prompt toward this skill. must-read declares the upstream files the agent should load alongside this skill. mutability tells Chion which blocks to regenerate on refresh and which to leave alone.
Writing a SQL skill by hand (worked example)
Before you reach for a compiler, it helps to write one skill by hand. This is what a minimum viable Postgres skill for Claude Code looks like — copy, paste, edit, commit.
---
name: revenue
description: Use when answering monthly recurring revenue, ARR, or revenue-by-plan questions on the Postgres warehouse.
triggers: [mrr, arr, revenue, recurring, plan]
must-read:
- CHION.md
---
# Revenue skill
## Source of truth
- table: `billing.subscriptions`
- grain: one row per subscription per active day
- metric column: `amount_cents` (additive, sum is safe)
## Verified query
```sql
SELECT date_trunc('month', billed_on) AS month,
plan,
SUM(amount_cents) / 100.0 AS mrr_usd
FROM billing.subscriptions
WHERE status = 'active'
AND billed_on >= now() - interval '12 months'
GROUP BY 1, 2
ORDER BY 1, 2
LIMIT 1000;
```
## Example prompt
"What was MRR by plan for the last 6 months?"Three things matter for routing: the description must start with "Use when", the triggers must match the vocabulary your team actually uses, and the verified SQL must be SELECT only, capped with LIMIT. Everything else is context the agent reads at the moment it picks the skill.
Why hand-written SQL skills go stale
Schemas drift, column names change, and hand-maintained Markdown falls behind.
The first SQL SKILL.md you write is great. The second one is fine. The tenth one is a maintenance problem. Schemas drift. Column names change. A new revenue rule lands and now three skills are quietly wrong.
The fix is not better Markdown. The fix is to treat the SKILL.md as a build artifact compiled from a source of truth your team already maintains: the verified queries you promote inside the analytics tool.
Exporting verified team queries as CHION.md and SKILL.md
The fix is to compile your team's verified queries into one root CHION.md (shared SQL discipline, schema map, read-only rules) and a SKILL.md per persona that must-reads back into it. The SQL-to-skill compilation flow is named, sequential, and deterministic — not a prompt that returns vibes. Source lives in supabase/functions/capability-context/compile/.
Harvest semantic layer
Pull every verified query promoted into this persona, plus the semantic layer mappings (ai_semantic_attributes, column_profiles) those queries depend on.
Stitch
Assemble the two-profile YAML frontmatter (portable defaults plus claude_code overrides), then the persona body, the rule layer, the script index, and the per-query READMEs.
Validate
Run the post-stitch structural validator. Description must start with 'Use when'. Persona body must be 3 to 5 sentences. Required headings must exist in the documented order.
Publish
Write one new domain_agents row, transition it from in_progress to draft to published, and supersede the prior version. Diffable like code.
One Opus pass per persona, roughly twenty credits each. A six-persona default workspace compiles a full agent repo in a single sitting. The artifact bundle is portable — see portable SQL skills for the cross-tool runtime details.
What skills get compiled for which persona
A workspace ships with named personas out of the box. Pick one to see the trigger vocabulary and the kind of skill artifact Chion will emit for it.
Revenue, MRR, ARR, churn, cohorts, refunds.
Triggers
Sample skill slug
monthly-recurring-revenue-by-planTwo-profile frontmatter: portable + claude_code
SKILL.md is an open standard, but Claude Code accepts a richer set of fields than the portable baseline. Chion writes both. The portable profile keeps the file readable in Cursor, Codex, or anywhere else. The claude_code profile layers on the optional fields that unlock Claude Code's routing and must-read behaviour.
The practical effect: the same artifact runs cleanly in three agents without forking.
The mutability model that lets you re-compile safely
Every block in a Chion SKILL.md has a declared mutability. This is what lets you re-run the compile on Friday afternoon without losing the rule edits you made on Monday morning.
- Layer 1 (locked): universal SQL discipline. Lives in CHION.md, referenced from every SKILL.md. Never overwritten by a persona compile.
- Layer 2 (overwrite-on-refresh): the persona body, regenerated from the latest verified queries every time the compile runs.
- Rules (pass-B): hand-authored conventions that survive refresh. This is where you put "always coalesce nulls in the revenue column".
Running skills in Claude Code, Codex, and Cursor
- Inside Chion, export your persona skills. You get a folder with one SKILL.md per persona, plus the shared CHION.md and a CLAUDE.md / AGENTS.md mirror.
- Commit the folder to the root of your repo. The structure follows the published Claude Code skills convention so no rewriting is needed.
- Open Claude Code, Codex, or Cursor. The agent picks up the root file on next launch and the skills folder on first prompt.
- When the database changes, re-run the compile in Chion and push the updated artifacts. Diff the SKILL.md the same way you diff source code.
For a deeper look at running the same skill across runtimes (Chion, Claude Code, Codex, Cursor), see the portable SQL skills explainer. Chion compiles and hosts these as portable SQL skills; the analyst-facing surface is Chion's SQL AI Analyst framework.
Pitfalls and how to avoid them
Description without "Use when"
Routing falls back to fuzzy matching across the body. Always lead with "Use when..." so Claude's router has a clean signal.
Overlapping triggers across skills
Two skills sharing revenue race for the same prompt. Scope triggers per persona; let CHION.md hold the shared vocabulary.
No LIMIT on the verified SQL
A skill without a row cap exfiltrates the table the first time it runs. Cap every query in the SKILL.md, not just at the runtime layer.
Hand edits in the wrong block
Edits inside overwrite-on-refresh blocks vanish on the next compile. Put durable rules in the pass-B rules section so they survive.
Forgetting to commit CHION.md
Every SKILL.md must-reads CHION.md. Without it, the shared SQL discipline never reaches the agent's context window.
Treating skills as one-off prose
A skill is a build artifact. Source-of-truth lives in the verified query, not the Markdown. Re-compile when the schema changes; never patch the Markdown by hand.
Quick reference
- Claude Code Skills are persona-scoped SKILL.md files with YAML frontmatter that Claude Code loads on conversation start.
- The five load-bearing frontmatter fields are name, description, triggers, must-read, and mutability.
- Chion auto-compiles SQL SKILL.md files from your verified queries via a four step pipeline: harvest, stitch, validate, publish.
- Two-profile frontmatter (portable plus claude_code) makes the same artifact run in Claude Code, Codex, and Cursor.
- The mutability model separates locked discipline, refreshable persona content, and durable hand-authored rules.
- CHION.md, CLAUDE.md, AGENTS.md, and SKILL.md mirrors are byte identical. Pick the filename your agent prefers.
Frequently asked
What are Claude Code Skills?
Claude Code Skills are persona-scoped Markdown files (SKILL.md) with YAML frontmatter that Claude Code loads on conversation start. Each skill declares a name, a description, triggers, and must-read context. Claude routes to the right skill based on the prompt and the trigger vocabulary.
How do Claude Code Skills work?
On conversation start, Claude Code reads CLAUDE.md at the repo root and discovers SKILL.md files under .claude/skills/. The agent indexes the description and triggers from each skill's YAML frontmatter, then routes the user's prompt to the best-matching skill at runtime. The matched skill's body and must-read files become part of the working context for that turn.
What is the SKILL.md format?
SKILL.md is a Markdown file with a YAML frontmatter block at the top. The five load-bearing fields are name (the persona slug), description (must start with "Use when..." for routing), triggers (an array of high-signal keywords), must-read (paths to upstream context files), and mutability (which blocks Chion regenerates vs preserves on refresh). The body below the frontmatter is the persona context the agent reads.
Where does Claude Code look for SKILL.md files?
Claude Code discovers skills under .claude/skills/ at the repo root — one folder per persona, like .claude/skills/finance-analyst/, each holding a SKILL.md. On conversation start it reads the root agent file for global context, then indexes each SKILL.md frontmatter (name, description, triggers) so it can route a prompt to the right skill. Chion writes its compiled skills into that same .claude/skills/ tree, so they load with no extra wiring.
Can I hand-write Claude Code Skills for SQL?
You can, and the open standard supports it. The trouble is that SQL skills go stale the moment your schema changes. Chion auto-compiles the SKILL.md files for you from the verified queries your team already runs, so the skill artifact stays grounded in the actual database, not in a snapshot of your repo prose.
What does Chion compile, exactly?
For each persona in your workspace, Chion runs a single Opus pass that stitches a SKILL.md with two-profile frontmatter (portable and claude_code), a persona body, the rule layer, the verified query index, and a per-script README. The pass is deterministic. Same inputs produce the same skill artifact, every time.
Where do triggers come from?
Triggers are extracted from the persona vocabulary plus the verified queries promoted into that persona. A finance-analyst skill that contains an MRR query will have mrr in its trigger list automatically. You can also edit triggers by hand. Both paths converge on the same SKILL.md.
Does this work with Codex and Cursor too?
Yes. Chion emits mirrors of the same content as CHION.md, CLAUDE.md, AGENTS.md, and SKILL.md. The bytes are identical. Drop any of them at the root of your repo. Claude Code reads CLAUDE.md, Codex reads AGENTS.md, Cursor reads either. The underlying skill is the same.
How do I make a Postgres skill for Claude by hand?
Create .claude/skills/<persona>/SKILL.md with YAML frontmatter (name, description starting with "Use when", triggers, must-read). In the body, document the table, the verified SELECT statement, expected row shape, and a worked example prompt. Reference a CHION.md at the repo root for shared SQL discipline (read-only, LIMIT, no PII columns) so every skill inherits the same guardrails.
What is the mutability model?
Layer 1 of every SKILL.md is locked discipline that lives in CHION.md and is referenced by every skill. Layer 2 is the persona body, which Chion overwrites on every refresh. Hand edits go into a dedicated rules block that survives refresh. This is what makes the compile safe to re-run.
Compile your first SQL SKILL.md.
Connect a read only Postgres role, promote a few verified queries, and export the persona skills folder.