Finalize structured diagnostic aggregation

This commit is contained in:
2026-08-27 16:40:17 +00:00
parent 480680b257
commit 4dbbf68051
112 changed files with 656 additions and 893 deletions

View File

@@ -4,7 +4,6 @@ import (
"fmt"
"sort"
"gitea.maximumdirect.net/eric/notarius/internal/framework/contracts"
"gitea.maximumdirect.net/eric/notarius/internal/framework/semanticreconcile"
"gitea.maximumdirect.net/eric/notarius/internal/modules/dnd"
"gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/items/identity"
@@ -31,7 +30,7 @@ func reconciliationInputs(records []normalizedRecord) ([]semanticreconcile.Candi
return candidates, envelopes, nil
}
func applyReconciliationPlan(plan semanticreconcile.Plan, records []normalizedRecord, envelopes []semanticreconcile.Record[dnd.Item], order shared.SourceRefOrder) ([]normalizedRecord, []contracts.Warning, []contracts.Warning, int, error) {
func applyReconciliationPlan(plan semanticreconcile.Plan, records []normalizedRecord, envelopes []semanticreconcile.Record[dnd.Item], order shared.SourceRefOrder) ([]normalizedRecord, []diagnostics.Finding, []diagnostics.Finding, int, error) {
application, err := semanticreconcile.ApplyPlan(plan, envelopes, semanticreconcile.ApplicationPolicy[dnd.Item]{
CloneValue: cloneItem,
RejectGroup: func(members []dnd.Item, _ dnd.Item) semanticreconcile.RejectionCategory {
@@ -66,7 +65,7 @@ func applyReconciliationPlan(plan semanticreconcile.Plan, records []normalizedRe
}
type orderedFinding struct {
position int
finding contracts.Warning
finding diagnostics.Finding
}
observations := make([]orderedFinding, 0, len(application.AppliedGroups()))
advisories := make([]orderedFinding, 0, len(application.RejectedGroups()))
@@ -81,7 +80,7 @@ func applyReconciliationPlan(plan semanticreconcile.Plan, records []normalizedRe
provenance := event.Provenance()
advisories = append(advisories, orderedFinding{
position: provenance.EarliestInputPosition(),
finding: contracts.Warning{
finding: diagnostics.Finding{
Scope: itemScope(provenance.EarliestInputPosition()),
ReasonCode: ReasonCodeItemSemanticProposalInvalid,
Message: "proposal group preserved because currency may only be consolidated with aliases of one denomination",
@@ -90,11 +89,11 @@ func applyReconciliationPlan(plan semanticreconcile.Plan, records []normalizedRe
}
sort.SliceStable(observations, func(left, right int) bool { return observations[left].position < observations[right].position })
sort.SliceStable(advisories, func(left, right int) bool { return advisories[left].position < advisories[right].position })
observationFindings := make([]contracts.Warning, len(observations))
observationFindings := make([]diagnostics.Finding, len(observations))
for index, entry := range observations {
observationFindings[index] = entry.finding
}
advisoryFindings := make([]contracts.Warning, len(advisories))
advisoryFindings := make([]diagnostics.Finding, len(advisories))
for index, entry := range advisories {
advisoryFindings[index] = entry.finding
}
@@ -139,7 +138,7 @@ func currencyDenomination(name string) string {
}
}
func semanticDuplicateFinding(provenance semanticreconcile.GroupProvenance, canonical normalizedRecord) contracts.Warning {
func semanticDuplicateFinding(provenance semanticreconcile.GroupProvenance, canonical normalizedRecord) diagnostics.Finding {
inputIndexes := provenance.OriginalInputIndexes()
details := make([]string, 0, len(inputIndexes)+1)
for _, inputIndex := range inputIndexes {
@@ -148,7 +147,7 @@ func semanticDuplicateFinding(provenance semanticreconcile.GroupProvenance, cano
if canonical.earliest != provenance.EarliestInputPosition() {
details = append(details, fmt.Sprintf("canonical display name from input index %d", canonical.earliest))
}
return contracts.Warning{
return diagnostics.Finding{
Scope: itemScope(provenance.EarliestInputPosition()),
ReasonCode: ReasonCodeDuplicateItemCollapsed,
Message: diagnostics.Aggregate("semantic duplicate consolidation", details),