How to teach every agent your team's conventions
Write your conventions once as a skill and have every agent across every repository load it when the task calls for it.
Every team has knowledge that is not in the code: which migrations need a backfill, how the error taxonomy works, why one module is off limits. Paste it into each agent's prompt and you maintain the same paragraph in nine configs. Write it once as a skill instead.
A skill is a directory with a SKILL.md: instructions and support files Claude Code loads by name when the task calls for them. Where the system prompt is what an agent must do every session, a skill is expertise it pulls in only when relevant, so one skill serves many agents without bloating any prompt.
Agents pick up skills three ways: automatically, from the .claude/skills/ directory of every repository in the sandbox; automatically, from Claude Code plugins the repository enables in its committed .claude/settings.json; and explicitly, from the config's skills list.
Check skills into a repository
Every repository in the sandbox contributes its .claude/skills/ at the session's checkout. No config change: add the directory, and every agent that clones the repository sees the skill.
A skill that teaches agents how splitshift-api migrations work, at splitshift-api/.claude/skills/schema-migrations/SKILL.md:
---
name: schema-migrations
description: How schema migrations work in splitshift-api. Use when writing, reviewing, or debugging a migration.
---
Migrations are dated SQL files under db/migrations/, applied in filename
order by `make migrate`. Rules:
- Never edit an applied migration; fix forward with a new file.
- Every new table needs a `restaurant_id` column and an index on it.
- Run `make check-migrations` before opening a pull request.The frontmatter name and description are what the agent sees at startup; it reads the body when the work matches the description. When the Linear issue implementer picks up a schedule-conflict bug that needs a schema change, it reads the skill, writes the migration as a dated file, and runs make check-migrations before opening the PR.
Because repository skills load at the session's checkout, skill and code move together: a PR session that edits both sees its own version of the skill.
Enable a repository's plugins
If a repository already packages its skills as a Claude Code plugin for laptop use, cloud sessions honor the same declaration. A repository enables a plugin by committing two things Claude Code already understands:
- A plugin marketplace directory inside the repository (a directory containing
.claude-plugin/marketplace.jsonand the plugin's files). - A
.claude/settings.jsonthat registers the marketplace and enables the plugin:
{
"enabledPlugins": { "splitshift-conventions@splitshift": true },
"extraKnownMarketplaces": {
"splitshift": { "source": { "source": "directory", "path": "./.agents" } }
}
}Every session that clones the repository loads the plugin at the session's checkout. Plugin skills arrive under the plugin's namespace (splitshift-conventions:pr-conventions), exactly as they do in local Claude Code, and the plugin's slash commands and subagents load with them.
Two rules keep this safe:
- Only marketplace directories inside the repository are honored. A marketplace with a remote source (a git repository or URL) is ignored: it would pull code the reviewed checkout does not contain.
- Plugin-declared MCP servers and hooks never run in cloud sessions. Ellipsis controls the sandbox's MCP servers through your connected integrations; a plugin that declares its own loads everything else and skips those.
A malformed plugin declaration never fails the session: the session runs without that repository's plugins. This differs from config-declared skills below, which fail the session loudly, because a plugin declaration is repository content that may predate Ellipsis rather than something you wrote for it.
Declare skills in the config
The skills list installs skills the sandbox repositories don't provide: a skill elsewhere in the config's repository, a shared skills repository your whole org maintains, or a public repository. Each entry names a directory containing a SKILL.md:
ellipsis:
version: v1
name: Linear issue implementer
description: Implements Linear issues as pull requests
claude:
system: |
Implement the Linear issue this session was started for. Open a
pull request and link the issue in its description.
trigger:
type: react
linear_issue:
on: [opened]
sandbox:
repositories:
- name: splitshift-api
skills:
- path: .agents/skills/pr-conventions
- path: skills/release-notes
repository:
name: platform-skillsThe first entry resolves in the repository this config lives in. The second pulls skills/release-notes from splitshift-hq/platform-skills, a repository this sandbox never clones: that is how one skills repository serves every agent in the org. repository takes any repository of your installation, or a public repository from another owner (owner: anthropics); private repositories outside your account are rejected.
Config-declared skills also work for sessions with no repositories at all, where there is no .claude/skills/ to load from.
How skills resolve
Config-declared skills are fetched at session start, before the agent begins:
- A bare
pathresolves in the config's repository: at the session's checkout when that repository is in the sandbox, otherwise at the head of the branch the config syncs from. - An entry with
repositoryresolves there: at the session's checkout when that repository is in the sandbox, otherwise atrepository.refif set, otherwise at the head of its default branch. - The files are installed at the sandbox's personal skill level (
~/.claude/skills/) under the last segment ofpath(the entrypath: skills/release-notesinstalls asrelease-notes). Personal skills take precedence over repository skills, so a config-declared skill deterministically overrides a same-named repository skill.
A skill that cannot be resolved fails the session before the agent starts: status is error, and the session's status_reason names the entry and what went wrong (no SKILL.md at the path, an unreachable repository, a limit exceeded). A session never runs with a silently missing skill.
Limits
- At most 10
skillsentries per config. - Each skill: at most 50 files and 512 KiB total, 64 KiB per file, UTF-8 text only. Binary assets are not supported.
- Installed names must be unique: two entries whose paths end in the same directory name fail validation.
Sync and pull request validation check each bare-path entry's SKILL.md at the pushed commit, so a typo'd path or broken frontmatter fails before the config registers. Entries with repository are checked at session start.
Next
- Every
skillsfield, default, and constraint: Agent config. - What else is in the sandbox skills land in: The sandbox.
How to give agents the tools and credentials your build needs
Bake your toolchain into a cached image, run setup hooks, and inject credentials so agents can actually build and test your code.
How to keep your skills from going stale
Run a daily agent that reads the day's merges and opens a pull request when the code has moved past what your skills claim.