# ADR-RGC-001: Global Config Cascade Strategy

## Status

Accepted

## Context

nWave rigor profiles are persisted in `.nwave/des-config.json` at the project level. Developers working across multiple projects (3-5 repos daily) must run `/nw:rigor` in every new project to configure their preferred quality settings. This is repetitive and error-prone.

The system needs a global configuration layer that applies a user's rigor preferences across all projects, while still allowing per-project overrides for specific repos (e.g., "lean" for documentation-only projects).

### Requirements

- A single global rigor preference that applies to all projects
- Per-project override capability
- Silent, graceful handling of missing or corrupted global config
- No behavioral change for users who never set a global config
- Testable (injectable paths for unit tests)

### Design Constraints

- DESConfig is a driven adapter in hexagonal architecture (read-only for config)
- The `_rigor()` method is the single access point for all rigor_* properties
- Global config path must be injectable (constructor parameter) for testability
- FP-preferred paradigm: pure resolution logic, side effects at boundaries

## Decision

Implement a full-block cascade resolution in DESConfig with three levels:

1. **Project**: `.nwave/des-config.json` rigor key (highest precedence)
2. **Global**: `~/.nwave/global-config.json` rigor key (fallback)
3. **Defaults**: Hardcoded standard profile values (lowest precedence)

Resolution is full-block override: if the project config contains a `rigor` key at all, the entire global rigor block is ignored. No per-field merging occurs. The global config file uses the same JSON schema as the project config (a complete `des-config.json` format, not a rigor-only schema).

The global config path defaults to `Path.home() / ".nwave" / "global-config.json"` and is injectable via the DESConfig constructor for testing.

## Alternatives Considered

### Alternative 1: Per-Field Merge

Project and global configs merged at the field level: project's `agent_model` overrides global's `agent_model`, but global's `reviewer_model` applies if project doesn't specify it.

**Evaluation**: Provides finer granularity. However, creates confusing behavior when a user sets rigor to "lean" in a project (expecting 2-phase TDD) but inherits `double_review: true` from their global "thorough" profile. The profile name would say "lean" but behavior would be a hybrid. Debugging this would require inspecting two files and understanding field-level merge rules.

**Rejected because**: Complexity outweighs benefit. The rigor profile is designed as a cohesive unit (7 fields that work together). Per-field merge breaks the profile abstraction and creates invisible hybrid states.

### Alternative 2: Environment Variable Override

Use environment variables (e.g., `NW_RIGOR_PROFILE=thorough`) for global preferences instead of a config file.

**Evaluation**: Works for CI/CD and shell-based workflows. Simple to implement. However, requires users to configure shell RC files, doesn't persist structured data well (7 rigor fields would need 7 env vars or JSON-in-env-var), and diverges from the existing config-file pattern used by DESConfig for other settings.

**Rejected because**: Inconsistent with existing config patterns. Env vars suit boolean overrides (like `DES_AUDIT_LOGGING_ENABLED`) but not structured config blocks. The rigor block has 7 interdependent fields.

### Alternative 3: XDG Base Directory Specification

Use `$XDG_CONFIG_HOME/nwave/global-config.json` (defaults to `~/.config/nwave/`) following the XDG spec.

**Evaluation**: Standards-compliant on Linux. However, XDG is not a convention on macOS (where `~/Library/Preferences/` is standard) or Windows (where `%APPDATA%` is standard). nWave already uses `~/.claude/` for its installation (not XDG-compliant), and Claude Code itself uses `~/.claude/`. Adding XDG support for one config file while the rest of the system ignores XDG creates inconsistency.

**Rejected because**: Inconsistent with the rest of the nWave/Claude Code ecosystem. `~/.nwave/` is a simple, predictable, cross-platform convention that parallels `~/.claude/`.

## Consequences

### Positive

- Zero friction for multi-project users: set rigor once globally, never run `/nw:rigor` in new projects
- Full backward compatibility: users who never set global config see zero behavioral change
- Simple mental model: "project wins, then global, then defaults"
- Single modification point in DESConfig (`_rigor()` method)
- Testable via constructor injection of `global_config_path`

### Negative

- Cannot mix global and project rigor fields (full-block override means no partial inheritance)
- Adds a second file read to DESConfig initialization (mitigated: only reads global when project has no rigor key)
- Users must understand the cascade order to debug unexpected rigor behavior
- `~/.nwave/` directory is a new convention that exists outside the project (user-level artifact)
