krz/domain-dig

an ios app for DNS & SSL analysis

clone: git clone https://gitbay.org/krz/domain-dig.git

v4.8.1: RELEASE_ROADMAP.md · raw

  1# DomainDig Release Roadmap
  2
  3Priority lens: **new user-facing features.** The inspection engine is already
  4deep (DNS, DNSSEC, CAA, TLS, TLSA/DANE, email security incl. BIMI/MTA-STS, RDAP,
  5ports, geolocation, subdomains, availability). The next several releases invest
  6in *reach and surfacing* — getting that data onto more iOS surfaces and into more
  7workflows — rather than adding raw protocol checks.
  8
  9Current version: `v4.8.1`.
 10
 11## v4.4.1 Patch: Release Readiness — ✅ shipped
 12
 13- Consolidated Audit Mode onto the single `DomainDig/DomainDig/Audit*`
 14  implementation and retired the prototype files.
 15- Aligned `AppVersion.current`, Xcode marketing version, and build number.
 16- Included audit sessions in backup/restore counts, summaries, and merge behavior.
 17- Removed the retired `DomainDigCLI` target and refreshed README/architecture docs.
 18
 19## v4.5.0 Minor: Home Screen & Shortcuts Reach — ✅ shipped
 20
 21Goal: put DomainDig data and actions where the user already is.
 22
 23- **App Intents / Shortcuts** — `InspectDomainIntent`, `AddToWatchlistIntent`, and
 24  `RunSweepIntent`, exposed via `DomainDigShortcuts` for Shortcuts, Spotlight, the
 25  Action button, and Siri.
 26- **`domaindig://` deep links** — `inspect`, `watch`, `domain` (detail), and
 27  `sweep`, routed in `RootTabView`.
 28- **WidgetKit portfolio widget** (Home Screen small/medium/large) — per-domain
 29  health, certificate countdowns, and portfolio health counts, shared from the app
 30  via an App Group; tapping a domain deep-links into its detail.
 31
 32Deferred to a later minor: **Lock Screen accessory widget families** and a richer
 33per-widget "last change" indicator.
 34
 35## v4.6.0 Minor: Alerts, Glances & iPad — ✅ shipped
 36
 37Goal: make monitoring and results feel first-class across contexts.
 38
 39- **Sweep Live Activity** — a batch/watchlist sweep drives a Live Activity with a
 40  progress bar, current domain, and change/warning counts on the Lock Screen and
 41  in the Dynamic Island (`SweepActivityController` around the batch pipeline).
 42- **Share extension** (`DomainDigShareExtension`) — "Dig Domain" accepts a web URL
 43  from the system share sheet, extracts the host, and hands it to the app via the
 44  App Group inbox; the app inspects it on next activation.
 45- **iPad-optimized layout** — `RootTabView` renders a `NavigationSplitView`
 46  (sidebar + detail) in the regular size class and the tab bar in compact.
 47- **Actionable notifications** — per-domain `threadIdentifier` grouping, a
 48  "Re-inspect" action, and taps that route into the domain's detail.
 49
 50Deferred: monitoring-alert Live Activities (only the sweep activity shipped) and
 51Lock Screen accessory widget families (carried over from v4.5.0).
 52
 53## v4.7.0 Minor: Intelligence & Comparison — ✅ shipped
 54
 55Goal: help users interpret and organize, not just collect.
 56
 57- **Domain-vs-domain comparison** — `DiffService.compare(domainA:domainB:)`
 58  reuses the existing section-diff builders; `DomainCompareView` (Watchlist
 59  toolbar → "Compare Domains") picks two tracked domains and renders the result
 60  with the existing diff section UI.
 61- **Reputation / blocklist signals** — a new pluggable data source
 62  (`ExternalDataService.reputation(domain:)`, Pro+) mirroring the existing
 63  ownership/DNS-history/pricing enrichment pattern. Ships with no bundled
 64  third-party endpoint; folds a listed status into risk score/factors and
 65  insights, so it rides the existing report and monitoring change-severity
 66  pipeline rather than needing bespoke monitoring wiring.
 67- **Tags and saved views** for the watchlist — freeform tags per tracked
 68  domain, tag filter chips, and named saved filter/sort/tag presets
 69  (UserDefaults-backed; not yet part of backup/restore).
 70
 71## v4.8.0 Minor: Reporting & Sharing — ✅ shipped
 72
 73Goal: turn point-in-time snapshots into shareable, scheduled deliverables.
 74
 75- **Markdown and PDF export formats** — `DomainExportFormat` gains `.markdown`
 76  and `.pdf` alongside text/csv/json. Markdown reuses the existing text-export
 77  content via a line-based transform (never drifts from the text export); PDF
 78  renders that Markdown via `UIGraphicsPDFRenderer`, mirroring the approach
 79  `AuditExporter` already used for audit sessions.
 80- **Scheduled report generation** — `ScheduledReportService` /
 81  `ScheduledReportScheduler` (Settings → Scheduled Reports): a BGTaskScheduler-
 82  driven daily/weekly job that builds a markdown/PDF/JSON report bundle for all
 83  tracked domains, writes it locally, logs the run, and notifies when ready.
 84  Mirrors `DomainMonitoringService`'s headless, storage-backed design; gated
 85  behind the same Pro `.automatedMonitoring` capability.
 86- **Stronger share affordances** — "Export Markdown"/"Export PDF" added to the
 87  single-result, batch, watchlist, and workflow export menus; generated
 88  scheduled reports are individually shareable from their log.
 89- **Export consistency verified** — the local API already serves the canonical
 90  `DomainReport` directly (no field allowlist), so `reputation`, `domainPricing`,
 91  and every other field added since v4.7.0 already flow through automatically.
 92  No code change was needed there.
 93
 94Deferred/scoped out: scheduled-report settings and logs are UserDefaults-only
 95(not part of `DomainDataPortabilityService` backup/restore), same reasoning as
 96v4.7.0's watchlist saved views — this is local automation config, not
 97user-authored content.
 98
 99## v4.8.1 Patch: Reporting & Sharing Fixes — ✅ shipped
