From a8ae2e9d5e0ba66133953df7630123914905a172 Mon Sep 17 00:00:00 2001 From: Eric Rakestraw Date: Sun, 25 Oct 2026 22:34:52 +0000 Subject: [PATCH] Clarify load context and inheritance handoffs --- docs/roadmap/implementation.md | 10 +++++++ internal/engine/load.go | 54 ++++++++-------------------------- internal/engine/load_input.go | 49 ++++++++++++++++++++++++++++++ 3 files changed, 71 insertions(+), 42 deletions(-) diff --git a/docs/roadmap/implementation.md b/docs/roadmap/implementation.md index 824ea52..e569bd8 100644 --- a/docs/roadmap/implementation.md +++ b/docs/roadmap/implementation.md @@ -749,6 +749,16 @@ and fail-before-later-callback cases remain intact. Re-run panic cleanup and retained-history integration cases after moving the handoffs. Focused check: `go test ./internal/engine -run 'Load|Overlay|Resource|Inheritance|Version|History'`. +Status: **complete** (third part of F02). Prior completed commits: `2736ddf`, +`deb9aa5`, `ae3408a`, `ea27f17`, `08a8c25`, `877c497`, `8aba43d`, `7bf2f0c`, +`0f9ecf1`, `119b42c`, `247a12b`, `4fcff5f`, `12d350a`, `08f2a8f`, `826062a`, +`e4a5ecb`, `3122e2f`, `6f6130f`, `4fd3bee`, `4bf940c`, `d8bf6ab`, and `f185821`. +Validation passed: `env GOTOOLCHAIN=local GOPROXY=off GOTELEMETRY=off go test ./internal/engine -run 'Load|Overlay|Resource|Inheritance|Version|History' -count=1`, +`env GOTOOLCHAIN=local GOPROXY=off GOTELEMETRY=off go test ./internal/engine -run 'ImportedAcquisitionCloses|History' -count=1`, +`env GOTOOLCHAIN=local GOPROXY=off GOTELEMETRY=off go test ./internal/engine -count=1`, +`env GOTOOLCHAIN=local GOPROXY=off GOTELEMETRY=off go test ./... -count=1`, +and `git diff --check`. + ## Stage 24 — Share Layered Tier Application And Evidence Projection Finding: completes **F02**. diff --git a/internal/engine/load.go b/internal/engine/load.go index 2b4cf43..466135e 100644 --- a/internal/engine/load.go +++ b/internal/engine/load.go @@ -260,52 +260,22 @@ func executeLoadRequest[T any](request loadRequest[T], secrets SecretBinding, lo } request.effectiveVersion = versionState.effectiveRule if request.ordinary && input.parsed.source != nil { - baseSources := make([]SourceInfo, 0, len(input.sources)) - for _, source := range input.sources { - if source.Layer == LayerBase { - baseSources = append(baseSources, source) - } - } - if len(baseSources) != 0 && input.contexts[baseSources[0].ID].FS == nil { - if input.resolvedFilesystem == nil && (request.main.source.kind == sourceFile || request.main.filesystem != nil || nativeContext(request.main.source, request.main.filesystem)) { - resolved, diagnostic := resolveFilesystemContext(request.main.source, request.main.filesystem, input.parsed, nil) - if diagnostic != nil { - accumulator.add(*diagnostic) - return nil, accumulator.loadError() - } - input.resolvedFilesystem = &resolved - } - contexts, diagnostic := contextsForResolvedSources(input.resolvedFilesystem, baseSources) - if diagnostic != nil { - accumulator.add(*diagnostic) - return nil, accumulator.loadError() - } - mergeResourceContexts(&input.contexts, contexts) + input, diagnostics = completeOrdinaryResourceContexts(input, request.main) + if len(diagnostics) != 0 { + accumulator.add(diagnostics...) + return nil, accumulator.loadError() } } - if input.document != nil && containsInheritanceDirective(input.document) { - composition, problems := compositionForInput(input) - if len(problems) != 0 { - accumulator.add(problems...) - return nil, accumulator.loadError() - } - expanded, problems := expandInheritanceWithCollectionRules( - composition.root, composition.origins, composition.collectionPolicies, policy.sequencePolicy, defaultProjectionLimits(), - ) - if len(problems) != 0 { - accumulator.add(problems...) - return nil, accumulator.loadError() - } - effectiveVersion, problem := projectInheritanceVersion(request.protectionVersion(), expanded) - if problem != nil { - accumulator.add(*problem) - return nil, accumulator.loadError() - } + var expanded bool + var effectiveVersion *VersionRule + input, effectiveVersion, expanded, diagnostics = expandStructuralInheritance(input, request.protectionVersion(), policy.sequencePolicy) + if len(diagnostics) != 0 { + accumulator.add(diagnostics...) + return nil, accumulator.loadError() + } + if expanded { request.effectiveVersion = effectiveVersion versionState.effectiveRule = effectiveVersion - input.composition = composition - input.inheritance = expanded - input.document = expanded.root } base := overridePreparationInput{root: input.document} diff --git a/internal/engine/load_input.go b/internal/engine/load_input.go index 09f3717..3b39564 100644 --- a/internal/engine/load_input.go +++ b/internal/engine/load_input.go @@ -129,6 +129,55 @@ func applyInputLayers(source Source, filesystem *FilesystemContext, overlay stri return input, nil } +func completeOrdinaryResourceContexts(input assembledInput, main loadInput) (assembledInput, []Diagnostic) { + baseSources := make([]SourceInfo, 0, len(input.sources)) + for _, source := range input.sources { + if source.Layer == LayerBase { + baseSources = append(baseSources, source) + } + } + if len(baseSources) == 0 || input.contexts[baseSources[0].ID].FS != nil { + return input, nil + } + if input.resolvedFilesystem == nil && (main.source.kind == sourceFile || main.filesystem != nil || nativeContext(main.source, main.filesystem)) { + resolved, diagnostic := resolveFilesystemContext(main.source, main.filesystem, input.parsed, nil) + if diagnostic != nil { + return input, []Diagnostic{*diagnostic} + } + input.resolvedFilesystem = &resolved + } + contexts, diagnostic := contextsForResolvedSources(input.resolvedFilesystem, baseSources) + if diagnostic != nil { + return input, []Diagnostic{*diagnostic} + } + mergeResourceContexts(&input.contexts, contexts) + return input, nil +} + +func expandStructuralInheritance(input assembledInput, protectionRule *VersionRule, policy sequencePolicy) (assembledInput, *VersionRule, bool, []Diagnostic) { + if input.document == nil || !containsInheritanceDirective(input.document) { + return input, nil, false, nil + } + composition, diagnostics := compositionForInput(input) + if len(diagnostics) != 0 { + return input, nil, false, diagnostics + } + expanded, diagnostics := expandInheritanceWithCollectionRules( + composition.root, composition.origins, composition.collectionPolicies, policy, defaultProjectionLimits(), + ) + if len(diagnostics) != 0 { + return input, nil, false, diagnostics + } + effectiveVersion, diagnostic := projectInheritanceVersion(protectionRule, expanded) + if diagnostic != nil { + return input, nil, false, []Diagnostic{*diagnostic} + } + input.composition = composition + input.inheritance = expanded + input.document = expanded.root + return input, effectiveVersion, true, nil +} + // compositionForInput initializes the structural handoff used by inheritance // expansion. Raw source bytes and mapping keys retain their budgets. func compositionForInput(input assembledInput) (*composedDocument, []Diagnostic) {