85 lines
3.9 KiB
Markdown
85 lines
3.9 KiB
Markdown
# ADR 0018: Apply CLI Overrides After Inheritance and Decoding
|
|
|
|
## Status
|
|
|
|
Accepted.
|
|
|
|
This supersedes the rule that CLI overrides apply before decoding in
|
|
[ADR 0005](0005-explicit-overrides-and-safe-explanation.md) and the
|
|
rule that they apply before inheritance in [ADR 0009](0009-sibling-inheritance.md).
|
|
Their remaining ownership, inheritance scope, and safe inspection decisions
|
|
continue to apply.
|
|
|
|
## Date
|
|
|
|
2026-10-22
|
|
|
|
## Context
|
|
|
|
Explicit command-line values are the operator's highest-priority input. If they
|
|
apply before inheritance, a sequence supplied as a replacement could gain
|
|
inherited records afterward. Its final contents would then differ from the
|
|
operator's assignment.
|
|
|
|
The application also needs these values when it fills missing settings,
|
|
normalizes values, or computes derived settings. ConfigKit needs a clear loading
|
|
order that preserves both CLI precedence and the application's role in resolving
|
|
the final configuration.
|
|
|
|
## Decision
|
|
|
|
ConfigKit uses this loading order:
|
|
|
|
1. Combine sources within tiers and apply precedence between layers.
|
|
2. Resolve sibling inheritance, apply typed defaults, and decode the configuration
|
|
into the application's types.
|
|
3. Apply explicit CLI overrides and check them against the application schema.
|
|
4. Run application resolution using the overridden configuration.
|
|
5. Look up effective secret references, validate the final configuration, and
|
|
return it.
|
|
|
|
CLI overrides are the highest-priority input to application resolution. A CLI
|
|
sequence replaces the whole sequence; mappings combine recursively. Collection
|
|
merge rules apply during the earlier source and inheritance steps. Inheritance
|
|
and typed defaulting do not run again after CLI overrides.
|
|
|
|
Keep track of which values were explicitly supplied and which CLI input supplied
|
|
them. Applications continue to parse command-line arguments; ConfigKit applies
|
|
and validates the overrides and makes their effects inspectable. Reject
|
|
structural directives in override paths and values, so instructions such as
|
|
inheritance relationships remain part of source processing.
|
|
|
|
Application resolution keeps its existing rules for defaults and recorded
|
|
changes under [ADR 0003](0003-preserve-presence-and-resolution-history.md).
|
|
It receives CLI values together with their presence and source information.
|
|
Defaults that only fill missing settings preserve explicit CLI values.
|
|
Application normalization and derived-value calculations can still change them,
|
|
with those changes recorded. Secret lookup and final validation use the resulting
|
|
configuration.
|
|
|
|
## Alternatives Considered
|
|
|
|
- **Apply CLI overrides before inheritance.** Preserves existing ordering, but
|
|
later merging needs special handling to preserve CLI replacement intent while
|
|
still combining ordinary source contributions.
|
|
- **Apply CLI overrides after inheritance but before typed decoding.** Allows an
|
|
override to fix a source value that would otherwise fail decoding, but leaves
|
|
typed defaulting after the operator's assignment. Completing defaulting and
|
|
decoding first gives CLI overrides an already resolved configuration to modify.
|
|
- **Apply CLI overrides after application resolution.** Applies assignments after
|
|
the application's changes, but derived settings still reflect earlier values
|
|
unless resolution runs again.
|
|
|
|
## Consequences
|
|
|
|
CLI overrides change a configuration whose inheritance and typed defaults are
|
|
already resolved. The application can then derive settings from the operator's
|
|
values. The final values, source information, history, and sensitivity handling
|
|
must remain consistent throughout loading.
|
|
|
|
CLI input can no longer add or cancel inheritance relationships or bypass an
|
|
earlier error in source assembly or inheritance. It also cannot fix a value that
|
|
fails the earlier decoding step. Semantic validation still runs after overrides
|
|
and application resolution. The [configuration contract](../config.md#explicit-cli-overrides)
|
|
and [consumer guidance](../consumers/README.md) describe this behavior.
|