Files
configkit/docs/roadmap/review.md

794 lines
69 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Public API Catalog And v1.0 Review
Reviewed revision: `fb71421956ba6b431bdc8745dcf7ab02607dac3a`.
Status: discussion draft; no API changes are selected or implemented by this review.
## Scope And Method
The supported consumer surface is the root package
`gitea.maximumdirect.net/eric/ConfigKit`, package name `configkit`.
[ADR 0006](../adr/0006-public-facade.md) owns root type identity and the private
implementation boundary. Exported engine names are not consumer API.
This catalog includes every exported root type, function, method, struct field,
and constant in the current build: **372 entries** comprising **54 types,
31 functions, 36 methods, 116 fields, and 135 constants**. There are no exported
package variables, named interfaces, type aliases, or anonymously embedded public
fields. Of the constants, 104 are diagnostic codes: the symbol count does not
mean that consumers must learn 372 independent operations.
Inventory was extracted from the root non-test Go declarations, cross-checked
against the package's build-selected files and `go doc -all .`, and reviewed
against declaration comments, the [configuration contract](../config.md),
[consumer examples](../consumers/README.md), the
[architecture policy](../policy/architecture.md), and relevant accepted ADRs.
This is an API-design review, not another correctness or performance audit.
Each catalog row has an assessment addressing clarity, ergonomics, and/or
consolidation. **Retain** means no revision is currently warranted, not a new
invariant or a promise to preserve private mechanics. **Discuss Dn** identifies
a possible pre-v1 naming/removal/signature decision below; **An** is an optional
additive idea. Struct declarations show their kind without private fields; all
exported fields are separate rows. Callable signatures include generic constraints
and receiver types. Constants include their current types and values.
Go declaration comments and the configuration contract remain the canonical
behavior owners. This roadmap is a revision-pinned review record, not a second
permanent API reference. Nothing here creates new release gates or consumer
requirements. Under the [release policy](../policy/release.md#versioning-and-compatibility),
v1 establishes compatibility expectations; it does not prevent later compatible
additions. The highest-value decisions now are potential renames/removals that
would otherwise require a later incompatible release.
## Overall Assessment
The facade has a coherent core: explicit source selection, one complete load,
application-owned rules, separate presence/provenance, and safe frozen inspection.
Its private implementation can evolve without changing public type ownership.
Most of the API should remain. The useful cleanup opportunities are concentrated
in vocabulary and small redundant state, not a wholesale loading framework.
Prioritize D1–D4: these names can encourage an incorrect interpretation of the
state a consumer receives. D5–D7 are useful additional naming/signature discussions;
D8 is a small surface-hygiene question. A1–A2 can wait unless a concrete consumer
need makes them useful now. These are recommendations for discussion, not approved
changes or a declaration that v1 must wait for every suggestion.
## Pre-v1 Discussion Candidates
### D1. Name the fixed resolution view as entry state
Affected: `Resolution.InputInfo`; the documentation of `Resolution` and
`FieldInfo`.
The lookup includes retained typed defaults and remains fixed while the resolver
changes the working configuration. “Input” can therefore suggest either raw
authored values or the mutable current value, neither of which is its complete
meaning.
Recommendation: consider renaming the method to `EntryInfo` and consistently
calling this the resolution-entry view. Keep its return type and silent
unknown/shape-mismatch result. Keep `IsExplicit` as the convenient surviving-input
question with its existing path-validation behavior.
Alternative: retain `InputInfo`, whose comment already explains the contract,
and improve the nearby example. That avoids consumer migration and is defensible
if the terminology is already well understood. Do not expose the growing history
model through the callback or collapse entry and final metadata to solve a naming
problem.
### D2. Distinguish sensitivity classification from secret references
Affected: `Definition.Secret`; related terminology around `Secret` and
`ValueSnapshot.Redacted`.
The function marks arbitrary semantic paths sensitive, including ordinary strings
and containers. It neither creates nor resolves the typed environment references
represented by `Secret`.
Recommendation: consider `Definition.Sensitive func(Path) bool`. This makes a
definition such as `Sensitive: func(path Path) bool { ... }` describe its purpose
without implying credential lookup. Preserve the existing tag/predicate union,
historical masking, and reference semantics.
Alternative: keep `Secret` on the field because it aligns with the existing
`configkit:"secret"` tag and the established documentation. The current name is
not functionally wrong. No tag rename, new classification policy, credential
provider, or declassification option follows from this discussion.
### D3. Make version-policy and version-evidence names literal
Affected: `SourceVersionModeDefault`, `SourceVersionCheck`, and
`SourceInfo.VersionCheck`.
“Default” describes an implementation/history relationship rather than the
selected main-only behavior. A “Check” record can exist for an absent declaration
without proving that its checker ran or accepted a value.
Recommendation: consider `SourceVersionModeMainOnly` for the existing zero mode,
`SourceVersionEvidence` for the record, and `SourceInfo.VersionEvidence` for the
field. Keep all existing mode values, invocation/absence rules, source-local
coordinates, consumption, and redaction behavior. In particular, an if-present
mode still has the documented main-absence checker behavior; naming cleanup
must not silently change it.
Alternative: retain the names and make their precise meanings prominent in
declaration comments and examples. “Default” is familiar for zero enums, and
existing consumers may already understand the evidence qualification. Do not add
an “accepted” boolean unless ConfigKit actually chooses to retain that fact under
a separately agreed contract.
### D4. Describe the empty-import-selection subset and remove redundant state
Affected: `ImportSelection`, `SourceInfo.ImportSelections`,
`ImportSelection.Outcome`, `ImportSelectionOutcome`, and `ImportSelectionNone`.
These records describe optional declarations that selected no source. They are
not a complete selection ledger. Their outcome has exactly one supported value,
`"none"`; successful acquisition is represented elsewhere by source records.
Recommendation: consider `EmptyImportSelection` and
`SourceInfo.EmptyImportSelections`, retaining path, location, and selector.
With that explicit scope, remove the constant-only outcome field/type/constant.
This reduces the public model without losing information that these records
currently communicate.
Alternative: retain the broad names and explicit outcome. It leaves room for
compatible additional outcomes and avoids migration, but consumers must learn
that the collection currently reports empty selections only. Future flexibility
alone should not imply an approved complete event-history feature.
### D5. Describe destination fallback evidence more precisely
Affected: `SourceInfo.DestinationUnresolved`.
The destination can be a useful nearest resolved enclosing container. The flag
does not mean every aspect of placement is unresolved, and a source's own item
container can be an exact destination without publishing its item index here.
Recommendation: consider `DestinationIsFallback` with the existing meaning.
Retain `Destination` and `PlacementMode`; another placement object/state machine
is not needed just to clarify this boolean.
Alternative: retain `DestinationUnresolved` and its detailed comment. It is
already specific enough for informed consumers. Neither option adds exact item
coordinates, identity tracking, or extra source-location guarantees.
### D6. Separate manual recording intents from inspection-only operation kinds
Affected: `Resolution.Record` and its use of `ChangeKind`.
Four named operation values are exported, but only derived-default and
normalization are valid manual recording intents. Decoding and inheritance
describe library processing. A caller can choose an apparently suitable exported
constant only to receive a load-time invalid-kind diagnostic.
Recommendation for discussion: consider replacing manual `Record` with
`RecordDerivedDefault(path Path, reason string, dependencies ...Path)` and
`RecordNormalization(path Path, reason string, dependencies ...Path)` methods.
Keep the generic assignment helpers `Default` and `Normalize`, which do different
work, and keep all inspection `ChangeKind` values. The explicit methods remove a
misleading input choice without changing the two accepted intents.
Alternative: retain the single method and prominently document its accepted
subset. A separate input-only kind type is another viable design, but adds a
second enum and conversion vocabulary; it is less attractive unless consumers
need to select recording intent dynamically. Do not change net-change auditing
or impose new recording obligations through this cleanup.
### D7. Make environment mutation evident in the bootstrap function name
Affected: `LoadSecretsDir`.
Unlike ordinary `Load`, this explicit startup operation writes previously unset
process environment variables and can report partial application failure.
Recommendation: consider `BootstrapSecretsDir`. It follows the repository's
existing bootstrap terminology and makes the distinction from configuration
loading easier to notice. Retain its report-plus-error return and all current
preflight, skip, partial-failure, and ownership behavior.
Alternative: retain `LoadSecretsDir`, whose comment clearly states the side
effects. Avoid a broad new bootstrap options framework or merging this operation
into ordinary loading. The purpose is naming clarity, not stronger filesystem
or process-transaction guarantees.
### D8. Resolve the intent of the unproduced options diagnostic code
Affected: `CodeOptionsUnavailable`.
The scoped implementation search found its root and engine declarations but no
named production producer. That is a reason to ask about its intended role, not
evidence that an exported symbol has no consumers.
Recommendation: establish whether there is an intentional supported/reserved case;
remove the constant before v1 if there is none. Do not invent a new failure merely
to give it a producer.
Alternative: retain it as deliberately reserved classification if there is a
concrete reason. Document that intent rather than automatically deleting it.
The other diagnostic families should not be collapsed just to reduce the count.
## Optional Additive Ideas
### A1. Direct source lookup on successful results
`Resolution.Source(id)` and both `SourceContext(id)` methods accept a source ID,
while a final result offers only `Sources()` for source records. A consumer
following many origin locations must scan or index that slice itself.
Consider `Result.Source(id string) (SourceInfo, bool)` with the same detached,
passive lookup meaning as the resolution query. Prefer it over a general source
registry abstraction if representative consumers repeatedly need this lookup.
Keeping only the ordered slice is a viable smaller API for consumers that
enumerate once. This is an addition that can follow v1; it need not block the
existing API freeze.
### A2. Path comparison without losing segment meaning
`Path.String()` is a JSON Pointer spelling, not a complete semantic identity:
an explicit numeric mapping key and an index can share it. The public type is
opaque and currently non-comparable, so consumers cannot directly compare its
segment choices without relying on reflection or private representation.
If consumers need path comparison, consider an explicitly documented comparison
operation. Decide whether it means exact segment representation (including
parsed-versus-explicit choice and invalid state), or resolution against a
document; those are different operations. Prefer a small exact-representation
operation over exposing mutable segments or adding another pattern language.
Do not label pointer-string equality semantic equality.
Alternatively keep Path solely as an opaque query/building value and clarify
the limitation in examples. No concrete need currently justifies a public
segment-inspection framework. A comparison method can be added compatibly later.
## Consolidation Assessment
| Area | Assessment |
| --- | --- |
| C1: ordinary versus layered loading | Keep two entry points. Ordinary options combine one input's choices with load-wide rules; layered Input owns the former and LayeredOptions the latter. Reusing one options type would introduce ignored/competing fields. Anonymous embedding also makes keyed composite literals less convenient. Existing Definition, ImportDefaults, Input, and Override sharing is useful consolidation already. |
| C2: filesystem vocabulary | Keep Filesystem (borrowed identity), FilesystemContext (input roots), and ResourceContext (passive returned access) distinct. FS means different concrete types because the roles differ. Clarify with paired host/native examples, rather than introducing one universal context or changing ownership. |
| C3: history versus explanation | Keep Change and ValueChange, Metadata.History and Result.Explain distinct. Metadata has composite/previous attribution; explanation has safe values and decoding/net replay. Their shared private evidence is the correct consolidation boundary. |
| C4: semantic path versus sequence selector | Keep Path and SequenceSelector distinct. One describes concrete/contextual queries, the other limited mapping-key wildcard registration. Unifying them would broaden grammar and validation for little current benefit. |
| Errors and renderers | Keep LoadError and SecretsError separate because bootstrap can accompany partial external effects. Keep structured diagnostics plus safe rendering. SecretsReport.WriteTo follows io.WriterTo; other renderers need not return byte counts merely for symmetry. |
| Presence records | Keep FieldInfo, Version and ValueSnapshot's purpose-specific booleans. A generic optional-value/tri-state framework would add vocabulary without simplifying the application configuration structs. |
| Result ownership | Keep caller-owned Config and frozen inspection. A copying accessor would not make arbitrary T language-enforced immutable and would add work; emphasize the established snapshot distinction instead. |
## Related Consumer Integration Contracts
The Go symbols are not the entire compatibility commitment. These established
integration surfaces also matter to v1, but are defined by their canonical
contracts rather than counted as additional exported Go declarations:
| Surface | Owner and assessment |
| --- | --- |
| Configuration structs, YAML field tags, standard text codecs, defaults and typed decoding | [Schema binding](../config.md#application-schema-binding), [defaults](../config.md#defaults-and-typed-decoding), and [projection](../config.md#typed-projection-and-ownership). Retain ordinary application types and supported standard codec integration; do not add parser-specific public hooks. |
| YAML declarations, composition, imports, overlays and sibling inheritance | [Configuration contract](../config.md) and accepted ADRs linked there. Retain the established coherent language; this review does not propose reserved-key or merge-policy changes. |
| Presence, provenance, recorded resolution and validation | [Metadata](../config.md#layered-metadata), [resolution](../config.md#recorded-application-resolution), and [validation](../config.md#semantic-validation). Retain the distinctions that remove consumer bookkeeping; naming discussions do not change these semantics. |
| Secret references, classification and explicit environment bootstrap | [Secret references](../config.md#typed-secret-references), [classification](../config.md#secret-classification-and-effective-rendering), and [bootstrap](../config.md#explicit-secrets-directory-bootstrap). D2/D7 concern API vocabulary, not a new credential or security model. |
| One-shot completion, resource ownership, safe rendering and comparison | [Completion](../config.md#completion-and-resource-lifetime), [source contexts](../config.md#source-resource-contexts), [explanation](../config.md#historical-value-explanation), and [diffs](../config.md#effective-configuration-diffs). Retain established lifetimes and safe snapshot boundaries rather than adding watching, lazy work or a required result Close operation. |
## Complete Catalog
All rows below assess the current declarations, not the proposed replacement
names. No proposed symbol is counted in the 372-entry inventory.
### Loading and application policy
Declarations: [layered.go](../../layered.go), [lifecycle.go](../../lifecycle.go).
| Entry | Declaration/type | Assessment |
| --- | --- | --- |
| `Input` | `type Input struct` | Retain a source plus placement/import/access settings; zero Source is invalid, unlike explicit NoSource. |
| `Input.Source` | `Source` | Retain the opaque source union; no provider interface or parser node exposure. |
| `Input.Destination` | `Path` | Retain the same root-relative placement meaning as ordinary options. |
| `Input.PlacementMode` | `PlacementMode` | Retain the same explicit placement enum as ordinary options. |
| `Input.Imports` | `bool` | Retain per-input traversal choice; it differs from load-wide declaration defaults. |
| `Input.Filesystem` | `*FilesystemContext` | Retain per-input access context, not a global context for unrelated namespaces. |
| `Underlay` | `type Underlay struct` | Retain a named strict tier; flattening all inputs would lose the peer-versus-precedence boundary. |
| `Underlay.Inputs` | `[]Input` | Retain ordered inputs in one strict group; an empty group remains a no-op. |
| `LayeredOptions` | `type LayeredOptions[T any] struct` | Retain separate layered entry-point options; input-level settings already belong to Input (C1). |
| `LayeredOptions.Definition` | `Definition[T]` | Retain the same Definition type as ordinary loading. |
| `LayeredOptions.SourceVersionMode` | `SourceVersionMode` | Discuss D3's mode name; retain one rule across the load rather than per-source policy switches. |
| `LayeredOptions.ImportDefaults` | `ImportDefaults` | Retain the shared type and one load-wide default policy. |
| `LayeredOptions.Underlays` | `[]Underlay` | Retain ordered low-to-high strict groups; no separate precedence numbers are needed. |
| `LayeredOptions.Overlay` | `string` | Retain the same selected-overlay concept as ordinary loading. |
| `LayeredOptions.OverlayFilesystem` | `*FilesystemContext` | Retain its explicit overlay-only purpose; merging it into main input context would change behavior (C1/C2). |
| `LayeredOptions.Overrides` | `[]Override` | Retain shared Override records and the same CLI semantics. |
| `LoadLayered` | `func LoadLayered[T any](main Input, supplied ...LayeredOptions[T]) (*Result[T], error)` | Retain explicit tiers and independent main input; do not make composition strategy a switch. See consolidation assessment C1. |
| `Definition` | `type Definition[T any] struct` | Retain reusable application rules separate from per-load selections; zero disables hooks and uses Go-zero defaults. |
| `Definition.Defaults` | `func() T` | Retain a fresh-value factory; zero-value configuration and shared mutable defaults are different concerns. |
| `Definition.Resolve` | `func(*T, *Resolution) error` | Retain audited mutation callback and error return; do not move application normalization outside loading. |
| `Definition.Validate` | `func(*T, *Validation)` | Retain read-only audited validation despite pointer parameter; a value parameter would not make maps/pointers immutable. |
| `Definition.Version` | `*VersionRule` | Retain optional application version policy; nil disables the rule. Do not confuse it with the ConfigKit release version. |
| `Definition.Secret` | `func(Path) bool` | Discuss D2: rename the classification predicate to Sensitive, distinguishing it from environment-backed Secret references. |
| `Definition.SequenceIdentities` | `[]SequenceIdentity` | Retain authoritative identity registrations; no new per-consumer merge strategy is needed. |
| `PlacementMode` | `type PlacementMode uint8` | Retain small explicit enum; zero is mapping placement, not automatic inference. |
| `SourceVersionMode` | `type SourceVersionMode uint8` | Discuss D3: the zero behavior deserves a descriptive MainOnly name rather than a historical Default label. |
| `ImportDefaults` | `type ImportDefaults struct` | Retain independent tri-state defaults; zero leaves library defaults in effect. Do not replace pointers with false-as-unspecified. |
| `ImportDefaults.Required` | `*bool` | Retain *bool: nil is unspecified, false is an explicit optional selection. |
| `ImportDefaults.Follow` | `*bool` | Retain *bool: explicit false must override the true library default. |
| `ImportDefaults.Hidden` | `*bool` | Retain *bool: explicit false must override the true library default. |
| `ImportDefaults.Recursive` | `*bool` | Retain *bool: distinguishes declaration defaulting from an explicit choice. |
| `ImportDefaults.Pattern` | `[]string` | Retain nil-versus-empty selection meaning; a new pattern language is unwarranted. |
| `Options` | `type Options[T any] struct` | Retain ordinary-load options with input-specific settings; do not consolidate by anonymously embedding another public options struct (C1). |
| `Options.Definition` | `Definition[T]` | Retain the shared Definition type; avoids duplicating callback configuration. |
| `Options.Destination` | `Path` | Retain literal mapping placement independent of filesystem paths; root is the zero Path. |
| `Options.PlacementMode` | `PlacementMode` | Retain explicit mapping/item choice; avoid inferring it from destination spelling. |
| `Options.Imports` | `bool` | Retain explicit opt-in; import defaults alone must not enable traversal. |
| `Options.ImportDefaults` | `ImportDefaults` | Retain one shared load-wide default type, not duplicate boolean fields here. |
| `Options.Overlay` | `string` | Retain one selected overlay name; empty selects none. |
| `Options.Filesystem` | `*FilesystemContext` | Retain context for ordinary source/import/overlay handling; distinguish from the layered overlay-only context (C1/C2). |
| `Options.Overrides` | `[]Override` | Retain explicit CLI assignments; do not generalize these into another arbitrary source tier. |
| `Options.SourceVersionMode` | `SourceVersionMode` | Discuss D3's zero-mode name; retain load-wide version policy here. |
| `FilesystemContext` | `type FilesystemContext struct` | Retain input access scope, distinct from returned ResourceContext. Consider documentation terminology rather than merging lifetimes (C2). |
| `FilesystemContext.BaseDir` | `string` | Retain host-absolute versus namespace-relative coordinates; clarify with paired examples (C2). |
| `FilesystemContext.Root` | `string` | Retain explicit scope separate from the source-relative base; do not silently strengthen filesystem security policy. |
| `FilesystemContext.FS` | `*Filesystem` | Retain *Filesystem identity, not raw fs.FS: nil selects host context and namespace identity matters (C2). |
| `Override` | `type Override struct` | Retain parser-neutral explicit CLI input, distinct from defaults and ordinary sources. |
| `Override.Path` | `Path` | Retain application-root semantic coordinates. |
| `Override.Value` | `any` | Retain built-in neutral values; accepting arbitrary typed objects would add another conversion contract. |
| `Override.Flag` | `string` | Retain safe display attribution, not the raw CLI argument or value. |
| `Load` | `func Load[T any](source Source, supplied ...Options[T]) (*Result[T], error)` | Retain the source-only call and one typed options record; the optional form avoids a mandatory empty options value or request builder. |
### Sources and filesystem namespaces
Declarations: [resource_context.go](../../resource_context.go), [source.go](../../source.go).
| Entry | Declaration/type | Assessment |
| --- | --- | --- |
| `ResourceContext` | `type ResourceContext struct` | Retain passive post-acquisition resource access distinct from input scope; zero has no filesystem (C2). |
| `ResourceContext.FS` | `fs.FS` | Retain borrowed fs.FS. Callers close files they open; a successful load itself needs no Close. |
| `ResourceContext.BaseDir` | `string` | Retain slash-relative source base; do not replace it with a host path that excludes embedded filesystems. |
| `Source` | `type Source struct` | Retain opaque acquisition descriptions and deferred validation; zero is invalid and NoSource is deliberate absence. |
| `Filesystem` | `type Filesystem struct` | Retain a reusable borrowed fs.FS namespace with identity; zero is not a valid namespace. |
| `NewFilesystem` | `func NewFilesystem(label string, filesystem fs.FS) Filesystem` | Retain label plus borrowed fs.FS, returning a namespace whose argument failures surface during load. |
| `Filesystem.File` | `func (f Filesystem) File(name string) Source` | Retain native namespace file selection as a method; replacing it with a raw fs.FS Source overload would lose identity/context. |
| `File` | `func File(path string) Source` | Retain the short reusable host-file constructor. |
| `Bytes` | `func Bytes(label string, data []byte) Source` | Retain immediate byte ownership snapshot and a safe label; delayed constructor diagnostics match other sources. |
| `Reader` | `func Reader(label string, input io.Reader) Source` | Retain explicit single-use borrowed-reader semantics; do not add automatic Close or hidden buffering for reuse. |
| `Mapping` | `func Mapping(label string, values map[string]any) Source` | Retain immediate neutral-map snapshot; nil root is invalid and empty mapping is meaningful. |
| `NoSource` | `func NoSource() Source` | Retain explicit absence separate from zero Source and an empty document. |
### Explicit main-file discovery
Declarations: [discovery.go](../../discovery.go).
| Entry | Declaration/type | Assessment |
| --- | --- | --- |
| `Search` | `type Search struct` | Retain immutable explicit host-search description; zero contributes no candidates. No independent discovery/execution stage is needed. |
| `FilenameGroup` | `type FilenameGroup struct` | Retain a small opaque description; zero contributes no names. It is not a general glob matcher. |
| `SearchOptions` | `type SearchOptions struct` | Retain whole-search absence policy separate from per-directory filename choices. |
| `SearchOptions.Required` | `bool` | Retain optional-by-default search exhaustion; selected-file errors remain terminal. |
| `DirectorySearchOptions` | `type DirectorySearchOptions struct` | Retain the filename-group option record; preserve nil/default versus empty/no-candidates distinction. |
| `DirectorySearchOptions.Filenames` | `[]FilenameGroup` | Retain ordered groups; no candidate list or candidate-attempt history is necessary. |
| `NamedFilenames` | `func NamedFilenames() FilenameGroup` | Retain application-named YAML filename preset; it keeps common consumer setup short. |
| `GenericFilenames` | `func GenericFilenames() FilenameGroup` | Retain generic YAML filename preset; separate selection avoids implicit convention changes. |
| `CustomFilenames` | `func CustomFilenames(names ...string) FilenameGroup` | Retain explicit filename components and order, not a second glob/template mechanism. |
| `SearchDirectory` | `func SearchDirectory(directory string, supplied ...DirectorySearchOptions) Search` | Retain directory search plus optional filenames; argument problems remain load-time diagnostics. |
| `Paths` | `func Paths(paths ...string) Search` | Retain literal host-candidate description. Document that this is discovery, not semantic Path construction. |
| `Searches` | `func Searches(searches ...Search) Search` | Retain ordered concatenation; it expresses one search, not repeated loads or fallback after parse failure. |
| `UnixSystemDirectories` | `func UnixSystemDirectories() Search` | Retain explicit platform preset; do not turn its presence into implicit cross-platform guarantees. |
| `UserConfigDirectory` | `func UserConfigDirectory() Search` | Retain explicit OS user-config location preset. |
| `HomeDirectory` | `func HomeDirectory() Search` | Retain explicit home-root search preset, distinct from user-config location. |
| `WorkingDirectory` | `func WorkingDirectory() Search` | Retain explicit working-directory preset; do not activate it automatically. |
| `SearchConfig` | `func SearchConfig(application string, search Search, supplied ...SearchOptions) Source` | Retain deferred source selection inside loading. Optional exhaustion and selected-file failure are intentionally different. |
### Paths and sequence identity registration
Declarations: [path.go](../../path.go), [sequence_identity.go](../../sequence_identity.go).
| Entry | Declaration/type | Assessment |
| --- | --- | --- |
| `Path` | `type Path struct` | Discuss A2: preserve opaque semantic paths; consider exact segment comparison only if consumers need it. Zero is root; current type is not comparable. |
| `Keys` | `func Keys(keys ...string) Path` | Retain concise literal-key construction and zero-argument root; do not interpret numeric keys as indexes. |
| `ParsePath` | `func ParsePath(pointer string) (Path, error)` | Retain contextual numeric tokens and an error return; pointer spelling alone is not full semantic identity (A2). |
| `Path.Key` | `func (p Path) Key(key string) Path` | Retain immutable literal-key append, including empty and numeric keys. |
| `Path.Index` | `func (p Path) Index(index int) Path` | Retain explicit sequence indexing; negative indexes produce an invalid path rejected by configuration operations. |
| `Path.String` | `func (p Path) String() string` | Retain canonical JSON Pointer formatting, but explicitly avoid calling it a complete semantic identity (A2). |
| `SequenceSelector` | `type SequenceSelector []SequenceSelectorSegment` | Retain the named slice of literal/wildcard mapping-key segments; zero selects root. Do not merge it with general Path syntax (C4). |
| `SequenceSelectorSegment` | `type SequenceSelectorSegment struct` | Retain the opaque segment; zero is the literal empty key, not a wildcard. |
| `SequenceLiteralKey` | `func SequenceLiteralKey(key string) SequenceSelectorSegment` | Retain explicit literal construction, including '*' as a real key. |
| `SequenceAnyMappingKey` | `func SequenceAnyMappingKey() SequenceSelectorSegment` | Retain an explicit wildcard constructor; textual '*' must not acquire a second meaning. |
| `SequenceIdentity` | `type SequenceIdentity struct` | Retain immutable registration value, not a pluggable merge strategy. Zero lacks required identity fields and is rejected during load. |
| `SequenceIdentityAt` | `func SequenceIdentityAt(path Path, fields ...string) SequenceIdentity` | Retain the exact-path convenience; it avoids building a selector for ordinary static destinations. |
| `SequenceIdentityMatching` | `func SequenceIdentityMatching(selector SequenceSelector, fields ...string) SequenceIdentity` | Retain wildcard mapping destinations for repeated namespaces; constructor copies inputs. |
### Resolution, validation, and application schema versions
Declarations: [lifecycle.go](../../lifecycle.go), [resource_context.go](../../resource_context.go).
| Entry | Declaration/type | Assessment |
| --- | --- | --- |
| `Resolution` | `type Resolution struct` | Retain a library-issued callback capability; nil/zero/closed contexts are invalid and panic. Do not add a general resolver service interface. |
| `VersionRule` | `type VersionRule struct` | Retain one application-owned version path/checker. Zero Path means root; a non-nil rule needs a checker. |
| `VersionRule.Path` | `Path` | Retain mode-defined effective/source-local coordinates; clarify the distinction in examples, not separate version systems. |
| `VersionRule.Check` | `func(Version, *Validation) error` | Retain Version plus diagnostic context and error return; application acceptance remains application-owned. |
| `Version` | `type Version struct` | Retain the compact absent/null/text record rather than imposing a semver or numeric version type. |
| `Version.Present` | `bool` | Retain: omission cannot be inferred from Text being empty. |
| `Version.Null` | `bool` | Retain: an explicit null is different from absence and an empty string. |
| `Version.Text` | `string` | Retain exact accepted spelling; do not expose YAML scalar kinds when string/integer equivalence is intentional. |
| `Validation` | `type Validation struct` | Retain the callback-only diagnostic capability; no public constructor or reusable context is needed. |
| `Resolution.IsExplicit` | `func (r *Resolution) IsExplicit(path Path) bool` | Retain surviving-input presence semantics, including inherited input; document its schema-path diagnostics versus a lookup miss. |
| `Resolution.InputInfo` | `func (r *Resolution) InputInfo(path Path) (FieldInfo, bool)` | Discuss D1: EntryInfo more accurately names the fixed pre-resolution view, including defaults. |
| `Resolution.Source` | `func (r *Resolution) Source(id string) (SourceInfo, bool)` | Retain direct acquired-source lookup by ID; optional Result parity is A1. |
| `Resolution.Record` | `func (r *Resolution) Record(path Path, kind ChangeKind, reason string, dependencies ...Path)` | Discuss D6: its ChangeKind argument admits inspection-only constants that loading rejects; consider intent-specific record methods. |
| `Resolution.Error` | `func (r *Resolution) Error(path Path, message string, related ...Path)` | Retain safe diagnostic collection; do not expose raw application errors automatically. |
| `Resolution.Warning` | `func (r *Resolution) Warning(path Path, message string, related ...Path)` | Retain warning/error symmetry and related semantic paths. |
| `Default` | `func Default[V any](resolution *Resolution, path Path, target *V, value V, reason string, dependencies ...Path)` | Retain the generic typed assignment helper; explicit zero/false/null must suppress absence-based assignment. |
| `Normalize` | `func Normalize[V any](resolution *Resolution, path Path, target *V, value V, reason string, dependencies ...Path)` | Retain unconditional typed assignment plus audit intent; not redundant with absence-based Default. |
| `Validation.Error` | `func (v *Validation) Error(path Path, message string, related ...Path)` | Retain value-free errors collected at semantic paths, distinct from unwrapping arbitrary callback errors. |
| `Validation.Warning` | `func (v *Validation) Warning(path Path, message string, related ...Path)` | Retain matching warning API; no generic severity switch is necessary. |
| `Resolution.SourceContext` | `func (r *Resolution) SourceContext(id string) (ResourceContext, bool)` | Retain passive source-context lookup during the callback, with no I/O. |
### Results, presence, and source/provenance evidence
Declarations: [inspection.go](../../inspection.go), [lifecycle.go](../../lifecycle.go), [metadata.go](../../metadata.go), [records.go](../../records.go), [resource_context.go](../../resource_context.go).
| Entry | Declaration/type | Assessment |
| --- | --- | --- |
| `Result.Explain` | `func (r *Result[T]) Explain(path Path) (Explanation, bool)` | Retain structured safe history plus found boolean; query semantics differ from Metadata.History (C3). |
| `Result.WriteEffective` | `func (r *Result[T]) WriteEffective(output io.Writer) error` | Retain frozen redacted YAML output and error-only writer convention; nil/zero snapshot or nil writer is an error. |
| `Result.WriteExplanation` | `func (r *Result[T]) WriteExplanation(output io.Writer, path Path) error` | Retain human-readable output. Clarify that unknown paths return an error without output; this is not a new behavior. |
| `Result` | `type Result[T any] struct` | Retain the successful configuration plus frozen inspection boundary; zero/nil has no usable loaded snapshot. |
| `Result.Config` | `T` | Retain caller-owned mutable T. Clarify that later mutation does not update inspection; replacing it with a cloning getter adds cost without immutability. |
| `Result.Metadata` | `func (r *Result[T]) Metadata() Metadata` | Retain detached effective/history query access; do not translate Explain output into metadata. |
| `Result.Sources` | `func (r *Result[T]) Sources() []SourceInfo` | Retain ordered detached acquisition records; optional direct Source lookup is A1. |
| `Result.Diagnostics` | `func (r *Result[T]) Diagnostics() []Diagnostic` | Retain successful-load nonfatal diagnostics, parallel to structured load failures. |
| `Metadata` | `type Metadata struct` | Retain opaque detached queries; zero contains no known paths. |
| `Metadata.Lookup` | `func (m Metadata) Lookup(path Path) (FieldInfo, bool)` | Retain effective FieldInfo plus found boolean; this handles absence without optional wrappers in application structs. |
| `Metadata.IsExplicit` | `func (m Metadata) IsExplicit(path Path) bool` | Retain ergonomic convenience over Lookup; inherited input is explicit and defaults/resolution do not invent presence. |
| `Metadata.History` | `func (m Metadata) History(path Path) []Change` | Retain attribution-only history, including removed paths; it intentionally differs from value replay (C3). |
| `Metadata.HistoricalPaths` | `func (m Metadata) HistoricalPaths() []Path` | Retain canonical-pointer enumeration, including removed/default/control paths; no extra per-shape enumeration API is justified. |
| `Layer` | `type Layer string` | Retain string-valued provenance categories; base/main terminology merits documentation clarity, not an automatic wire-value rename. |
| `SourceKind` | `type SourceKind string` | Retain acquisition kind independently of precedence layer. |
| `ChangeKind` | `type ChangeKind string` | Discuss D6's recording input; retain all inspection operations and the empty/default definition state. |
| `Location` | `type Location struct` | Retain source ID plus optional line/column coordinates; zero coordinates mean unavailable/synthetic. |
| `Location.SourceID` | `string` | Retain a load-local acquired-source key, not a host filename. |
| `Location.Line` | `int` | Retain line coordinate; zero means unavailable. |
| `Location.Column` | `int` | Retain column coordinate; zero means unavailable. |
| `SourceInfo` | `type SourceInfo struct` | Retain structured acquisition and placement evidence; simplify misleading evidence names in D3–D5, not source identity. |
| `SourceInfo.ID` | `string` | Retain load-local ID independent of physical path or label. |
| `SourceInfo.Label` | `string` | Retain safe display label separate from path and stable identity. |
| `SourceInfo.Path` | `string` | Retain host-canonical/native-relative location where present; do not imply every source has a path. |
| `SourceInfo.Destination` | `Path` | Retain effective mapping/sequence-container placement; it is not always an item's exact value path. |
| `SourceInfo.PlacementMode` | `PlacementMode` | Retain explicit placement evidence, independent of acquisition kind. |
| `SourceInfo.DestinationUnresolved` | `bool` | Discuss D5: DestinationIsFallback would describe the enclosing-container evidence more precisely. |
| `SourceInfo.Layer` | `Layer` | Retain provenance tier independent of acquisition order and source kind. |
| `SourceInfo.Kind` | `SourceKind` | Retain acquisition category rather than inferring it from path syntax. |
| `SourceInfo.UnderlayIndex` | `int` | Retain one-based original tier position, zero otherwise; do not renumber around empty tiers. |
| `SourceInfo.ImportedFrom` | `*Location` | Retain optional declaring location rather than a second parent-source object graph. |
| `SourceInfo.VersionCheck` | `*SourceVersionCheck` | Discuss D3: VersionEvidence avoids implying that the checker ran or accepted anything. |
| `SourceInfo.ImportSelections` | `[]ImportSelection` | Discuss D4: name the empty-selection-only scope explicitly. |
| `ImportSelector` | `type ImportSelector string` | Retain path/directory/glob selector classification; do not combine it with source acquisition kind. |
| `ImportSelectionOutcome` | `type ImportSelectionOutcome string` | Discuss D4: this public enum has only one supported outcome and may be redundant in an explicitly empty-selection record. |
| `ImportSelection` | `type ImportSelection struct` | Discuss D4: EmptyImportSelection would accurately name the currently reported subset. |
| `ImportSelection.Path` | `Path` | Retain declaration-local path if the record is renamed; not the selected source's destination. |
| `ImportSelection.Location` | `Location` | Retain declaration mapping/source coordinates. |
| `ImportSelection.Selector` | `ImportSelector` | Retain the authored selector kind; empty path, directory, and glob choices differ. |
| `ImportSelection.Outcome` | `ImportSelectionOutcome` | Discuss D4: remove the constant-only none field if empty-only scope is made explicit. |
| `SourceVersionCheck` | `type SourceVersionCheck struct` | Discuss D3: SourceVersionEvidence better describes observed declaration state without implying validation success. |
| `SourceVersionCheck.Path` | `Path` | Retain requested source-local version path, including absent evidence. |
| `SourceVersionCheck.Version` | `Version` | Retain absent/null/text observation, not an acceptance result. |
| `SourceVersionCheck.Location` | `*Location` | Retain optional actual/nearest authored location. |
| `SourceVersionCheck.Redacted` | `bool` | Retain explicit withheld-text indication; absence cannot be inferred from empty Text. |
| `InheritanceStep` | `type InheritanceStep struct` | Retain explicit transfer/control provenance; it adds no acquired source or precedence layer. |
| `InheritanceStep.From` | `Path` | Retain contributor semantic path. |
| `InheritanceStep.To` | `Path` | Retain destination semantic path. |
| `InheritanceStep.Reference` | `Path` | Retain controlling extends path, distinct from the inherited value path. |
| `InheritanceStep.Locations` | `[]Location` | Retain directive coordinates rather than mislabeling them as value coordinates. |
| `Origin` | `type Origin struct` | Retain composite locations, precedence, operation and transfer trace; no generic untyped metadata bag. |
| `Origin.Layer` | `Layer` | Retain provenance classification; inheritance does not invent another layer. |
| `Origin.Locations` | `[]Location` | Retain ordered composite origins; one SourceID field would lose strict composition evidence. |
| `Origin.Operation` | `ChangeKind` | Retain inspection ChangeKind, including decoding/inheritance (D6 concerns recording input only). |
| `Origin.Inheritance` | `[]InheritanceStep` | Retain concrete derivation steps separately from acquired source locations. |
| `FieldInfo` | `type FieldInfo struct` | Retain compact effective presence/null/origin record. |
| `FieldInfo.Explicit` | `bool` | Retain input presence independent of the final Go zero value. |
| `FieldInfo.Null` | `bool` | Retain explicit null independently of missing lookup and scalar zero. |
| `FieldInfo.Origin` | `Origin` | Retain final effective attribution. |
| `Change` | `type Change struct` | Retain attribution-only history and Previous origins; not redundant with ValueChange (C3). |
| `Change.Path` | `Path` | Retain reported operation path, which may enclose the queried affected path. |
| `Change.Origin` | `Origin` | Retain this definition/operation's attribution. |
| `Change.Previous` | `[]Origin` | Retain preceding selected origins after shape filtering. |
| `Change.Reasons` | `[]string` | Retain ordered recorded reasons without embedding configuration values. |
| `Change.Dependencies` | `[]Path` | Retain original recorded dependency paths independently of replay grouping. |
| `Result.SourceContext` | `func (r *Result[T]) SourceContext(id string) (ResourceContext, bool)` | Retain passive lookup by origin source ID; do not open or cache resource files implicitly. |
### Safe value inspection and comparison
Declarations: [diff.go](../../diff.go), [inspection.go](../../inspection.go).
| Entry | Declaration/type | Assessment |
| --- | --- | --- |
| `Difference` | `type Difference struct` | Retain a separate changed-region record; effective comparison is not a provenance/history diff. |
| `Difference.Path` | `Path` | Retain canonical changed-region coordinates. |
| `Difference.Left` | `ValueSnapshot` | Retain the safe left snapshot under combined classification, not independently rendered context. |
| `Difference.Right` | `ValueSnapshot` | Retain left/right symmetry; before/after belongs to chronological history. |
| `Difference.HiddenChanged` | `bool` | Retain actual concealed-change indication distinct from Redacted. |
| `Diff` | `func Diff[T any](left, right *Result[T]) ([]Difference, error)` | Retain same-type frozen-result comparison; nil/zero results are errors and credential contents are not compared. |
| `ValueSnapshot` | `type ValueSnapshot struct` | Retain detached Present/Redacted/YAML state, shared by explanation and diff without exposing parser nodes. |
| `ValueSnapshot.Present` | `bool` | Retain absence/deletion versus explicit null; YAML text alone is insufficient. |
| `ValueSnapshot.Redacted` | `bool` | Retain a structured mask flag; consumers must not interpret marker text. |
| `ValueSnapshot.YAML` | `string` | Retain deterministic safe text, not a reloadable or mutable node promise. |
| `ValueChange` | `type ValueChange struct` | Retain value-bearing replay record distinct from metadata Change; do not force both projections into one record (C3). |
| `ValueChange.Before` | `ValueSnapshot` | Retain the earlier safe value with explicit presence. |
| `ValueChange.After` | `ValueSnapshot` | Retain chronological before/after symmetry. |
| `ValueChange.Origin` | `Origin` | Retain attribution from shared evidence, without requiring identical metadata/explanation event lists. |
| `ValueChange.Reasons` | `[]string` | Retain ordered application intent; consumers remain responsible for safe prose. |
| `ValueChange.Dependencies` | `[]Path` | Retain recorded dependencies and their semantic paths. |
| `SecretReferenceInfo` | `type SecretReferenceInfo struct` | Retain explicit resolved-reference annotation; it is different from redaction classification. |
| `SecretReferenceInfo.Name` | `string` | Retain public environment name only; do not add credential content. |
| `Explanation` | `type Explanation struct` | Retain effective state plus safe chronological values; not a second mutable configuration object. |
| `Explanation.Path` | `Path` | Retain the queried semantic path. |
| `Explanation.Effective` | `ValueSnapshot` | Retain final safe value even for a path now absent. |
| `Explanation.Origin` | `Origin` | Retain effective provenance separate from each historical event's origin. |
| `Explanation.History` | `[]ValueChange` | Retain ValueChange replay, not a converted Metadata.History list (C3). |
| `Explanation.SecretReference` | `*SecretReferenceInfo` | Retain optional resolved-reference name; a classified path can withhold this annotation. |
### Typed credentials and explicit bootstrap
Declarations: [secret.go](../../secret.go), [secrets.go](../../secrets.go).
| Entry | Declaration/type | Assessment |
| --- | --- | --- |
| `Secret` | `type Secret struct` | Retain opaque environment reference and explicit credential access. Zero is unresolved/unspecified; a surviving non-pointer Secret is required. |
| `SecretEnv` | `func SecretEnv(name string) Secret` | Retain an explicit reference constructor; no plain-string credential constructor. |
| `Secret.EnvName` | `func (s Secret) EnvName() string` | Retain public reference access separate from credential access. |
| `Secret.Value` | `func (s Secret) Value() string` | Retain deliberate credential accessor; empty means unresolved. Do not combine it with formatting. |
| `Secret.IsResolved` | `func (s Secret) IsResolved() bool` | Retain cheap explicit resolution-state query despite nonempty-value validation. |
| `Secret.Format` | `func (s Secret) Format(state fmt.State, _ rune)` | Retain fmt.Formatter safety for all formatting verbs; do not replace it with only String. |
| `Secret.MarshalJSON` | `func (s Secret) MarshalJSON() ([]byte, error)` | Retain name-only json.Marshaler behavior, not a credential serialization API. |
| `SecretFileStatus` | `type SecretFileStatus string` | Retain distinct loaded/skipped/not-applied/failed states; partial bootstrap needs more than success/failure. |
| `SecretFileResult` | `type SecretFileResult struct` | Retain value-free per-entry bootstrap outcome, distinct from load sources. |
| `SecretFileResult.Name` | `string` | Retain entry/environment name, never content. |
| `SecretFileResult.Path` | `string` | Retain safe source-file attribution. |
| `SecretFileResult.Status` | `SecretFileStatus` | Retain structured status, not interpretation of report text. |
| `SecretFileResult.ExistingEmpty` | `bool` | Retain empty-existing winner evidence for skipped entries; zero does not mean that an entry was loaded. |
| `SecretsReport` | `type SecretsReport struct` | Retain detached bootstrap outcomes; zero/nil has no entries. A report may accompany an error. |
| `SecretsReport.Entries` | `func (r *SecretsReport) Entries() []SecretFileResult` | Retain copied filename-ordered outcomes. |
| `SecretsReport.WriteTo` | `func (r *SecretsReport) WriteTo(output io.Writer) (int64, error)` | Retain io.WriterTo-compatible count/error convention; do not force other renderers to return counts just for symmetry. |
| `SecretsError` | `type SecretsError struct` | Retain separate bootstrap failure type: reports partial external effects, unlike a failed configuration load. |
| `SecretsError.Error` | `func (e *SecretsError) Error() string` | Retain safe value-free summary and errors.As support through its type. |
| `SecretsError.Diagnostics` | `func (e *SecretsError) Diagnostics() []Diagnostic` | Retain detached bootstrap diagnostics; no automatic raw filesystem/environment error unwrapping. |
| `LoadSecretsDir` | `func LoadSecretsDir(directory string) (*SecretsReport, error)` | Discuss D7: BootstrapSecretsDir makes process-environment mutation clearer than another Load name. |
### Diagnostics and failed loads
Declarations: [diagnostic.go](../../diagnostic.go), [records.go](../../records.go).
| Entry | Declaration/type | Assessment |
| --- | --- | --- |
| `LoadError` | `type LoadError struct` | Retain a concrete inspectable load error and errors.As workflow; zero/nil renders a safe generic failure. |
| `LoadError.Error` | `func (e *LoadError) Error() string` | Retain value-free summary, not detailed raw parser/application errors. |
| `LoadError.Diagnostics` | `func (e *LoadError) Diagnostics() []Diagnostic` | Retain detached structured diagnostics; do not add Unwrap that defeats safe error boundaries. |
| `LoadError.Sources` | `func (e *LoadError) Sources() []SourceInfo` | Retain acquired-source evidence available before failure. |
| `WriteDiagnostics` | `func WriteDiagnostics(output io.Writer, diagnostics []Diagnostic) error` | Retain writer-first safe deterministic rendering; do not promise stable prose beyond established contracts. |
| `Severity` | `type Severity string` | Retain the two diagnostic severities; no arbitrary numeric priority surface. |
| `Code` | `type Code string` | Retain detailed stable diagnostic codes; collapsing categories would lose useful consumer handling. |
| `Diagnostic` | `type Diagnostic struct` | Retain a common safe problem record across loading, hooks, and bootstrap. |
| `Diagnostic.Code` | `Code` | Retain stable machine classification rather than matching prose. |
| `Diagnostic.Severity` | `Severity` | Retain explicit severity, independent of diagnostic code spelling. |
| `Diagnostic.Path` | `Path` | Retain semantic configuration path, not a filesystem location. |
| `Diagnostic.Message` | `string` | Retain human-readable safe context; no automatic secret inference or blanket prose-stability guarantee. |
| `Diagnostic.Primary` | `*Location` | Retain optional primary source position; synthetic reports may lack one. |
| `Diagnostic.Related` | `[]Location` | Retain ordered related locations; do not homogenize semantically meaningful composition claimant order. |
### Constants and their values
Each constant is separately listed. Retaining a diagnostic code preserves a
machine-readable failure distinction; consumers should not infer new guarantees
from a name or assume that the current set can never grow. D8 notes the one
unproduced named code identified for discussion. This catalog does not prescribe
new diagnostics or merge existing failure categories.
#### PlacementMode constants
| Entry | Type and value | Assessment |
| --- | --- | --- |
| `PlacementModeMapping` | `PlacementMode = 0` | Retain explicit mapping default. |
| `PlacementModeSequenceItem` | `PlacementMode = 1` | Retain explicit record placement. |
#### SourceVersionMode constants
| Entry | Type and value | Assessment |
| --- | --- | --- |
| `SourceVersionModeDefault` | `SourceVersionMode = 0` | Discuss D3: MainOnly names the existing zero behavior more precisely. |
| `SourceVersionModeIfPresent` | `SourceVersionMode = 1` | Retain; keep the documented main-absence checker behavior. |
| `SourceVersionModeRequired` | `SourceVersionMode = 2` | Retain participating-document requirement and existing NoSource behavior. |
#### Layer constants
| Entry | Type and value | Assessment |
| --- | --- | --- |
| `LayerDefault` | `Layer = "default"` | Retain distinct provenance layer. |
| `LayerBase` | `Layer = "base"` | Retain established base/main attribution; no automatic wire-value rename. |
| `LayerUnderlay` | `Layer = "underlay"` | Retain distinct provenance layer. |
| `LayerOverlay` | `Layer = "overlay"` | Retain distinct provenance layer. |
| `LayerCLI` | `Layer = "cli"` | Retain distinct provenance layer. |
| `LayerResolution` | `Layer = "resolution"` | Retain distinct provenance layer. |
#### SourceKind constants
| Entry | Type and value | Assessment |
| --- | --- | --- |
| `SourceKindFile` | `SourceKind = "file"` | Retain distinct acquisition kind, independent of layer. |
| `SourceKindFilesystem` | `SourceKind = "filesystem"` | Retain distinct acquisition kind, independent of layer. |
| `SourceKindBytes` | `SourceKind = "bytes"` | Retain distinct acquisition kind, independent of layer. |
| `SourceKindReader` | `SourceKind = "reader"` | Retain distinct acquisition kind, independent of layer. |
| `SourceKindMapping` | `SourceKind = "mapping"` | Retain distinct acquisition kind, independent of layer. |
| `SourceKindCLI` | `SourceKind = "cli"` | Retain distinct acquisition kind, independent of layer. |
#### ChangeKind constants
| Entry | Type and value | Assessment |
| --- | --- | --- |
| `ChangeDecoding` | `ChangeKind = "decoding"` | Retain inspection value; D6 addresses its misleading availability as a Record argument. |
| `ChangeInheritance` | `ChangeKind = "inheritance"` | Retain inspection value; D6 addresses its misleading availability as a Record argument. |
| `ChangeDerivedDefault` | `ChangeKind = "derived_default"` | Retain recorded/inspected intent; discuss the Record input shape in D6. |
| `ChangeNormalization` | `ChangeKind = "normalization"` | Retain recorded/inspected intent; discuss the Record input shape in D6. |
#### Severity constants
| Entry | Type and value | Assessment |
| --- | --- | --- |
| `SeverityError` | `Severity = "error"` | Retain explicit diagnostic severity. |
| `SeverityWarning` | `Severity = "warning"` | Retain explicit diagnostic severity. |
#### Code constants
| Entry | Type and value | Assessment |
| --- | --- | --- |
| `CodeSourceInvalid` | `Code = "source.invalid"` | Retain distinct source / invalid classification. |
| `CodeSourceMissing` | `Code = "source.missing"` | Retain distinct source / missing classification. |
| `CodeSourcePermission` | `Code = "source.permission"` | Retain distinct source / permission classification. |
| `CodeSourceRead` | `Code = "source.read"` | Retain distinct source / read classification. |
| `CodeSourceNotRegular` | `Code = "source.not_regular"` | Retain distinct source / not regular classification. |
| `CodeSourceLimitExceeded` | `Code = "source.limit_exceeded"` | Retain distinct source / limit exceeded classification. |
| `CodeSourceReaderUsed` | `Code = "source.reader_used"` | Retain distinct source / reader used classification. |
| `CodeYAMLInvalid` | `Code = "yaml.invalid"` | Retain distinct yaml / invalid classification. |
| `CodeYAMLEmpty` | `Code = "yaml.empty"` | Retain distinct yaml / empty classification. |
| `CodeYAMLMultipleDocuments` | `Code = "yaml.multiple_documents"` | Retain distinct yaml / multiple documents classification. |
| `CodeYAMLRootType` | `Code = "yaml.root_type"` | Retain distinct yaml / root type classification. |
| `CodeYAMLDuplicateKey` | `Code = "yaml.duplicate_key"` | Retain distinct yaml / duplicate key classification. |
| `CodeYAMLTag` | `Code = "yaml.tag"` | Retain distinct yaml / tag classification. |
| `CodeYAMLAnchor` | `Code = "yaml.anchor"` | Retain distinct yaml / anchor classification. |
| `CodeYAMLAlias` | `Code = "yaml.alias"` | Retain distinct yaml / alias classification. |
| `CodeYAMLMergeKey` | `Code = "yaml.merge_key"` | Retain distinct yaml / merge key classification. |
| `CodeYAMLScalar` | `Code = "yaml.scalar"` | Retain distinct yaml / scalar classification. |
| `CodeYAMLDepthLimit` | `Code = "yaml.depth_limit"` | Retain distinct yaml / depth limit classification. |
| `CodeYAMLNodeLimit` | `Code = "yaml.node_limit"` | Retain distinct yaml / node limit classification. |
| `CodeSchemaRoot` | `Code = "schema.root"` | Retain distinct schema / root classification. |
| `CodeSchemaUnsupportedType` | `Code = "schema.unsupported_type"` | Retain distinct schema / unsupported type classification. |
| `CodeSchemaAmbiguousField` | `Code = "schema.ambiguous_field"` | Retain distinct schema / ambiguous field classification. |
| `CodeSchemaTag` | `Code = "schema.tag"` | Retain distinct schema / tag classification. |
| `CodeSchemaTextCodec` | `Code = "schema.text_codec"` | Retain distinct schema / text codec classification. |
| `CodeSchemaInline` | `Code = "schema.inline"` | Retain distinct schema / inline classification. |
| `CodeSchemaCycle` | `Code = "schema.cycle"` | Retain distinct schema / cycle classification. |
| `CodeSchemaProjectionLimit` | `Code = "schema.projection_limit"` | Retain distinct schema / projection limit classification. |
| `CodeSchemaCodec` | `Code = "schema.codec"` | Retain distinct schema / codec classification. |
| `CodeSchemaNonFinite` | `Code = "schema.non_finite"` | Retain distinct schema / non finite classification. |
| `CodeSchemaDynamicType` | `Code = "schema.dynamic_type"` | Retain distinct schema / dynamic type classification. |
| `CodeDecodeType` | `Code = "decode.type"` | Retain distinct decode / type classification. |
| `CodeDecodeNull` | `Code = "decode.null"` | Retain distinct decode / null classification. |
| `CodeDecodeRange` | `Code = "decode.range"` | Retain distinct decode / range classification. |
| `CodeDecodeDuration` | `Code = "decode.duration"` | Retain distinct decode / duration classification. |
| `CodeDecodeText` | `Code = "decode.text"` | Retain distinct decode / text classification. |
| `CodeDecodeUnknownField` | `Code = "decode.unknown_field"` | Retain distinct decode / unknown field classification. |
| `CodeDecodeArrayLength` | `Code = "decode.array_length"` | Retain distinct decode / array length classification. |
| `CodeOptionsInvalid` | `Code = "options.invalid"` | Retain distinct options / invalid classification. |
| `CodeOptionsUnavailable` | `Code = "options.unavailable"` | Discuss D8: confirm intentional reservation or remove the unproduced classification. |
| `CodeImportDisabled` | `Code = "import.disabled"` | Retain distinct import / disabled classification. |
| `CodeImportInvalid` | `Code = "import.invalid"` | Retain distinct import / invalid classification. |
| `CodeImportMissing` | `Code = "import.missing"` | Retain distinct import / missing classification. |
| `CodeImportPermission` | `Code = "import.permission"` | Retain distinct import / permission classification. |
| `CodeImportRead` | `Code = "import.read"` | Retain distinct import / read classification. |
| `CodeImportOutsideRoot` | `Code = "import.outside_root"` | Retain distinct import / outside root classification. |
| `CodeImportCycle` | `Code = "import.cycle"` | Retain distinct import / cycle classification. |
| `CodeImportRepeated` | `Code = "import.repeated"` | Retain distinct import / repeated classification. |
| `CodeImportLimitExceeded` | `Code = "import.limit_exceeded"` | Retain distinct import / limit exceeded classification. |
| `CodeImportVersion` | `Code = "import.version"` | Retain distinct import / version classification. |
| `CodeSequenceInvalid` | `Code = "sequence.invalid"` | Retain distinct sequence / invalid classification. |
| `CodeSequenceConflict` | `Code = "sequence.conflict"` | Retain distinct sequence / conflict classification. |
| `CodeUnderlayVersion` | `Code = "underlay.version"` | Retain distinct underlay / version classification. |
| `CodeOverlayInvalid` | `Code = "overlay.invalid"` | Retain distinct overlay / invalid classification. |
| `CodeOverlayMissing` | `Code = "overlay.missing"` | Retain distinct overlay / missing classification. |
| `CodeOverlayOutsideRoot` | `Code = "overlay.outside_root"` | Retain distinct overlay / outside root classification. |
| `CodeOverlayRepeated` | `Code = "overlay.repeated"` | Retain distinct overlay / repeated classification. |
| `CodeOverlayDirective` | `Code = "overlay.directive"` | Retain distinct overlay / directive classification. |
| `CodeOverlayVersion` | `Code = "overlay.version"` | Retain distinct overlay / version classification. |
| `CodeOverlayLimitExceeded` | `Code = "overlay.limit_exceeded"` | Retain distinct overlay / limit exceeded classification. |
| `CodeComposeInvalid` | `Code = "compose.invalid"` | Retain distinct compose / invalid classification. |
| `CodeComposeConflict` | `Code = "compose.conflict"` | Retain distinct compose / conflict classification. |
| `CodeVersionType` | `Code = "version.type"` | Retain distinct version / type classification. |
| `CodeVersionError` | `Code = "version.error"` | Retain distinct version / error classification. |
| `CodeVersionWarning` | `Code = "version.warning"` | Retain distinct version / warning classification. |
| `CodeVersionHookFailed` | `Code = "version.hook_failed"` | Retain distinct version / hook failed classification. |
| `CodeResolveError` | `Code = "resolve.error"` | Retain distinct resolve / error classification. |
| `CodeResolveWarning` | `Code = "resolve.warning"` | Retain distinct resolve / warning classification. |
| `CodeResolveHookFailed` | `Code = "resolve.hook_failed"` | Retain distinct resolve / hook failed classification. |
| `CodeResolveInvalidPath` | `Code = "resolve.invalid_path"` | Retain distinct resolve / invalid path classification. |
| `CodeResolveInvalidKind` | `Code = "resolve.invalid_kind"` | Retain distinct resolve / invalid kind classification. |
| `CodeResolveInvalidRecord` | `Code = "resolve.invalid_record"` | Retain distinct resolve / invalid record classification. |
| `CodeResolveInvalidTarget` | `Code = "resolve.invalid_target"` | Retain distinct resolve / invalid target classification. |
| `CodeResolveInvalidValue` | `Code = "resolve.invalid_value"` | Retain distinct resolve / invalid value classification. |
| `CodeResolveUnrecordedChange` | `Code = "resolve.unrecorded_change"` | Retain distinct resolve / unrecorded change classification. |
| `CodeValidateError` | `Code = "validate.error"` | Retain distinct validate / error classification. |
| `CodeValidateWarning` | `Code = "validate.warning"` | Retain distinct validate / warning classification. |
| `CodeValidateInvalidPath` | `Code = "validate.invalid_path"` | Retain distinct validate / invalid path classification. |
| `CodeValidateMutation` | `Code = "validate.mutation"` | Retain distinct validate / mutation classification. |
| `CodeSecretsInvalidPath` | `Code = "secrets.invalid_path"` | Retain distinct secrets / invalid path classification. |
| `CodeSecretsMissing` | `Code = "secrets.missing"` | Retain distinct secrets / missing classification. |
| `CodeSecretsPermission` | `Code = "secrets.permission"` | Retain distinct secrets / permission classification. |
| `CodeSecretsRead` | `Code = "secrets.read"` | Retain distinct secrets / read classification. |
| `CodeSecretsNotRegular` | `Code = "secrets.not_regular"` | Retain distinct secrets / not regular classification. |
| `CodeSecretsInvalidName` | `Code = "secrets.invalid_name"` | Retain distinct secrets / invalid name classification. |
| `CodeSecretsLimitExceeded` | `Code = "secrets.limit_exceeded"` | Retain distinct secrets / limit exceeded classification. |
| `CodeSecretsInvalidValue` | `Code = "secrets.invalid_value"` | Retain distinct secrets / invalid value classification. |
| `CodeSecretsApplyFailed` | `Code = "secrets.apply_failed"` | Retain distinct secrets / apply failed classification. |
| `CodeSecretRequired` | `Code = "secret.required"` | Retain distinct secret / required classification. |
| `CodeSecretInvalidName` | `Code = "secret.invalid_name"` | Retain distinct secret / invalid name classification. |
| `CodeSecretUnset` | `Code = "secret.unset"` | Retain distinct secret / unset classification. |
| `CodeSecretEmpty` | `Code = "secret.empty"` | Retain distinct secret / empty classification. |
| `CodeOverrideInvalidPath` | `Code = "override.invalid_path"` | Retain distinct override / invalid path classification. |
| `CodeOverrideInvalidLabel` | `Code = "override.invalid_label"` | Retain distinct override / invalid label classification. |
| `CodeOverrideInvalidValue` | `Code = "override.invalid_value"` | Retain distinct override / invalid value classification. |
| `CodeOverrideDuplicate` | `Code = "override.duplicate"` | Retain distinct override / duplicate classification. |
| `CodeOverrideOverlap` | `Code = "override.overlap"` | Retain distinct override / overlap classification. |
| `CodeOverrideDirective` | `Code = "override.directive"` | Retain distinct override / directive classification. |
| `CodeOverrideVersion` | `Code = "override.version"` | Retain distinct override / version classification. |
| `CodeOverrideLimitExceeded` | `Code = "override.limit_exceeded"` | Retain distinct override / limit exceeded classification. |
| `CodeExplainLimitExceeded` | `Code = "explain.limit_exceeded"` | Retain distinct explain / limit exceeded classification. |
| `CodeInheritanceInvalid` | `Code = "inheritance.invalid"` | Retain distinct inheritance / invalid classification. |
| `CodeInheritanceMissing` | `Code = "inheritance.missing"` | Retain distinct inheritance / missing classification. |
| `CodeInheritanceCycle` | `Code = "inheritance.cycle"` | Retain distinct inheritance / cycle classification. |
| `CodeInheritanceVersion` | `Code = "inheritance.version"` | Retain distinct inheritance / version classification. |
#### ImportSelector constants
| Entry | Type and value | Assessment |
| --- | --- | --- |
| `ImportSelectorPath` | `ImportSelector = "path"` | Retain distinct authored selector kind. |
| `ImportSelectorDirectory` | `ImportSelector = "dir"` | Retain distinct authored selector kind. |
| `ImportSelectorGlob` | `ImportSelector = "glob"` | Retain distinct authored selector kind. |
#### ImportSelectionOutcome constants
| Entry | Type and value | Assessment |
| --- | --- | --- |
| `ImportSelectionNone` | `ImportSelectionOutcome = "none"` | Discuss D4: redundant if the record explicitly describes empty selections only. |
#### SecretFileStatus constants
| Entry | Type and value | Assessment |
| --- | --- | --- |
| `SecretFileLoaded` | `SecretFileStatus = "loaded"` | Retain successful application outcome. |
| `SecretFileSkippedExisting` | `SecretFileStatus = "skipped_existing"` | Retain existing-environment winner, including empty winners. |
| `SecretFileNotApplied` | `SecretFileStatus = "not_applied"` | Retain planned but unapplied outcome, distinct from a failed entry. |
| `SecretFileFailed` | `SecretFileStatus = "failed"` | Retain failed-entry outcome, distinct from unapplied siblings. |
## Validation And Next Discussion
The catalog has one row for each of the 372 exported declarations/members
found by the syntax inventory. The callable/type/field signatures were read from
the declarations rather than reconstructed from the graph. The graph supported
navigation and reference checks; its inventory alone was not treated as proof of
completeness. Implicit interfaces include error for `*LoadError` and
`*SecretsError`, fmt.Stringer for Path, fmt.Formatter and json.Marshaler for Secret,
and io.WriterTo for `*SecretsReport`; there are no separate exported interface types.
Useful existing behavioral owners include the public facade boundary and
compatibility tests, callback-context guards, consumer examples, and metadata,
secret, explanation, source-version, discovery, and sequence tests linked by the
[development guide](../development.md#task-to-test-map). This documentation-only
review adds no tests or production changes. Validation completed: the syntax
comparison found exactly one catalog row for all 372 entries, with no missing
entries. The local documentation-link and public-facade boundary tests passed,
as did the whitespace check.
Next, decide which D1–D8 candidates merit changes. Prepare a scoped roadmap/plan
only for accepted decisions and update the declaration comments, contract owners,
examples and consumers together during that implementation. Preserve the current
loading, presence, composition, callback-lifetime, redaction and ownership contracts
unless a separately explicit decision changes one. No release or tagging action
is authorized by this review.