diff options
| author | Christian Cleberg <[email protected]> | 2026-04-22 09:47:24 -0500 |
|---|---|---|
| committer | Christian Cleberg <[email protected]> | 2026-04-22 09:47:24 -0500 |
| commit | 7b41195620eadd54d25fa98dcd36735cba906ba3 (patch) | |
| tree | 929a791a4c2fd3278f98c17c0ae5476940a01312 /DomainDig/DomainDiffService.swift | |
| parent | 36ea668d7fc9070770973b0bc329f4319bf43cab (diff) | |
| download | domain-dig-7b41195620eadd54d25fa98dcd36735cba906ba3.tar.gz domain-dig-7b41195620eadd54d25fa98dcd36735cba906ba3.tar.bz2 domain-dig-7b41195620eadd54d25fa98dcd36735cba906ba3.zip | |
feat(v2.7.0): add provenance, confidence, and reproducibility metadata
* add result provenance across major sections
* introduce confidence levels for ambiguous outputs
* distinguish observed facts from inferred summaries
* expand snapshot metadata for reproducibility
* improve error classification and partial snapshot handling
* include provenance and confidence in export
* add local notes for tracked domains and history
Diffstat (limited to 'DomainDig/DomainDiffService.swift')
| -rw-r--r-- | DomainDig/DomainDiffService.swift | 27 |
1 files changed, 26 insertions, 1 deletions
diff --git a/DomainDig/DomainDiffService.swift b/DomainDig/DomainDiffService.swift index 340873d..528841d 100644 --- a/DomainDig/DomainDiffService.swift +++ b/DomainDig/DomainDiffService.swift @@ -67,16 +67,33 @@ enum DomainDiffService { let highlights = summaryHighlights(from: allChangedItems) let severity = allChangedItems.map(\.severity).max() ?? .low let message = summaryMessage(from: allChangedItems, highlights: highlights) + let observedFacts = observedFacts(from: allChangedItems) + let inferredConclusions = highlights.isEmpty ? [] : [message] + let contextNote = comparisonContextNote(from: oldSnapshot, to: newSnapshot) return DomainChangeSummary( hasChanges: !allChangedItems.isEmpty, changedSections: highlights, message: message, severity: severity, - generatedAt: generatedAt + generatedAt: generatedAt, + observedFacts: observedFacts, + inferredConclusions: inferredConclusions, + contextNote: contextNote ) } + static func comparisonContextNote(from oldSnapshot: LookupSnapshot, to newSnapshot: LookupSnapshot) -> String? { + var notes: [String] = [] + if oldSnapshot.resolverURLString != newSnapshot.resolverURLString { + notes.append("Compared snapshots used different DNS resolvers.") + } + if oldSnapshot.resultSource != newSnapshot.resultSource { + notes.append("Compared snapshots came from different collection modes.") + } + return notes.isEmpty ? nil : notes.joined(separator: " ") + } + static func certificateWarningLevel(for snapshot: LookupSnapshot) -> CertificateWarningLevel { guard let days = snapshot.sslInfo?.daysUntilExpiry else { return .none @@ -410,6 +427,14 @@ enum DomainDiffService { return "\(highlights[0]) and \(highlights[1].lowercased())" } + private static func observedFacts(from items: [DomainDiffItem]) -> [String] { + items.prefix(3).map { item in + let oldValue = item.oldValue ?? "none" + let newValue = item.newValue ?? "none" + return "\(item.label): \(oldValue) -> \(newValue)" + } + } + private static func normalized(_ value: String?) -> String? { guard let value = value?.trimmingCharacters(in: .whitespacesAndNewlines), !value.isEmpty else { return nil |
