Settle main-source eligibility for relative context binding
This commit is contained in:
@@ -1,8 +1,7 @@
|
||||
# Main-relative companion imports and overlays
|
||||
|
||||
Status: accepted direction, public API structure, absent-main behavior, and
|
||||
containment/symlink convention; main-source eligibility remains open.
|
||||
Not implemented. Baseline: `191015e`.
|
||||
Status: all four design decisions settled; not implemented. Final API spelling
|
||||
and implementation planning remain. Baseline: `191015e`.
|
||||
|
||||
## Purpose
|
||||
|
||||
@@ -14,7 +13,8 @@ boilerplate to the main file or creating a manifest on disk.
|
||||
|
||||
The central addition is deferred filesystem-context binding for application-owned
|
||||
underlay inputs, including `Mapping` and `Bytes` sources containing native import
|
||||
declarations. Bind their imports to the selected main directory during loading.
|
||||
declarations. Bind their imports to the main input's resolved filesystem context
|
||||
during loading: for file mains, lookup starts beside the selected main file.
|
||||
Reuse existing optional-file, directory, recursion, pattern, destination, and
|
||||
composition behavior. A new file constructor alone would not cover this workflow,
|
||||
and a second fragment-discovery implementation is unnecessary.
|
||||
@@ -32,6 +32,11 @@ root override, `/srv/campaign/audita.yml` supplies the location
|
||||
lookup uses the configuration root, which can differ from the main directory.
|
||||
Optional discovery exhaustion provides no inferred context.
|
||||
|
||||
Non-file mains can already carry an explicit filesystem context. Absent inputs,
|
||||
including optional discovery exhaustion, can also retain a supplied context;
|
||||
for an absent host input, an explicit root supplies the base when `BaseDir` is
|
||||
omitted. Reusing these validated contexts requires no filename inference.
|
||||
|
||||
The [layered API](../config.md#layered-loading) has the coordination gap:
|
||||
|
||||
- An active overlay requires `LayeredOptions.OverlayFilesystem`. Preflight
|
||||
@@ -94,10 +99,11 @@ selects main-derived filesystem binding for that input. `Mapping` and `Bytes`
|
||||
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 resolved directory and inherits its namespace and containment root
|
||||
under OD-3. Existing import selection then acquires the companion files. Each
|
||||
imported file uses its own directory for further relative imports. An import of
|
||||
Once the main context is resolved, ConfigKit inherits its base, namespace, and
|
||||
containment root under OD-3 and OD-4. File mains supply their resolved directory;
|
||||
non-file or absent mains may supply an explicit context. Existing import selection
|
||||
then acquires the companion files. Each imported file uses its own directory for
|
||||
further relative imports. An import of
|
||||
`extra.yml` from `glossary/terms.yml` resolves to `glossary/extra.yml`.
|
||||
|
||||
Applications choose underlay groups and their order. A group composes strictly;
|
||||
@@ -118,14 +124,15 @@ native imports. Ordinary `File` paths do not silently gain new relative semantic
|
||||
### Layered overlays
|
||||
|
||||
For an active layered overlay, use an explicit `OverlayFilesystem` when supplied.
|
||||
Otherwise derive the overlay context automatically from the available main-file
|
||||
information; the common workflow requires no `OverlayFromMain` flag. An invalid
|
||||
explicit context fails rather than falling back. Inactive overlays need no
|
||||
Otherwise derive the overlay context automatically from the main input's usable
|
||||
resolved context; the common workflow requires no `OverlayFromMain` flag. An
|
||||
invalid explicit context fails rather than falling back. Inactive overlays need no
|
||||
context. Missing-main and fallback cases are addressed below and in OD-2.
|
||||
|
||||
For this newly derived layered context, the lookup location is the main file's
|
||||
directory, independently of a wider containment root. If the main is
|
||||
`/srv/campaign/audita.yml` and its permitted root is `/srv`, the selected file
|
||||
For this newly derived layered context, lookup uses the main context's resolved
|
||||
base, independently of a wider containment root. For file mains this is the
|
||||
main file's directory. If the main is `/srv/campaign/audita.yml` and its permitted
|
||||
root is `/srv`, the selected file
|
||||
is `/srv/campaign/overlays/production.yml`, not `/srv/overlays/production.yml`.
|
||||
Widening containment must not relocate the automatically selected companions.
|
||||
|
||||
@@ -138,7 +145,8 @@ precedence, and validation retain their existing semantics.
|
||||
### Absent main and optional companions
|
||||
|
||||
Optional discovery may find no main file while defaults and CLI settings still
|
||||
permit a successful application load. When no usable base is available, skip
|
||||
permit a successful application load. An explicit context on that absent main
|
||||
can still supply a usable base under OD-4. When no usable base is available, skip
|
||||
optional companion import expansion while retaining the declaring input's
|
||||
ordinary payload and validation. Required imports still fail. Applications can
|
||||
require a base or supply an explicit fallback context on each derived binding.
|
||||
@@ -188,21 +196,22 @@ No release version or additional release gate is selected here.
|
||||
|
||||
## Work from the baseline
|
||||
|
||||
1. **Finalize context declarations and absence policy.** Resolve the remaining
|
||||
choices below and prepare Go examples for Audita's mapping/bytes workflow,
|
||||
explicit context overrides, and independently located embedded inputs.
|
||||
1. **Finalize API spelling and examples.** Translate the settled decisions below
|
||||
into concrete declarations and prepare Go examples for Audita's mapping/bytes
|
||||
workflow, explicit overrides, non-file main contexts, and independently located
|
||||
embedded inputs.
|
||||
2. **Carry binding intent through the public facade and load request.** Update
|
||||
the relevant input/options declarations and conversions in `layered.go` and
|
||||
`lifecycle.go`, retaining root-owned public types and normal ownership rules.
|
||||
Distinguish a deferred relationship from a concrete filesystem context.
|
||||
3. **Bind underlay import contexts after main selection.** Extend preparation
|
||||
and acquisition in `internal/engine/load_request.go`, `load_input.go`, and
|
||||
`acquisition.go` as needed. Reuse the acquired main's directory and namespace,
|
||||
apply the chosen missing-base policy, and delegate selection to existing import
|
||||
3. **Bind underlay import contexts after main context resolution.** Extend
|
||||
preparation and acquisition in `internal/engine/load_request.go`, `load_input.go`, and
|
||||
`acquisition.go` as needed. Reuse the main's resolved base, root, and namespace,
|
||||
apply the settled missing-base policy, and delegate selection to existing import
|
||||
machinery. Preserve independently supplied contexts.
|
||||
4. **Derive overlay context and separate lookup from containment.** Remove the
|
||||
unconditional explicit-context requirement for the new layered default.
|
||||
Preserve explicit and ordinary lookup while enabling a main-directory lookup
|
||||
Preserve explicit and ordinary lookup while using the main context's resolved
|
||||
base inside a potentially wider root. Reuse selected-overlay loading and its
|
||||
failure and resource-ownership behavior.
|
||||
5. **Verify the complete workflow and document it.** Add maintained consumer
|
||||
@@ -219,6 +228,9 @@ Validate behavior through the public loading boundary, including:
|
||||
|
||||
- Explicit and discovered main files, early and later search candidates, and an
|
||||
unrelated invocation directory. Companions follow the same selected main.
|
||||
- Native file mains, bytes/readers/mappings with explicit host or native contexts,
|
||||
and absent mains with explicit contexts. Cover absent host root-only contexts,
|
||||
missing and invalid contexts, and context reuse without enabling main imports.
|
||||
- Mapping and bytes underlays containing optional named-file and recursive
|
||||
directory imports with `*.yml`/`*.yaml` filtering and mounted destinations.
|
||||
- File only, directory only, both, neither, empty directories, and invalid or
|
||||
@@ -308,6 +320,9 @@ context in this order:
|
||||
|
||||
A fallback can satisfy require-base: the option requires a usable context, not
|
||||
an actual main file. Consumers requiring a main file can make discovery required.
|
||||
Under OD-4, an explicit context on a non-file or absent main can also satisfy it;
|
||||
the absence policy applies when no usable base exists, not merely when no main
|
||||
content exists.
|
||||
An invalid selected context fails; it does not activate a lower-priority choice.
|
||||
Fallback applies only when the main cannot provide a base, never after a failure
|
||||
reading or processing a selected main, or after missing or invalid companion
|
||||
@@ -326,10 +341,11 @@ Companion absence settings do not make a selected overlay optional.
|
||||
|
||||
### OD-3: Containment inheritance and symlink convention — settled
|
||||
|
||||
Derived companion imports and derived layered overlays inherit the selected
|
||||
main's resolved filesystem namespace and containment root. Lookup starts at the
|
||||
main file's resolved directory, even when its configured root is wider. Keep
|
||||
existing explicit overlay context and ordinary `Load` lookup behavior.
|
||||
Derived companion imports and derived layered overlays inherit the main input's
|
||||
resolved filesystem namespace and containment root. Lookup uses its resolved
|
||||
base under OD-4, which for file mains is the file's resolved directory, even when
|
||||
its configured root is wider. Keep existing explicit overlay context and ordinary
|
||||
`Load` lookup behavior.
|
||||
|
||||
For a host main at `/srv/campaign/audita.yml` with root `/srv`, companion
|
||||
`glossary.yml` resolves to `/srv/campaign/glossary.yml`, while an import of
|
||||
@@ -352,27 +368,41 @@ under the normal rules when they choose another location or scope.
|
||||
Each imported file continues to resolve further imports from its own directory,
|
||||
within the inherited root. Existing import `follow` controls still govern
|
||||
discovered symlink entries; they do not select the base of a symlinked main.
|
||||
Preserve existing containment checks and traversal controls. For any eligible
|
||||
native main under OD-4, retain that filesystem's namespace and link-handling
|
||||
Preserve existing containment checks and traversal controls. For native main
|
||||
contexts under OD-4, retain that filesystem's namespace and link-handling
|
||||
capabilities without imposing host-filesystem guarantees on every `fs.FS`.
|
||||
|
||||
## Open Decisions
|
||||
### OD-4: Main-source eligibility beyond discovered host files — settled
|
||||
|
||||
### OD-4: Main-source eligibility beyond discovered host files
|
||||
Derive from any usable, validated main filesystem context, regardless of the
|
||||
main source's format. Document `MainRelative` as using the main input's resolved
|
||||
filesystem context. For the common file workflow, this means lookup beside the
|
||||
selected main file. Reuse existing context resolution rather than adding another
|
||||
acquisition mechanism or requiring main imports to be enabled.
|
||||
|
||||
**Settled:** both explicitly selected and discovered host mains support the
|
||||
workflow. Non-file companion inputs, especially mappings and bytes, are in scope;
|
||||
this decision concerns the main input that supplies their base.
|
||||
- Explicit host files and successful discovery supply the canonical file directory
|
||||
and resolved containment root.
|
||||
- `Filesystem.File` mains supply their directory and root within their existing
|
||||
namespace. Dependent loading stays in that namespace.
|
||||
- `Bytes`, `Reader`, and `Mapping` mains can supply an explicit context with a
|
||||
usable base, root, and namespace under their existing validation rules.
|
||||
- `NoSource` and optional discovery exhaustion can retain an explicit main
|
||||
context. Reuse its resolved base: existing absent-host rules allow an explicit
|
||||
root to serve as the base when `BaseDir` is omitted; native contexts retain
|
||||
their existing requirements.
|
||||
|
||||
**Recommendation:** also support native `Filesystem.File` mains using their
|
||||
namespace's path and ownership rules. For an initial file-based scope, non-file
|
||||
mains use independently supplied or fallback contexts rather than implicitly
|
||||
providing a main-file directory. This covers the requested workflow and avoids
|
||||
making discovery a prerequisite for equivalent file inputs.
|
||||
For example, a bytes main with host `BaseDir: /srv/campaign` and `Root: /srv`
|
||||
can supply the same companion lookup and containment as a file main in that
|
||||
directory with the same root. An absent main with a usable explicit context
|
||||
can likewise supply companion and overlay lookup without creating main content.
|
||||
|
||||
**Alternative:** derive from any usable main context, including `BaseDir` on a
|
||||
byte, reader, or mapping main. This is more uniform with context-based loading
|
||||
and avoids excluding a known base, but requires explaining main-relative as
|
||||
main-context-relative and deciding how root-only or absent-main contexts behave.
|
||||
A host-only initial scope is smaller but leaves native-file consumers with the
|
||||
same coordination gap.
|
||||
Without a usable main context, apply OD-2's fallback, optional-import skipping,
|
||||
or error behavior. Invalid supplied contexts fail rather than selecting a
|
||||
fallback. Never infer filesystem locations from diagnostic labels or unsuccessful
|
||||
search candidates, manufacture a main source, or change source evidence to make
|
||||
a non-file input appear file-backed.
|
||||
|
||||
This preserves one context-reuse rule when applications change how they supply
|
||||
main content. OD-1's concrete overrides and OD-3's containment, namespace, and
|
||||
link-handling rules continue to apply. Existing ordinary `Load` and explicit
|
||||
overlay context lookup semantics remain unchanged.
|
||||
|
||||
Reference in New Issue
Block a user