Hierarchical Configuration
Forge can load configuration from your user and system profiles and from a multi-repository application, not only from the repository. Use this to share agent, toolchain, command, and workflow settings across repositories while each repository keeps control. This page explains the load order, how to enable external sources, and how to set up an application.
Load order
Forge looks for configuration in these locations. A higher-priority source overrides a lower-priority one:
| Priority | Source | Location |
|---|---|---|
| 1 (highest) | Repository | .forge/config/<file>.toml |
| 2 | Application | .forge/config/ next to application.toml in the application root |
| 3 | User profile | ~/.config/forge/<file>.toml ($XDG_CONFIG_HOME/forge/ when set) |
| 4 | System profile | /etc/forge/<file>.toml |
| 5 (lowest) | Built-in defaults | — |
These files support hierarchical loading:
| File | Description |
|---|---|
agents.toml | Agent and model selection |
toolchain.toml | Development tools |
commands.toml | Prompt overrides and custom commands |
workflows/*.toml | Stateful workflow definitions |
project.toml is always read from the repository. telemetry.toml has its own lookup; see Configuration Files Reference.
Merge behavior
- Scalar values: the higher-priority source wins.
- Tables: nested values merge.
- Arrays: the higher-priority source replaces the whole array.
- Workflows: a workflow file with the same name in a higher-priority source replaces the lower-priority file completely.
Enable external sources
External sources are disabled by default. Forge loads only repository configuration until you enable them in project.toml:
[config.external_sources]
enabled = true
agents = true # Load agents.toml from user and system profiles
toolchain = false # Keep toolchain.toml repository-only
commands = true
workflows = true
enabledis the master switch. When it isfalse, the per-file toggles have no effect.- A per-file toggle that you omit defaults to
truewhenenabled = true.
Warning: Only enable external sources when you trust the files in your user and system profiles. They change what the agent is told to do.
Force repository-only configuration
Set FORGE_DISABLE_EXTERNAL_CONFIGS to ignore external sources regardless of project.toml. This is useful in CI for reproducible runs:
export FORGE_DISABLE_EXTERNAL_CONFIGS=true
frg config validate
Example: share agent settings
- Create a user-profile
agents.toml:
mkdir -p ~/.config/forge
cat > ~/.config/forge/agents.toml << 'EOF'
schema_version = "1.0.0"
[agent]
default = "claude_code"
EOF
- Enable external sources in the repository's
project.toml:
[config.external_sources]
enabled = true
- Confirm that Forge loads the file:
frg config validate
Example output (abbreviated):
Validating configuration files...
- application.toml — absent
✓ project.toml — valid (Repo)
✓ agents.toml — valid (User)
✓ toolchain.toml — valid (Repo)
For organization-wide defaults, an administrator can place the same files in /etc/forge/.
See which sources are loaded
frg config validateshows the source of each file:Repo,App, orUser.frg config showlists the loaded files under Configuration Sources, grouped as Repository, Application, User Profile, and System Profile.
frg config show --verbose
Lock hierarchical configuration
frg config lock validates the configuration and writes .forge/.config_lock with a SHA-256 hash of each configuration file. Re-run it after you change any source. If a locked file changes, workflow commands are blocked until you lock again.
Multi-repository applications
An application groups related repositories, such as microservices in sibling directories, so they share configuration and can run workflows together. For running application workflows, see Multi-Repository Application Commands.
Create an application
Run frg config init --app in the application root:
cd /path/to/my-application
frg config init --app
Forge creates .forge/config/application.toml and prints the application ID:
schema_version = "1.0.0"
repositories = []
[application]
id = "186ee0e9-5ef4-490a-bcba-2e38cb7dd98a"
name = "my-application"
description = "Multi-repository application: my-application"
[discovery]
enabled = true
max_depth = 5
exclude = [
"node_modules",
"target",
".git",
"vendor",
"dist",
"build",
]
Add --issues, --tickets, --scanner, --code, --agent, and --models to create toolchain.toml and agents.toml alongside application.toml:
frg config init --app --issues github_issues --code github --agent github_copilot --models balanced
--app cannot be combined with --force.
Opt repositories in
Each repository joins the application explicitly. Add the application ID to its project.toml:
[project]
name = "api-service"
# ...required fields...
allow_app = "186ee0e9-5ef4-490a-bcba-2e38cb7dd98a"
Discover repositories
From the application root, find repositories whose allow_app matches and write them to application.toml:
frg app discover
| Option | Description |
|---|---|
-f, --force | Overwrite the existing repository list in application.toml |
--auto | Generate project.toml with AI for discovered repositories that do not have one, and set allow_app. Set FORGE_ACCEPT_AUTO_RISK=true to skip the warning in CI. |
Discovery settings:
| Key | Description | Default |
|---|---|---|
discovery.enabled | Enable discovery | true |
discovery.max_depth | Maximum directory depth to scan | 5 |
discovery.exclude | Directory names to skip. A pattern that would exclude everything is rejected. | See example above |
To list repositories explicitly, replace repositories = [] with entries:
[[repositories]]
name = "api-service"
path = "./services/api"
[[repositories]]
name = "shared-lib"
path = "../shared-lib"
External sources for an application
application.toml can control external sources for the application:
[external_sources]
enabled = true
agents = true
toolchain = true
When a repository joins an application with allow_app, the application's [external_sources] settings apply instead of the repository's [config.external_sources].
Troubleshooting
External sources are not loaded
Cause: External sources are disabled, a per-file toggle is false, or FORGE_DISABLE_EXTERNAL_CONFIGS is set.
Solution:
- Confirm that
project.toml(orapplication.toml) containsenabled = trueunder external sources. - Confirm that the per-file toggle is not
false. - Run
echo "$FORGE_DISABLE_EXTERNAL_CONFIGS"and unset it if needed. - Confirm that the file exists, for example
~/.config/forge/agents.toml.
Verify: frg config validate shows (User) next to the file.
Application has external_sources individual toggles set but enabled = false.
Cause: application.toml sets per-file toggles while enabled = false.
Solution:
- Set
enabled = true, or remove the per-file toggles.
No valid repositories available. Check application.toml and ensure repositories exist with correct allow_app UUID.
Cause: No repository matches the application ID, or the listed paths do not exist.
Solution:
- Copy the
idfromapplication.tomlinto each repository'sallow_app. - Confirm that each repository has
.forge/config/project.tomland is withindiscovery.max_depth. - Confirm that
discovery.excludedoes not match the repository directory. - Run
frg app discover --force.
A workflow is blocked after configuration changes
Cause: A locked configuration file changed.
Solution:
- Review the change and run
frg config validate. - Run
frg config lock.