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

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:

CopyOwnerSafe to edit?On the next install
module/package source (upstream)BMAD maintainersno, unless forkingreplaced
installed _bmad/ + generated .claude/skills/*the installernoregenerated
_bmad/custom/* and _bmad-output/*youyespreserved, 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:

ShapeMerge rule
scalar (string, number, bool)higher layer replaces lower
tabledeep-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 arrayappend (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.toml is personal and gitignored. Every other *.toml in _bmad/custom/ is team-shared and committed. BMAD gitignores the .user.toml files for you automatically.

Applied to the whole install:

PathCommit to main?Why
_bmad/custom/config.toml, _bmad/custom/*.toml (not .user)yesyour team's shared conventions and agent shaping
_bmad/custom/*.user.tomlno (auto-gitignored)personal tone, private facts, local preferences
_bmad/_config/manifest.yamlyesreproducibility: what versions the team runs
_bmad/config.toml, _bmad/config.user.tomlyour callinstaller-generated; regenerated on install, so committing is optional and mostly informational
_bmad/core/, _bmad/bmm/, _bmad/<module>/optionalinstaller-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/*)optionalregenerable from the install command; commit if you want them versioned, otherwise gitignore
_bmad-output/planning-artifacts/* (research, brief, PRD, architecture, epics)yesthe reviewed spec chain; these are the point of SDD, reviewed in PRs
_bmad-output/implementation-artifacts/sprint-status.yamlyesshared sprint state the whole team reads
_bmad-output/project-context.mdyesthe 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:

RankSourceScope
1enterprise managed policyorg, cannot be overridden
2CLI arguments (--model, --permission-mode)this run
3.claude/settings.local.jsonpersonal, gitignored
4.claude/settings.jsonteam, committed
5~/.claude/settings.jsonyour 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. 👉