Record input destination decision and baseline

This commit is contained in:
2026-10-14 13:05:09 +00:00
parent d3d468a8b4
commit ea55ab43ce
2 changed files with 105 additions and 3 deletions

View File

@@ -0,0 +1,70 @@
# ADR 0011: Place Configuration Inputs at Mapping Destinations
## Status
Accepted. The [input-destinations roadmap](../roadmap/input-destinations.md)
owns implementation status and the [implementation plan](../roadmap/implementation.md)
owns sequencing and completion evidence.
## Date
2026-10-14
## Context
Consumers assembling collections of independently authored configuration
fragments need each source to contribute beneath a selected application path.
Requiring consumers to rewrite source documents or merge completed values would
separate placement from ConfigKit's existing composition, precedence, source
identity, and inspection behavior. Placement should remain part of the ordinary
loading lifecycle and preserve the root-owned public facade.
## Decision
Add an optional `Destination Path` to root-owned `Input` and expose the effective
destination on existing `SourceInfo` records. The empty path means the existing
application root. A non-empty destination is a sequence of literal mapping keys;
explicit sequence-index segments are invalid. Existing reserved structural keys
remain reserved, while keys that merely contain their spelling remain ordinary
keys.
Acquire and interpret each source using its original physical identity and
source-local directives, then place its application body before strict
composition and the existing final lifecycle. Imported application bodies
inherit the input destination. Placement applies to main and underlay inputs;
ordinary root loading, selected overlays, and CLI inputs retain root placement.
The main-owned version rule continues to check its effective application path
at its existing lifecycle point.
Placement preserves authored node locations and source identity. Introduced
mapping structure belongs to the contributing source and uses that document's
root location as its source-coordinate fallback. A present empty mapping
materializes its destination; an absent `NoSource` contributes nothing. The
result continues through the existing strict composition, overlay, inheritance,
typed loading, diagnostics, provenance, history, sensitivity, and resource
context mechanisms.
The added exported fields preserve keyed and zero-value struct use. Callers
using unkeyed composite literals for `Input` or `SourceInfo` must migrate to
keyed literals. Treat this feature as minor-release work; select the version and
document the compatibility impact during separately authorized release
preparation, consistent with the release policy.
## Alternatives considered
- **Rewrite or merge sources in consumers.** This makes each consumer reproduce
placement, strict composition, source attribution, and inspection semantics.
- **Add a separate loading entry point or public wrapper type.** This creates a
parallel API for a behavior that belongs to existing per-input loading.
- **Load each fragment as a complete application before placement.** This runs
defaults, decoding, resolution, and validation on incomplete fragments rather
than once on the assembled application.
## Consequences
Consumers can assemble contributions at effective mapping paths in one ordinary
layered load and inspect each source's placement through existing source
records. Paths, conflicts, and later application operations use the placed
structure while source coordinates and relative-resource contexts continue to
identify their original sources. Public field additions require release-note
guidance for callers using unkeyed literals.

View File

@@ -123,7 +123,7 @@ completion evidence. Planning baseline: `6353598`.
## Stage 1 — Record the decision and capture the baseline
Status: planned. Scope: decision record and evidence, no feature code.
Status: complete. Scope: decision record and evidence, no feature code.
1. Read the roadmap, request, relevant policies, and ADRs 0001, 0003, 0006,
0008, and 0009. Inspect the owners identified in the roadmap and the function
@@ -142,8 +142,40 @@ Status: planned. Scope: decision record and evidence, no feature code.
as minor-release work; select a version and write its note only during
separately authorized release preparation.
Validate: local-link test and whitespace checks. Done: baseline evidence and
the decision are recorded; implemented contracts remain unchanged.
Validated: `./scripts/check.sh` (go1.26.8 linux/amd64) passed on candidate
`d3d468a8b47d780787fca329ff65b107d98ca59f`; this includes formatting,
whitespace, local documentation links, tests, vet, and build. The planning
baseline `6353598bd6cce2eb78a5fe990e144cc0cadf1280` is present in history. The
worktree was clean before this stage.
Coverage located for later destination work:
- Root and equivalent source loading: `TestEquivalentSourceFormsPreserveInputSemantics`
(`facade_equivalence_test.go`) and
`TestFacadeLayeredZeroUnderlaysMatchesOrdinaryLoad` (`facade_layered_test.go`).
- Strict underlays and group budgets: `TestGroupedLoadStrictConflictsRepetitionAndBudgets`
and `TestGroupedLoadPrecedenceSourceOrderAndSingleLifecycle`
(`internal/engine/load_request_test.go`).
- Version ownership and imported claims: `TestLoadRejectsImportConflictsAndFragmentVersions`
(`internal/engine/imports_test.go`) and version-path coverage in
`internal/engine/load_test.go`.
- Repeated physical sources: `TestRepeatedImportsAcrossTiersAndReaderConsumption`
(`facade_equivalence_test.go`).
- History and source contexts: `TestUnderlayHistoryRetainsLaterMappingContributors`
(`facade_underlay_origins_test.go`) and
`TestFacadeSourceContextsFollowOriginsWithoutQueryIO`
(`facade_resource_context_test.go`).
- Detached records: `TestLoadMetadataReflectsDefaultsInputAndDetachedRecords`
(`internal/engine/load_test.go`) and
`TestMetadataQueriesReturnDetachedRecords` (`internal/engine/metadata_test.go`).
The decision is recorded in [ADR 0011](../adr/0011-input-destinations.md).
Compatibility assessment: adding the two public fields breaks callers using
unkeyed literals for `Input` or `SourceInfo`; keyed and zero-value use remains
compatible. The release policy permits the intentional pre-1.0 contract change
in a minor release when the release note states impact and migration. Version
selection and release-note preparation remain out of scope until separately
authorized. No feature code or current behavior contract changed.
## Stage 2 — Add private destination normalization and wrapping