From daa0cf9e88894012f9c56a21997717860c6f7787 Mon Sep 17 00:00:00 2001 From: Eric Rakestraw Date: Mon, 9 Nov 2026 17:55:27 +0000 Subject: [PATCH] Settle containment and symlink behavior for companion inputs --- docs/roadmap/main-relative-inputs.md | 64 +++++++++++++++++----------- 1 file changed, 38 insertions(+), 26 deletions(-) diff --git a/docs/roadmap/main-relative-inputs.md b/docs/roadmap/main-relative-inputs.md index 2c778fe..3c6681f 100644 --- a/docs/roadmap/main-relative-inputs.md +++ b/docs/roadmap/main-relative-inputs.md @@ -1,8 +1,8 @@ # Main-relative companion imports and overlays -Status: accepted direction, public API structure, and absent-main behavior; -containment and main-source eligibility remain open. Not implemented. Baseline: -`191015e`. +Status: accepted direction, public API structure, absent-main behavior, and +containment/symlink convention; main-source eligibility remains open. +Not implemented. Baseline: `191015e`. ## Purpose @@ -95,9 +95,9 @@ 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 -import selection then acquires the companion files. Every imported file uses -its own directory for its further relative imports. For example, an import of +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 `extra.yml` from `glossary/terms.yml` resolves to `glossary/extra.yml`. Applications choose underlay groups and their order. A group composes strictly; @@ -324,28 +324,40 @@ fallback. When no overlay is selected, no overlay context is needed. An active selection requires a usable context and the named file; never silently skip it. 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. + +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 +`../shared/terms.yml` may resolve to `/srv/shared/terms.yml` within that root. +Overlay `production` resolves to `/srv/campaign/overlays/production.yml`. +Without an explicit wider root, the host main's canonical directory remains +its default containment root. Preserve intentional wider roots rather than +establishing a fresh, narrower companion root. Parent-relative paths remain +permitted when existing containment rules allow them. + +For host symlinks, use the canonical target directory. If +`/etc/audita/audita.yml` points to `/srv/releases/v3/audita.yml`, derived +companions and overlays are located under `/srv/releases/v3`. A subsequent load +follows the newly selected bundle if the symlink changes. Document that files +beside the link in `/etc/audita` are not selected by this derived convention. +This matches existing file/import bases; no separate symlink-base selector is +needed for this feature. Applications may supply concrete context overrides +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 +capabilities without imposing host-filesystem guarantees on every `fs.FS`. + ## Open Decisions -### OD-3: Containment inheritance and symlink convention - -**Settled:** derived companion imports and derived layered overlays use the main -file's directory for lookup, even with a wider configured containment root. -Explicit overlay contexts retain their current lookup semantics. - -**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. - -**Alternative:** create a fresh containment root at the selected main directory. -This keeps companions locally scoped but discards intentional wider roots and -prevents some sibling-directory layouts. Anchoring to the lexical symlink directory -is also viable for deployment bundles; it differs from current file/import -behavior and would need distinct lookup and containment handling. - ### OD-4: Main-source eligibility beyond discovered host files **Settled:** both explicitly selected and discovered host mains support the