Revise the companion input roadmap around main-derived contexts
This commit is contained in:
@@ -1,286 +1,330 @@
|
|||||||
# Main-relative underlays and overlays
|
# Main-relative companion imports and overlays
|
||||||
|
|
||||||
Status: accepted direction; API and filesystem-policy decisions remain open.
|
Status: accepted direction; public representation and remaining filesystem-policy
|
||||||
Not implemented. Planning baseline: `191015e`.
|
choices are open. Not implemented. Implementation baseline: `191015e`.
|
||||||
|
|
||||||
## Purpose
|
## Purpose
|
||||||
|
|
||||||
Allow an application to select its main configuration through ConfigKit's
|
Make the common workflow straightforward: discover the main configuration file,
|
||||||
existing discovery descriptions, then load explicitly declared underlay files
|
load optional companion fragments beside it, and apply a selected native overlay
|
||||||
and a selected overlay relative to that main file. Applications should not need
|
in one configuration load. Applications choose their conventions; operators can
|
||||||
to repeat discovery themselves or run a preliminary configuration load to learn
|
drop resource definitions into the declared locations without adding import
|
||||||
the selected directory.
|
boilerplate to the main file or creating a manifest on disk.
|
||||||
|
|
||||||
The application continues to choose its search conventions, underlay tiers, and
|
The central addition is deferred filesystem-context binding for application-owned
|
||||||
overlay name. ConfigKit resolves their filesystem relationship within the same
|
underlay inputs, including `Mapping` and `Bytes` sources containing native import
|
||||||
load. Independently located inputs remain useful and can be combined with
|
declarations. Bind their imports to the selected main directory during loading.
|
||||||
main-relative inputs.
|
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.
|
||||||
|
|
||||||
## Current baseline
|
## Current baseline
|
||||||
|
|
||||||
The [discovery contract](../config.md#configuration-discovery) resolves a
|
The [discovery contract](../config.md#configuration-discovery) resolves
|
||||||
`SearchConfig` source inside loading. It selects one host file or absent input;
|
`SearchConfig` inside loading to one host file or absent input. Selected-file
|
||||||
errors processing the selected file do not resume the search. The public
|
failures do not resume discovery. The constructor returns a source description,
|
||||||
constructor returns a source description, not a selected filename.
|
not a selected filename.
|
||||||
|
|
||||||
Ordinary `Load` already derives an overlay context from a selected file. Without
|
Ordinary `Load` already infers overlay context from a file source. Without a
|
||||||
an explicit root override, selecting `/etc/example/config.yml` permits overlay
|
root override, `/srv/campaign/audita.yml` supplies the location
|
||||||
`production` to load from `/etc/example/overlays/production.yml`. Optional search
|
`/srv/campaign/overlays/production.yml` for overlay `production`. Existing overlay
|
||||||
exhaustion supplies no inferred root; ordinary loading then needs an explicit
|
lookup uses the configuration root, which can differ from the main directory.
|
||||||
context for an active overlay.
|
Optional discovery exhaustion provides no inferred context.
|
||||||
|
|
||||||
The [layered API](../config.md#layered-loading) differs:
|
The [layered API](../config.md#layered-loading) has the coordination gap:
|
||||||
|
|
||||||
- An active overlay requires `LayeredOptions.OverlayFilesystem` independently of
|
- An active overlay requires `LayeredOptions.OverlayFilesystem`. Preflight
|
||||||
the main source. Grouped preflight rejects its absence before discovery runs.
|
rejects its absence before discovery runs.
|
||||||
- `Underlay.Inputs` contains independently specified sources and contexts. A
|
- Underlay sources and contexts are supplied independently. Application-owned
|
||||||
file source can establish its own context, but no declaration binds an
|
mappings or bytes can already contain import declarations, but cannot obtain
|
||||||
underlay filename to the main file that discovery will select.
|
their import context from the main file that discovery will select.
|
||||||
- Main acquisition already precedes underlay acquisition. Underlay groups are
|
- Native imports already support optional named files and recursive directory
|
||||||
subsequently composed from lowest to highest priority, beneath the main tier.
|
searches with filename filtering and placement. They compose as peers of
|
||||||
- Ordinary relative imports are peers of their declaring input. They do not
|
their declaring input, so putting declarations in an underlay gives them
|
||||||
express lower-priority underlay tiers.
|
underlay priority. Putting the same declarations in the main file does not.
|
||||||
|
- Main acquisition already precedes underlay acquisition. Existing composition
|
||||||
|
subsequently applies underlay groups from lowest to highest beneath the main.
|
||||||
|
|
||||||
The extension can therefore reuse the selected main's acquired filesystem
|
This feature extends context selection and binding within that lifecycle.
|
||||||
information and the existing grouped lifecycle. It needs a way to express the
|
|
||||||
relationship publicly and bind it before dependent acquisition.
|
## Audita workflow
|
||||||
|
|
||||||
|
Audita supplies the companion import declarations in application-owned mappings
|
||||||
|
or bytes. Their filesystem bases follow the selected main file, whether selected
|
||||||
|
explicitly or through ConfigKit's built-in searches. For a main file at
|
||||||
|
`/srv/campaign/audita.yml`, running from `/tmp` must not relocate these companions:
|
||||||
|
|
||||||
|
| Resource | Application-declared locations | Role |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| Glossaries | Optional `glossary.yml` and recursive `glossary/` | Underlay contributions mounted at `glossary_collections` using the appropriate existing destination and placement controls |
|
||||||
|
| Prompt definitions | Optional `prompts.yml` and recursive `prompts/` | Operator contributions above the bundled PromptKit catalog and Audita's embedded prompts |
|
||||||
|
| Selected native overlay | `overlays/<name>.yml` | The one named overlay applied after main composition |
|
||||||
|
|
||||||
|
Both resource-directory searches select `*.yml` and `*.yaml`. The file and
|
||||||
|
its corresponding directory contribute together if both exist; neither suppresses
|
||||||
|
the other. Each pair composes strictly as peers within its tier. Missing optional
|
||||||
|
resources contribute nothing; unreadable selected files, invalid definitions,
|
||||||
|
and composition conflicts remain errors.
|
||||||
|
|
||||||
|
Prompt overrides rely on existing tier and identity rules. The operator prompt
|
||||||
|
tier sits above embedded prompt tiers, allowing whole-record upsert by registered
|
||||||
|
prompt ID under the applicable collection policy. Two operator fragments defining
|
||||||
|
the same ID in that tier conflict; filename ordering does not choose a winner.
|
||||||
|
The consuming application selects each fragment's schema and placement.
|
||||||
|
|
||||||
|
This does not require combining Audita's and PromptKit's schemas. If PromptKit
|
||||||
|
uses a separate engine, its catalog load establishes the prompt tiers and can
|
||||||
|
use the selected main's recorded context after Audita's application load. That
|
||||||
|
is a separate domain load, not a preliminary load to repeat main discovery.
|
||||||
|
This feature's acceptance does not require changing another repository.
|
||||||
|
|
||||||
|
The overlay directory is not imported wholesale as an underlay: its files are
|
||||||
|
alternative named configurations. No selection means no overlay. Selecting a
|
||||||
|
name retains the existing missing-selected-overlay error. An aggregate
|
||||||
|
`overlays.yml` would need its own named-definition and conflict rules and is
|
||||||
|
outside this feature; it is not a second spelling for current overlay lookup.
|
||||||
|
|
||||||
## Targeted end state
|
## Targeted end state
|
||||||
|
|
||||||
### Application declarations
|
### Companion underlays
|
||||||
|
|
||||||
An application can declare, before loading:
|
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.
|
||||||
|
|
||||||
1. A main `Input` using `SearchConfig`, with any supported combination of search
|
Once the main is selected, ConfigKit supplies the underlay import base from
|
||||||
presets and custom candidates.
|
that file's directory and binds the namespace and containment policy. Existing
|
||||||
2. One or more underlay files whose paths are relative to the selected main
|
import selection then acquires the companion files. Every imported file uses
|
||||||
file's directory, grouped and ordered through the existing underlay API.
|
its own directory for its further relative imports. For example, an import of
|
||||||
3. A selected overlay whose context is derived from the selected main file.
|
`extra.yml` from `glossary/terms.yml` resolves to `glossary/extra.yml`.
|
||||||
|
|
||||||
The relationship is explicit and declarative. It does not require a new
|
Applications choose underlay groups and their order. A group composes strictly;
|
||||||
application callback, a second load, or a public intermediate configuration.
|
separate groups establish precedence. Existing destinations, sequence placement,
|
||||||
Exact API spelling and context selection are subject to OD-1. Missing-main
|
source-version policies, and load-wide import defaults still apply. Binding a
|
||||||
behavior, filesystem policy, and eligible main sources are subject to OD-2
|
context does not itself enable imports or change collection operations.
|
||||||
through OD-4; the examples below assume a successfully selected host file.
|
|
||||||
|
|
||||||
Existing input destinations, placement, import opt-in, and load-wide policies
|
The relationship is explicit on companion inputs. Independently located and
|
||||||
remain applicable to underlay inputs. The new relationship determines where an
|
embedded inputs keep their own contexts and can coexist in the same load.
|
||||||
input is acquired; it does not change its precedence or composition rules.
|
Providing a concrete context should select that complete context over derived
|
||||||
An underlay's own relative imports continue to resolve from that underlay's
|
binding, without field-by-field fallback or recovery from an invalid explicit
|
||||||
declaring directory.
|
context. OD-1 addresses how to represent those choices cleanly.
|
||||||
|
|
||||||
### Examples
|
There is no requirement to add a dedicated main-relative file constructor.
|
||||||
|
Optional named-file acquisition is already expressible through the underlay's
|
||||||
|
native imports. Ordinary `File` paths do not silently gain new relative semantics.
|
||||||
|
|
||||||
These describe intended behavior, not implemented Go syntax. Assume there is no
|
### Layered overlays
|
||||||
explicit configuration-root override and that the selected main file is:
|
|
||||||
|
|
||||||
```text
|
For an active layered overlay, use an explicit `OverlayFilesystem` when supplied.
|
||||||
/etc/example/config.yml
|
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
|
||||||
|
context. Missing-main and fallback cases are addressed below and in OD-2.
|
||||||
|
|
||||||
| Application declaration | Selected input |
|
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
|
||||||
| Main-relative underlay `defaults/base.yml` | `/etc/example/defaults/base.yml` |
|
`/srv/campaign/audita.yml` and its permitted root is `/srv`, the selected file
|
||||||
| Main-relative underlay `defaults/site.yml` | `/etc/example/defaults/site.yml` |
|
is `/srv/campaign/overlays/production.yml`, not `/srv/overlays/production.yml`.
|
||||||
| Main-relative overlay context, overlay name `production` | `/etc/example/overlays/production.yml` |
|
Widening containment must not relocate the automatically selected companions.
|
||||||
|
|
||||||
If the underlays are placed in separate groups in that order, effective priority
|
Keep existing explicit-overlay-context lookup behavior and ordinary `Load`
|
||||||
is typed defaults, base underlay, site underlay, main, overlay, then CLI.
|
behavior. The implementation must represent the derived lookup base separately
|
||||||
Putting both underlay inputs in one group instead composes them strictly as
|
from its containment root where necessary, rather than simply copying today's
|
||||||
peers. A declaration of `extras.yml` inside `defaults/base.yml` resolves beside
|
root-relative overlay context. Native overlay names, filenames, selection,
|
||||||
that file, at `/etc/example/defaults/extras.yml`.
|
precedence, and validation retain their existing semantics.
|
||||||
|
|
||||||
If discovery instead selects a file in the user's configuration directory, the
|
### Absent main and optional companions
|
||||||
same relative declarations follow that file's directory. An embedded or otherwise
|
|
||||||
independent underlay may coexist with these inputs and retains its own namespace
|
|
||||||
and context. No directory is searched for underlays merely because it exists.
|
|
||||||
|
|
||||||
### Loading and inspection
|
Optional discovery may find no main file while defaults and CLI settings still
|
||||||
|
permit a successful application load. Support a declared absent-main policy for
|
||||||
|
dependent companion imports. Skipping optional companions is the intended default
|
||||||
|
for this workflow; applications can instead require a base or supply an explicit
|
||||||
|
fallback directory/context. The representation and exact skip scope remain in
|
||||||
|
OD-2, including inputs with required imports or additional application payload.
|
||||||
|
|
||||||
Resolve the main-relative descriptions using the selected main's acquired
|
Do not infer a directory from unsuccessful candidates or silently use the working
|
||||||
filesystem information, before acquiring the inputs that depend on it. Keep
|
directory. An application may explicitly choose the working directory as its
|
||||||
discovery within the existing single loading lifecycle and preserve main-first
|
fallback. An active selected overlay still needs a usable context and the selected
|
||||||
acquisition, underlay tier order, version processing, selected-overlay timing,
|
file; optional companion imports do not make that overlay optional. Independent
|
||||||
and the existing defaults, resolution, secret, and validation phases.
|
underlays and explicitly located overlays retain their absent-main behavior.
|
||||||
|
No fallback applies to a failure reading or processing an actually selected main.
|
||||||
|
|
||||||
Static declaration errors can still be checked before source acquisition;
|
### Lifecycle, evidence, and compatibility
|
||||||
checks that need the selected directory must run after it is available. The
|
|
||||||
implementation plan should identify this division without imposing a new global
|
|
||||||
ordering guarantee for unrelated diagnostics or filesystem checks.
|
|
||||||
|
|
||||||
After binding, use ordinary source acquisition, parsing, import handling, and
|
Bind dependent contexts after the main information is available and before
|
||||||
overlay loading. A missing required input, unreadable selected file, or invalid
|
traversing their imports or loading the overlay. Preserve main-first acquisition,
|
||||||
configuration follows the applicable existing failure rules; it does not cause
|
underlay precedence, version processing, selected-overlay timing, and the existing
|
||||||
main discovery to try another candidate. This feature does not itself introduce
|
defaults, CLI, resolution, secret, and validation phases. No application context
|
||||||
optional-file syntax, underlay globbing, additional overlay filenames, or a new
|
callback, second discovery API, or preliminary full load is required.
|
||||||
overlay stack.
|
|
||||||
|
|
||||||
Acquired files retain their actual source identity, path, source-local locations,
|
Check static declarations during preflight where possible; defer checks requiring
|
||||||
layer, underlay index, and passive resource context. Do not create an extra
|
the selected directory. Do not introduce a global ordering guarantee for unrelated
|
||||||
source or precedence tier for the relative declaration itself. Preserve existing
|
diagnostics or filesystem checks. Selected-file and companion acquisition errors
|
||||||
namespace identity, repetition scope, shared acquisition budgets, detached
|
remain terminal rather than restarting discovery.
|
||||||
inspection, and resource cleanup. Use ordinary diagnostic classifications where
|
|
||||||
they fit; decide whether any new classification is needed during API design.
|
|
||||||
|
|
||||||
### Compatibility and scope
|
Application-supplied mappings or bytes remain ordinary input sources with their
|
||||||
|
own labels, evidence, and existing validation obligations. Binding a context does
|
||||||
|
not manufacture a main document, exempt these inputs from source-version policy,
|
||||||
|
or give them a fabricated physical file path. Imported files retain their actual
|
||||||
|
source identity, locations, precedence layer, underlay index, and passive resource
|
||||||
|
context. Preserve namespace identity, repetition scope, shared budgets, detached
|
||||||
|
inspection, and acquisition-handle cleanup.
|
||||||
|
|
||||||
Preserve successful existing ordinary and layered loading behavior. Main-relative
|
Successful existing ordinary and explicitly configured layered loads should retain
|
||||||
selection should be additive and opt-in, with independently supplied sources and
|
their behavior. Automatically deriving a layered overlay context intentionally
|
||||||
contexts continuing to work. Preserve existing named-overlay lookup semantics;
|
relaxes the former missing-context error. Companion directory conventions are
|
||||||
OD-3 determines the root used by the new context selection.
|
selected by applications; ConfigKit does not universally scan `glossary/` or
|
||||||
|
`prompts/` without those declarations.
|
||||||
|
|
||||||
The work does not add general resource-path resolution, changes to process working
|
This work adds no general resource-path resolver, remote acquisition, mutation of
|
||||||
directory, remote acquisition, or a generic source-provider callback framework.
|
the process working directory, filesystem race-protection guarantee, or general
|
||||||
These are scope boundaries for this feature, not new architectural exclusions.
|
source-provider callback framework. These are scope boundaries, not new permanent
|
||||||
There is no new filesystem race-protection or sandbox guarantee.
|
architectural exclusions. The design follows
|
||||||
|
[ADR 0019](../adr/0019-explicit-configuration-discovery.md). Review ADR and policy
|
||||||
The design follows [ADR 0019](../adr/0019-explicit-configuration-discovery.md):
|
follow-up for deferred context ownership without rewriting accepted decisions.
|
||||||
applications select conventions while ConfigKit performs selection and loading.
|
No release version or additional release gate is selected here.
|
||||||
Review whether the finalized context-ownership decision needs an additional ADR;
|
|
||||||
do not rewrite an accepted ADR's decision content. No release version or new
|
|
||||||
release gate is selected by this roadmap.
|
|
||||||
|
|
||||||
## Work from the baseline
|
## Work from the baseline
|
||||||
|
|
||||||
1. **Settle the public declaration and filesystem policies.** Resolve the open
|
1. **Finalize context declarations and absence policy.** Resolve the remaining
|
||||||
decisions below, document combinations with explicit contexts, and prepare
|
choices below and prepare Go examples for Audita's mapping/bytes workflow,
|
||||||
representative API examples. Keep public types owned by the root package.
|
explicit context overrides, and independently located embedded inputs.
|
||||||
2. **Represent the relationship through the facade and request preparation.**
|
2. **Carry binding intent through the public facade and load request.** Update
|
||||||
Update the relevant declarations and conversions in `layered.go`,
|
the relevant input/options declarations and conversions in `layered.go` and
|
||||||
`lifecycle.go`, or `source.go` as the selected API requires. Carry the intent
|
`lifecycle.go`, retaining root-owned public types and normal ownership rules.
|
||||||
through the private request without prematurely interpreting paths against
|
Distinguish a deferred relationship from a concrete filesystem context.
|
||||||
the working directory. Preserve reusable-description and input-ownership
|
3. **Bind underlay import contexts after main selection.** Extend preparation
|
||||||
conventions.
|
and acquisition in `internal/engine/load_request.go`, `load_input.go`, and
|
||||||
3. **Bind dependent inputs during acquisition.** Extend the request preparation
|
`acquisition.go` as needed. Reuse the acquired main's directory and namespace,
|
||||||
and acquisition boundary in `internal/engine/load_request.go`,
|
apply the chosen missing-base policy, and delegate selection to existing import
|
||||||
`load_input.go`, and `acquisition.go`. Reuse discovery's selected concrete
|
machinery. Preserve independently supplied contexts.
|
||||||
source and filesystem-context resolution. Establish which checks remain in
|
4. **Derive overlay context and separate lookup from containment.** Remove the
|
||||||
preflight and which require resolved main information.
|
unconditional explicit-context requirement for the new layered default.
|
||||||
4. **Integrate underlays and overlays.** Resolve relative underlay files into
|
Preserve explicit and ordinary lookup while enabling a main-directory lookup
|
||||||
ordinary acquisitions with their own import bases; derive the selected
|
base inside a potentially wider root. Reuse selected-overlay loading and its
|
||||||
overlay context and reuse its loader. Preserve independent input contexts,
|
failure and resource-ownership behavior.
|
||||||
namespace handling, cleanup on failure, and source/error evidence.
|
5. **Verify the complete workflow and document it.** Add maintained consumer
|
||||||
5. **Verify observable behavior and update documentation.** Add focused public
|
examples, public integration coverage, and focused engine tests. Update the
|
||||||
coverage and maintained consumer examples, then update the discovery,
|
discovery, layered-loading, import-context, and selected-overlay contracts,
|
||||||
layered-loading, and selected-overlay contracts, declaration comments, and
|
declaration comments, and internal ownership documentation when implemented.
|
||||||
relevant internal ownership documentation. Explain the difference between a
|
|
||||||
file's directory and the configured root when they differ.
|
|
||||||
|
|
||||||
This is dependency order for a later implementation plan, not a required commit
|
This is dependency order for a later implementation plan, not a required commit
|
||||||
layout or a requirement to expose intermediate stages to consumers. Reuse the
|
layout or a requirement to expose intermediate stages to consumers.
|
||||||
existing lifecycle; a new discovery pass or a second configuration load is not
|
|
||||||
needed.
|
|
||||||
|
|
||||||
## Validation and completion
|
## Validation and completion
|
||||||
|
|
||||||
Exercise the behavior through the public API, supported by focused engine tests:
|
Validate behavior through the public loading boundary, including:
|
||||||
|
|
||||||
- Main discovery selects an early or later candidate; the dependent files follow
|
- Explicit and discovered main files, early and later search candidates, and an
|
||||||
the actual selection, including when it is outside the working directory.
|
unrelated invocation directory. Companions follow the same selected main.
|
||||||
- Relative and independent underlays coexist; multiple groups retain precedence,
|
- Mapping and bytes underlays containing optional named-file and recursive
|
||||||
and peers in one group retain strict-composition conflicts.
|
directory imports with `*.yml`/`*.yaml` filtering and mounted destinations.
|
||||||
- Underlay imports use their own file's directory. Placement and source-version
|
- File only, directory only, both, neither, empty directories, and invalid or
|
||||||
policies remain effective after binding.
|
unreadable selected fragments. Both forms compose as peers when present.
|
||||||
- Active and inactive overlays, explicit contexts, optional search exhaustion,
|
- Operator prompt overrides above embedded catalogs using registered identity;
|
||||||
and required-search failures follow the settled policies.
|
same-tier duplicate IDs remain conflicts. Main and overlay precedence survive.
|
||||||
- Symlinked main files, explicit root overrides, parent-relative paths, and
|
- Mixed embedded and companion inputs, multiple underlay tiers, transitive
|
||||||
namespace boundaries follow OD-3 and OD-4 without broadening existing access
|
imports, placement, source-version checks, and load-wide import defaults.
|
||||||
guarantees.
|
- Automatic derived overlays and explicit overrides, active and inactive names,
|
||||||
- Selected-file failures and dependent acquisition failures are terminal; no
|
broader containment roots, and missing selected overlays.
|
||||||
repeated full load or duplicate defaults/resolution/validation callbacks are
|
- Optional discovery exhaustion, required discovery, fallback and skip policies,
|
||||||
introduced.
|
mixed payload/required-import cases from OD-2, and terminal selected-main errors.
|
||||||
- Source records, underlay indexes, origins, passive contexts, and failed-load
|
- Symlinks, eligible namespaces, parent-relative paths within the selected scope,
|
||||||
evidence identify the actual acquired inputs. Existing handle cleanup and
|
context validity, and namespace identity under OD-3 and OD-4.
|
||||||
budget accounting still cover dependent acquisitions.
|
- Normal source evidence, diagnostics, passive resource contexts, cleanup, and
|
||||||
- Existing ordinary discovery and overlay loading, independent layered inputs,
|
budget accounting; no duplicate lifecycle callbacks or preliminary full load.
|
||||||
and reuse of descriptions across loads retain their behavior.
|
- Existing ordinary and explicit layered workflows and description reuse.
|
||||||
|
|
||||||
Run focused checks during implementation and the repository's applicable normal
|
Run focused checks during implementation and applicable normal repository checks
|
||||||
checks before completion. No benchmark campaign or additional release gate is
|
before completion. No benchmark campaign is required. Completion means the
|
||||||
required for this feature. Completion means applications can demonstrate the
|
application can discover its main, bind companion imports and the selected
|
||||||
discovery-plus-relative-input workflow in one load, with documented public
|
overlay, and receive normal resolved configuration and inspection in one load,
|
||||||
declarations and verified failure behavior.
|
without an application directory walker, parser, or extra discovery pass.
|
||||||
|
|
||||||
## Open Decisions
|
## Open Decisions
|
||||||
|
|
||||||
### OD-1: Public declaration shape and explicit-context combinations
|
### OD-1: Public representation of deferred context binding
|
||||||
|
|
||||||
**Recommendation:** add declarative, explicit choices for a main-relative
|
**Settled:** companion `Mapping` and `Bytes` inputs must work; native imports own
|
||||||
underlay file and a main-derived overlay context. A dedicated underlay source
|
fragment selection. Layered overlays derive automatically when no explicit
|
||||||
constructor and a small overlay context-selection option are plausible shapes;
|
context is supplied. Concrete contexts override derivation as a whole.
|
||||||
names remain to be chosen. Keep the existing independent-source/context path as
|
|
||||||
the default. For overlays, an explicitly supplied `OverlayFilesystem` should
|
|
||||||
take precedence over a request to derive context, allowing application overrides
|
|
||||||
without changing shared setup. Specify analogous precedence for any permitted
|
|
||||||
underlay context overrides. This keeps common use short without making nil
|
|
||||||
contexts change meaning or introducing callback lifetime concerns.
|
|
||||||
|
|
||||||
**Alternative:** add a general deferred filesystem-context descriptor shared by
|
**Recommendation:** represent main-derived context as a small declarative choice
|
||||||
inputs and overlays. This could give context selection one uniform representation
|
on an underlay `Input`, with a helper or constructor for the common case. Preserve
|
||||||
and accommodate later relationships, but risks expanding a small feature into
|
its existing source, placement, import enablement, and tier. If both binding intent
|
||||||
a general context API. It is attractive if concrete API sketches show less
|
and `Input.Filesystem` are supplied, use the concrete context without merging
|
||||||
duplication than separate declarations. Rejecting simultaneous explicit and
|
fields. This is appropriate for mapping/bytes inputs because their context owns
|
||||||
derived overlay choices is also viable: it catches ambiguous setup, but requires
|
import resolution; it does not reinterpret a file source's own path. Include the
|
||||||
callers to clear the derived choice when supplying an override.
|
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.
|
||||||
|
|
||||||
### OD-2: No main file is selected
|
**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.
|
||||||
|
|
||||||
**Recommendation:** when an active dependent declaration needs a main-file base
|
### OD-2: Scope and representation of absent-main handling
|
||||||
and none exists, fail with a clear diagnostic. Do not use an attempted candidate
|
|
||||||
directory or the working directory as an implicit substitute. This makes an
|
|
||||||
unresolvable relationship explicit without making discovery globally required.
|
|
||||||
Applications can require the main search or use independent inputs and an
|
|
||||||
explicit overlay context when absent-main operation is intended. Inactive
|
|
||||||
overlays do not require a derived context.
|
|
||||||
|
|
||||||
**Alternative:** treat main-relative inputs as conditional on main presence and
|
**Settled:** optional companions should support defaults-only startup; a declared
|
||||||
skip them after optional exhaustion. This supports defaults-only startup and is
|
fallback is useful, and guessed candidate directories or implicit working-directory
|
||||||
consistent with a permissive search, but could silently omit an explicitly
|
fallback are inappropriate. Selected-main failures remain terminal.
|
||||||
selected overlay or expected underlay. A selectable skip policy could support
|
|
||||||
that use case, at the cost of another option; adopting it would require defining
|
|
||||||
its effect on tier evidence and distinguishing absent main from a missing file
|
|
||||||
beside an existing main.
|
|
||||||
|
|
||||||
### OD-3: Relative base, configuration root, and symlinks
|
**Recommendation:** put absence behavior on each derived binding. Default to
|
||||||
|
skipping optional companion import expansion when no main base exists. Provide
|
||||||
|
an explicit require-base choice and a concrete fallback context; use a fallback
|
||||||
|
only when no main base is available, never to recover from a selected-file error.
|
||||||
|
Keep any independent payload in the underlay input, and do not silently waive
|
||||||
|
required import declarations. A supplied fallback for the overlay can likewise
|
||||||
|
provide its lookup base; an active overlay without any usable context fails.
|
||||||
|
This preserves useful absent-main behavior without silently discarding unrelated
|
||||||
|
configuration or conflating required imports with optional ones. Finalize how
|
||||||
|
these choices are represented and how a fallback declares lookup base and root.
|
||||||
|
|
||||||
**Recommendation:** anchor underlay filenames to the canonical selected main
|
**Alternative:** scope skip to the entire explicitly designated companion input.
|
||||||
file's directory, consistent with existing file/import behavior. Derive overlay
|
This is simpler for the import-only mappings Audita describes and avoids partial
|
||||||
context from the main's resolved context, so overlay lookup remains relative to
|
input processing, but also omits any payload or required imports in that input.
|
||||||
its configuration root. When an explicit main root is wider than the main
|
It needs clear semantics for that deliberate condition. A single load-wide
|
||||||
directory, underlay filenames still use the directory as their base and overlays
|
absence policy is another viable convenience, but cannot express different
|
||||||
use that root. Inherit the main's root for dependent underlay acquisition and
|
requirements for separate companion inputs as directly.
|
||||||
imports unless an explicitly supported context override selects another root.
|
|
||||||
Each acquired underlay supplies its own import base. Apply existing canonical
|
|
||||||
containment checks; allow parent-relative traversal when it stays within the
|
|
||||||
selected root rather than adding a blanket prohibition on `..`.
|
|
||||||
|
|
||||||
This distinguishes lookup from containment, reuses existing machinery, and
|
### OD-3: Containment inheritance and symlink convention
|
||||||
supports sibling directories under an explicitly wider root. It also means a
|
|
||||||
symlinked main selects resources beside its target, which must be documented.
|
|
||||||
|
|
||||||
**Alternative:** always create a fresh root at the main file's directory for
|
**Settled:** derived companion imports and derived layered overlays use the main
|
||||||
both kinds of input. This makes every main-relative lookup visually local,
|
file's directory for lookup, even with a wider configured containment root.
|
||||||
including with a wider main root, but discards intentional root configuration
|
Explicit overlay contexts retain their current lookup semantics.
|
||||||
and prevents some sibling-directory layouts. Using the main file's lexical
|
|
||||||
symlink directory instead is another viable convention for deployment bundles;
|
|
||||||
it would differ from current canonical import behavior and require separate
|
|
||||||
handling for lookup and containment.
|
|
||||||
|
|
||||||
### OD-4: Eligible main sources and namespaces
|
**Recommendation:** use the selected main's canonical directory, and inherit its
|
||||||
|
resolved namespace and containment root for derived bindings. Existing import
|
||||||
|
rules then provide file-local bases for transitive imports. Permit parent-relative
|
||||||
|
paths when existing containment rules allow them. This reuses current canonical
|
||||||
|
file behavior and preserves intentional wider roots without relocating companions.
|
||||||
|
A concrete underlay context override can select a different scope under its
|
||||||
|
normal rules. Document the symlink-target-directory convention explicitly.
|
||||||
|
|
||||||
**Recommendation:** support discovered and explicit host files, and native
|
**Alternative:** create a fresh containment root at the selected main directory.
|
||||||
`Filesystem.File` mains, using each namespace's existing path rules and resource
|
This keeps companions locally scoped but discards intentional wider roots and
|
||||||
ownership. Discovery currently selects host files; a native file should not
|
prevents some sibling-directory layouts. Anchoring to the lexical symlink directory
|
||||||
require discovery merely to provide the same directory relationship. Bind paths
|
is also viable for deployment bundles; it differs from current file/import
|
||||||
within the selected namespace and reuse its identity. For this initial feature,
|
behavior and would need distinct lookup and containment handling.
|
||||||
byte, reader, mapping, and absent mains do not supply a main-file directory;
|
|
||||||
independently specified contexts remain available for those workflows.
|
|
||||||
|
|
||||||
**Alternative:** derive from any resolved main filesystem context, including an
|
### OD-4: Main-source eligibility beyond discovered host files
|
||||||
explicit `BaseDir` for non-file inputs. This is more uniform for context-based
|
|
||||||
loading and avoids an artificial file requirement when a base is already known,
|
**Settled:** both explicitly selected and discovered host mains support the
|
||||||
but changes the concept from relative-to-main-file to relative-to-main-context.
|
workflow. Non-file companion inputs, especially mappings and bytes, are in scope;
|
||||||
It needs explicit rules for absent mains and root-only contexts, where root and
|
this decision concerns the main input that supplies their base.
|
||||||
base are not interchangeable. Limiting the first implementation to host files
|
|
||||||
is also viable and smaller, but would leave native-filesystem consumers with
|
**Recommendation:** also support native `Filesystem.File` mains using their
|
||||||
the same coordination gap.
|
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.
|
||||||
|
|
||||||
|
**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.
|
||||||
|
|||||||
Reference in New Issue
Block a user