Caveman Configuration Resolution Order: How Default Modes Are Determined
Caveman resolves its default mode through a four-tier priority chain: environment variables override repo-local configs, which override user-level configs, with a built-in fallback to "full" mode.
The JuliusBrussee/caveman project implements a deterministic configuration system that determines which operation mode (off, lite, full, ultra, etc.) the tool uses at startup. Understanding the Caveman configuration resolution order is essential for managing different behaviors across local development, CI/CD pipelines, and personal workstations.
The Four-Tier Resolution Hierarchy
1. Environment Variable (Highest Priority)
Caveman checks the CAVEMAN_DEFAULT_MODE environment variable first. If set to a valid mode—such as off, lite, full, or ultra—this value wins outright regardless of any configuration files present.
2. Repository-Local Configuration
If no environment variable is set, Caveman searches for repo-local settings by walking up the directory tree from the current working directory. It looks for .caveman/config.json or .caveman.json in each directory until reaching the filesystem root. The first file found containing a valid defaultMode field determines the behavior.
3. User-Level Configuration File
When neither environment variables nor repo-local configs are present, Caveman checks per-user defaults. On Unix-like systems, it reads $XDG_CONFIG_HOME/caveman/config.json (or ~/.config/caveman/config.json if XDG_CONFIG_HOME is unset). On Windows, it checks %APPDATA%\caveman\config.json.
4. Built-in Fallback Default
If all preceding sources fail to yield a valid mode, Caveman defaults to "full" mode as the safe baseline.
Core Implementation in src/hooks/caveman-config.js
The resolution logic is implemented in src/hooks/caveman-config.js, specifically within the getDefaultMode() function. This module also defines VALID_MODES to ensure only accepted strings are recognized:
function getDefaultMode() {
// 1️⃣ env var
const envMode = process.env.CAVEMAN_DEFAULT_MODE;
if (envMode && VALID_MODES.includes(envMode.toLowerCase())) {
return envMode.toLowerCase();
}
// 2️⃣ repo‑local config
const repoConfigPath = findRepoConfigPath(process.cwd());
if (repoConfigPath) {
const repoMode = readModeFromConfigFile(repoConfigPath);
if (repoMode) return repoMode;
}
// 3️⃣ user config
const userMode = readModeFromConfigFile(getConfigPath());
if (userMode) return userMode;
// 4️⃣ fallback
return 'full';
}
The helper functions findRepoConfigPath() and readModeFromConfigFile() handle the directory traversal and JSON parsing, while getConfigPath() determines the appropriate user-level directory based on platform conventions. The test suite in tests/test_repo_local_config.js verifies this hierarchy, ensuring that environment variables correctly override file-based configurations.
Practical Configuration Examples
Override with Environment Variable
Set the mode for a single invocation without modifying any files:
CAVEMAN_DEFAULT_MODE=lite caveman run
Project-Specific Defaults
Create .caveman/config.json in your project root to ensure all team members use the same mode:
{
"defaultMode": "commit"
}
Running caveman from anywhere inside the project directory tree will start in commit mode unless overridden by the environment variable.
Personal Defaults
Configure your user-level file at ~/.config/caveman/config.json (Linux/macOS) or %APPDATA%\caveman\config.json (Windows):
{
"defaultMode": "review"
}
Fallback Behavior
Without any configuration, Caveman automatically uses "full" mode:
caveman status # Executes in "full" mode
Summary
- Environment variables take precedence:
CAVEMAN_DEFAULT_MODEoverrides all other sources. - Repo-local configs are priority two: Files named
.caveman/config.jsonor.caveman.jsonin the project hierarchy apply next. - User-level configs provide personal defaults: Located in XDG config directories or Windows AppData.
- Safe fallback: The built-in default is
"full"mode when no other configuration exists. - Source location: The
getDefaultMode()function insrc/hooks/caveman-config.jsimplements this hierarchy.
Frequently Asked Questions
What is the Caveman configuration resolution order?
Caveman resolves configuration through a strict four-level hierarchy: environment variables (CAVEMAN_DEFAULT_MODE) are checked first, followed by repository-local config files (.caveman/config.json or .caveman.json), then user-level config files (~/.config/caveman/config.json or %APPDATA%\caveman\config.json), and finally falls back to the built-in default of "full" mode.
Where does Caveman look for repository-local configuration?
Caveman searches for .caveman/config.json or .caveman.json starting from the current working directory and walking upward through parent directories until reaching the filesystem root. The first valid file encountered in this traversal determines the configuration.
How do I set a system-wide default mode for Caveman?
Set the CAVEMAN_DEFAULT_MODE environment variable in your shell profile or system environment settings. Alternatively, create a user-level config file at ~/.config/caveman/config.json on Unix systems or %APPDATA%\caveman\config.json on Windows to apply defaults across all projects that lack repo-specific configurations.
What happens if I specify an invalid mode in my config file?
Invalid mode values are ignored during the resolution process. If a config file contains an invalid defaultMode, Caveman continues to the next level in the hierarchy. If no valid mode is found throughout the entire chain, the tool defaults to "full" mode.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →