Commit e818eefdee
Unsigned
Layout: unified · split
RELEASE_ROADMAP.md +53 −23
| @@ -264,30 +264,60 @@ VoiceOver or Voice Control at all: | ||
| 264 | 264 | The Liquid Glass (iOS 26+) runtime check is **done** — it ran on simulator |
| 265 | 265 | alongside the classic-chrome floor. |
| 266 | 266 | |
| 267 | ## v5.0.0 Major: Contract Stabilization & Engineering Health | |
| 268 | ||
| 269 | Goal: earn long-term compatibility promises — and pay down the debt that the | |
| 270 | feature releases above will accumulate. | |
| 271 | ||
| 272 | - Define migration policy for persisted snapshots, backups, audits, workflows, | |
| 273 | and settings. | |
| 274 | - Stabilize the public local API response contract; document compatibility | |
| 275 | guarantees and planned deprecations. | |
| 276 | - **Extend the test net to the deterministic core.** v4.9.0 established | |
| 277 | `DomainDigUITests` (accessibility audit + enforcement gate); unit coverage of | |
| 278 | `DomainReportBuilder`, `DomainReportExporter`, `DomainDataPortabilityService` | |
| 279 | (merge/replace dedup), and `DiffService` is still needed before locking down | |
| 280 | external contracts. | |
| 281 | - **Decompose the god-files** behind that test net: `DomainViewModel.swift` | |
| 282 | (~4.7k lines) and `ContentView.swift` (~3.8k lines) into focused units | |
| 283 | (audit, monitoring, workflows, portability). | |
| 267 | ## v5.0.0 Major: Contract Stabilization & Engineering Health — ✅ engineering complete (release cut pending) | |
| 268 | ||
| 269 | Goal: earn long-term compatibility promises — and pay down the debt the feature | |
| 270 | releases above accumulated. All four workstreams have landed on `main`; cutting | |
| 271 | the release itself (version bump and submission) is the only remaining step. | |
| 272 | ||
| 273 | - **Deterministic-core test net — done first**, as the cross-cutting note below | |
| 274 | required. Added `DomainDigTests`, the project's first XCTest unit target, | |
| 275 | hosted by the app with `@testable import`. `SnapshotFixture` builds the deep | |
| 276 | `LookupSnapshot`/`DomainReport` models through the real builder; 58 tests cover | |
| 277 | `DiffService`, `DomainReportBuilder`, `DomainReportExporter`, | |
| 278 | `DomainDataPortabilityService` (merge/replace dedup), the migration runner, and | |
| 279 | the Local API contract. Runs in CI and the pre-push hook. (#43) | |
| 280 | - **Local API `v1` contract stabilized.** `LocalAPIContract` is the single source | |
| 281 | of truth for the wire version and JSON encoder; the response envelope and every | |
| 282 | payload are promoted to a first-class, documented contract. | |
| 283 | `Docs/local-api.md` documents each endpoint, the envelope, the encoding | |
| 284 | conventions (notably: absent optionals are omitted, not null), and a | |
| 285 | semantic-version compatibility policy. 16 golden structure tests pin the JSON | |
| 286 | shape so a renamed/removed field fails CI. (#45) | |
| 287 | - **Versioned store-migration policy** for persisted snapshots, backups, audits, | |
| 288 | workflows, and settings. `DataMigrationService` became a forward-only, | |
| 289 | idempotent, never-downgrades runner keyed by an integer store schema version, | |
| 290 | replacing the one-shot boolean marker. `Docs/data-migration.md` documents the | |
| 291 | policy, the two independent version lines (on-device store vs. backup export), | |
| 292 | and when to use lenient decoding vs. a migration step; legacy-fixture tests | |
| 293 | cover it. (#46) | |
| 294 | - **God-files decomposed** behind that test net, one behavior-preserving slice | |
| 295 | per PR (each built clean with 58/58 tests, no logic changes): | |
| 296 | - `DomainViewModel.swift` **4864 → 4170 lines** — audit, monitoring, export, | |
| 297 | workflow, and history surfaces moved to `DomainViewModel+*.swift` | |
| 298 | extensions. (#47–#51) | |
| 299 | - `ContentView.swift` **3881 → 1625 lines** — Settings screens to | |
| 300 | `SettingsViews.swift` and the nine result section views to | |
| 301 | `ResultSectionViews.swift`. (#52–#53) | |
| 302 | ||
| 303 | Left in place deliberately: the tightly-coupled inspection core (the section | |
| 304 | runners, `performLookup`/`saveHistoryEntry`, batch orchestration) and a few | |
| 305 | remaining `ContentView` cards/primitives. Splitting the inspection core further | |
| 306 | is a *design* change — extracting a collaborator object — not a mechanical move, | |
| 307 | so it is deferred rather than forced through visibility promotions. | |
| 308 | ||
| 309 | Remaining to cut the release: bump `MARKETING_VERSION` 4.9.0 → 5.0.0 and | |
| 310 | increment `CURRENT_PROJECT_VERSION`, keep `AppVersion.current` in sync, and | |
| 311 | archive/submit. | |
| 284 | 312 | |
| 285 | 313 | ## Cross-cutting note |
| 286 | 314 | |
| 287 | 315 | New feature surfaces (widgets, intents, extensions) each add a target and a |
| 288 | persistence/entitlement seam. This project still has **no XCTest target** — | |
| 289 | v4.5.0 through v4.7.0 all shipped without the characterization-test safety net | |
| 290 | originally recommended before v4.7.0. That gap is now larger (comparison, | |
| 291 | reputation, and tags/saved-views all touch persisted models with hand-written | |
| 292 | backward-compatible decoders) and should be the very first thing v5.0.0 does, | |
| 293 | not a later item within it. | |
| 316 | persistence/entitlement seam. Through v4.9.0 the project had **no XCTest unit | |
| 317 | target** — v4.5.0 through v4.7.0 all shipped without the characterization-test | |
| 318 | safety net originally recommended before v4.7.0, and that gap only grew | |
| 319 | (comparison, reputation, and tags/saved-views all touch persisted models with | |
| 320 | hand-written backward-compatible decoders). v5.0.0 closed it first: the | |
| 321 | `DomainDigTests` deterministic-core net went in before anything else, which is | |
| 322 | what made stabilizing the external contracts and decomposing the god-files safe | |
| 323 | to attempt. | |