From e36740313d00082be4e7be7a50271add548d1fae Mon Sep 17 00:00:00 2001 From: Eric Rakestraw Date: Mon, 9 Nov 2026 17:46:31 +0000 Subject: [PATCH] Settle the main-relative context binding API --- docs/roadmap/main-relative-inputs.md | 77 ++++++++++++++++++---------- 1 file changed, 49 insertions(+), 28 deletions(-) diff --git a/docs/roadmap/main-relative-inputs.md b/docs/roadmap/main-relative-inputs.md index 29a1dde..c9cfd5a 100644 --- a/docs/roadmap/main-relative-inputs.md +++ b/docs/roadmap/main-relative-inputs.md @@ -1,7 +1,8 @@ # Main-relative companion imports and overlays -Status: accepted direction; public representation and remaining filesystem-policy -choices are open. Not implemented. Implementation baseline: `191015e`. +Status: accepted direction and public API structure; absent-main and remaining +filesystem-policy choices are open. Not implemented. Implementation baseline: +`191015e`. ## Purpose @@ -90,8 +91,8 @@ outside this feature; it is not a second spelling for current overlay lookup. The application declares an underlay `Input` containing native imports and selects main-derived filesystem binding for that input. `Mapping` and `Bytes` -are first-class supported sources for this use. Exact Go declarations remain -open in OD-1; no new operator-facing YAML syntax is needed. +are first-class supported sources for this use. OD-1 settles the public API +structure below; no new operator-facing YAML syntax is needed. Once the main is selected, ConfigKit supplies the underlay import base from that file's directory and binds the namespace and containment policy. Existing @@ -106,9 +107,9 @@ context does not itself enable imports or change collection operations. The relationship is explicit on companion inputs. Independently located and embedded inputs keep their own contexts and can coexist in the same load. -Providing a concrete context should select that complete context over derived +Providing a concrete context selects that complete context over derived binding, without field-by-field fallback or recovery from an invalid explicit -context. OD-1 addresses how to represent those choices cleanly. +context. OD-1 records the representation and precedence rules. There is no requirement to add a dedicated main-relative file constructor. Optional named-file acquisition is already expressible through the underlay's @@ -242,30 +243,50 @@ application can discover its main, bind companion imports and the selected overlay, and receive normal resolved configuration and inspection in one load, without an application directory walker, parser, or extra discovery pass. +## Settled Decisions + +### OD-1: Public representation of deferred context binding — settled + +Add a small, optional main-relative binding description to `Input`, retaining +the concrete `Input.Filesystem` field. A helper supplies the common default +description; explicit settings group any absent-main controls decided in OD-2. +Companion `Mapping` and `Bytes` inputs use native imports for fragment selection. +Preserve the input's source, placement, import enablement, and tier. + +The proposed shape is an `Input.MainRelative` field of type +`*MainRelativeContext`, with a `MainRelative()` convenience helper. These names +illustrate the settled structure; final spelling and OD-2's settings can be +finished during API design. For example, this unimplemented API sketch assumes +`companionDeclarations` contains ordinary native import declarations: + +```go +configkit.Input{ + Source: configkit.Mapping("companions", companionDeclarations), + Imports: true, + MainRelative: configkit.MainRelative(), +} +``` + +A nil binding preserves existing independent context behavior. A non-nil binding +requests context derivation during loading. If `Input.Filesystem` is also supplied, +that complete concrete context wins. Do not merge fields or fall back to derivation +when the explicit context is invalid. This permits overriding reusable companion +setup without clearing its binding declaration. + +Layered overlays derive automatically when `OverlayFilesystem` is absent; no +additional opt-in flag is needed. An explicit overlay context wins as a whole. +If OD-2 calls for configurable overlay fallback behavior, reuse the small binding +settings where appropriate without requiring a general context-selection API. + +Keep the binding on `Input`: `Source` still describes the supplied content and +`FilesystemContext` still describes a concrete location. This does not reinterpret +a file source's own path. Grouping related settings avoids scattering them across +a boolean and sibling fields, while keeping the addition smaller than a general +context selector. No source wrapper, deferred fields on `FilesystemContext`, +callback, or second file-selection API is needed for this design. + ## Open Decisions -### OD-1: Public representation of deferred context binding - -**Settled:** companion `Mapping` and `Bytes` inputs must work; native imports own -fragment selection. Layered overlays derive automatically when no explicit -context is supplied. Concrete contexts override derivation as a whole. - -**Recommendation:** represent main-derived context as a small declarative choice -on an underlay `Input`, with a helper or constructor for the common case. Preserve -its existing source, placement, import enablement, and tier. If both binding intent -and `Input.Filesystem` are supplied, use the concrete context without merging -fields. This is appropriate for mapping/bytes inputs because their context owns -import resolution; it does not reinterpret a file source's own path. Include the -absent-main policy from OD-2 in the binding description. Exact names and shape -need an API sketch, but no callback or second file-selection API is necessary. - -**Alternative:** introduce a shared context-selection descriptor for both inputs -and overlays, representing explicit, main-derived, and fallback contexts. This -could make the choices more uniform, particularly as fallback policy grows, but -adds a wider abstraction and must coexist with today's concrete context fields. -Rejecting simultaneous concrete and derived choices is viable but requires -callers to clear shared setup when providing an explicit override. - ### OD-2: Scope and representation of absent-main handling **Settled:** optional companions should support defaults-only startup; a declared