# How TOML Configuration Resolution Order Works in DeepSeek-Reasonix: Flag → Project → User → Defaults

> Understand TOML configuration resolution order in DeepSeek-Reasonix. Learn how flags, project, user, and default settings interact to define your configurations.

- Repository: [YHH/DeepSeek-Reasonix](https://github.com/esengine/DeepSeek-Reasonix)
- Tags: how-to-guide
- Published: 2026-06-22

---

**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`](https://github.com/esengine/DeepSeek-Reasonix/blob/main/internal/config/config.go):

```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`](https://github.com/esengine/DeepSeek-Reasonix/blob/main/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`](https://github.com/esengine/DeepSeek-Reasonix/blob/main/./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`](https://github.com/esengine/DeepSeek-Reasonix/blob/main/cmd/reasonix/main.go) (such as `--model`, `--workspace_root`, or `--sandbox.bash=off`) are applied. According to the source in [`internal/config/load.go`](https://github.com/esengine/DeepSeek-Reasonix/blob/main/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`](https://github.com/esengine/DeepSeek-Reasonix/blob/main/internal/config/load.go). The `config.Load()` function orchestrates the entire resolution sequence:

1. **Initialize** with `config.Default()`
2. **Merge** user config if `config.UserConfigPath()` exists
3. **Merge** project config if `config.ProjectConfigPath()` exists
4. **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:

```go
// 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:

```go
// 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`](https://github.com/esengine/DeepSeek-Reasonix/blob/main/./reasonix.toml) > user [`config.toml`](https://github.com/esengine/DeepSeek-Reasonix/blob/main/config.toml) > built-in defaults.
- **Source of truth** for this hierarchy is documented in the package comment at [`internal/config/config.go`](https://github.com/esengine/DeepSeek-Reasonix/blob/main/internal/config/config.go) lines 1-3 and implemented in [`internal/config/load.go`](https://github.com/esengine/DeepSeek-Reasonix/blob/main/internal/config/load.go).
- **User configuration** typically resides in `$XDG_CONFIG_HOME/reasonix/config.toml` and is merged after defaults but before project settings.
- **Project configuration** via [`./reasonix.toml`](https://github.com/esengine/DeepSeek-Reasonix/blob/main/./reasonix.toml) allows repository-specific overrides that apply to all team members.
- **CLI flags** parsed in [`cmd/reasonix/main.go`](https://github.com/esengine/DeepSeek-Reasonix/blob/main/cmd/reasonix/main.go) receive 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`](https://github.com/esengine/DeepSeek-Reasonix/blob/main/./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`](https://github.com/esengine/DeepSeek-Reasonix/blob/main/internal/config/config.go), Reasonix searches for a [`config.toml`](https://github.com/esengine/DeepSeek-Reasonix/blob/main/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`](https://github.com/esengine/DeepSeek-Reasonix/blob/main/./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.