Expose ConfigKit diagnostic adaptation
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
# Audit remediation implementation plan
|
# Audit remediation implementation plan
|
||||||
|
|
||||||
Status: in progress; Stages 1–10 complete.
|
Status: in progress; Stages 1–11 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
|
||||||
@@ -380,6 +380,12 @@ Complete when exported guidance accurately states the already selected rules.
|
|||||||
|
|
||||||
## Stage 11 — Export the shared ConfigKit diagnostic adapter
|
## Stage 11 — Export the shared ConfigKit diagnostic adapter
|
||||||
|
|
||||||
|
**Complete.** `ckconfig.AdaptDiagnostics` captures the existing diagnostic
|
||||||
|
presentation for ordinary and comparison callers. Focused ConfigKit adapter and
|
||||||
|
comparison tests passed offline in the aligned Go 1.27.0 workspace with
|
||||||
|
`-mod=readonly`, including public helper snapshot and writer-failure coverage.
|
||||||
|
F21 remains open until ckprompt adopts it in Stage 12.
|
||||||
|
|
||||||
Findings: F21, ckconfig portion. Source: ckconfig `configkit_adapter.go`.
|
Findings: F21, ckconfig portion. Source: ckconfig `configkit_adapter.go`.
|
||||||
|
|
||||||
1. Expose the existing configKitDiagnosticsWithHeading responsibility as:
|
1. Expose the existing configKitDiagnosticsWithHeading responsibility as:
|
||||||
|
|||||||
@@ -127,14 +127,17 @@ func loadComparisonSide[I, S, T any](
|
|||||||
}
|
}
|
||||||
|
|
||||||
func configKitDiagnostics(scope string, sources []configkit.SourceInfo, records []configkit.Diagnostic) ([]commandkit.Diagnostic, commandkit.Explanation) {
|
func configKitDiagnostics(scope string, sources []configkit.SourceInfo, records []configkit.Diagnostic) ([]commandkit.Diagnostic, commandkit.Explanation) {
|
||||||
return configKitDiagnosticsWithHeading("Configuration scope "+strconv.Quote(scope)+":\n", sources, records)
|
return AdaptDiagnostics("Configuration scope "+strconv.Quote(scope)+":\n", sources, records)
|
||||||
}
|
}
|
||||||
|
|
||||||
func configKitComparisonDiagnostics(scope, side string, sources []configkit.SourceInfo, records []configkit.Diagnostic) ([]commandkit.Diagnostic, commandkit.Explanation) {
|
func configKitComparisonDiagnostics(scope, side string, sources []configkit.SourceInfo, records []configkit.Diagnostic) ([]commandkit.Diagnostic, commandkit.Explanation) {
|
||||||
return configKitDiagnosticsWithHeading("Configuration scope "+strconv.Quote(scope)+" "+side+":\n", sources, records)
|
return AdaptDiagnostics("Configuration scope "+strconv.Quote(scope)+" "+side+":\n", sources, records)
|
||||||
}
|
}
|
||||||
|
|
||||||
func configKitDiagnosticsWithHeading(heading string, sources []configkit.SourceInfo, records []configkit.Diagnostic) ([]commandkit.Diagnostic, commandkit.Explanation) {
|
// AdaptDiagnostics captures ConfigKit diagnostics as CLI presentation evidence.
|
||||||
|
// It does not print, acquire configuration, determine outcomes, or schedule messages.
|
||||||
|
// The heading is used as supplied when the captured evidence is rendered.
|
||||||
|
func AdaptDiagnostics(heading string, sources []configkit.SourceInfo, records []configkit.Diagnostic) ([]commandkit.Diagnostic, commandkit.Explanation) {
|
||||||
if len(records) == 0 {
|
if len(records) == 0 {
|
||||||
return nil, commandkit.Explanation{}
|
return nil, commandkit.Explanation{}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -235,20 +235,23 @@ func TestFromConfigKitRetainsResultEvidenceWithApplicationFailure(t *testing.T)
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestConfigKitDiagnosticsMapSeverityAndPropagateWriterFailures(t *testing.T) {
|
func TestConfigKitDiagnosticsMapSeverityAndPropagateWriterFailures(t *testing.T) {
|
||||||
warning, noExplanation := configKitDiagnostics("app", nil, []configkit.Diagnostic{{Severity: configkit.SeverityWarning, Message: "safe warning"}})
|
warning, noExplanation := AdaptDiagnostics("scope:\n", nil, []configkit.Diagnostic{{Severity: configkit.SeverityWarning, Message: "safe warning"}})
|
||||||
if len(warning) != 1 || warning[0].Severity != commandkit.SeverityWarning {
|
if len(warning) != 1 || warning[0].Severity != commandkit.SeverityWarning {
|
||||||
t.Fatalf("warning diagnostics = %#v", warning)
|
t.Fatalf("warning diagnostics = %#v", warning)
|
||||||
}
|
}
|
||||||
if noExplanation.Message != "" || len(noExplanation.Details) != 0 {
|
if noExplanation.Message != "" || len(noExplanation.Details) != 0 {
|
||||||
t.Fatalf("warning-only explanation = %#v", noExplanation)
|
t.Fatalf("warning-only explanation = %#v", noExplanation)
|
||||||
}
|
}
|
||||||
withWarning, withExplanation := configKitDiagnostics("app", nil, []configkit.Diagnostic{
|
withWarning, withExplanation := AdaptDiagnostics("scope:\n", nil, []configkit.Diagnostic{
|
||||||
{Severity: configkit.SeverityWarning, Message: "safe warning"},
|
{Severity: configkit.SeverityWarning, Message: "safe warning"},
|
||||||
{Severity: configkit.SeverityError, Message: "safe error"},
|
{Severity: configkit.SeverityError, Message: "safe error"},
|
||||||
})
|
})
|
||||||
if len(withWarning) != 1 || withWarning[0].Severity != commandkit.SeverityWarning || len(withExplanation.Details) != 1 {
|
if len(withWarning) != 1 || withWarning[0].Severity != commandkit.SeverityWarning || len(withExplanation.Details) != 1 {
|
||||||
t.Fatalf("mixed diagnostics = %#v, explanation = %#v", withWarning, withExplanation)
|
t.Fatalf("mixed diagnostics = %#v, explanation = %#v", withWarning, withExplanation)
|
||||||
}
|
}
|
||||||
|
if empty, explanation := AdaptDiagnostics("unused", nil, nil); len(empty) != 0 || len(explanation.Details) != 0 {
|
||||||
|
t.Fatalf("empty evidence = %#v, %#v", empty, explanation)
|
||||||
|
}
|
||||||
|
|
||||||
if err := withWarning[0].Write(shortWriter{}); !errors.Is(err, io.ErrShortWrite) {
|
if err := withWarning[0].Write(shortWriter{}); !errors.Is(err, io.ErrShortWrite) {
|
||||||
t.Fatalf("short writer error = %v, want %v", err, io.ErrShortWrite)
|
t.Fatalf("short writer error = %v, want %v", err, io.ErrShortWrite)
|
||||||
@@ -280,10 +283,11 @@ func TestConfigKitTerminalContextRetainsRelatedLocationsAndSnapshots(t *testing.
|
|||||||
Primary: primary,
|
Primary: primary,
|
||||||
Related: related,
|
Related: related,
|
||||||
}}
|
}}
|
||||||
_, explanation := configKitDiagnostics("app", sources, records)
|
_, explanation := AdaptDiagnostics("Configuration scope \"app\":\n", sources, records)
|
||||||
primary.SourceID = "mutated-primary"
|
primary.SourceID = "mutated-primary"
|
||||||
related[0].SourceID = "mutated-related"
|
related[0].SourceID = "mutated-related"
|
||||||
sources[0].Path = "mutated.yml"
|
sources[0].Path = "mutated.yml"
|
||||||
|
records[0].Message = "mutated message"
|
||||||
|
|
||||||
if len(explanation.Details) != 1 {
|
if len(explanation.Details) != 1 {
|
||||||
t.Fatalf("explanation = %#v", explanation)
|
t.Fatalf("explanation = %#v", explanation)
|
||||||
@@ -297,7 +301,7 @@ func TestConfigKitTerminalContextRetainsRelatedLocationsAndSnapshots(t *testing.
|
|||||||
t.Errorf("terminal context %q omits %q", output.String(), fragment)
|
t.Errorf("terminal context %q omits %q", output.String(), fragment)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if strings.Contains(output.String(), "mutated-") || strings.Contains(output.String(), "mutated.yml") {
|
if strings.Contains(output.String(), "mutated-") || strings.Contains(output.String(), "mutated.yml") || strings.Contains(output.String(), "mutated message") {
|
||||||
t.Fatalf("terminal renderer retained caller mutations: %q", output.String())
|
t.Fatalf("terminal renderer retained caller mutations: %q", output.String())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user