Integrate collection policies across layered assembly

This commit is contained in:
2026-10-23 19:49:12 +00:00
parent 89a9684f0d
commit acd9e9a9fa
15 changed files with 269 additions and 93 deletions

View File

@@ -130,16 +130,20 @@ nothing. Underlay groups are listed from lowest to highest priority. Repeating
a file within one group remains an import/repetition error; the same reusable
source may be selected again in another tier.
ConfigKit acquires and composes the main input first, constructs the schema,
and checks the optional application version from the main tier only. Underlay
roots cannot claim that version path (`underlay.version`); imported fragments
retain `import.version` protection. It then acquires and composes underlay
groups in order, recursively combines the groups, and applies the main tier,
one selected overlay, and explicit CLI overrides. Scalar, sequence, and null
definitions replace lower values between tiers; mappings combine recursively.
Syntax and strict-composition errors inside a tier cannot be masked by a
higher-priority tier. Defaults, typed decoding, resolution, secret lookup,
validation, and publication run once on the final assembled input.
ConfigKit acquires the main input first and constructs the schema. It then
acquires and strictly composes underlay groups from lowest to highest priority,
passing each group's accumulated lower collection policy into the next group.
Each group is applied once as a precedence tier. The main tier is then composed
with the accumulated underlay policy, and the optional application version is
checked against that composed main tier only. Underlay roots cannot claim that
version path (`underlay.version`); imported fragments retain `import.version`
protection. ConfigKit then applies the selected overlay and explicit CLI
overrides. Scalar, sequence, and null definitions replace lower values between
tiers unless a collection policy defines the sequence operation; mappings
combine recursively. Syntax and strict-composition errors inside a tier cannot
be masked by a higher-priority tier. Defaults, typed decoding, resolution,
secret lookup, validation, and publication run once on the final assembled
input.
An active layered overlay requires `LayeredOptions.OverlayFilesystem` explicitly,
independent of the main source's namespace. Its name and root-relative lookup
@@ -149,7 +153,10 @@ Ordinary `Load` continues to infer its selected-overlay context from its source.
Source IDs follow acquisition order—main and its depth-first imports, then each
underlay tier's inputs and depth-first imports, then overlay and CLI—even though
history follows precedence order. Source `Layer` describes precedence while
history follows precedence order. Default main-version checking happens after
underlay composition because the main tier inherits the accumulated collection
policy. Enabled per-source version checks retain acquisition order and source
local headers. Source `Layer` describes precedence while
`Kind` describes acquisition. Underlay records use `LayerUnderlay` and a
one-based `UnderlayIndex` giving their original tier position; all other records
have index zero. Explicit empty groups and `NoSource` consume no source ID.
@@ -824,8 +831,8 @@ headers are consumed before strict composition and cannot supply a registered
record identity. Final typed decoding and application validation still run on the
completed configuration.
Ordinary sources and selected overlays may declare collection behavior under
`configkit.sequences` at the document root. Each entry has a required literal
Ordinary sources, layered inputs, and selected overlays may declare collection
behavior under `configkit.sequences` at the document root. Each entry has a required literal
`destination` and may specify `key` as one string or a nonempty list of strings,
plus a `mode` of `replace`, `append`, or `upsert`. These controls are removed
before application decoding. A declaration destination is relative to that
@@ -841,11 +848,14 @@ replaces a complete matched record at its existing position and appends new
identities in incoming order; it does not merge record fields.
Declarations govern ordinary strict source composition, including loads with
imports disabled, and selected-overlay precedence. Overlay declarations apply
after the base source graph is composed and must agree with retained collection
identity and any application registration. They do not change layered
precedence, inheritance, or CLI behavior. A root `configkit.imports`
declaration still requires `Options.Imports`; `NoSource` has no declaration scope.
imports disabled, and each strict scope in layered loading. Layered groups and
main apply their resolved sequence operation between precedence tiers; a higher
strict scope inherits the lower identity and explicit mode before peer
composition. Overlay declarations apply after the base source graph is composed
and must agree with retained collection identity and any application
registration. These policies do not change inheritance or CLI behavior. A root
`configkit.imports` declaration still requires `Options.Imports`; `NoSource` has
no declaration scope.
An empty mapping contributes no child definitions. Two empty mappings compose, and
an empty mapping neither clears nor conflicts with another mapping's children.

View File

@@ -1,6 +1,6 @@
# Sequence Identity And Combination Implementation Plan
Status: implementation in progress; Stages 1–14 complete.
Status: implementation in progress; Stages 1–15 complete.
Audience: a Luna coding agent implementing one numbered stage per prompt, in
order. This plan starts at commit
@@ -556,6 +556,12 @@ Do not absorb unfinished work from Stages 5–14 into this stage.
Validation: layered/grouped, source-version, dependency scheduling, destination,
and metadata tests plus the everyday check.
**Completion:** Implemented lower collection-policy propagation across underlay
groups, main composition, and layered overlays. Verified policy-only lower
tiers, inherited identity and explicit mode, explicit replacement, source
version behavior, sequence history, and consumer examples. Validation:
`go test ./internal/engine -count=1` and `./scripts/check.sh`.
## Stage 16 — Verify Replacement And Nested Policy Ownership End To End
Scope: the consequential lifetime cases across the now-active source assembly.