diff --git a/docs/roadmap/remediation.md b/docs/roadmap/remediation.md index d36d1c5..2eda4cc 100644 --- a/docs/roadmap/remediation.md +++ b/docs/roadmap/remediation.md @@ -14,12 +14,13 @@ was preserved; this review changes no production code or tests. The architecture now separates resolution comparison from the atomic comparator used by public diff. A private entry-to-final correspondence for registered collections feeds auditing, snapshots, metadata refresh, and shared history -selection/replay. The main design is in place, but the following issues remain. +selection/replay. All five findings below have now been addressed. Original +audit observations are retained for context; completion notes describe the fixes. A follow-up integration and algorithm audit at `27be6ba`, including the same pre-existing working-tree changes, added Findings 4 and 5. It preserved the -decided comparison, identity, ordering, and history policies. Findings 1–3 remain -open; Finding 3 already covers the principal collection-size quadratic loop and +decided comparison, identity, ordering, and history policies. Findings 1–3 were +still open at that audit; Finding 3 covers the principal collection-size quadratic loop and is not duplicated below. ## Finding 1 — Metadata history rejects a valid matched historical field @@ -225,7 +226,13 @@ adding timing thresholds or exact allocation assertions. ## Finding 5 — Delta sorting formats pointers inside every comparison -**Priority:** P3. **Status:** Open; lower-priority efficiency improvement. +**Priority:** P3. **Status:** Complete. + +Completion: both comparison operations share the existing decorated delta sort, +which constructs one pointer per delta and preserves canonical pointer ordering +and the kind tie-break. Existing comparison and diff coverage passed, along with +`./scripts/check.sh` and the final `go test -race ./...` run. No performance +thresholds, persistent cache, or new public contract were introduced. **Code:** [resolution comparison](../../internal/engine/resolution_compare.go), `compareResolutionValues` at lines 64–69; compare the existing decorated sort in @@ -269,3 +276,15 @@ benchmark gate, or API change is needed. benchmarks were needed; prior successful checks apply to the unchanged production and test files. The amended document's links and whitespace were checked separately. + +## Remediation validation + +All five issues were addressed sequentially in separate nonempty commits, each +with its completion note and relevant verification. Final validation passed +`./scripts/check.sh` and `go test -race ./...` with Go 1.27.0 on Linux. The +development check includes formatting, whitespace, tests, local documentation +links, vet, and build checks. No benchmark thresholds or release gates were added. + +The directly related pending sensitivity regression was retained with Finding 3. +Unrelated pre-existing documentation and public-comment changes were preserved +outside the remediation commits. diff --git a/internal/engine/document_compare.go b/internal/engine/document_compare.go index fd6c79a..61d4b79 100644 --- a/internal/engine/document_compare.go +++ b/internal/engine/document_compare.go @@ -2,8 +2,9 @@ package engine import ( "cmp" - "go.maximumdirect.net/configkit/internal/document" "slices" + + "go.maximumdirect.net/configkit/internal/document" ) type documentDeltaKind uint8 @@ -24,6 +25,10 @@ type documentDelta struct { func compareConfigurationValues(before, after *document.Node) []documentDelta { var deltas []documentDelta compareConfigurationValue(before, after, Path{}, &deltas) + return sortDocumentDeltas(deltas) +} + +func sortDocumentDeltas(deltas []documentDelta) []documentDelta { type orderedDelta struct { delta documentDelta pointer string diff --git a/internal/engine/resolution_compare.go b/internal/engine/resolution_compare.go index e2d7348..03a54ce 100644 --- a/internal/engine/resolution_compare.go +++ b/internal/engine/resolution_compare.go @@ -1,11 +1,6 @@ package engine -import ( - "cmp" - "slices" - - "go.maximumdirect.net/configkit/internal/document" -) +import "go.maximumdirect.net/configkit/internal/document" // compareResolutionValues reports field-level changes at stable list positions. func compareResolutionValues(before, after *document.Node, correspondence ...resolutionCorrespondence) []documentDelta { @@ -61,11 +56,5 @@ func compareResolutionValues(before, after *document.Node, correspondence ...res } } compare(before, after, Path{}) - slices.SortFunc(deltas, func(a, b documentDelta) int { - if order := cmp.Compare(a.path.String(), b.path.String()); order != 0 { - return order - } - return int(a.kind) - int(b.kind) - }) - return deltas + return sortDocumentDeltas(deltas) }