How TOML Configuration Resolution Order Works in DeepSeek-Reasonix: Flag → Project → User → Defaults
DeepSeek-Reasonix resolves configuration values through a strict four-layer hierarchy where command-line flags override project-level TOML files, which override user-level settings, which finally override built-in defaults.
The esengine/DeepSeek-Reasonix project implements a cascading TOML configuration resolution order to determine runtime behavior. This precedence system ensures that local project requirements take priority over user preferences, while CLI arguments remain the ultimate authority for temporary overrides.
Understanding the Four Configuration Layers
The resolution logic is explicitly documented in the package comment at the top of internal/config/config.go:
// Package config loads Reasonix's runtime configuration from TOML. Resolution order: flag > project ./reasonix.toml > user config.toml (in the OS user‑config dir) > built‑in defaults.
Each layer is applied sequentially, with later sources overwriting earlier ones.
Layer 1: Built-in Defaults
The foundation starts with config.Default(), defined near the end of internal/config/config.go. This function returns a fully populated Config struct containing sensible defaults for all settings, including the default model and sandbox configurations.
Layer 2: User-Level Configuration
Next, config.UserConfigPath() resolves the per-user configuration file, typically located at $XDG_CONFIG_HOME/reasonix/config.toml or ~/.config/reasonix/config.toml on Unix systems. If this file exists, its contents are decoded and merged on top of the built-in defaults, replacing any keys that are explicitly set.
Layer 3: Project-Level Configuration
Then config.ProjectConfigPath() searches for a ./reasonix.toml file in the current working directory (or parent project directories). If present, these values override both the user configuration and the defaults, allowing projects to enforce specific team settings.
Layer 4: Command-Line Flags
Finally, flags parsed in cmd/reasonix/main.go (such as --model, --workspace_root, or --sandbox.bash=off) are applied. According to the source in internal/config/load.go, this happens after the LoadForEdit step, ensuring flag values have the highest precedence and override any conflicting entries from project or user files.
How the Merge Logic Works in Code
The actual merging implementation resides in internal/config/load.go. The config.Load() function orchestrates the entire resolution sequence:
- Initialize with
config.Default() - Merge user config if
config.UserConfigPath()exists - Merge project config if
config.ProjectConfigPath()exists - Inject CLI flag values last
Because each layer overwrites the previous, the final Config object visible to the running Reasonix process always reflects the highest-priority source that supplied a given key.
Practical Code Examples
Loading the Effective Configuration
Call config.Load() from your entry point to trigger the full resolution chain:
// Load the configuration (called by the CLI in internal/serve/serve.go)
cfg, err := config.Load() // ← defaults ↔ user ↔ project ↔ flags
if err != nil {
log.Fatalf("failed to load config: %v", err)
}
// Example: a flag overrides project config
// $ reasonix --workspace_root=/tmp/workspace
// Project file contains: [sandbox]\nworkspace_root = "./myproject"
fmt.Println("Effective workspace root:", cfg.Sandbox.WorkspaceRoot)
// → prints "/tmp/workspace"
Inspecting Individual Layers
You can examine each configuration layer separately for debugging:
// Manually inspect each layer
def := config.Default()
user, _ := config.LoadUser() // reads only the user file
proj, _ := config.LoadProject() // reads only the project file
fmt.Printf("Default model: %s\n", def.DefaultModel)
fmt.Printf("User model: %s\n", user.DefaultModel) // may be empty → falls back to default
fmt.Printf("Project model: %s\n", proj.DefaultModel) // overrides user if set
Summary
- TOML configuration resolution order follows a strict precedence: command-line flags > project
./reasonix.toml> userconfig.toml> built-in defaults. - Source of truth for this hierarchy is documented in the package comment at
internal/config/config.golines 1-3 and implemented ininternal/config/load.go. - User configuration typically resides in
$XDG_CONFIG_HOME/reasonix/config.tomland is merged after defaults but before project settings. - Project configuration via
./reasonix.tomlallows repository-specific overrides that apply to all team members. - CLI flags parsed in
cmd/reasonix/main.goreceive the highest priority, ensuring temporary overrides always succeed.
Frequently Asked Questions
What is the exact TOML configuration resolution order in Reasonix?
The resolution order is strictly flag > project > user > defaults. This means command-line flags override project-level TOML files, which override user-level configuration files, which finally override the built-in defaults returned by config.Default().
How do I override a project config setting temporarily?
Use command-line flags when invoking the Reasonix binary. For example, if ./reasonix.toml sets workspace_root = "./myproject", you can override it with reasonix --workspace_root=/tmp/workspace. Flags are applied last in config.Load(), ensuring they take precedence over file-based configurations.
Where does Reasonix look for user-level configuration?
According to config.UserConfigPath() in internal/config/config.go, Reasonix searches for a config.toml file in the OS user-config directory, typically $XDG_CONFIG_HOME/reasonix/config.toml or ~/.config/reasonix/config.toml on Unix systems. This file is optional and only overrides the built-in defaults if present.
What happens if a configuration key is missing from the project file?
When a key is absent from ./reasonix.toml, the resolution falls back to the next layer in the hierarchy. The system first checks the user config file, then finally uses the value from config.Default(). Only explicitly set keys at each layer override the values inherited from lower-priority sources.
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 →