feat(config): implement three-scope config resolution with local config file support #937

Closed
opened 2026-03-14 01:16:25 +00:00 by freemo · 1 comment
Owner

Background and Context

The specification defines a three-scope configuration system (spec §Configuration, §Architecture > Configuration): global (~/.config/cleveragents/config.toml), project (<project-root>/config.toml), and local (<project-root>/config.local.toml). Resolution follows local > project > global precedence with deep merge. The local scope is intended for developer-specific overrides that are .gitignored.

The current implementation in src/cleveragents/config/settings.py and src/cleveragents/application/services/config_service.py only supports 2 scopes (global + project). The local scope and config.local.toml file are completely missing. Additionally, project-root config discovery (walking up the directory tree to find the nearest project root) is not implemented — the code uses a fixed path.

Affected files

  • src/cleveragents/config/settings.pyConfigScope enum, ConfigSettings loader
  • src/cleveragents/application/services/config_service.pyConfigService scope resolution
  • src/cleveragents/cli/commands/config_commands.py — CLI config commands need --scope local support

Expected Behavior

Configuration must resolve across three scopes (local > project > global) with deep merge. config.local.toml must be auto-discovered alongside config.toml in the project root. The config set --scope local command must work.

Acceptance Criteria

  • ConfigScope enum includes LOCAL alongside GLOBAL and PROJECT
  • config.local.toml auto-discovered in project root directory
  • Three-scope deep merge: local > project > global
  • Project-root discovery walks up directory tree from CWD
  • config set --scope local writes to config.local.toml
  • config get resolves values with correct precedence
  • config list shows effective merged config with source annotations
  • Default .gitignore template includes config.local.toml

Metadata

  • Commit message: feat(config): implement three-scope config resolution with local config file support
  • Branch: feature/config-three-scope-resolution
  • Parent Epic: None (standalone feature — no uncovered Epic yet)
  • Blocks: None
  • Blocked by: None

Subtasks

  • Add LOCAL to ConfigScope enum
  • Implement project-root discovery (walk up from CWD looking for cleveragents.toml or .cleveragents/)
  • Implement config.local.toml file loading in ConfigSettings
  • Implement three-scope deep merge in ConfigService
  • Update CLI config set --scope to accept local
  • Update CLI config list to show source annotations per key
  • Add config.local.toml to default .gitignore template in init command
  • Tests (Behave): Add scenarios for three-scope resolution
  • Tests (Unit): Add tests for project-root discovery
  • Verify coverage >=97% via nox -s coverage_report
  • Run nox (all default sessions), fix any errors

Definition of Done

This issue is complete when the configuration system resolves across all three scopes with correct precedence, config.local.toml is auto-discovered, and all CLI config commands support the local scope.

