Separate configuration suite capture

This commit is contained in:
2026-11-07 15:58:16 +00:00
parent a62f1f056b
commit b66a00da26
3 changed files with 41 additions and 14 deletions

View File

@@ -1,6 +1,6 @@
# Consolidated audit catalog # 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: numbered entries in seven audit documents. Reviewed audit state:
`db732e3a1de55c844f77870e1c6db683c2685d5d`. `db732e3a1de55c844f77870e1c6db683c2685d5d`.
@@ -373,6 +373,10 @@ records the accepted boundary.
## F17 — P3: Configuration scope capture combines several compilation phases ## 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, ckconfig's `captureSuite` interleaves scope and selector capture, validation,
comparison-binding renaming, binding attachment, operation unions, and discovery comparison-binding renaming, binding attachment, operation unions, and discovery
inventory. Several partially populated collections must be understood together. inventory. Several partially populated collections must be understood together.

View File

@@ -1,6 +1,6 @@
# Audit remediation implementation plan # Audit remediation implementation plan
Status: in progress; Stages 1–18 complete. Status: in progress; Stages 1–19 complete.
Baseline: `d492c7747175c01a53261206c2b4356e53453621`. Before this sprint, Baseline: `d492c7747175c01a53261206c2b4356e53453621`. Before this sprint,
intervening changes recorded decisions and retired the completed older 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 ## 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. Findings: F17. Source: ckconfig `family.go` captureSuite.
1. Extract cohesive scope capture/validation and selector capture/attachment; 1. Extract cohesive scope capture/validation and selector capture/attachment;

View File

@@ -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)), byName: make(map[string]*preparedScope[I, S], len(suite.Scopes)),
bindingsByOperation: make(map[Operation][]commandkit.Flag[I]), bindingsByOperation: make(map[Operation][]commandkit.Flag[I]),
} }
selectors := make([]Selector[I], len(suite.Selectors)) seenNames := captureConfigScopes(prepared, suite.Scopes)
against := make([]commandkit.Flag[I], len(suite.Selectors)) selectors, against := captureConfigSelectors(prepared, suite.Selectors, seenNames)
for index, selector := range suite.Selectors { captureOperationBindings(prepared, selectors, against)
selector.Scopes = append([]string(nil), selector.Scopes...) captureScopeInventory(prepared)
selectors[index] = selector return prepared
if selector.AgainstName != "" {
against[index] = commandkit.RenameFlag(selector.Binding, selector.AgainstName)
}
} }
seenNames := make(map[string]struct{}, len(suite.Scopes)) func captureConfigScopes[I, S any](prepared *preparedSuite[I, S], scopes []Scope[I, S]) map[string]struct{} {
for _, original := range suite.Scopes { seenNames := make(map[string]struct{}, len(scopes))
for _, original := range scopes {
scope := original scope := original
scope.Operations = normalizeOperations(scope.Operations, &prepared.issues, scope.Name) scope.Operations = normalizeOperations(scope.Operations, &prepared.issues, scope.Name)
scope.issues = append([]error(nil), original.issues...) 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) 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 { for index, selector := range selectors {
seen := make(map[string]struct{}, len(selector.Scopes)) seen := make(map[string]struct{}, len(selector.Scopes))
uniqueScopes := make([]string, 0, 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 _, operation := range []Operation{Validate, Show, Sources, Explain, Diff} {
for _, scope := range prepared.scopes { for _, scope := range prepared.scopes {
if containsOperation(scope.scope.Operations, operation) { 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 { for _, scope := range prepared.scopes {
prepared.inventory.Scopes = append(prepared.inventory.Scopes, scopeMetadata{ prepared.inventory.Scopes = append(prepared.inventory.Scopes, scopeMetadata{
Name: scope.scope.Name, 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), Features: featureNames(scope.scope.Features),
}) })
} }
return prepared
} }
func normalizeOperations(operations []Operation, issues *[]error, scope string) []Operation { func normalizeOperations(operations []Operation, issues *[]error, scope string) []Operation {