From b915dd776af22b978b336321bd5a4c36abe8edc0 Mon Sep 17 00:00:00 2001 From: Eric Rakestraw Date: Sun, 25 Oct 2026 13:18:54 +0000 Subject: [PATCH] Consolidate selected overlay acquisition --- docs/roadmap/implementation.md | 12 +- internal/engine/filesystem.go | 57 ++------- internal/engine/filesystem_context.go | 4 + internal/engine/load_input.go | 25 +++- internal/engine/load_request.go | 27 +++-- internal/engine/selected_overlay.go | 147 +++++++---------------- internal/engine/selected_overlay_test.go | 16 ++- internal/engine/source_context.go | 24 ---- internal/engine/source_version_test.go | 19 ++- 9 files changed, 138 insertions(+), 193 deletions(-) diff --git a/docs/roadmap/implementation.md b/docs/roadmap/implementation.md index 995929c..548cb10 100644 --- a/docs/roadmap/implementation.md +++ b/docs/roadmap/implementation.md @@ -1,6 +1,6 @@ # Consolidation Implementation Plan -Status: in progress. Stages 1 through 8 are complete; follow Stage 9 through Stage 20 in order. +Status: in progress. Stages 1 through 9 are complete; follow Stage 10 through Stage 20 in order. The target executor is a Luna coding agent working through one end-to-end sprint. ## Authority, Baseline, And Execution @@ -413,7 +413,7 @@ sources. Migrated the ordinary backfill and reordered-source context test. The selected-overlay adapters remain for Stage 9. Focused context/acquisition tests, `GOTOOLCHAIN=local GOPROXY=off go test ./...`, and `git diff --check` passed. -## Stage 9 — Migrate Selected Overlays Without Merging Their Semantics +## Stage 9 — Migrate Selected Overlays Without Merging Their Semantics (Complete) **Owners:** engine `selected_overlay.go`, ordinary `applyInputLayers`, and `assembleLayeredInput`. @@ -445,6 +445,14 @@ ordinary and independent layered overlay semantics remain distinct. Run A when buildable; carry any genuine remaining migration dependencies to the next integration opportunity instead of adding scaffolding or stopping the sprint. +Progress notes (2026-10-25): introduced the named overlay request and migrated +ordinary and independent layered overlay acquisition to resolved facts plus +explicit access. Replaced the variadic compatibility branch with the existing +collection-aware path, removed old context adapters, and retained overlay +validation timing, source evidence, budgets, version protection, and close +reporting. Validation group A, consumer examples, the full Go suite, and +`git diff --check` passed. + ## Stage 10 — Give Import Responsibilities Focused Files **Owners:** engine `imports.go` and new `import_acquisition.go`, diff --git a/internal/engine/filesystem.go b/internal/engine/filesystem.go index c273f95..6692173 100644 --- a/internal/engine/filesystem.go +++ b/internal/engine/filesystem.go @@ -12,17 +12,20 @@ func validateFilesystemContext(source Source, context *FilesystemContext, main p return validateAbsentHostFilesystemContext(context) } if nativeContext(source, context) { - access, basePath, mainPath, diagnostic := nativeFilesystemAccess(source, context) + resolved, diagnostic := resolveNativeFilesystemContext(source, context) if diagnostic != nil { return diagnostic } - return validateNativeDirectories(access, basePath, mainPath) + return validateResolvedFilesystemDirectories(resolved) } - rootPath, _, _, diagnostic := importFilesystem(source, context, main) + resolved, diagnostic := resolveHostFilesystemContext(source, context, main, nil) if diagnostic != nil { return diagnostic } - root, err := os.OpenRoot(rootPath) + if diagnostic := validateResolvedFilesystemDirectories(resolved); diagnostic != nil { + return diagnostic + } + root, err := os.OpenRoot(resolved.rootPath) if err != nil { value := globFilesystemDiagnostic(err, "configuration root could not be opened", Location{}) value.Primary = nil @@ -133,52 +136,6 @@ func nativeContext(source Source, context *FilesystemContext) bool { return source.kind == sourceFilesystem || context != nil && context.FS != nil } -// nativeFilesystemAccess resolves namespace context without opening caller -// resources. File inputs always derive their base from the selected file. -func nativeFilesystemAccess(source Source, context *FilesystemContext) (*filesystemAccess, string, string, *Diagnostic) { - resolved, diagnostic := resolveNativeFilesystemContext(source, context) - if diagnostic != nil { - return nil, "", "", diagnostic - } - access, err := openResolvedFilesystemAccess(resolved) - if err != nil { - value := globFilesystemDiagnostic(err, "configuration root could not be opened", Location{}) - value.Primary = nil - return nil, "", "", &value - } - return access, resolved.basePath, resolved.mainPath, nil -} - -func validateNativeDirectories(access *filesystemAccess, basePath, mainPath string) *Diagnostic { - if !access.contains(basePath) || mainPath != "" && !access.contains(mainPath) { - value := importDiagnostic(CodeImportOutsideRoot, "selected source and import base must stay inside the configuration root", nil) - return &value - } - for _, directory := range []string{access.rootPath, basePath} { - info, err := access.stat(directory) - if err != nil || !info.IsDir() { - value := importDiagnostic(CodeImportInvalid, "configuration root and import base must be directories", nil) - return &value - } - } - return nil -} - -func importFilesystem(source Source, context *FilesystemContext, main parsedSource) (rootPath, basePath, mainPath string, diagnostic *Diagnostic) { - if main.source == nil || main.document == nil { - value := importDiagnostic(CodeImportInvalid, "imports require a selected configuration source", nil) - return "", "", "", &value - } - resolved, diagnostic := resolveHostFilesystemContext(source, context, main, nil) - if diagnostic != nil { - return "", "", "", diagnostic - } - if diagnostic := validateResolvedFilesystemDirectories(resolved); diagnostic != nil { - return "", "", "", diagnostic - } - return resolved.rootPath, resolved.basePath, resolved.mainPath, nil -} - func canonicalExistingPath(name string) (string, error) { absolute, err := filepath.Abs(name) if err != nil { diff --git a/internal/engine/filesystem_context.go b/internal/engine/filesystem_context.go index d9f8d1f..8bc8583 100644 --- a/internal/engine/filesystem_context.go +++ b/internal/engine/filesystem_context.go @@ -43,6 +43,10 @@ func resolveAbsentFilesystemContext(context *FilesystemContext) (resolvedFilesys return resolvedFilesystemContext{}, &value } } + if !containedPath(rootPath, basePath) { + value := importDiagnostic(CodeImportOutsideRoot, "selected source and import base must stay inside the configuration root", nil) + return resolvedFilesystemContext{}, &value + } return resolvedFilesystemContext{rootPath: rootPath, basePath: basePath}, nil } diff --git a/internal/engine/load_input.go b/internal/engine/load_input.go index a9e3e59..14f9498 100644 --- a/internal/engine/load_input.go +++ b/internal/engine/load_input.go @@ -97,14 +97,29 @@ func applyInputLayers(source Source, filesystem *FilesystemContext, overlay stri return input, diagnostics } assembly := newAssemblyAccumulator(composition) - input.sources, diagnostics = loadSelectedOverlayIntoWithVersion( - source, filesystem, input.parsed, assembly, input.sources, - overlay, protectionRule, defaultImportLimits(), input.versionState, policy, - ) + resolved, diagnostic := resolveOrdinaryOverlayFilesystem(source, filesystem, input.parsed, input.resolvedFilesystem) + if diagnostic != nil { + return input, []Diagnostic{*diagnostic} + } + if source.kind != sourceNone || nativeContext(source, filesystem) { + if diagnostic := validateResolvedFilesystemDirectories(resolved); diagnostic != nil { + return input, []Diagnostic{*diagnostic} + } + } + request := selectedOverlayRequest{ + name: overlay, filesystem: resolved, protectionRule: protectionRule, + sequencePolicy: policy, limits: defaultImportLimits(), versionState: input.versionState, + } + access, diagnostic := openSelectedOverlayAccess(resolved) + if diagnostic != nil { + return input, []Diagnostic{*diagnostic} + } + input.sources, diagnostics = loadSelectedOverlay(request, access, assembly, input.sources) if len(diagnostics) != 0 { return input, diagnostics } - contexts, diagnostic := contextsForAcquiredSources(source, filesystem, input.parsed.source, input.sources[len(input.sources)-1:]) + input.resolvedFilesystem = &resolved + contexts, diagnostic := contextsForResolvedSources(&resolved, input.sources[len(input.sources)-1:]) if diagnostic != nil { return input, []Diagnostic{*diagnostic} } diff --git a/internal/engine/load_request.go b/internal/engine/load_request.go index 5678160..93318f7 100644 --- a/internal/engine/load_request.go +++ b/internal/engine/load_request.go @@ -192,17 +192,30 @@ func assembleLayeredInput[T any](request loadRequest[T], input assembledInput, p assembly.current.inputBytes = state.accounting.bytes assembly.current.inputNodes = state.accounting.nodes if activeOverlay(request.overlay) { - // The selected overlay context is independent of the main input. This - // synthetic descriptor creates no source record or input contribution. - selection := Source{kind: sourceBytes} - selected := parsedSource{document: &document.Node{Kind: document.Mapping}, source: &SourceInfo{}} + if request.overlayFilesystem == nil { + return input, append(versionDiagnostics, optionDiagnostic(CodeOptionsInvalid, "selected overlay requires explicit filesystem context")) + } + resolved, diagnostic := resolveAbsentFilesystemContext(request.overlayFilesystem) + if diagnostic != nil { + return input, append(versionDiagnostics, *diagnostic) + } + if diagnostic := validateResolvedFilesystemDirectories(resolved); diagnostic != nil { + return input, append(versionDiagnostics, *diagnostic) + } + overlayRequest := selectedOverlayRequest{ + name: request.overlay, filesystem: resolved, protectionRule: request.protectionVersion(), + sequencePolicy: policy.sequencePolicy, limits: defaultImportLimits(), versionState: input.versionState, + } var diagnostics []Diagnostic - overlayPolicy := []sequencePolicy{policy.sequencePolicy} - input.sources, diagnostics = loadSelectedOverlayIntoWithVersion(selection, request.overlayFilesystem, selected, assembly, input.sources, request.overlay, request.protectionVersion(), defaultImportLimits(), input.versionState, overlayPolicy...) + access, diagnostic := openSelectedOverlayAccess(resolved) + if diagnostic != nil { + return input, append(versionDiagnostics, *diagnostic) + } + input.sources, diagnostics = loadSelectedOverlay(overlayRequest, access, assembly, input.sources) if len(diagnostics) != 0 { return input, append(versionDiagnostics, diagnostics...) } - contexts, diagnostic := contextsForAcquiredSources(selection, request.overlayFilesystem, selected.source, input.sources[len(input.sources)-1:]) + contexts, diagnostic := contextsForResolvedSources(&resolved, input.sources[len(input.sources)-1:]) if diagnostic != nil { return input, append(versionDiagnostics, *diagnostic) } diff --git a/internal/engine/selected_overlay.go b/internal/engine/selected_overlay.go index 9d352d1..caff47b 100644 --- a/internal/engine/selected_overlay.go +++ b/internal/engine/selected_overlay.go @@ -28,84 +28,51 @@ func validOverlayName(name string) bool { return true } -func loadSelectedOverlayDocument(source Source, context *FilesystemContext, main parsedSource, base *composedDocument, sources []SourceInfo, name string, rule *VersionRule, limits importLimits) (*composedDocument, []SourceInfo, []Diagnostic) { - assembly := newAssemblyAccumulator(cloneComposedDocument(base)) - allSources, diagnostics := loadSelectedOverlayInto(source, context, main, assembly, sources, name, rule, limits) - if len(diagnostics) != 0 { - return nil, allSources, diagnostics - } - return assembly.current, allSources, nil +type selectedOverlayRequest struct { + name string + filesystem resolvedFilesystemContext + protectionRule *VersionRule + sequencePolicy sequencePolicy + limits importLimits + versionState *sourceVersionState } -func loadSelectedOverlayInto(source Source, context *FilesystemContext, main parsedSource, base *assemblyAccumulator, sources []SourceInfo, name string, rule *VersionRule, limits importLimits) ([]SourceInfo, []Diagnostic) { - return loadSelectedOverlayIntoWithVersion(source, context, main, base, sources, name, rule, limits, nil) -} - -func loadSelectedOverlayIntoWithVersion(source Source, context *FilesystemContext, main parsedSource, base *assemblyAccumulator, sources []SourceInfo, name string, rule *VersionRule, limits importLimits, versionState *sourceVersionState, policies ...sequencePolicy) ([]SourceInfo, []Diagnostic) { - var policy sequencePolicy - if len(policies) != 0 { - policy = policies[0] - } - if nativeContext(source, context) { - access, basePath, mainPath, diagnostic := nativeFilesystemAccess(source, context) - if diagnostic != nil { - return cloneSourceInfos(sources), []Diagnostic{*diagnostic} - } - if diagnostic := validateNativeDirectories(access, basePath, mainPath); diagnostic != nil { - return cloneSourceInfos(sources), []Diagnostic{*diagnostic} - } - if len(policies) == 0 { - return loadSelectedOverlayWithAccessAndVersion(access, base, sources, name, rule, limits, versionState) - } - return loadSelectedOverlayWithAccessAndVersion(access, base, sources, name, rule, limits, versionState, policy) - } - var rootPath string +func resolveOrdinaryOverlayFilesystem(source Source, context *FilesystemContext, main parsedSource, existing *resolvedFilesystemContext) (resolvedFilesystemContext, *Diagnostic) { if source.kind == sourceNone { if context == nil { value := optionDiagnostic(CodeOptionsInvalid, "NoSource overlays require explicit filesystem context") - return cloneSourceInfos(sources), []Diagnostic{value} - } - var err error - rootPath, err = canonicalExistingPath(context.Root) - if err != nil { - value := importDiagnostic(CodeImportInvalid, "configuration root could not be canonicalized", nil) - return cloneSourceInfos(sources), []Diagnostic{value} - } - } else { - var diagnostic *Diagnostic - rootPath, _, _, diagnostic = importFilesystem(source, context, main) - if diagnostic != nil { - return cloneSourceInfos(sources), []Diagnostic{*diagnostic} + return resolvedFilesystemContext{}, &value } + return resolveAbsentFilesystemContext(context) } - access, err := openHostAccess(rootPath) + if existing != nil { + return *existing, nil + } + return resolveFilesystemContext(source, context, main, nil) +} + +func openSelectedOverlayAccess(resolved resolvedFilesystemContext) (*filesystemAccess, *Diagnostic) { + access, err := openResolvedFilesystemAccess(resolved) if err != nil { value := globFilesystemDiagnostic(err, "configuration root could not be opened for the selected overlay", Location{}) value.Primary = nil - return cloneSourceInfos(sources), []Diagnostic{value} + return nil, &value } - if len(policies) == 0 { - return loadSelectedOverlayWithAccessAndVersion(access, base, sources, name, rule, limits, versionState) - } - return loadSelectedOverlayWithAccessAndVersion(access, base, sources, name, rule, limits, versionState, policy) + return access, nil } -func loadSelectedOverlayWithAccess(access *filesystemAccess, base *assemblyAccumulator, sources []SourceInfo, name string, rule *VersionRule, limits importLimits) ([]SourceInfo, []Diagnostic) { - return loadSelectedOverlayWithAccessAndVersion(access, base, sources, name, rule, limits, nil) -} - -func loadSelectedOverlayWithAccessAndVersion(access *filesystemAccess, base *assemblyAccumulator, sources []SourceInfo, name string, rule *VersionRule, limits importLimits, versionState *sourceVersionState, policies ...sequencePolicy) ([]SourceInfo, []Diagnostic) { - var policy sequencePolicy - if len(policies) != 0 { - policy = policies[0] - } +func loadSelectedOverlay(request selectedOverlayRequest, access *filesystemAccess, base *assemblyAccumulator, sources []SourceInfo) ([]SourceInfo, []Diagnostic) { + policy := request.sequencePolicy + rule := request.protectionRule + limits := request.limits + versionState := request.versionState closed := false defer func() { if !closed { _ = access.close() } }() - overlayPath := access.join(access.rootPath, "overlays/"+name+".yml") + overlayPath := access.join(access.rootPath, "overlays/"+request.name+".yml") canonical, err := access.canonical(overlayPath) if err != nil { code := CodeOverlayInvalid @@ -138,7 +105,7 @@ func loadSelectedOverlayWithAccessAndVersion(access *filesystemAccess, base *ass sourceID := "source-" + strconv.Itoa(len(sources)+1) overlayLocation := &Location{SourceID: sourceID} kind := SourceKindFile - label := "overlays/" + name + ".yml" + label := "overlays/" + request.name + ".yml" if access.native != nil { kind = SourceKindFilesystem label = access.label + "/" + canonical @@ -160,66 +127,44 @@ func loadSelectedOverlayWithAccessAndVersion(access *filesystemAccess, base *ass if base.current.inputNodes+nodeCount > limits.nodes { return sources, []Diagnostic{importDiagnostic(CodeOverlayLimitExceeded, "selected overlay exceeds the aggregate node limit", overlayLocation)} } - if diagnostics := overlayDirectiveDiagnostics(overlayRoot, Path{}, len(policies) != 0); len(diagnostics) != 0 { + if diagnostics := overlayDirectiveDiagnostics(overlayRoot, Path{}, true); len(diagnostics) != 0 { return sources, diagnostics } var processed sourceVersionProcessingResult var failures []Diagnostic - if len(policies) != 0 { - if versionState != nil { - processed, failures = versionState.processWithDirectiveContext( - overlayRoot, sourceVersionContribution, Path{}, sourceID, placementModeMapping, rootDirectiveContextOverlay, - ) - } else { - processed = processSourceVersionWithDirectiveContext( - overlayRoot, rule, sourceVersionContribution, Path{}, sourceVersionModeDefault, rootDirectiveContextOverlay, - ) - failures = processed.diagnostics - } + if versionState != nil { + processed, failures = versionState.processWithDirectiveContext( + overlayRoot, sourceVersionContribution, Path{}, sourceID, placementModeMapping, rootDirectiveContextOverlay, + ) } else { - if versionState != nil && versionState.mode != sourceVersionModeDefault { - processed, failures = versionState.process(overlayRoot, sourceVersionContribution, Path{}, sourceID, placementModeMapping) - } else { - processed = sourceVersionProcessingResult{payload: overlayRoot} - } + processed = processSourceVersionWithDirectiveContext( + overlayRoot, rule, sourceVersionContribution, Path{}, sourceVersionModeDefault, rootDirectiveContextOverlay, + ) + failures = processed.diagnostics } if len(failures) != 0 { return sources, failures } overlayPayload := processed.payload - if versionNode := fragmentVersionClaim(overlayPayload, rule); len(policies) == 0 && versionNode != nil { - location := publicLocation(versionNode.Location) - return sources, []Diagnostic{{ - Code: CodeOverlayVersion, Severity: SeverityError, Path: rule.Path.clone(), - Message: "overlays cannot contribute to or replace the schema-version path", Primary: &location, - }} - } closeErr := access.close() closed = true if closeErr != nil { return sources, []Diagnostic{importDiagnostic(CodeImportRead, "configuration root could not be closed after reading the selected overlay", nil)} } - var overlayDiagnostics []Diagnostic - if len(policies) != 0 { - overlayDiagnostics = base.applyOverlayWithCollectionPolicy(overlayPayload, nil, collectionPolicyScope{}, nil, LayerOverlay, policy, processed.sequences) - } else { - overlayDiagnostics = base.applyOverlay(overlayPayload, nil, nil, LayerOverlay) - } + overlayDiagnostics := base.applyOverlayWithCollectionPolicy(overlayPayload, nil, collectionPolicyScope{}, nil, LayerOverlay, policy, processed.sequences) if len(overlayDiagnostics) != 0 { return sources, overlayDiagnostics } - if len(policies) != 0 { - // The selected overlay retains one application with the actual item - // assignments. Raw list indexes cannot identify an upsert's destination. - application := base.current.applications[len(base.current.applications)-1] - if node := versionClaimFromApplication(application, rule); node != nil { - location := publicLocation(node.Location) - return sources, []Diagnostic{{ - Code: CodeOverlayVersion, Severity: SeverityError, Path: rule.Path.clone(), - Message: "overlays cannot contribute to or replace the schema-version path", Primary: &location, - }} - } + // The selected overlay retains one application with the actual item + // assignments. Raw list indexes cannot identify an upsert's destination. + application := base.current.applications[len(base.current.applications)-1] + if node := versionClaimFromApplication(application, rule); node != nil { + location := publicLocation(node.Location) + return sources, []Diagnostic{{ + Code: CodeOverlayVersion, Severity: SeverityError, Path: rule.Path.clone(), + Message: "overlays cannot contribute to or replace the schema-version path", Primary: &location, + }} } base.current.inputBytes += int64(len(data)) base.current.inputNodes += nodeCount diff --git a/internal/engine/selected_overlay_test.go b/internal/engine/selected_overlay_test.go index 8258adc..3cb3fa6 100644 --- a/internal/engine/selected_overlay_test.go +++ b/internal/engine/selected_overlay_test.go @@ -585,7 +585,21 @@ func TestLoadOverlayCountsAgainstAggregateBudgets(t *testing.T) { } base.inputBytes = main.bytes base.inputNodes = countInputNodes(main.document) - _, _, diagnostics = loadSelectedOverlayDocument(File(mainPath), nil, main, base, sourceInfos(main.source), "testing", nil, test.limits(main, len(overlayData))) + resolved, diagnostic := resolveFilesystemContext(File(mainPath), nil, main, nil) + if diagnostic != nil { + t.Fatal(diagnostic) + } + request := selectedOverlayRequest{ + name: "testing", filesystem: resolved, limits: test.limits(main, len(overlayData)), + } + if diagnostic := validateResolvedFilesystemDirectories(resolved); diagnostic != nil { + t.Fatal(diagnostic) + } + access, diagnostic := openSelectedOverlayAccess(resolved) + if diagnostic != nil { + t.Fatal(diagnostic) + } + _, diagnostics = loadSelectedOverlay(request, access, newAssemblyAccumulator(base), sourceInfos(main.source)) if len(diagnostics) == 0 || diagnostics[0].Code != CodeOverlayLimitExceeded { t.Fatalf("diagnostics = %#v", diagnostics) } diff --git a/internal/engine/source_context.go b/internal/engine/source_context.go index c13f35b..107aed9 100644 --- a/internal/engine/source_context.go +++ b/internal/engine/source_context.go @@ -66,30 +66,6 @@ func contextsForResolvedSources(resolved *resolvedFilesystemContext, sources []S return result, nil } -// contextsForAcquiredSources is retained for selected-overlay callers until -// their request migration. Input acquisition resolves the facts at its own -// lifecycle boundary and uses contextsForResolvedSources directly. -func contextsForAcquiredSources(source Source, context *FilesystemContext, baseSource *SourceInfo, sources []SourceInfo) (map[string]ResourceContext, *Diagnostic) { - if len(sources) == 0 { - return nil, nil - } - if source.kind == sourceNone { - if context == nil { - return nil, nil - } - resolved, diagnostic := resolveAbsentFilesystemContext(context) - if diagnostic != nil { - return nil, diagnostic - } - return contextsForResolvedSources(&resolved, sources) - } - resolved, diagnostic := resolveFilesystemContext(source, context, parsedSource{source: baseSource}, nil) - if diagnostic != nil { - return nil, diagnostic - } - return contextsForResolvedSources(&resolved, sources) -} - func mergeResourceContexts(target *map[string]ResourceContext, incoming map[string]ResourceContext) { if len(incoming) == 0 { return diff --git a/internal/engine/source_version_test.go b/internal/engine/source_version_test.go index d00df1f..97bfb02 100644 --- a/internal/engine/source_version_test.go +++ b/internal/engine/source_version_test.go @@ -1487,9 +1487,22 @@ func TestSourceVersionOverlayProtectsMountedMainAndPreservesSequenceCoordinates( t.Fatalf("compose base: %#v", compositionDiagnostics) } assembly := newAssemblyAccumulator(base) - _, diagnostics = loadSelectedOverlayIntoWithVersion( - File(mainPath), nil, main, assembly, sourceInfos(main.source), "testing", effectiveRule, defaultImportLimits(), state, - ) + resolved, diagnostic := resolveFilesystemContext(File(mainPath), nil, main, nil) + if diagnostic != nil { + t.Fatalf("resolve overlay context: %#v", diagnostic) + } + request := selectedOverlayRequest{ + name: "testing", filesystem: resolved, protectionRule: effectiveRule, + limits: defaultImportLimits(), versionState: state, + } + if diagnostic := validateResolvedFilesystemDirectories(resolved); diagnostic != nil { + t.Fatalf("validate overlay context: %#v", diagnostic) + } + access, diagnostic := openSelectedOverlayAccess(resolved) + if diagnostic != nil { + t.Fatalf("open overlay context: %#v", diagnostic) + } + _, diagnostics = loadSelectedOverlay(request, access, assembly, sourceInfos(main.source)) if len(diagnostics) != 0 { t.Fatalf("load selected overlay: %#v", diagnostics) }