Contributing to Foundry
For engineers extending Foundry itself — this page is the skill-authoring standard. Everything Foundry ships is a skill, so contributing means writing one (or improving one) to the conventions below. If you're a Foundry user (consuming it via npx @engineering11/e11-foundry install), this page isn't for you; see Installation and the rest of the guide.
Repo layout
e11-foundry/ # pnpm monorepo root (private)
├── packages/
│ ├── foundry/ # @engineering11/e11-foundry — published to GitHub Packages
│ │ ├── src/
│ │ │ ├── foundry/ # The Foundry module
│ │ │ │ ├── tasks/ # Anytime tools — one skill directory each
│ │ │ │ ├── workflows/ # Lifecycle skills, grouped by phase folder
│ │ │ │ ├── teams/ # Roster data
│ │ │ │ ├── data/ # Shared templates
│ │ │ │ ├── module.yaml # Install prompts + agent roster
│ │ │ │ └── module-help.csv # The command catalog
│ │ │ └── scripts/ # resolve-customization.mjs, resolve-config.mjs, …
│ │ ├── tools/ # CLI, installers, validators
│ │ ├── templates/ # Starter templates (skill-template/)
│ │ └── test/skills/ # Vitest suites for skill helper scripts
│ ├── guide/ # @engineering11/foundry-guide — this site
│ └── eval/ # Behavioral eval harness
└── pnpm-workspace.yamlDevelopment setup
git clone https://github.com/engineering11/e11-foundry
cd e11-foundry
pnpm install
pnpm run build # TypeScript compile + asset copypnpm run build:check runs tsc --noEmit for fast type checks.
What a skill is
A skill is a directory containing, at minimum:
SKILL.md— the instructions. Frontmatter requirements:namemust match the directory name exactly.descriptionis one sentence saying what the skill does, followed by the trigger phrases that should activate it ("Use when the user says …"). The description is how host tools route requests — write it for the router, not for humans browsing.
customize.toml— the skill's customization surface: a[workflow]table as the baseline, or an[agent]table for agent personas. Every customizable behavior the skill has is declared here as data (see below).
Plus, as needed: a steps/ directory, templates, checklists, and references/ files the body loads just-in-time, and scripts/ for .mjs helpers.
Every skill body carries the shared conversation rules, in its RULES block (step files) or activation (agents): speak in {communication_language}, and never emit a bare code or ID — AC4, [DF], CAP-2, FR3, story keys are always paired with a human-readable name on first use in a message. Copy both lines verbatim from a shipped skill rather than retyping them; readers shouldn't need a decoder ring, and the wording should not drift per skill.
Where skills live
tasks/<skill-name>/— anytime tools: skills with no lifecycle position, invokable at any point (help, knowledge, refine, the review finders, shard/index, customize).workflows/<N-phase>/<skill-name>/— lifecycle skills: anything that belongs to a delivery phase (1-analysis…5-scaffold), including the phase's agent-skill.
That's the whole rule. If a skill has a phase, it lives in the phase folder; if it doesn't, it's a task.
Pick a body shape
Three canonical shapes. Match the skill you're writing to one of them — don't invent a fourth.
1. Prose sections — short single-purpose tools
For a tool that does one thing in one pass (canonical example: e11-index-docs). The body is plain Markdown sections:
- Goal / Your Role — one line each.
- Inputs — named inputs with one-line descriptions.
- EXECUTION — numbered steps as prose. Small enough to be read whole.
- OUTPUT FORMAT — the exact shape of what the skill returns or writes.
- HALT CONDITIONS — when to stop and what to say.
No activation ceremony unless the skill needs config or customization at run time; retrievers that other skills call constantly (like e11-knowledge) keep activation deliberately cheap.
2. steps/ directory — multi-stage interactive workflows
For anything with checkpoints, user decisions, or distinct stages (canonical example: e11-code-review). The SKILL.md holds the standard On Activation block (resolve the [workflow] block through the customization layers → prepend steps → persistent facts → config → greet → append steps — copy it from an existing skill, don't retype it) plus the step-processing rules; the procedure itself lives in steps/step-NN-<name>.md files:
- Numbered
step-01-…,step-02-…; the agent loads exactly one step at a time, just-in-time, never pre-loading the rest. - Each step is self-contained: rules, instructions, checkpoints, and an explicit NEXT ("read fully and follow
./step-02-….md") or a HALT. - Runtime state (
{diff_output},{spec_file}, …) is declared in step frontmatter and threaded between steps.
3. Agents — the shared activation protocol
Agents are skills whose entire body is the eight-step activation protocol: resolve the [agent] block, prepend steps, adopt persona, persistent facts, config, greet, append steps, dispatch-or-present-the-menu. Copy the body from an existing e11-agent-* skill and change only the Overview (the hardcoded identity) — the protocol text is shared and should not drift per agent. Everything an agent does — persona fields, principles, facts, menu — is data in its customize.toml, not prose in the body. Register the agent in module.yaml's agents: roster so it lands in central config.
Older skills: some bodies still use an XML-ish inline dialect (
<workflow><step n="1">…). It's supported and won't be rewritten wholesale, but do not use it for new skills — pick one of the three shapes above.
customize.toml conventions
The surface is a contract with every team that installs Foundry, so it's held to rules:
- DO-NOT-EDIT header. Every file starts with the comment block naming the override files (
.foundry/custom/<skill>.toml/.user.toml) and the merge rules (scalars override · arrays append · keyed arrays replace-or-append). Copy it from any shipped skill. - Baseline fields. Every surface ships
activation_steps_prepend,activation_steps_append,persistent_facts, andon_complete(workflow surfaces), or their[agent]equivalents plus persona fields and[[agent.menu]]. - Content-anchored knobs only. Every field must be read somewhere in the skill body. A knob the body never consults is a lie to the customizer — don't ship speculative fields.
- Keyed arrays use
idorcode. Any array-of-tables a user might want to override entry-by-entry ([[workflow.review_layers]],[[agent.menu]],[[workflow.extra_query_keys]]) carries a stableid/codekey so overrides can replace one entry surgically. - Platform-behavior gates use the
e11_platform_*prefix. Any boolean that turns E11-specific behavior on or off (alloy pre-loads, capability maps, SDK stamps) is namede11_platform_<behavior>, defaults totrue, and the body checks it before running the gated step — that's what lets a non-platform repo turn the behavior off with a one-line override. - No removal semantics. Overrides can't delete — design fields so an empty value neutralizes (empty
instructiondisables a review layer,falsedisables a gate).
E11 grafts
When platform behavior must live inside a skill body that otherwise tracks a generic shape, mark it:
<!-- E11-GRAFT:begin <graft-name> -->
…the platform-specific steps…
<!-- E11-GRAFT:end <graft-name> -->(# E11-GRAFT (<graft-name>): as a leading comment in TOML.) The markers make platform grafts findable and diffable as a unit.
Prefer the customize surface over inline grafts. If the behavior can be expressed as data — a gated field, an extra review layer, a persistent fact — put it in customize.toml where teams can override it, and keep the body graft to the minimal hook that reads it. Every inline graft should be gated by an e11_platform_* field.
Catalog registration
- Menu codes are unique across the whole catalog (
module-help.csv), not per agent. Check before claiming one. - Every user-facing skill gets a row in
module-help.csv— columns: module · phase · name · code · sequence · workflow-file (skill:<name>) · command · required · agent · options · description · output-location · outputs. Tasks usephase=anytime. The installer assembles all module catalogs into.foundry/_config/e11-help.csv, which is what E11 Master ande11-helpread — a skill missing its row is invisible to routing. - Skills reached only through an agent's menu also get their
[[agent.menu]]entry in that agent'scustomize.toml.
Starter template
Start new skills from packages/foundry/templates/skill-template/ — it carries the frontmatter shape, the DO-NOT-EDIT header, the baseline surface fields, and the activation preamble in each variant. (If the template isn't in your checkout yet, copy the nearest shipped skill of the same body shape instead — that's what the template is distilled from.)
Testing and gates
Helper scripts get tests. Any
scripts/*.mjsa skill ships gets a vitest suite underpackages/foundry/test/skills/<skill-name>/(seetest/skills/e11-discovery/for the pattern). Run withpnpm --filter @engineering11/e11-foundry test.Repo gates — run before opening a PR:
bashpnpm --filter @engineering11/e11-foundry test # vitest suites pnpm run validate:refs # every file reference inside skills resolves pnpm run validate:guide # guide coverage of the catalog pnpm run lint && pnpm run format:check # ESLint / Prettier, 0-warning baseline pnpm run lint:md # markdownlint over *.md pnpm run lint:vocabulary # banned-vocabulary lintPre-commit hooks (Husky + lint-staged) run lint/format/markdownlint on staged files automatically.
Guide coverage
pnpm run validate:guide fails the moment a lifecycle skill exists without a guide reference: every workflows/<phase>/<slug>/SKILL.md must be linked from its phase page (packages/guide/02-workflows/<phase>.md). When you add a skill, add it to the phase page's table (or, for agents, a depth page under packages/guide/01-agents/ plus a row in the quick-reference table).
Guide depth pages follow an 8-section shape: What it produces · When to use it · How to invoke · Inputs · Outputs & where they land · Example session · Gotchas · Source.
Doc site
The guide deploys to foundry.engineering11.com via .github/workflows/docs.yml on pushes to main that touch packages/guide/.
pnpm run docs:dev # local server with hot reload
pnpm run docs:build # build static siteSidebar/nav live in packages/guide/.vitepress/config.mts — add new pages to the relevant sidebar group. Cross-repo links (../../src/...) are for GitHub readers and skipped by the dead-link checker; intra-guide links are checked and fail the build when broken.
Releases
Releases go through changesets: pnpm changeset in your PR describes the change and bump level; the release workflow versions and publishes @engineering11/e11-foundry to GitHub Packages.
What not to commit
.gitignore already covers it, but as a reminder:
.foundry/,.foundry-output/— consumer install output, never inside Foundry itself..claude/,.agents/,.opencode/— tool surfaces are generated, not authored.- Generated
dist/.
Source
Skill sources: packages/foundry/src/foundry/tasks/ · packages/foundry/src/foundry/workflows/ · catalog: packages/foundry/src/foundry/module-help.csv · resolvers: packages/foundry/src/scripts/ · CLI + validators: packages/foundry/tools/ · tests: packages/foundry/test/skills/ (repo paths — open them in your checkout)