summaryrefslogtreecommitdiff
path: root/DomainDig/DomainDiffService.swift
diff options
context:
space:
mode:
authorChristian Cleberg <[email protected]>2026-04-22 09:47:24 -0500
committerChristian Cleberg <[email protected]>2026-04-22 09:47:24 -0500
commit7b41195620eadd54d25fa98dcd36735cba906ba3 (patch)
tree929a791a4c2fd3278f98c17c0ae5476940a01312 /DomainDig/DomainDiffService.swift
parent36ea668d7fc9070770973b0bc329f4319bf43cab (diff)
downloaddomain-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.swift27
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