Add safe historical configuration explanations
This commit is contained in:
@@ -916,7 +916,9 @@ the [current redaction contract](../config.md#secret-classification-and-effectiv
|
||||
`Result.Config`, `Metadata`, `Sources`, `Diagnostics`, and `WriteEffective`, together
|
||||
with `LoadError` and `WriteDiagnostics`, are implemented at the current loading boundary.
|
||||
The [current loading contract](../config.md#single-source-loading) and Go reference
|
||||
comments own their behavior. Historical-value explanation below remains target work.
|
||||
comments own their behavior. Historical-value explanation is also implemented and
|
||||
owned by the
|
||||
[current explanation contract](../config.md#historical-value-explanation).
|
||||
|
||||
```go
|
||||
type Result[T any] struct {
|
||||
@@ -976,74 +978,14 @@ func InspectPipeline(path, profile string, output io.Writer) error {
|
||||
|
||||
Applications can use `Metadata().Lookup`, `Metadata().History`, and `Sources()`
|
||||
for structured inspection without implementing value rendering or importing a
|
||||
parser. The explanation API below supplies safe values and formatting for application-owned
|
||||
`config explain` commands.
|
||||
parser. The implemented explanation API supplies safe values and formatting for
|
||||
application-owned `config explain` commands.
|
||||
|
||||
### Historical-value explanation
|
||||
|
||||
```go
|
||||
func (r *Result[T]) Explain(path Path) (Explanation, bool)
|
||||
func (r *Result[T]) WriteExplanation(output io.Writer, path Path) error
|
||||
|
||||
type Explanation struct {
|
||||
Path Path
|
||||
Effective ValueSnapshot
|
||||
Origin Origin
|
||||
History []ValueChange
|
||||
SecretReference *SecretReferenceInfo
|
||||
}
|
||||
type ValueSnapshot struct {
|
||||
Present bool
|
||||
Redacted bool
|
||||
YAML string
|
||||
}
|
||||
type ValueChange struct {
|
||||
Before, After ValueSnapshot
|
||||
Origin Origin
|
||||
Reasons []string
|
||||
Dependencies []Path
|
||||
}
|
||||
type SecretReferenceInfo struct { Name string } // successful resolved lookup
|
||||
```
|
||||
|
||||
Snapshots contain detached deterministic YAML text, never `any`, parser objects,
|
||||
or mutable internal trees. `Present=false` is absence/deletion and has empty YAML;
|
||||
null is present with `null` YAML. Redacted snapshots use the quoted marker
|
||||
`[REDACTED]`; `Redacted` also marks containers containing redacted descendants.
|
||||
Apply the same historical sensitivity/dependency closure as effective rendering
|
||||
before exposing any snapshots. A `Secret` projects only its environment name;
|
||||
its resolved value is never captured, even privately as history. For classified
|
||||
reference paths omit `SecretReference` as well as masking the projected name.
|
||||
|
||||
Retain private persistent node snapshots or operation deltas with structural
|
||||
sharing; do not copy the entire tree for every changed leaf. Explain a known final
|
||||
or historical path, including removed paths; unknown paths return false, and the
|
||||
writer returns a safe unknown-path error without output. Malformed query paths
|
||||
also fail safely. Render the canonical JSON-pointer path, effective value/source,
|
||||
and chronological history: initial application-default (or Go-zero baseline),
|
||||
base contributions in traversal order, profile, CLI, and recorded domain changes.
|
||||
Include before/after values for changed or explicitly redefined paths, equal-value
|
||||
writes, removals, reasons/dependencies, and composite origins. Inputs overridden
|
||||
before decoding retain policy-validated node values even when they would not fit
|
||||
the final Go type. Defaults/final/domain snapshots use canonical typed projection;
|
||||
label those representations rather than claiming every historical input was typed.
|
||||
|
||||
Container queries reconstruct the value at each relevant operation; descendant
|
||||
queries include ancestor replacement/removal and whole-sequence replacements,
|
||||
without implying element-wise sequence merging. Omitted fields/default retention
|
||||
must agree with the presence/default contract; do not fabricate a write for every
|
||||
import that leaves a path alone. Resolution history records the audited net change
|
||||
per path, not every intermediate Go assignment. Lookup of a secret reference
|
||||
annotates its effective name as resolved from the process environment; bootstrap
|
||||
file outcomes come from the separate report and are never guessed.
|
||||
|
||||
`WriteExplanation` is a deterministic human renderer over this safe structured
|
||||
result. Escape control characters in paths, labels, names, and reasons, propagate
|
||||
writer errors/short writes, and permit partial output only on writer failure.
|
||||
No unredacted switch or bundled command is provided. For example an application
|
||||
can call it for `/transcription/concurrency` to show default `4`, an explicitly
|
||||
imported file's `8`, then a testing profile's `1`, with file line numbers and the
|
||||
profile as effective source. This does not require automatic `conf.d` discovery.
|
||||
Historical explanation is implemented. The
|
||||
[current explanation contract](../config.md#historical-value-explanation) owns its
|
||||
public records, replay ordering, redaction, rendering, and allocation bounds.
|
||||
|
||||
### Module-specific options
|
||||
|
||||
|
||||
Reference in New Issue
Block a user