Files
ConfigKit/docs/roadmap/relative-import-destinations.md

7.4 KiB

Relative Import Destinations Roadmap

Status: complete. The implementation plan and its evidence were replaced by the shared source-version plan and remain in Git history at d9f08ff:docs/roadmap/implementation.md. This roadmap addresses only the relative-import-destination addition in the PromptKit request. Source-version checks were outside this roadmap's scope and are now implemented separately in the shared source-version roadmap.

Targeted end state

Authors can assign a relative mapping destination to a path or glob import. ConfigKit appends its literal key segments to the immediate importing document's effective destination, then processes the imported application content through the existing placement and loading lifecycle. Applications continue to select entry sources, input destinations, filesystem contexts, and precedence tiers.

Selected YAML syntax:

configkit:
  imports:
    - path: metadata.yml
    - glob: prompts/*.yml
      destination: [prompts]
    - glob: profiles/*.yml
      destination: [profiles]

If the application places this entry at [collections, weather], its metadata import contributes at that same path, and each prompt file contributes at [collections, weather, prompts]. An import declared inside a prompt file with destination: [extras] contributes at [collections, weather, prompts, extras]. A subsequent sibling import from the entry is still relative to [collections, weather].

This example does not declare or consume a source specification header. A source-local version remains ordinary payload unless governed by the existing main-owned version contract. The combined header example in the broader request is not an acceptance requirement for this roadmap.

The feature must preserve these requested and existing behaviors:

  • Omission and an empty destination list retain the importing document's destination. Each glob match receives the same relative placement. Transitive imports accumulate destinations from their immediate parents.
  • An explicit destination is a sequence of strings. Null, scalar values, and non-string members are invalid directive shapes; values are not coerced. For a numeric-looking key, use a string such as destination: ["0"].
  • Segments are mapping keys under the existing Input.Destination rules. Dots, slashes, and numeric-looking text within a key are literal. There is no filesystem-style normalization, parent traversal, or application-root reset. Do not add a collection-name grammar or reject otherwise supported literal keys merely because their spelling resembles a filesystem path.
  • Imports retain their strict-composition tier. Placement and traversal order do not confer precedence. Later tiers retain existing recursive overlay behavior; sequences remain atomic and overlapping destinations use existing composition rules.
  • Filesystem paths resolve from their declaring source independently of logical placement. Import opt-in, optionality, glob behavior, containment, cycle and repeated-source rules, source kinds, and ownership remain unchanged. A new destination does not allow a physical source to repeat within a strict group.
  • Source-root directives are interpreted before application placement. Existing reserved-key rules continue to apply to destinations. Invalid new directive shapes produce normal structured failures rather than being ignored.
  • SourceInfo.Destination reports each acquired source's resulting effective destination, including nested imports and sources recorded on failed loads to the extent supported by existing error reporting.
  • Composition and value diagnostics use effective application paths and real source locations. Directive errors identify their source-local declaration. Placement does not manufacture authored coordinates or alter resource bases.
  • Main-owned version protection applies at the resulting effective paths. Ordinary nested version fields stay ordinary payload. Inheritance resolves in the assembled sibling scope, then defaults, decoding, resolution, secret lookup, and validation follow the existing single-load lifecycle.
  • Presence, provenance, history, explanations, rendering, diffs, and sensitivity agree with the placed contributions. Source-relative resource contexts survive inheritance and precedence under their existing contracts.
  • Accumulated placement and introduced wrappers participate in existing depth and node accounting. This work does not select new limit values or promise new performance bounds. An actually imported empty mapping retains existing placement behavior; an optional import that finds no source creates no payload.

The syntax is available wherever existing explicit imports are supported, including ordinary root loading and layered main/underlay inputs. It does not require a new Go loading entry point, mount registry, or consumer-side rewriting.

Source header policies and consumption, cross-collection inheritance, sequence merging, root-reset syntax, automatic discovery, recursive glob syntax, and collection management are outside this delivery. This scope statement does not establish new permanent exclusions beyond existing deferred scope.

Pre-implementation baseline

Reviewed baseline: 315f464, with input destinations implemented. At that revision, the configuration contract and ADR 0011 described that feature.

  • Directive parsing accepted path or glob plus optional; it rejects unrecognized fields. Import declarations carried no relative destination.
  • Import traversal held one destination for an input's entire import tree. Both document placement and imported source records use it. Per-document effective placement is therefore required.
  • Input acquisition assigned the input destination to all returned imported source records. That uniform assignment must no longer overwrite distinct import destinations.
  • Destination helpers already validate literal mapping paths, place document bodies, and check introduced depth and node costs. Composition, version protection, and retained source applications already operate on placed content.
  • The root facade already exposes SourceInfo.Destination; the new syntax can use that inspection surface without a separate placement API.

The change extends traversal and directive parsing. It should reuse existing placement and assembly rather than introduce a second merge or validation model.

Selected Design Decision

YAML destination representation

Use destination as a sequence of strings, for example destination: [prompts, "0"]. Omission and [] inherit placement. Null, scalar destinations, and non-string members are invalid shapes rather than values to coerce. Every string key allowed by existing destination rules remains valid, including the empty string.

This representation directly expresses literal segments and keeps numeric key text distinct from YAML numbers. It provides one explicit notation consistent with the existing mapping-destination model. These shape rules define the new directive syntax; other configuration values retain their existing semantics.