# Configuration Resolution

CleverAgents resolves every configuration value through a **5-level precedence
chain**. The first level that supplies a non-`None` value wins.

## Resolution Order

| Priority | Source | Example |
|----------|--------|---------|
| 1 (highest) | **CLI flag** | `--format json`, `--data-dir /tmp` |
| 2 | **Environment variable** | `CLEVERAGENTS_CORE_LOG_LEVEL=WARNING` |
| 3 | **Project-scoped config** | `[project."myapp"]` table in TOML |
| 4 | **Global config file** | `~/.cleveragents/config.toml` |
| 5 (lowest) | **Built-in default** | Hardcoded in key registry |

```
$ export CLEVERAGENTS_CORE_LOG_LEVEL=WARNING
$ agents config set core.log_level DEBUG      # writes to global config
$ agents config get core.log_level
# -> WARNING  (env var at priority 2 beats global config at priority 4)
```

## Key Format

Keys use hierarchical dot-separated names. The segment before the first dot is
the **group**; everything after it is the **key name** within that group.

```
core.log.level
plan.budget.per-plan
provider.openai.api-key
```

Environment variable mapping follows the pattern
`CLEVERAGENTS_<GROUP>_<KEY>` with dots and hyphens replaced by underscores and
all characters uppercased:

- `core.log.level` → `CLEVERAGENTS_CORE_LOG_LEVEL`
- `plan.budget.per-plan` → `CLEVERAGENTS_PLAN_BUDGET_PER_PLAN`

**Exception:** `provider.*` credential keys use standard provider env vars
(see [Provider Credentials](#provider-credentials)).

## Configuration Groups

| Group | Keys | Scope | Description |
|-------|------|-------|-------------|
| `core.*` | 14 | Mixed | Core system settings — logging, data dirs, database, runtime env |
| `server.*` | 4 | Global only | Server mode — bind host, port, TLS, workers |
| `actor.*` | 5 | Mixed | Actor defaults — timeout, retry, concurrency |
| `plan.*` | 8 | Mixed | Plan execution — budget, retries, auto-apply, timeout |
| `sandbox.*` | 5 | Mixed | Sandbox and checkpointing — strategy, cleanup, max age |
| `index.*` | 12 | Mixed | Code intelligence and indexing — backend, embedding model, dimensions |
| `context.*` | 43 | **All project-scopable** | Context tier defaults — token limits, file caps, inclusion rules |
| `provider.*` | 11 | Global only | LLM provider credentials and model defaults |
| `skills.*` | 1 | Project-scopable | Agent Skills discovery paths |

**Total: 103 registered keys.**

## Project-Scopable Keys

Keys marked as project-scopable can be overridden per-project in the
`[project."<name>"]` TOML table. When a project name is active, the resolver
checks this table at priority 3 before falling back to the global value.

**Fully project-scopable groups:**

- `context.*` — all 43 keys

**Partially project-scopable groups:**

- `core.*` — `automation-profile`
- `plan.*` — `concurrency`, `max-child-depth`, `budget.per-plan`
- `sandbox.*` — `strategy`, `checkpoint.enabled`
- `skills.*` — `agent_skills_paths`

**Never project-scopable:**

- `server.*` — applies globally to the running process
- `provider.*` — credentials are always global
- `actor.*` — actor defaults are global
- `index.*` — index backends are global

### Setting project overrides

Use the `--project` flag on `config set` to store a value under the
project-scoped TOML table:

```bash
agents config set core.automation-profile manual --project my-project
agents config set plan.concurrency 16 --project my-project
```

### Reading project-scoped values

When `--project` is provided, the resolver checks the project table at
priority 3 between environment variables and the global config file:

```bash
agents config get core.automation-profile --project my-project
```

### Listing project overrides only

`config list --project <name>` shows **only** the keys that have been
explicitly overridden for that project — not the full resolved view:

```bash
agents config list --project my-project
```

### Non-scopable key rejection

Attempting to set a non-project-scopable key (e.g. `core.data-dir`) via
`--project` raises an error:

```bash
$ agents config set core.data-dir /tmp --project my-project
Error: Key 'core.data-dir' is not project-scopable.
```

## CLI Commands

### `agents config set`

```
agents config set <key> <value> [--project <name>]
```

Writes a value to the global config file (or to the project-scoped table when
`--project` is supplied). The value is coerced to the key's registered type.

### `agents config get`

```
agents config get <key> [--verbose] [--project <name>]
```

| Flag | Effect |
|------|--------|
| `--verbose` | Print the full resolution chain showing every level |
| `--project` | Resolve as if inside the named project |

Verbose output example:

```
$ agents config get core.log.level --verbose
Key:    core.log.level
Value:  INFO
Source: default

Resolution chain (highest → lowest):
  cli_flag       → (not set)
  env_var        → (not set)  [CLEVERAGENTS_CORE_LOG_LEVEL]
  project        → (not set)
  global         → (not set)  [~/.cleveragents/config.toml]
  default        → INFO       ← active
```

### `agents config list`

```
agents config list [pattern] [--filter-values] [--show-secrets] [--project <name>]
```

| Flag | Effect |
|------|--------|
| `pattern` | Glob filter on key names (e.g. `core.*`, `plan.budget.*`) |
| `--filter-values` | Only show keys whose resolved value differs from the default |
| `--show-secrets` | Unmask secret values (provider keys are masked by default) |
| `--project` | Resolve values in the context of the named project |

## TOML File Format

`~/.cleveragents/config.toml`:

```toml
[core]
log_level = "DEBUG"
data_dir  = "/var/lib/cleveragents"

[plan]
auto_apply  = true
max_retries = 5

[sandbox]
strategy = "container"

[index]
enabled         = true
backend         = "faiss"
embedding_model = "text-embedding-3-small"

# Project-scoped overrides
[project."myapp"]
core.log_level     = "WARNING"
plan.auto_apply    = false
context.max_tokens = 64000

[project."data-pipeline"]
plan.budget.per_plan = 2.50
sandbox.strategy     = "git_worktree"
```

Parent directories are created automatically on the first write.

## Provider Credentials

Provider keys use **standard provider environment variable names**, not the
`CLEVERAGENTS_*` convention. This avoids requiring users to duplicate
credentials under a project-specific prefix.

| Key | Environment Variable |
|-----|---------------------|
| `provider.openai.api-key` | `OPENAI_API_KEY` |
| `provider.anthropic.api-key` | `ANTHROPIC_API_KEY` |
| `provider.google.api-key` | `GOOGLE_API_KEY` |
| `provider.azure.api-key` | `AZURE_OPENAI_API_KEY` |
| `provider.default-provider` | `CLEVERAGENTS_PROVIDER_DEFAULT_PROVIDER` |
| `provider.default-model` | `CLEVERAGENTS_PROVIDER_DEFAULT_MODEL` |
| `provider.temperature` | `CLEVERAGENTS_PROVIDER_TEMPERATURE` |

Provider credential values are **masked** in `config list` output by default.
Use `--show-secrets` to reveal them.

## Validation

- **Unknown keys** produce an actionable error listing valid keys.
- **Type mismatches** raise `TypeError` with the expected type and actual value.
- Boolean coercion accepts `true`/`false`, `1`/`0`, `yes`/`no` (case-insensitive).
