Summary
The user config directory is resolved as a relative path first, so when the backend is started the way the docs describe (cd atlas && python main.py), config/ resolves to atlas/config/ — the package defaults. Project-root config/ overrides are never loaded.
atlas/modules/config/config_loader.py:63
candidates: List[Path] = [
config_dir / file_name, # relative to CWD
config_dir_project / file_name, # project root
package_defaults,
]
With APP_CONFIG_DIR at its default of config, the first candidate is the relative path config/mcp.json. Started from atlas/, that resolves to atlas/config/mcp.json, which exists, so it wins before the project-root candidate is considered.
Reproduction
With a config/mcp.json present at the project root:
cd atlas && ../.venv/bin/uvicorn main:app --host 127.0.0.1 --port 8000
INFO | config_loader | Found JSON config at: /path/to/atlas-ui-3/atlas/config/mcp.json
INFO | config_loader | Loaded MCP config with 10 servers: [package defaults]
The project-root override is ignored. Setting an absolute APP_CONFIG_DIR loads it correctly:
APP_CONFIG_DIR=/path/to/atlas-ui-3/config ../.venv/bin/uvicorn main:app ...
Why it matters
This contradicts two things in AGENTS.md:
- The documented two-layer configuration model, in which
config/ overrides atlas/config/.
- "NEVER modify files in
atlas/config/" and "ALWAYS use config/ (project root) for test configurations and local overrides."
Following both instructions at once produces an app that silently ignores every local override. The failure is silent: the log line names the file it loaded, but nothing indicates that an override existed and lost.
agent_start.sh may set this up correctly; the problem shows up when the backend is launched directly, which the docs also present as a supported path.
Suggested fix
Resolve a relative APP_CONFIG_DIR against the project root rather than the current working directory, or drop the CWD-relative candidate entirely. At minimum, skip the relative candidate when it resolves to the package defaults directory, and log at WARNING when a project-root override is shadowed.
Summary
The user config directory is resolved as a relative path first, so when the backend is started the way the docs describe (
cd atlas && python main.py),config/resolves toatlas/config/— the package defaults. Project-rootconfig/overrides are never loaded.atlas/modules/config/config_loader.py:63With
APP_CONFIG_DIRat its default ofconfig, the first candidate is the relative pathconfig/mcp.json. Started fromatlas/, that resolves toatlas/config/mcp.json, which exists, so it wins before the project-root candidate is considered.Reproduction
With a
config/mcp.jsonpresent at the project root:The project-root override is ignored. Setting an absolute
APP_CONFIG_DIRloads it correctly:Why it matters
This contradicts two things in
AGENTS.md:config/overridesatlas/config/.atlas/config/" and "ALWAYS useconfig/(project root) for test configurations and local overrides."Following both instructions at once produces an app that silently ignores every local override. The failure is silent: the log line names the file it loaded, but nothing indicates that an override existed and lost.
agent_start.shmay set this up correctly; the problem shows up when the backend is launched directly, which the docs also present as a supported path.Suggested fix
Resolve a relative
APP_CONFIG_DIRagainst the project root rather than the current working directory, or drop the CWD-relative candidate entirely. At minimum, skip the relative candidate when it resolves to the package defaults directory, and log at WARNING when a project-root override is shadowed.