100
101Goal: fix what UAT of v4.8.0 turned up.
102
103- **Scheduled reports were unreachable manually** — the Overview section wrapped
104  every control in a single `VStack` inside one `List` row, so SwiftUI collapsed
105  them into one tap target and the Cadence `Picker` captured taps meant for
106  "Generate Now". Each control is now its own row.
107- **Pro gate completed on that screen** — `.automatedMonitoring` previously
108  disabled only the toggle, leaving both pickers and "Generate Now" interactive
109  on Free where they silently no-opped against the service-side guard.
110- **Markdown/PDF reports rendered `=` underlines as bullets** — the plain-text
111  transform only recognized `-`, so `batchText`'s title underline and its
112  48-character inter-report separators leaked through as literal list items.
113- **Duplicate DNS record values** — the report concatenated apex and wildcard
114  records without dedup, listing every value twice on domains with wildcard DNS.
115- **Inspect tab keyboard behavior** — removed the "Dismiss Keyboard" toolbar
116  button and the launch-time focus that raised the keyboard on app open.
117- **In-app purchases were unbuyable** — none of the four product ID constants in
118  `PurchaseService` matched the auto-renewable subscriptions configured in App
119  Store Connect, so `Product.products(for:)` returned nothing and `tier(for:)`
120  resolved every purchase to `.free`. Product IDs are permanent once created, so
121  the constants were corrected to match the store rather than the reverse.
122- **Local StoreKit testing** — added `DomainDig.storekit` mirroring the App Store
123  Connect group (Pro+ at level 1, Pro at level 2) and wired it into the Run
124  action, so the purchase and entitlement paths can be exercised without the
125  `DOMAIN_DIG_FORCE_PRO_PLUS` launch argument that bypasses StoreKit entirely.
126
127Known open follow-ups filed during UAT: integration events to a disabled target
128vanish with no delivery-log row (#8), "Process Queue Now" does not force a
129backed-off retry (#9), and a monitoring snapshot fallback silently reports "No
130meaningful changes" (#10).
131
132## v5.0.0 Major: Contract Stabilization & Engineering Health
133
134Goal: earn long-term compatibility promises — and pay down the debt that the
135feature releases above will accumulate.
136
137- Define migration policy for persisted snapshots, backups, audits, workflows,
138  and settings.
139- Stabilize the public local API response contract; document compatibility
140  guarantees and planned deprecations.
141- **Establish a test target.** The project currently has no XCTest target and no
142  tests; add one and cover the deterministic core first — `DomainReportBuilder`,
143  `DomainReportExporter`, `DomainDataPortabilityService` (merge/replace dedup),
144  and `DiffService` — before locking down external contracts.
145- **Decompose the god-files** behind that test net: `DomainViewModel.swift`
146  (~4.7k lines) and `ContentView.swift` (~3.8k lines) into focused units
147  (audit, monitoring, workflows, portability).
148
149## Cross-cutting note
150
151New feature surfaces (widgets, intents, extensions) each add a target and a
152persistence/entitlement seam. This project still has **no XCTest target**153v4.5.0 through v4.7.0 all shipped without the characterization-test safety net
154originally recommended before v4.7.0. That gap is now larger (comparison,
155reputation, and tags/saved-views all touch persisted models with hand-written
156backward-compatible decoders) and should be the very first thing v5.0.0 does,
157not a later item within it.