# Configuration Input Destinations Roadmap Status: implemented. This roadmap records the approved behavior and rationale for the [PromptKit feature request](promptkit-feature-request.md). The [implementation plan](implementation.md) records the completed sequence and audit evidence; the [configuration contract](../config.md#input-destinations) owns current behavior. ## Targeted end state A consumer can assign a mapping destination to a configuration input and perform one ordinary `LoadLayered` call. The input's application content contributes beneath that destination while retaining normal composition, precedence, inheritance, typed loading, diagnostics, and inspection. PromptKit can assemble collections without parsing and rewriting sources, merging values, or rebuilding provenance itself. For example, a fragment defining `summarize.alerts` can contribute beneath `collections`, `weatherreporter`, `prompts`. An independent source with the same local key can contribute beneath another collection without conflict. Collection and prompt names remain ordinary application keys, not ConfigKit namespaces. The public surface adds an optional `Destination Path` field on `Input`, not a new loading entry point or an operation on completed results. Content-bearing main inputs and underlay inputs support the same destination model; root placement remains the default. The following behavior defines the target: - Omitted and empty destinations retain root placement. Destinations consist of literal mapping keys, including dots, slashes, and numeric-looking text. Explicit sequence-index destinations are outside the requested capability. - A valid destination on `NoSource` contributes nothing. An actual empty application mapping materializes its destination mappings as explicit input, matching authored wrappers, without clearing lower-tier children. - Existing structural reservations apply to introduced mappings. Destinations that materialize `configkit` or a mapping-valued `extends` contrary to existing contracts fail through the structured loading-error boundary. Keys merely containing those words remain ordinary keys. - Host files, native filesystem files, bytes, readers, and mapping sources all support placement under their existing acquisition and ownership contracts. Filesystem context, import opt-in, and precedence remain independent choices. - Mounted contributions have the same application values and conflict behavior as explicitly wrapped contributions, with accurate original source locations. Disjoint mappings combine; overlapping non-mapping values within a group conflict even when equal. A later tier cannot repair a strict-group conflict. - Different destinations can coexist in one group, and the same destination can occur in different tiers. Ancestor/descendant destinations follow ordinary composition and overlay rules without namespace uniqueness restrictions. Later tiers recursively overlay mappings and replace other values. Empty mappings do not clear lower values; sequences remain atomic. - A prompt's ordinary `version` override changes that field and retains omitted lower fields. It neither identifies a merge record nor replaces a whole prompt. - Source-root `configkit.imports` remains structural. Imported application data inherits the input destination transitively. Import paths still resolve from their declaring source; containment, optionality, cycles, and repeated-source rules remain applicable. Placement does not change physical source identity. - Sibling inheritance runs after assembly in the effective destination scope. Peer fragments can supply a child and its sibling parent. Qualified PromptKit references do not acquire cross-collection inheritance meaning. - Version ownership is enforced at effective application paths. A collection's mounted `version` is ordinary data, while underlay/import contributions to the actual protected path, or replacements of its ancestors, remain invalid. There is one main-owned version check and no blanket nested numeric conversion. - Defaults, decoding, resolution, secret lookup, and validation run once on the assembled application, not independently on fragments. Callbacks and value diagnostics use effective paths. Failures use structured load errors and yield no usable partial result. - Presence, provenance, history, explanations, effective rendering, and diffs agree with the final values. Sensitivity is evaluated at effective application paths under the existing historical and dependency rules. - Existing source records expose placement, including inherited import placement. Introduced ancestor mappings retain the contributing source's identity; any root-location fallback identifies that document, not an authored wrapper. Actual content retains its real source coordinates. - Original source locations and passive resource contexts survive placement, overrides, and inheritance. `Result.SourceContext` and `Resolution.SourceContext` still identify the declaring filesystem and base directory for a field such as `content_file: ./summary.md`. - Destinations and the structure they introduce participate in existing load limits; placement cannot bypass depth or node accounting. Source ownership, complete-on-return loading, and detached result behavior remain intact. Import-destination syntax, independent collection specification headers, and cross-collection inheritance are separate possible follow-ups. This work does not add directory discovery, collection installation, remote acquisition, namespace ownership enforcement, dependency solving, live reload, filename-based identity, arbitrary transformations, or new merge strategies. PromptKit owns its collection inventory, qualified IDs, and execution semantics. ## Implementation baseline (v0.7.1) The request reviewed v0.7.1. At that baseline, the relevant boundaries were: - [Input](../../layered.go) holds a source, import opt-in, and filesystem context, but no destination. Root types delegate to the engine through the existing [facade boundary](../internal/overview.md). - [Layered loading](../config.md#layered-loading) already provides strict groups, ordered precedence, shared acquisition budgets, and one final lifecycle. [Underlay acquisition](../../internal/engine/load_request.go) gathers source applications and recomposes them into their strict group. - [Input acquisition](../../internal/engine/load_input.go) and [import traversal](../../internal/engine/imports.go) process source-root directives and source identity before final assembly. Imported version claims are checked during traversal; underlay claims are checked before group composition. These currently operate without a destination. - [Version claim checks](../../internal/engine/directives.go) inspect a document using the configured application path. Wrapping only an already acquired result would leave early fragment checks and diagnostic paths incorrect. - [Sibling inheritance](../adr/0009-sibling-inheritance.md) already runs after source precedence and preserves source-to-destination derivation. Placement must feed that existing mechanism rather than resolve fragments independently. - Existing source records identify acquisition and precedence but do not expose input placement. Existing history retains source applications, so moving only the final tree would be insufficient for coherent inspection. The architectural fit is an extension of input assembly, not a parser extension or a second configuration model. The [architecture policy](../policy/architecture.md) supplies the ownership and consistency constraints; [deferred scope](deferred.md) continues to govern the unrequested features above. ## Selected Design Decisions ### Main-input destinations and absent inputs Allow the same destination model for content-bearing main inputs and underlays, with `VersionRule.Path` remaining an effective application path and any specification declaration still owned by main. The checker retains its existing handling of an absent declaration and its existing lifecycle phase. `NoSource` contributes nothing even with a valid destination. This keeps `Input` coherent across its roles and preserves absence without per-fragment version checks. ### Public placement inspection and synthetic ancestors Expose effective placement as `SourceInfo.Destination Path` on existing source records, including inherited import placement. Use original source identity for introduced ancestor mappings, documenting that any root-location fallback identifies the contributing document rather than a physically authored wrapper. Actual content keeps its real coordinates. This allows consumers to connect placement to sources without a new query system. Preserve that relationship through inherited fields, composite origins, and the same source selected in separate tiers. Placement is per source application; consumers can inspect it without inferring it from final paths. ### Reserved structural keys in destinations Use existing `Path` conventions for literal keys and parsed numeric tokens, reject explicit index segments, and preserve current structural reservations in the effective tree. Reject destination segments that would materialize `configkit` or a mapping-valued `extends` contrary to those contracts, with a clear structured destination error. Ordinary keys containing those words, dots, or slashes remain ordinary keys. Source-root directives are processed before placement and are not rejected simply because their application body is mounted. Mounted and authored wrappers therefore retain the same structural meaning. Destination diagnostics identify placement as the cause of invalid introduced structure, using existing error categories where suitable. ### Empty mappings and presence of introduced containers Mounting an actual empty application mapping materializes its destination mappings as explicit contributions, matching authored wrappers. This preserves the request's equivalence principle and lets consumers inspect an intentionally empty collection. Such mappings still do not clear lower-tier children. An absent source contributes nothing. This applies equally to empty imported application bodies and inputs containing only import directives. Presence follows the contribution's meaning rather than whether an implementation happened to allocate wrapper nodes.