From 88725e79abcffcb4a5235f3ce52595946a8e31d6 Mon Sep 17 00:00:00 2001 From: Eric Rakestraw Date: Thu, 5 Nov 2026 20:07:55 +0000 Subject: [PATCH] Detach captured backend and profile values --- docs/roadmap/implementation.md | 6 ++++++ internal/backend/registry.go | 16 ++++------------ internal/backend/registry_test.go | 10 ++-------- internal/configuration/targets.go | 14 +++----------- internal/domain/smoke_diagnostics.go | 10 +++------- internal/domain/smoke_diagnostics_test.go | 15 +++++++++++---- 6 files changed, 29 insertions(+), 42 deletions(-) diff --git a/docs/roadmap/implementation.md b/docs/roadmap/implementation.md index 37689aa..f099c78 100644 --- a/docs/roadmap/implementation.md +++ b/docs/roadmap/implementation.md @@ -300,6 +300,12 @@ passed. ## Stage 11: Detach Captured Backend And Profile Values Without Revalidation +**Completed:** Backend registry construction and lookups, and captured profile +lookups, use trusted detached copies while configured acceptance and overlay +validation remain intact. Go 1.27.3 `go test ./internal/backend +./internal/configuration ./internal/domain` passed, including ownership, +composition, presence, and construction-error coverage. + **Finding:** 5; preserve 8. **Files:** `internal/domain/smoke_diagnostics.go`, `internal/backend/registry.go`, `internal/configuration/targets.go`, associated tests. diff --git a/internal/backend/registry.go b/internal/backend/registry.go index 772a18c..69cb883 100644 --- a/internal/backend/registry.go +++ b/internal/backend/registry.go @@ -27,17 +27,13 @@ type Registry struct { // NewEffectiveRegistry stores already-validated effective backend definitions // under their exact configuration keys. Configuration validation and // normalization precede this ownership boundary. -func NewEffectiveRegistry(definitions map[string]domain.Backend) (*Registry, error) { +func NewEffectiveRegistry(definitions map[string]domain.Backend) *Registry { registry := &Registry{backends: make(map[string]domain.Backend, len(definitions))} for id, definition := range definitions { definition.ID = id - cloned, err := domain.CloneBackend(definition) - if err != nil { - return nil, fmt.Errorf("backend %q: %w", id, err) - } - registry.backends[id] = cloned + registry.backends[id] = domain.CloneBackend(definition) } - return registry, nil + return registry } // GetBackend returns a defensive copy of the backend registered with id. @@ -49,11 +45,7 @@ func (r *Registry) GetBackend(id string) (domain.Backend, error) { if !ok { return domain.Backend{}, fmt.Errorf("%w: %q", ErrBackendNotFound, id) } - cloned, err := domain.CloneBackend(definition) - if err != nil { - return domain.Backend{}, fmt.Errorf("copy backend %q: %w", id, err) - } - return cloned, nil + return domain.CloneBackend(definition), nil } // CapacityPolicies returns a copy of the normalized policies for limited diff --git a/internal/backend/registry_test.go b/internal/backend/registry_test.go index 3a12147..0b4c72a 100644 --- a/internal/backend/registry_test.go +++ b/internal/backend/registry_test.go @@ -22,16 +22,13 @@ func TestEffectiveRegistryOwnsDefinitionsAndCapacityPolicies(t *testing.T) { Kind: &authenticationKind, Endpoint: &authenticationEndpoint, }, } - registry, err := backend.NewEffectiveRegistry(map[string]domain.Backend{ + registry := backend.NewEffectiveRegistry(map[string]domain.Backend{ " local.v1 ": { Endpoint: "https://backend.example/v1", ExtraParams: params, ConcurrencyLimit: 2, QueueCapacity: 3, SmokeTests: smokeTests, }, }) - if err != nil { - t.Fatal(err) - } params["nested"].(map[string]any)["enabled"] = false defaultProfile = "mutated-profile" reachabilityEndpoint = "https://mutated.example/ready" @@ -79,10 +76,7 @@ func TestEffectiveRegistryOwnsDefinitionsAndCapacityPolicies(t *testing.T) { } func TestEffectiveRegistryMissingBackend(t *testing.T) { - registry, err := backend.NewEffectiveRegistry(nil) - if err != nil { - t.Fatal(err) - } + registry := backend.NewEffectiveRegistry(nil) if _, err := registry.GetBackend("missing"); !errors.Is(err, backend.ErrBackendNotFound) { t.Fatalf("missing backend error = %v", err) } diff --git a/internal/configuration/targets.go b/internal/configuration/targets.go index d374742..16a3a59 100644 --- a/internal/configuration/targets.go +++ b/internal/configuration/targets.go @@ -19,15 +19,11 @@ func (state *loaded) buildExecutionProfiles() error { config := backendConfigs[id] definitions[id] = captureBackend(id, config) } - registry, err := backend.NewEffectiveRegistry(definitions) - if err != nil { - return err - } - state.registry = registry + state.registry = backend.NewEffectiveRegistry(definitions) state.indexedProfiles = make(map[string]domain.ExecutionProfile, len(profileConfigs)) for _, id := range sortedKeys(profileConfigs) { config := profileConfigs[id] - profile, err := captureExecutionProfile(id, config, state.profiles[id], registry) + profile, err := captureExecutionProfile(id, config, state.profiles[id], state.registry) if err != nil { return err } @@ -199,11 +195,7 @@ func (state *loaded) GetProfile(ctx context.Context, id string) (*domain.Executi return nil, err } target := *profile.ResolvedTarget - params, err := jsonvalue.CopyMap(target.ExtraParams) - if err != nil { - return nil, err - } - target.ExtraParams = params + target.ExtraParams = jsonvalue.CloneTrusted(target.ExtraParams).(map[string]any) profile.ResolvedTarget = &target return &profile, nil } diff --git a/internal/domain/smoke_diagnostics.go b/internal/domain/smoke_diagnostics.go index a7dab0a..b6f2641 100644 --- a/internal/domain/smoke_diagnostics.go +++ b/internal/domain/smoke_diagnostics.go @@ -122,15 +122,11 @@ const ( ) // CloneBackend returns a copy of a backend, including its mutable settings. -func CloneBackend(backend Backend) (Backend, error) { +func CloneBackend(backend Backend) Backend { cloned := backend - var err error - cloned.ExtraParams, err = jsonvalue.CopyMap(backend.ExtraParams) - if err != nil { - return Backend{}, err - } + cloned.ExtraParams = jsonvalue.CloneTrusted(backend.ExtraParams).(map[string]any) cloned.SmokeTests = CloneBackendSmokeTestConfig(backend.SmokeTests) - return cloned, nil + return cloned } // CloneBackendSmokeTestConfig returns an independent copy of optional metadata. diff --git a/internal/domain/smoke_diagnostics_test.go b/internal/domain/smoke_diagnostics_test.go index 14d9273..fdbf715 100644 --- a/internal/domain/smoke_diagnostics_test.go +++ b/internal/domain/smoke_diagnostics_test.go @@ -19,10 +19,7 @@ func TestCloneBackendCopiesDiagnosticMetadataAndProviderValues(t *testing.T) { }, } - cloned, err := CloneBackend(backend) - if err != nil { - t.Fatal(err) - } + cloned := CloneBackend(backend) *cloned.SmokeTests.DefaultProfile = "changed" *cloned.SmokeTests.Reachability.Endpoint = "changed" *cloned.SmokeTests.Authentication.Kind = "changed" @@ -37,3 +34,13 @@ func TestCloneBackendCopiesDiagnosticMetadataAndProviderValues(t *testing.T) { t.Fatalf("source provider parameter changed through clone: %v", got) } } + +func TestCloneBackendPreservesProviderMapPresence(t *testing.T) { + if cloned := CloneBackend(Backend{}); cloned.ExtraParams != nil { + t.Fatalf("nil provider map became %#v", cloned.ExtraParams) + } + cloned := CloneBackend(Backend{ExtraParams: map[string]any{"empty": map[string]any{}, "null": nil}}) + if cloned.ExtraParams == nil || cloned.ExtraParams["empty"].(map[string]any) == nil || cloned.ExtraParams["null"] != nil { + t.Fatalf("provider map presence changed: %#v", cloned.ExtraParams) + } +}