diff --git a/docs/roadmap/audit/catalog.md b/docs/roadmap/audit/catalog.md index 9b75934..de5c4ae 100644 --- a/docs/roadmap/audit/catalog.md +++ b/docs/roadmap/audit/catalog.md @@ -1,6 +1,6 @@ # Consolidated audit catalog -Status: **7 distinct open findings: 7 P3**, consolidated from 30 +Status: **6 distinct open findings: 6 P3**, consolidated from 30 numbered entries in seven audit documents. Reviewed audit state: `db732e3a1de55c844f77870e1c6db683c2685d5d`. @@ -373,6 +373,10 @@ records the accepted boundary. ## F17 — P3: Configuration scope capture combines several compilation phases +**Complete.** Scope capture, selector attachment, operation binding unions and +inventory construction are distinct responsibilities. Focused family, selector, +comparison, capture and discovery checks pass. + ckconfig's `captureSuite` interleaves scope and selector capture, validation, comparison-binding renaming, binding attachment, operation unions, and discovery inventory. Several partially populated collections must be understood together. diff --git a/docs/roadmap/implementation.md b/docs/roadmap/implementation.md index aa1680f..210d2fe 100644 --- a/docs/roadmap/implementation.md +++ b/docs/roadmap/implementation.md @@ -1,6 +1,6 @@ # Audit remediation implementation plan -Status: in progress; Stages 1–18 complete. +Status: in progress; Stages 1–19 complete. Baseline: `d492c7747175c01a53261206c2b4356e53453621`. Before this sprint, intervening changes recorded decisions and retired the completed older @@ -608,6 +608,11 @@ changing the selected lifecycle or adding machinery solely to shorten functions. ## Stage 19 — Separate configuration suite capture responsibilities +**Complete.** Scope capture, selector attachment, operation binding unions and +inventory construction are explicit responsibilities over the existing prepared +types. Focused suite, selector, comparison, capture, help and discovery tests +passed offline in the aligned Go 1.27.0 workspace with `-mod=readonly`. + Findings: F17. Source: ckconfig `family.go` captureSuite. 1. Extract cohesive scope capture/validation and selector capture/attachment; diff --git a/integrations/ckconfig/family.go b/integrations/ckconfig/family.go index 069baf7..b3491a9 100644 --- a/integrations/ckconfig/family.go +++ b/integrations/ckconfig/family.go @@ -91,18 +91,16 @@ func captureSuite[I, S any](suite Suite[I, S]) *preparedSuite[I, S] { byName: make(map[string]*preparedScope[I, S], len(suite.Scopes)), bindingsByOperation: make(map[Operation][]commandkit.Flag[I]), } - selectors := make([]Selector[I], len(suite.Selectors)) - against := make([]commandkit.Flag[I], len(suite.Selectors)) - for index, selector := range suite.Selectors { - selector.Scopes = append([]string(nil), selector.Scopes...) - selectors[index] = selector - if selector.AgainstName != "" { - against[index] = commandkit.RenameFlag(selector.Binding, selector.AgainstName) - } - } + seenNames := captureConfigScopes(prepared, suite.Scopes) + selectors, against := captureConfigSelectors(prepared, suite.Selectors, seenNames) + captureOperationBindings(prepared, selectors, against) + captureScopeInventory(prepared) + return prepared +} - seenNames := make(map[string]struct{}, len(suite.Scopes)) - for _, original := range suite.Scopes { +func captureConfigScopes[I, S any](prepared *preparedSuite[I, S], scopes []Scope[I, S]) map[string]struct{} { + seenNames := make(map[string]struct{}, len(scopes)) + for _, original := range scopes { scope := original scope.Operations = normalizeOperations(scope.Operations, &prepared.issues, scope.Name) scope.issues = append([]error(nil), original.issues...) @@ -146,6 +144,20 @@ func captureSuite[I, S any](suite Suite[I, S]) *preparedSuite[I, S] { } prepared.scopeChoices = joinNames(names) + return seenNames +} + +func captureConfigSelectors[I, S any](prepared *preparedSuite[I, S], originals []Selector[I], seenNames map[string]struct{}) ([]Selector[I], []commandkit.Flag[I]) { + selectors := make([]Selector[I], len(originals)) + against := make([]commandkit.Flag[I], len(originals)) + for index, selector := range originals { + selector.Scopes = append([]string(nil), selector.Scopes...) + selectors[index] = selector + if selector.AgainstName != "" { + against[index] = commandkit.RenameFlag(selector.Binding, selector.AgainstName) + } + } + for index, selector := range selectors { seen := make(map[string]struct{}, len(selector.Scopes)) uniqueScopes := make([]string, 0, len(selector.Scopes)) @@ -181,6 +193,10 @@ func captureSuite[I, S any](suite Suite[I, S]) *preparedSuite[I, S] { } } + return selectors, against +} + +func captureOperationBindings[I, S any](prepared *preparedSuite[I, S], selectors []Selector[I], against []commandkit.Flag[I]) { for _, operation := range []Operation{Validate, Show, Sources, Explain, Diff} { for _, scope := range prepared.scopes { if containsOperation(scope.scope.Operations, operation) { @@ -200,6 +216,9 @@ func captureSuite[I, S any](suite Suite[I, S]) *preparedSuite[I, S] { } } } +} + +func captureScopeInventory[I, S any](prepared *preparedSuite[I, S]) { for _, scope := range prepared.scopes { prepared.inventory.Scopes = append(prepared.inventory.Scopes, scopeMetadata{ Name: scope.scope.Name, @@ -207,7 +226,6 @@ func captureSuite[I, S any](suite Suite[I, S]) *preparedSuite[I, S] { Features: featureNames(scope.scope.Features), }) } - return prepared } func normalizeOperations(operations []Operation, issues *[]error, scope string) []Operation {