Customize and Extend
Customize FMAD
You want an agent to remember your organization’s rules, a workflow to publish its output somewhere, a menu item that runs your own skill, or a different name on the roster. Each of these is an override file next to FMAD’s installed defaults. Updates do not touch your files, and you do not edit installed files.
Start with the guided path
Section titled “Start with the guided path”Run the fmad-customize skill and say what you want changed. It scans your
installation for what is customizable, picks the right surface for your
intent (an agent or a workflow), writes the override file, and verifies
that the merged result contains your change. Use it for any per-skill
change. The rest of this page describes what each surface exposes and how
the pieces combine.
There are two surfaces:
| Surface | File | Shapes |
|---|---|---|
| Per-skill override | _fmad/custom/<skill>.toml | How one agent or workflow behaves when it activates: persona, facts, hooks, menu, workflow fields |
| Central configuration | _fmad/custom/config.toml | Install answers and the agent roster that other skills read |
fmad-customize writes per-skill overrides only. Central configuration is
hand-authored; see Central configuration.
For ready-made team recipes (an agent-wide rule, publishing to Confluence, swapping a template, a rebranded roster), see Adopt FMAD Across a Team.
What an agent is made of
Section titled “What an agent is made of”Every named agent has two parts. Name, title, and domain are fixed: “hey Ember” always activates the analyst. Everything else is customizable: role, identity statement, communication style, principles, icon, menu, persistent facts, and activation hooks. The shipped agents are listed in Agents.
The per-skill file controls how the agent behaves when it activates.
Central configuration controls how fmad-party-mode, fmad-retrospective,
and fmad-advanced-elicitation introduce the agent. Rewriting Ember’s
principles is per-skill; changing the one-line description a party uses
to introduce her is central.
How overrides merge
Section titled “How overrides merge”Every customizable skill ships a customize.toml in its installed folder.
That file is the schema: read it to see what is customizable. Never edit
it; updates overwrite it. Instead, create sparse override files that
contain only the fields you change.
Three layers. The resolver reads three files and the highest wins:
Priority 1 (wins): _fmad/custom/<skill>.user.toml (personal, gitignored)Priority 2: _fmad/custom/<skill>.toml (team, committed)Priority 3 (base): the skill's own customize.toml (shipped defaults)_fmad/custom/ starts empty. Files appear only when someone customizes.
Four rules, by shape. The resolver does not treat fields differently by name; the merge depends only on the value’s shape:
| Shape | Rule |
|---|---|
| Scalar (string, int, bool, float) | Override wins |
| Table | Deep merge — apply these rules recursively |
Array of tables where every item has code, or every item has id | Merge by that key: matching keys replace in place, new keys append |
Any other array (scalars, tables with no key, arrays mixing code and id) | Append — base items, then team, then user |
No removal. An override cannot delete a base item. To suppress a
default menu item, override it by code with a description or prompt that
does nothing; to restructure an array further, fork the skill. If you
author your own array of tables, use code on every item or id on every
item — mixing them falls back to append.
Read-only fields. agent.name and agent.title sit in
customize.toml as metadata, but the agent never reads them at runtime.
name = "Bob" in an override does nothing. For a differently named agent,
copy the skill folder, rename it, and ship it as a custom skill.
Customize an agent
Section titled “Customize an agent”Find the surface. The schema is the skill’s installed customize.toml:
.claude/skills/fmad-agent-pm/customize.tomlThe path varies by IDE — Cursor uses .cursor/skills/, Cline
.cline/skills/, and so on. Fields live directly under [agent].
Scalars. Create _fmad/custom/ in your project root if it does not
exist, then add <skill>.toml with only the fields you change. icon, role, identity, and communication_style are scalars,
so the override wins:
[agent]icon = "🏥"role = "Drives product discovery for a regulated healthcare domain."communication_style = "Precise, regulatory-aware, asks compliance-shaped questions early."Facts, principles, and hooks. These four arrays append: shipped items
first, then team, then user. persistent_facts are static context the
agent keeps in mind all session; an entry is a literal sentence or a
file: reference (globs allowed) whose contents are loaded as facts.
[agent]persistent_facts = [ "Our org is AWS-only -- do not propose GCP or Azure.", "file:{project-root}/docs/compliance/hipaa-overview.md",]
principles = [ "Ship nothing that can't pass an FDA audit.",]
# Runs before the greeting.activation_steps_prepend = [ "Scan {project-root}/docs/compliance/ and load any HIPAA-related documents as context.",]
# Runs after the greeting, before the menu.activation_steps_append = [ "Read {project-root}/_fmad/custom/company-glossary.md if it exists.",]Prepend runs before the greeting, when the greeting itself needs that context. Append runs after, for setup the user should not wait on.
Menu. [[agent.menu]] is an array of tables keyed by code, so a
matching code replaces the shipped item and a new code appends. Each item
has exactly one of skill or prompt:
# Replace the shipped TK item with your own skill[[agent.menu]]code = "TK"description = "Plan epics and tickets using our delivery framework"skill = "custom-ticket"
# Add a new item[[agent.menu]]code = "RC"description = "Run compliance pre-check"prompt = """Read {project-root}/_fmad/custom/compliance-checklist.mdand scan all documents in {output_folder}/{active_initiative} against it."""When any field points at a file, spell out the full path from
{project-root}, even for a file sitting next to your override in
_fmad/custom/. The agent resolves {project-root} at runtime.
Team or personal. The team file (fmad-agent-pm.toml) is committed
and shared: compliance rules, company persona, custom menu items. The
personal file (fmad-agent-pm.user.toml) is gitignored: tone, private
preferences, facts only you want the agent to hold.
[agent]persistent_facts = [ "Always include a rough complexity estimate (low/medium/high) when presenting options.",]Customize a workflow
Section titled “Customize a workflow”Workflows — skills that drive a multi-step process, such as
fmad-product-brief — use the same files and rules. Their surface lives
under [workflow]. The baseline fields every customizable workflow
exposes are the same hooks and facts as agents plus on_complete. For
workflows, a persistent_facts entry is a literal sentence, a file:
path or glob, or a skill: reference to a skill that holds relevant
knowledge. on_complete is a string, or an array of instructions run in
order, that runs once the workflow finishes its main output:
[workflow]activation_steps_prepend = [ "Load {project-root}/docs/product/north-star-principles.md as context.",]
persistent_facts = [ "All briefs must include an explicit regulatory-risk section.", "file:{project-root}/docs/compliance/product-brief-checklist.md",]
on_complete = "Summarize the brief in three bullets and offer to email it via the gws-gmail-send skill."Individual workflows add fields on top — output paths, templates, toggles —
and each follows the shape rules above. For example, fmad-code-review
exposes review, the default review depth:
[workflow]review = "quick"Read a workflow’s customize.toml to see the fields it exposes. If the
field you need is not there, use activation_steps_* and
persistent_facts, or open an issue asking for a customization point.
Activation order. A customizable workflow activates in a fixed sequence, so you know when each hook fires:
- Resolve the
[workflow]block (base, then team, then user). - Run
activation_steps_prepend. - Load
persistent_factsas context for the run. - Load config and resolve standard variables (project name, languages, paths, date).
- Greet the user.
- Run
activation_steps_append.
The workflow body begins after step 6.
Override one rendered invocation
Section titled “Override one rendered invocation”To change a skill’s customization for one run only, add --set key=value
arguments or an --overrides <file.toml> file to the render_skill.py
command in its SKILL.md. Persistent project and user files stay as they
are.
uv run /abs/project/_fmad/scripts/render_skill.py \ --project-root /abs/project \ --skill /abs/path/to/fmad-build \ --overrides ./invocation.toml \ --set 'workflow.on_complete=Summarize the result in three bullets.'Keys are dotted parameter paths such as workflow.on_complete. The
override file has the same shape as the skill’s customize.toml. Both
layer on top of the persistent files, and --set wins over the file.
String values can be written as plain text. Other types use TOML syntax:
--set 'workflow.persistent_facts=["Additional context"]'Central configuration
Section titled “Central configuration”Per-skill files cover one agent or workflow. Central configuration holds
[core] values such as output_folder, module answers under
[modules.<code>], and optional [agents.<code>] tables. It lives in
three TOML files:
_fmad/config.toml (created by fmad setup) team answers (committed)_fmad/custom/config.toml (hand-written only) team pins (committed)_fmad/custom/config.user.toml (fmad setup, and by hand) personal answers (gitignored), including `[core] active_initiative`Three layers, merged with the same shape rules:
Priority 1 (wins): _fmad/custom/config.user.tomlPriority 2: _fmad/custom/config.tomlPriority 3 (base): _fmad/config.tomlWhat lives where. fmad setup asks the config_questions declared in
each module’s fmod.toml and files each answer under [modules.<code>]
by the question’s scope: team answers land in _fmad/config.toml,
user answers in _fmad/custom/config.user.toml. The agent roster comes
from each installed module’s roster.toml, not from central config.
[agents.<code>] tables are laid on top of it: use them to add an agent
of your own, or to add details such as team or description to an
installed one. An installed agent’s name, title, and icon come from its
skill and its per-skill override, so setting them here has no effect.
Editing rules. All three files may be hand-edited. fmad setup never
changes an existing value, so to change an answer, edit its key in the
file fmad setup reports for it. fmad setup never writes
_fmad/custom/config.toml; it is the place for custom agents, descriptor
additions, and any team value you want pinned over the answers in
_fmad/config.toml.
Rebrand an agent. Party mode and other roster skills pick up the new
description automatically. To change the agent’s icon as well, set icon
under [agent] in its per-skill override (_fmad/custom/fmad-agent-pm.toml):
[agents.fmad-agent-pm]description = "Healthcare PM — regulatory-aware, stakeholder-driven, FDA-shaped questions first."Add a fictional agent. No skill folder is needed; the descriptor alone
lets a party include Kirk, and the team field filters who gets invited.
See Run Multi-Agent Discussions.
[agents.kirk]team = "startrek"name = "Captain James T. Kirk"title = "Starship Captain"icon = "🖖"description = "Bold, rule-bending commander. Speaks in dramatic pauses."Override an install setting. The team pin wins over the answer in
_fmad/config.toml; a developer’s own _fmad/custom/config.user.toml
still wins over it:
[core]output_folder = "/shared/org-fmad-output"Which surface to use:
| Need | Use |
|---|---|
| Add MCP tool calls to every dev workflow | Per-skill: _fmad/custom/fmad-agent-dev.toml persistent_facts |
| Add a menu item to an agent | Per-skill: _fmad/custom/fmad-agent-<role>.toml [[agent.menu]] |
| Swap a workflow’s output template | Per-skill: _fmad/custom/<workflow>.toml scalar override |
| Rebrand an agent’s public descriptor | Central: _fmad/custom/config.toml [agents.<code>] |
| Add a custom or fictional agent to the roster | Central: _fmad/custom/config.*.toml new [agents.<code>] |
| Pin team-enforced install settings | Central: _fmad/custom/config.toml [modules.<code>] or [core] |
| Choose which initiative your documents and tickets go to | Central: _fmad/custom/config.user.toml [core] active_initiative, or ask the fmad skill to switch it |
Check what resolved
Section titled “Check what resolved”On activation, a shared Python script merges the files and returns the result as JSON. Run it yourself to see exactly what an agent or workflow will use:
# Resolve the full agent blockuv run {project-root}/_fmad/scripts/resolve_customization.py \ --skill /abs/path/to/fmad-agent-pm \ --project-root {project-root} \ --key agent
# Resolve a single fielduv run {project-root}/_fmad/scripts/resolve_customization.py \ --skill /abs/path/to/fmad-agent-pm \ --project-root {project-root} \ --key agent.icon
# Full dump: omit --keyReplace {project-root} with your project root; the skill resolves it
for you at activation, but a shell will not.
--skill points at the skill’s installed directory; the script derives
the skill name from that folder and finds the matching _fmad/custom/
files itself. Output is always JSON.
--project-root names the project whose _fmad/custom/ files apply.
Skills pass it on activation. Omit it and the script infers a root —
working directory first, then its own install path, then the skill
directory — which lands correctly in ordinary use but has to guess when a
skill is installed under your home directory and a ~/_fmad exists there
too. If it picks a root with no override for that skill while another
candidate has one, it says so on stderr rather than quietly returning
defaults.
Use uv run so the script gets Python 3.11 or later. If you run it with
python3 instead, check the version: 3.10 and earlier lack tomllib.
If the script cannot run, an agent reads the three TOML files and applies
the same rules; many workflows fall back to shipped defaults, so keep uv
working if you rely on workflow overrides.
Troubleshooting
Section titled “Troubleshooting”Customization not appearing. Check that the file is in _fmad/custom/
and named exactly after the skill directory. Check TOML syntax: strings
quoted, [section] for tables, [[section]] for arrays of tables, and a
table’s scalar or array keys placed before any of its [[subtables]]. For
agents, fields belong under [agent]. Remember that agent.name and
agent.title are read-only.
An update broke it. You probably copied the full customize.toml.
Trim the override back to only the fields you changed.
See what is customizable. Run fmad-customize, which lists every
customizable skill and which already have overrides, or read the skill’s
customize.toml directly.
Reset. Delete the override file from _fmad/custom/. The skill falls
back to its shipped defaults.