Settle the main-relative context binding API

This commit is contained in:
2026-11-09 17:46:31 +00:00
parent 1960304f6f
commit e36740313d

View File

@@ -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