The pipeline runs sequentially on a single host but each phase only depends on artifacts on disk, so a CI matrix can split phases across runners trivially.
JSON on disk, not memory. Every cross-phase contract is materialised as a Pydantic-validated JSON file. The orchestrator is reproducible from any phaseN/ directory.
No mocks. Whenever the pipeline cannot produce real data (APK won't build, DroidBot crashes, emulator unavailable) it emits BLOCKED with an explicit blocked_reason.
Single source of truth for versions. All bumps go through gradle/libs.versions.toml. Direct edits to build.gradle.kts are ignored on purpose — the workflow targets the catalog layout that Dependabot uses.
Static and dynamic are complementary. Static produces a complete but conservative set of impacted files; dynamic produces a small but observed set of impacted screens. The consolidator combines them.
Source-set aware. Impact is reported per source set (commonMain, androidMain, iosMain, …), matching the KMP review model.