Detach captured backend and profile values

This commit is contained in:
2026-11-05 20:07:55 +00:00
parent 6c015a17fa
commit 88725e79ab
6 changed files with 29 additions and 42 deletions

View File

@@ -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.

View File

@@ -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

View File

@@ -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)
}

View File

@@ -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
}

View File

@@ -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.

View File

@@ -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)
}
}