Anatomy of an install: files, config, and what to commit
The install page got you running. This page opens the box: what the installer wrote, how BMAD's configuration layers resolve, and, the question every team asks on day one, which files belong in git and which stay local. Get this right once and the rest of BMAD is calm.
On this page
- The two folders
- Inside _bmad/
- Inside _bmad-output/
- Three copies of “BMAD,” and only one is yours
- Configuration resolution: two override stacks
- What to commit, and what to keep local
- project-context.md: the constitution
- Hands-on: inspect what got installed and set up commit hygiene
- Under Claude Code: the .claude/ tree and settings precedence
The two folders
A fresh install creates two top-level folders in your project:
your-project/
├── _bmad/ the method: modules, config, scripts (installer-owned + your overrides)
└── _bmad-output/ the work: research, briefs, PRD, architecture, stories, sprint state
The rule of thumb behind everything below: _bmad/ is machinery, _bmad-output/
is product. You rarely touch the machinery by hand except in one place
(_bmad/custom/), and the product is the reviewable artifact chain your team
reads in pull requests.
Inside _bmad/
_bmad/
├── core/ built-in core framework (bundled in the installer)
├── bmm/ the BMad Method module (bundled)
├── bmb/ cis/ ... each installed add-on module
├── _config/
│ ├── manifest.yaml every module: version, channel, source, sha
│ └── agents/ agent customization files
├── config.toml installer-owned, TEAM scope (install answers + agent roster)
├── config.user.toml installer-owned, USER scope (your name, language, skill level)
├── custom/ YOUR overrides (starts empty; the only folder you hand-edit)
│ ├── config.toml team overrides
│ ├── config.user.toml personal overrides
│ ├── bmad-agent-dev.toml a per-agent override
│ └── bmad-prd.toml a per-workflow override
├── <module>/config.yaml per-module config (prompt defaults, carry-forward)
└── scripts/ resolvers (resolve_customization.py, memlog.py, ...)
manifest.yaml is worth knowing, because it is your reproducibility record. It
lists every module with its resolved version, channel (stable, next, or
pinned), source, and git sha:
modules:
- name: bmb
version: v1.7.0 # the tag, or "main" for the next channel
channel: stable
sha: 86033fc9aeae2ca6d52c7cdb675c1f4bf17fc1c1
source: external
repoUrl: https://github.com/bmad-code-org/bmad-builder
A "stable" install resolves to the newest tag at install time, so to reproduce
an install on another machine you convert manifest.yaml's tags into explicit
--pin flags rather than trusting --modules to resolve the same way twice.
Inside _bmad-output/
_bmad-output/
├── planning-artifacts/ research/, brief, PRD, ux (DESIGN.md/EXPERIENCE.md), architecture, epics/
├── implementation-artifacts/ sprint-status.yaml, story specs, deferred-work.md
└── project-context.md optional; your project's implementation "constitution"
The output folder is configurable (it is the output_folder core setting, with
planning_artifacts under the bmm module), but _bmad-output/ is the default.
This is the chain the SDD page describes, made real on
disk: each file is a reviewable, greppable message from one phase to the next.
Three copies of "BMAD," and only one is yours
The single most common source of confusion, and update pain, is editing the wrong copy. There are three:
| Copy | Owner | Safe to edit? | On the next install |
|---|---|---|---|
| module/package source (upstream) | BMAD maintainers | no, unless forking | replaced |
installed _bmad/ + generated .claude/skills/* | the installer | no | regenerated |
_bmad/custom/* and _bmad-output/* | you | yes | preserved, never touched |
Treat the installer-owned files as generated code. Editing _bmad/config.toml
or a generated SKILL.md directly works today and is silently overwritten on the
next npx bmad-method install. All durable behavior changes go in
_bmad/custom/; all durable content goes in the output folder. The installation
is deliberately inspectable, not an opaque service: manifest.yaml, the skill
directories, and git diff after an update answer almost every "what do I
actually have?" question.
Configuration resolution: two override stacks
BMAD separates central configuration (cross-cutting: paths, the agent roster, install answers) from per-skill behavior (one agent or workflow). Each has its own layered resolution, highest layer wins.
Central configuration, four layers:
highest _bmad/custom/config.user.toml personal, durable (gitignored)
_bmad/custom/config.toml team, durable (committed)
_bmad/config.user.toml installer-generated personal
lowest _bmad/config.toml installer-generated team/base
Per-skill behavior, three layers:
highest _bmad/custom/bmad-prd.user.toml personal (gitignored)
_bmad/custom/bmad-prd.toml team (committed)
lowest .claude/skills/bmad-prd/customize.toml the shipped schema/defaults (never edit)
The resolver merges by the shape of each value, and knowing the four rules is what lets you keep overrides sparse:
| Shape | Merge rule |
|---|---|
| scalar (string, number, bool) | higher layer replaces lower |
| table | deep-merge (recurse) |
array of tables that all share a code (or all share an id) | match by that key: replace in place, append new |
| any other array | append (base, then team, then user) |
There is deliberately no deletion operator. To neutralize a shipped item,
override it by code with a no-op; to remove behavior wholesale, fork the skill.
Copying an entire shipped customize.toml into your override freezes old
defaults and masks every future improvement, so change only the handful of fields
you mean to. The resolver is a small stdlib script (tomllib, hence Python
3.11+), and every skill falls back to reading the three TOML files directly if
the script is unavailable.
What to commit, and what to keep local
This is the answer to "what BMAD files do I push to main." BMAD encodes the team-vs-personal split directly in the filename, and the rule is mechanical:
*.user.tomlis personal and gitignored. Every other*.tomlin_bmad/custom/is team-shared and committed. BMAD gitignores the.user.tomlfiles for you automatically.
Applied to the whole install:
| Path | Commit to main? | Why |
|---|---|---|
_bmad/custom/config.toml, _bmad/custom/*.toml (not .user) | yes | your team's shared conventions and agent shaping |
_bmad/custom/*.user.toml | no (auto-gitignored) | personal tone, private facts, local preferences |
_bmad/_config/manifest.yaml | yes | reproducibility: what versions the team runs |
_bmad/config.toml, _bmad/config.user.toml | your call | installer-generated; regenerated on install, so committing is optional and mostly informational |
_bmad/core/, _bmad/bmm/, _bmad/<module>/ | optional | installer-owned; committing pins the exact files but bloats diffs. Many teams gitignore these and rely on manifest.yaml + a documented install command instead |
generated skills (.claude/skills/bmad-*, .agents/skills/*) | optional | regenerable from the install command; commit if you want them versioned, otherwise gitignore |
_bmad-output/planning-artifacts/* (research, brief, PRD, architecture, epics) | yes | the reviewed spec chain; these are the point of SDD, reviewed in PRs |
_bmad-output/implementation-artifacts/sprint-status.yaml | yes | shared sprint state the whole team reads |
_bmad-output/project-context.md | yes | the project's implementation constitution |
A pragmatic .gitignore that most teams converge on:
# BMAD: keep team overrides, shared config, and all product artifacts;
# ignore personal overrides and regenerable machinery.
_bmad/**/*.user.toml
_bmad/core/
_bmad/bmm/
_bmad/cis/
_bmad/bmb/
.claude/skills/bmad-*/ # if you prefer to regenerate skills per machine
Two teams reasonably differ on one point: whether to commit the installed module
source and generated skills. Committing them makes the repo fully
self-contained and pins exact behavior, at the cost of large, noisy diffs on
every upgrade. Ignoring them keeps the repo clean and treats BMAD like any other
dependency, resolved from manifest.yaml and a one-line install command in the
README. Either is defensible; pick one and write it down. What is not optional
is committing the _bmad-output/ spec chain and the team *.toml overrides:
those are the shared brain, and a teammate who clones the repo without them gets
a different BMAD.
project-context.md: the constitution
One output file deserves special mention because it is the highest-value file
a team keeps. project-context.md is "your project's implementation guide
for AI agents, similar to a constitution in other development systems." Every
implementation workflow loads it automatically if it exists:
bmad-architecture, bmad-create-story, bmad-dev-story, bmad-code-review,
bmad-quick-dev, bmad-sprint-planning, bmad-retrospective, and
bmad-correct-course.
It holds two things: your technology stack with specific versions, and your critical implementation rules, the patterns an agent might miss from reading code. The official guidance is to focus on the unobvious:
## Technology Stack
- Node 20.x, TypeScript 5.3, React 18.2
- State: Zustand (not Redux)
- Testing: Vitest, Playwright, MSW
## Critical Implementation Rules
- No `any` types without explicit approval.
- All API calls go through the `apiClient` singleton; never `fetch` directly.
- Feature flags via `featureFlag()` from `@/lib/flags`.
- All offline splits are chronological; random interaction splits are forbidden.
Create it manually at _bmad-output/project-context.md, or generate it with
bmad-generate-project-context (which scans your architecture doc or, for an
existing codebase, the code itself). Workflows look there and also match
**/project-context.md anywhere in the tree. Keep it living: update it when the
architecture changes or when you notice an agent repeating a mistake it should
have known better than to make. The memory page
returns to this file as one of BMAD's three kinds of durable memory.
Hands-on: inspect what got installed and set up commit hygiene
Ten minutes in a repo that already ran npx bmad-method install. No new
concepts, just the exact commands to see what landed on disk and stage the right
subset, so you know which files to commit and why.
1. Walk the two folders. List the top of each tree before you touch anything.
ls _bmad
ls _bmad/custom
ls _bmad-output/planning-artifacts
Illustrative (run it in your own repo; not machine-verified here).
$ ls _bmad
core bmm bmb cis _config config.toml config.user.toml custom scripts
$ ls _bmad/custom
config.toml config.user.toml
$ ls _bmad-output/planning-artifacts
research brief.md PRD.md architecture.md epics
One rule: _bmad/ is machinery, _bmad-output/ is product. Inside the
machinery, _bmad/custom/ is the only folder you hand-edit.
2. Read a skill's schema. Each generated skill ships a customize.toml
documenting its overridable fields. Open one and skim the [workflow] and
[agent] tables.
sed -n '1,40p' .claude/skills/bmad-prd/customize.toml
Illustrative (run it in your own repo; not machine-verified here).
[workflow]
instructions = "..."
elicitation = true
output_file = "{output_folder}/planning-artifacts/PRD.md"
[agent]
name = "John"
role = "Product Manager"
These are the shipped defaults, the lowest layer. Never edit this file; mirror
only the fields you want to change into _bmad/custom/bmad-prd.toml.
3. Author the .gitignore. Commit the shared config and the product chain;
ignore personal overrides and runtime junk.
# BMAD: commit shared config + the spec chain; ignore personal + runtime.
_bmad/**/*.user.toml
_bmad/core/
_bmad/bmm/
_bmad/cis/
_bmad/bmb/
_bmad-output/**/.cache/
**/__pycache__/
*.log
Note what this does not touch: _bmad/**/*.toml (your team overrides),
_bmad/_config/manifest.yaml (the reproducibility record), and everything under
_bmad-output/planning-artifacts/. Those stay tracked.
4. Stage the shared config.
git add .gitignore \
_bmad/custom/*.toml \
_bmad/_config/manifest.yaml \
_bmad-output/
git status --short
The *.toml glob skips *.user.toml because git already ignores it, so even a
stray git add -A will not leak personal settings.
5. Confirm the merge before you trust it. Committing an override is committing
its effect. page 11 runs
resolve_customization.py to print the three-layer merge (shipped
customize.toml, then team .toml, then personal .user.toml) so you stage
config whose resolved value you have actually seen, not guessed.
Under Claude Code: the .claude/ tree and settings precedence
This chapter is BMAD's on-disk layout, its layered config, and the commit rule.
The worked host has a parallel tree of its own. Claude Code reads everything from
a project .claude/ directory: settings.json (committed), settings.local.json
(gitignored), and the subdirectories skills/, agents/, commands/, rules/,
and output-styles/, plus a project-root .mcp.json. Prose memory lives in
CLAUDE.md (project, committed) and CLAUDE.local.md (gitignored), with the
user-scoped copies under ~/.claude/.
Settings resolve by a five-level precedence, highest first:
| Rank | Source | Scope |
|---|---|---|
| 1 | enterprise managed policy | org, cannot be overridden |
| 2 | CLI arguments (--model, --permission-mode) | this run |
| 3 | .claude/settings.local.json | personal, gitignored |
| 4 | .claude/settings.json | team, committed |
| 5 | ~/.claude/settings.json | your machine, all projects |
CLAUDE.md is a hierarchy too (managed, user ~/.claude/CLAUDE.md, project,
local, then nested per-subdir loaded on demand). It supports @path imports up
to four levels deep, and a # at the prompt appends a line to memory.
The mapping is direct. BMAD's commit rule ("commit *.toml, gitignore
*.user.toml") is Claude Code's rule one layer up: commit .claude/settings.json,
gitignore .claude/settings.local.json. Same committed-shared versus
local-personal split, encoded in the filename. The two systems stack rather than
compete: BMAD's TOML merge (the four shape rules above) runs to produce a skill's
effective config, and that skill sits inside a .claude/ tree whose own settings
resolve by the five levels here. Two override stacks, one on top of the other.
With the files understood, the next page lays out the moving parts they configure: every module, the four phases, the six named agents, and the workflow map that ties them together. 👉