diff --git a/docs/roadmap/review.md b/docs/roadmap/review.md new file mode 100644 index 0000000..095ad19 --- /dev/null +++ b/docs/roadmap/review.md @@ -0,0 +1,793 @@ +# 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.