## Background and Context The specification defines a three-scope configuration system (spec §Configuration, §Architecture > Configuration): **global** (`~/.config/cleveragents/config.toml`), **project** (`<project-root>/config.toml`), and **local** (`<project-root>/config.local.toml`). Resolution follows `local > project > global` precedence with deep merge. The local scope is intended for developer-specific overrides that are `.gitignore`d. The current implementation in `src/cleveragents/config/settings.py` and `src/cleveragents/application/services/config_service.py` only supports **2 scopes** (global + project). The `local` scope and `config.local.toml` file are completely missing. Additionally, project-root config discovery (walking up the directory tree to find the nearest project root) is not implemented — the code uses a fixed path. ### Affected files - `src/cleveragents/config/settings.py` — `ConfigScope` enum, `ConfigSettings` loader - `src/cleveragents/application/services/config_service.py` — `ConfigService` scope resolution - `src/cleveragents/cli/commands/config_commands.py` — CLI `config` commands need `--scope local` support ## Expected Behavior Configuration must resolve across three scopes (`local > project > global`) with deep merge. `config.local.toml` must be auto-discovered alongside `config.toml` in the project root. The `config set --scope local` command must work. ## Acceptance Criteria - [ ] `ConfigScope` enum includes `LOCAL` alongside `GLOBAL` and `PROJECT` - [ ] `config.local.toml` auto-discovered in project root directory - [ ] Three-scope deep merge: `local > project > global` - [ ] Project-root discovery walks up directory tree from CWD - [ ] `config set --scope local` writes to `config.local.toml` - [ ] `config get` resolves values with correct precedence - [ ] `config list` shows effective merged config with source annotations - [ ] Default `.gitignore` template includes `config.local.toml` ## Metadata - **Commit message**: `feat(config): implement three-scope config resolution with local config file support` - **Branch**: `feature/config-three-scope-resolution` - **Parent Epic**: None (standalone feature — no uncovered Epic yet) - **Blocks**: None - **Blocked by**: None ## Subtasks - [ ] Add `LOCAL` to `ConfigScope` enum - [ ] Implement project-root discovery (walk up from CWD looking for `cleveragents.toml` or `.cleveragents/`) - [ ] Implement `config.local.toml` file loading in `ConfigSettings` - [ ] Implement three-scope deep merge in `ConfigService` - [ ] Update CLI `config set --scope` to accept `local` - [ ] Update CLI `config list` to show source annotations per key - [ ] Add `config.local.toml` to default `.gitignore` template in `init` command - [ ] Tests (Behave): Add scenarios for three-scope resolution - [ ] Tests (Unit): Add tests for project-root discovery - [ ] Verify coverage >=97% via `nox -s coverage_report` - [ ] Run `nox` (all default sessions), fix any errors ## Definition of Done This issue is complete when the configuration system resolves across all three scopes with correct precedence, `config.local.toml` is auto-discovered, and all CLI config commands support the local scope.
freemo added the
Points
5
Priority
Medium
State
Verified
Type
Feature
labels 2026-03-14 01:18:13 +00:00
freemo added this to the v3.5.0 milestone 2026-03-14 01:18:22 +00:00
CoreRasurae was assigned by freemo 2026-03-14 04:27:13 +00:00
CoreRasurae was unassigned by freemo 2026-03-29 02:30:30 +00:00
freemo self-assigned this 2026-03-29 02:30:31 +00:00
freemo added
State
In Progress
and removed
State
Verified
labels 2026-03-29 02:30:41 +00:00
Author
Owner

Implementation submitted in PR #1195.

What was implemented:

  • ConfigScope enum with GLOBAL, PROJECT, LOCAL values
  • ConfigLevel.LOCAL added to precedence chain between ENV_VAR and PROJECT
  • discover_project_root() — walks up from CWD looking for cleveragents.toml or .cleveragents/
  • config.local.toml file loading via read_local_config()
  • Three-scope deep merge: local > project > global via _deep_merge() and read_merged_config()
  • CLI config set --scope local|project|global support
  • config.local.toml added to .gitignore and DEFAULT_IGNORE_PATTERNS
  • 18 Behave BDD scenarios for three-scope resolution

Nox results:

  • lint: pass
  • format: pass
  • typecheck (pyright): 0 errors, 0 warnings
  • build: pass
  • security_scan: pass
  • dead_code: pass
  • complexity: pass
  • unit_tests (behave): pre-existing hang in step-definition loading (regex performance issue in behave's parse matcher — affects all features, not specific to this PR)
Implementation submitted in PR #1195. ### What was implemented: - `ConfigScope` enum with `GLOBAL`, `PROJECT`, `LOCAL` values - `ConfigLevel.LOCAL` added to precedence chain between `ENV_VAR` and `PROJECT` - `discover_project_root()` — walks up from CWD looking for `cleveragents.toml` or `.cleveragents/` - `config.local.toml` file loading via `read_local_config()` - Three-scope deep merge: `local > project > global` via `_deep_merge()` and `read_merged_config()` - CLI `config set --scope local|project|global` support - `config.local.toml` added to `.gitignore` and `DEFAULT_IGNORE_PATTERNS` - 18 Behave BDD scenarios for three-scope resolution ### Nox results: - lint: pass - format: pass - typecheck (pyright): 0 errors, 0 warnings - build: pass - security_scan: pass - dead_code: pass - complexity: pass - unit_tests (behave): pre-existing hang in step-definition loading (regex performance issue in behave's parse matcher — affects all features, not specific to this PR)
freemo added
State
In Review
and removed
State
In Progress
labels 2026-03-29 09:31:02 +00:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: cleveragents/cleveragents-core#937