11. XDG as default config location; CORTEX_PATH becomes a legacy fallback
Date: 2026-06-06
Status
Accepted. Supersedes the implicit decision in 0007: TOML configuration format (which assumed CORTEX_PATH would point at the config).
Context
The cerebro CLI and TUI load config.toml via this priority:
CORTEX_PATH env var > --config CLI flag > XDG config dir > ./config.toml
That ordering made CORTEX_PATH the de-facto requirement: a user who didn’t set it would either find an XDG config (if one happened to exist) or fail. The README and onboarding docs reflected this by instructing users to “place config.toml in your cortex” — i.e., the directory pointed to by CORTEX_PATH.
In practice, this means the user had to:
- Decide on a cortex location.
- Set
CORTEX_PATHin their shell rc. - Restart the shell.
- Only then would the binary find the config.
If any step was missed, the binary either picked up an unintended file (the ./config.toml fallback) or errored out. The MCP server kept working because it falls back to ~/Projects/cortex, but the CLI/TUI did not — they sat silently on an absent config.
The principle of least surprise: a freshly installed tool should not require environment variables to do its job. The XDG base-directory spec already gives us a sensible default: $XDG_CONFIG_HOME/cerebro/config.toml, falling back to $HOME/.config/cerebro/config.toml when XDG_CONFIG_HOME is unset. The same path works on every platform, which avoids the surprise of dirs::config_dir() returning ~/Library/Application Support on macOS for users coming from Linux. The CORTEX_PATH mechanism was solving two unrelated problems at once (where is my config, where is my data) and the conflation was the source of the confusion.
Decision
The CLI and TUI (cerebro, cerebro-tui) use this new resolution order:
--config <path>CLI flag — explicit override, always wins.- XDG config dir (
$XDG_CONFIG_HOME/cerebro/config.toml, or$HOME/.config/cerebro/config.tomlifXDG_CONFIG_HOMEis unset) — the default. Users who do nothing get this. Same path on every platform. CORTEX_PATHenv var — legacy fallback. If a user already hasCORTEX_PATHpointing at a directory that containsconfig.toml, it still works../config.tomlin the current working directory — last-resort fallback (unchanged).
The MCP server (cerebro-mcp) is unchanged: it still uses CORTEX_PATH to locate the cortex data directory (where generated content/ lives) and falls back to ~/Projects/cortex. This is a separate concern from config and was never the source of confusion.
crates/cerebro/src/main.rs::resolve_config_path and crates/cerebro-tui/src/bin/cerebro-tui.rs::resolve_config_path both implement the new priority. Integration tests in crates/cerebro/tests/integration.rs now pass --config explicitly so they don’t pick up a developer’s real XDG config from their machine.
Consequences
Pros
- New users: install, run
cerebro build, it reads the XDG default. No env vars required. - Existing users with
CORTEX_PATHset: still work via fallback #3. - Power users / scripted runs:
--configalways wins, no surprises. CORTEX_PATHis now documented for what it is: a data-directory pointer used by the MCP server, not a config prerequisite.
Cons
- A user with both an XDG config and
CORTEX_PATHset to a different cortex will silently get the XDG config. This is the desired behavior, but it meansCORTEX_PATHno longer “wins” — release notes should call this out. - Tests now depend on
--configbeing passed; future test authors must remember to do so. The existing integration tests were updated as part of this change. - The example
config.tomlin the README was reworked; any external tutorials/screenshots showing the old “put it in your cortex” pattern are stale.
Migration
For users currently relying on CORTEX_PATH to point at their config:
# Old: config was at $CORTEX_PATH/config.toml
# New: move it to the XDG location
mv "$CORTEX_PATH/config.toml" ~/.config/cerebro/config.toml
# CORTEX_PATH can stay set (MCP still uses it) or be unset if you accept the default
For users with no config at all, run cerebro build once after install and follow the “config not found” error message — it points at the XDG path.
Notes
- The
dirscrate handleshome_dir(); we readXDG_CONFIG_HOMEourselves with$HOME/.configas the fallback so the resolution is identical on every platform. We intentionally do NOT usedirs::config_dir(), which on macOS returns~/Library/Application Supportand would surprise users coming from Linux. - The integration tests previously relied on
CORTEX_PATHfor config; they now pass--configexplicitly. Unit tests inmain.rs::testswere already structured to not depend on a real XDG config and required no changes. - The MCP server’s use of
CORTEX_PATHis intentionally not touched — it serves a different purpose (data dir, not config).