diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/nearby/modules/detectiontracker/DefaultExposureDetectionTracker.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/nearby/modules/detectiontracker/DefaultExposureDetectionTracker.kt
index 909a66247fd7405a3239631942052de2892add21..0375e974226341dae587918b107e4e51374622d0 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/nearby/modules/detectiontracker/DefaultExposureDetectionTracker.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/nearby/modules/detectiontracker/DefaultExposureDetectionTracker.kt
@@ -88,7 +88,8 @@ class DefaultExposureDetectionTracker @Inject constructor(
             mutate {
                 this[identifier] = TrackedExposureDetection(
                     identifier = identifier,
-                    startedAt = timeStamper.nowUTC
+                    startedAt = timeStamper.nowUTC,
+                    enfVersion = TrackedExposureDetection.EnfVersion.V2_WINDOW_MODE
                 )
             }
         }
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/nearby/modules/detectiontracker/TrackedExposureDetection.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/nearby/modules/detectiontracker/TrackedExposureDetection.kt
index 20fdddefe71875201448539b662f89f782f986dd..e5ecf15fb0fbaa6ba111ed922c022c4cce5cf25a 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/nearby/modules/detectiontracker/TrackedExposureDetection.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/nearby/modules/detectiontracker/TrackedExposureDetection.kt
@@ -9,7 +9,8 @@ data class TrackedExposureDetection(
     @SerializedName("identifier") val identifier: String,
     @SerializedName("startedAt") val startedAt: Instant,
     @SerializedName("result") val result: Result? = null,
-    @SerializedName("finishedAt") val finishedAt: Instant? = null
+    @SerializedName("finishedAt") val finishedAt: Instant? = null,
+    @SerializedName("enfVersion") val enfVersion: EnfVersion? = null
 ) {
 
     val isCalculating: Boolean
@@ -28,4 +29,11 @@ data class TrackedExposureDetection(
         @SerializedName("TIMEOUT")
         TIMEOUT
     }
+
+    enum class EnfVersion {
+        @SerializedName("V1_LEGACY_MODE")
+        V1_LEGACY_MODE,
+        @SerializedName("V2_WINDOW_MODE")
+        V2_WINDOW_MODE
+    }
 }
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/risk/RiskLevelTask.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/risk/RiskLevelTask.kt
index d3d813eb935764ccb77b309ba248e30a0284a334..22dee506434f413a1b73769c5ebf2b7c8e300074 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/risk/RiskLevelTask.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/risk/RiskLevelTask.kt
@@ -8,6 +8,8 @@ import de.rki.coronawarnapp.diagnosiskeys.storage.KeyCacheRepository
 import de.rki.coronawarnapp.exception.ExceptionCategory
 import de.rki.coronawarnapp.exception.reporting.report
 import de.rki.coronawarnapp.nearby.ENFClient
+import de.rki.coronawarnapp.nearby.modules.detectiontracker.ExposureDetectionTracker
+import de.rki.coronawarnapp.nearby.modules.detectiontracker.TrackedExposureDetection
 import de.rki.coronawarnapp.risk.RiskLevelResult.FailureReason
 import de.rki.coronawarnapp.risk.storage.RiskLevelStorage
 import de.rki.coronawarnapp.task.Task
@@ -188,19 +190,27 @@ class RiskLevelTask @Inject constructor(
     }
 
     data class Config(
-        // TODO unit-test that not > 9 min
+        private val exposureDetectionTracker: ExposureDetectionTracker,
         override val executionTimeout: Duration = Duration.standardMinutes(8),
-
         override val collisionBehavior: TaskFactory.Config.CollisionBehavior =
             TaskFactory.Config.CollisionBehavior.SKIP_IF_SIBLING_RUNNING
+    ) : TaskFactory.Config {
 
-    ) : TaskFactory.Config
+        override val preconditions: List<suspend () -> Boolean>
+            get() = listOf {
+                // check whether we already have a successful v2 exposure
+                exposureDetectionTracker.calculations.first().values.any {
+                    it.enfVersion == TrackedExposureDetection.EnfVersion.V2_WINDOW_MODE && it.isSuccessful
+                }
+            }
+    }
 
     class Factory @Inject constructor(
-        private val taskByDagger: Provider<RiskLevelTask>
+        private val taskByDagger: Provider<RiskLevelTask>,
+        private val exposureDetectionTracker: ExposureDetectionTracker
     ) : TaskFactory<DefaultProgress, RiskLevelTaskResult> {
 
-        override suspend fun createConfig(): TaskFactory.Config = Config()
+        override suspend fun createConfig(): TaskFactory.Config = Config(exposureDetectionTracker)
         override val taskProvider: () -> Task<DefaultProgress, RiskLevelTaskResult> = {
             taskByDagger.get()
         }
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/risk/TimeVariables.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/risk/TimeVariables.kt
index 2c442de6f5aedad84c5541f73d3dd5aa264a8115..274b0db8df8b25b9841982516e82a158dcf4ff8a 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/risk/TimeVariables.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/risk/TimeVariables.kt
@@ -79,7 +79,7 @@ object TimeVariables {
      */
     fun getMinActivatedTracingTime(): Int = MIN_ACTIVATED_TRACING_TIME
 
-    private const val MILISECONDS_IN_A_SECOND = 1000
+    private const val MILLISECONDS_IN_A_SECOND = 1000
     private const val SECONDS_IN_A_MINUTES = 60
     private const val MINUTES_IN_AN_HOUR = 60
     private const val HOURS_IN_AN_DAY = 24
@@ -93,9 +93,9 @@ object TimeVariables {
      */
     fun getManualKeyRetrievalDelay() =
         if (CWADebug.buildFlavor == CWADebug.BuildFlavor.DEVICE_FOR_TESTERS) {
-            MILISECONDS_IN_A_SECOND * SECONDS_IN_A_MINUTES
+            MILLISECONDS_IN_A_SECOND * SECONDS_IN_A_MINUTES
         } else {
-            MILISECONDS_IN_A_SECOND * SECONDS_IN_A_MINUTES * MINUTES_IN_AN_HOUR * HOURS_IN_AN_DAY
+            MILLISECONDS_IN_A_SECOND * SECONDS_IN_A_MINUTES * MINUTES_IN_AN_HOUR * HOURS_IN_AN_DAY
         }
 
     /**
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/task/TaskController.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/task/TaskController.kt
index 36d2b2c85115e44d7c5800d879c1031c7c3c23de..6db01b71292562462a2db3d0cd7202e68f772f29 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/task/TaskController.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/task/TaskController.kt
@@ -124,14 +124,14 @@ class TaskController @Inject constructor(
     private suspend fun processMap() = internalTaskData.updateSafely {
         Timber.tag(TAG).d("Processing task data (count=%d)", size)
 
-        // Procress all unprocessed finished tasks
-        procressFinishedTasks(this).let {
+        // Process all unprocessed finished tasks
+        processFinishedTasks(this).let {
             this.clear()
             this.putAll(it)
         }
 
         // Start new tasks
-        procressPendingTasks(this).let {
+        processPendingTasks(this).let {
             this.clear()
             this.putAll(it)
         }
@@ -156,7 +156,7 @@ class TaskController @Inject constructor(
         )
     }
 
-    private fun procressFinishedTasks(data: Map<UUID, InternalTaskState>): Map<UUID, InternalTaskState> {
+    private fun processFinishedTasks(data: Map<UUID, InternalTaskState>): Map<UUID, InternalTaskState> {
         val workMap = data.toMutableMap()
         workMap.values
             .filter { it.job.isCompleted && it.executionState != TaskState.ExecutionState.FINISHED }
@@ -181,7 +181,7 @@ class TaskController @Inject constructor(
         return workMap
     }
 
-    private fun procressPendingTasks(data: Map<UUID, InternalTaskState>): Map<UUID, InternalTaskState> {
+    private suspend fun processPendingTasks(data: Map<UUID, InternalTaskState>): Map<UUID, InternalTaskState> {
         val workMap = data.toMutableMap()
         workMap.values
             .filter { it.executionState == TaskState.ExecutionState.PENDING }
@@ -198,12 +198,18 @@ class TaskController @Inject constructor(
                     Timber.tag(TAG).v("Sibling are:\n%s", siblingTasks.joinToString("\n"))
                 }
 
+                Timber.tag(TAG).v("Checking preconditions for request: %s", state.config)
+                val arePreconditionsMet = state.config.preconditions.fold(true) { allPreConditionsMet, precondition ->
+                    allPreConditionsMet && precondition()
+                }
+
                 // Handle collision behavior for tasks of same type
                 when {
                     siblingTasks.isEmpty() -> {
                         workMap[state.id] = state.toRunningState()
                     }
-                    state.config.collisionBehavior == CollisionBehavior.SKIP_IF_SIBLING_RUNNING -> {
+                    !arePreconditionsMet ||
+                        state.config.collisionBehavior == CollisionBehavior.SKIP_IF_SIBLING_RUNNING -> {
                         workMap[state.id] = state.toSkippedState()
                     }
                     state.config.collisionBehavior == CollisionBehavior.ENQUEUE -> {
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/task/TaskFactory.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/task/TaskFactory.kt
index 652bf1b58f63604bcc2aaa5cd17f895ea7f55ac4..25dfd34f5f19af7d6a7ebbfc0f055dd0936dd5de 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/task/TaskFactory.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/task/TaskFactory.kt
@@ -15,6 +15,9 @@ interface TaskFactory<
 
         val collisionBehavior: CollisionBehavior
 
+        val preconditions: List<suspend () -> Boolean>
+            get() = emptyList()
+
         enum class CollisionBehavior {
             ENQUEUE,
             SKIP_IF_SIBLING_RUNNING
diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/nearby/modules/detectiontracker/DefaultExposureDetectionTrackerTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/nearby/modules/detectiontracker/DefaultExposureDetectionTrackerTest.kt
index 0521bdb63cc6523f953df8dd9cf190428c27f25b..9012e23cf22f3a22d07d72703bbba373bf6788a9 100644
--- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/nearby/modules/detectiontracker/DefaultExposureDetectionTrackerTest.kt
+++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/nearby/modules/detectiontracker/DefaultExposureDetectionTrackerTest.kt
@@ -95,7 +95,8 @@ class DefaultExposureDetectionTrackerTest : BaseTest() {
                 key shouldBe expectedIdentifier
                 value shouldBe TrackedExposureDetection(
                     identifier = expectedIdentifier,
-                    startedAt = Instant.EPOCH
+                    startedAt = Instant.EPOCH,
+                    enfVersion = TrackedExposureDetection.EnfVersion.V2_WINDOW_MODE
                 )
             }
 
diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/nearby/modules/detectiontracker/ExposureDetectionTrackerStorageTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/nearby/modules/detectiontracker/ExposureDetectionTrackerStorageTest.kt
index 61e3bcab5f453800bc1bd2b581cdd4f4ed0c6fbf..f6d10c1e31ad6001a9444be1db0ce83e8866c67e 100644
--- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/nearby/modules/detectiontracker/ExposureDetectionTrackerStorageTest.kt
+++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/nearby/modules/detectiontracker/ExposureDetectionTrackerStorageTest.kt
@@ -34,7 +34,8 @@ class ExposureDetectionTrackerStorageTest : BaseIOTest() {
                 "identifier": "b2b98400-058d-43e6-b952-529a5255248b",
                 "startedAt": {
                   "iMillis": 1234
-                }
+                },
+                "enfVersion": "V2_WINDOW_MODE"
               },
               "aeb15509-fb34-42ce-8795-7a9ae0c2f389": {
                 "identifier": "aeb15509-fb34-42ce-8795-7a9ae0c2f389",
@@ -44,7 +45,8 @@ class ExposureDetectionTrackerStorageTest : BaseIOTest() {
                 "result": "UPDATED_STATE",
                 "finishedAt": {
                   "iMillis": 1603473968125
-                }
+                },
+                "enfVersion": "V1_LEGACY_MODE"
               }
             }
         """.trimIndent()
@@ -52,13 +54,15 @@ class ExposureDetectionTrackerStorageTest : BaseIOTest() {
     private val demoData = run {
         val calculation1 = TrackedExposureDetection(
             identifier = "b2b98400-058d-43e6-b952-529a5255248b",
-            startedAt = Instant.ofEpochMilli(1234)
+            startedAt = Instant.ofEpochMilli(1234),
+            enfVersion = TrackedExposureDetection.EnfVersion.V2_WINDOW_MODE
         )
         val calculation2 = TrackedExposureDetection(
             identifier = "aeb15509-fb34-42ce-8795-7a9ae0c2f389",
             startedAt = Instant.ofEpochMilli(5678),
             finishedAt = Instant.ofEpochMilli(1603473968125),
-            result = TrackedExposureDetection.Result.UPDATED_STATE
+            result = TrackedExposureDetection.Result.UPDATED_STATE,
+            enfVersion = TrackedExposureDetection.EnfVersion.V1_LEGACY_MODE
         )
         mapOf(
             calculation1.identifier to calculation1,
diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/risk/RiskLevelTaskConfigTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/risk/RiskLevelTaskConfigTest.kt
index 5e1cbd3839de8c388a5281a9e8084e7b3e1981a3..1e5267810c9e8314c6a8a61a3ae6aac7f2e394ca 100644
--- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/risk/RiskLevelTaskConfigTest.kt
+++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/risk/RiskLevelTaskConfigTest.kt
@@ -1,15 +1,90 @@
 package de.rki.coronawarnapp.risk
 
+import de.rki.coronawarnapp.nearby.modules.detectiontracker.ExposureDetectionTracker
+import de.rki.coronawarnapp.nearby.modules.detectiontracker.TrackedExposureDetection
 import io.kotest.matchers.shouldBe
+import io.mockk.MockKAnnotations
+import io.mockk.every
+import io.mockk.impl.annotations.MockK
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.runBlocking
 import org.joda.time.Duration
+import org.joda.time.Instant
+import org.junit.jupiter.api.BeforeEach
 import org.junit.jupiter.api.Test
 import testhelpers.BaseTest
 
 class RiskLevelTaskConfigTest : BaseTest() {
 
+    @MockK lateinit var exposureDetectionTracker: ExposureDetectionTracker
+
+    @BeforeEach
+    fun setup() {
+        MockKAnnotations.init(this)
+    }
+
     @Test
     fun `risk level task max execution time is not above 9 minutes`() {
-        val config = RiskLevelTask.Config()
-        config.executionTimeout.isShorterThan(Duration.standardMinutes(9)) shouldBe true
+        RiskLevelTask.Config(exposureDetectionTracker)
+            .executionTimeout
+            .isShorterThan(Duration.standardMinutes(9)) shouldBe true
+    }
+
+    @Test
+    fun `risk level preconditions are met`() {
+        every { exposureDetectionTracker.calculations } returns MutableStateFlow(mapOf("" to TrackedExposureDetection(
+            identifier = "",
+            startedAt = Instant(),
+            result = TrackedExposureDetection.Result.NO_MATCHES,
+            enfVersion = TrackedExposureDetection.EnfVersion.V2_WINDOW_MODE
+        )))
+        runBlocking {
+            RiskLevelTask.Config(exposureDetectionTracker)
+                .preconditions.fold(true) { result, precondition ->
+                    result && precondition()
+                } shouldBe true
+        }
+    }
+
+    @Test
+    fun `risk level preconditions are not met, because there are no detections`() {
+        every { exposureDetectionTracker.calculations } returns MutableStateFlow(emptyMap())
+            runBlocking {
+            RiskLevelTask.Config(exposureDetectionTracker)
+                .preconditions.fold(true) { result, precondition ->
+                    result && precondition()
+                } shouldBe false
+        }
+    }
+
+    @Test
+    fun `risk level preconditions are not met, because there are no enf V2 detections`() {
+        every { exposureDetectionTracker.calculations } returns MutableStateFlow(mapOf("" to TrackedExposureDetection(
+            identifier = "",
+            startedAt = Instant(),
+            result = TrackedExposureDetection.Result.NO_MATCHES,
+            enfVersion = TrackedExposureDetection.EnfVersion.V1_LEGACY_MODE
+        )))
+        runBlocking {
+            RiskLevelTask.Config(exposureDetectionTracker)
+                .preconditions.fold(true) { result, precondition ->
+                    result && precondition()
+                } shouldBe false
+        }
+    }
+
+    @Test
+    fun `risk level preconditions are not met, because detection is not finished yet`() {
+        every { exposureDetectionTracker.calculations } returns MutableStateFlow(mapOf("" to TrackedExposureDetection(
+            identifier = "",
+            startedAt = Instant(),
+            enfVersion = TrackedExposureDetection.EnfVersion.V2_WINDOW_MODE
+        )))
+        runBlocking {
+            RiskLevelTask.Config(exposureDetectionTracker)
+                .preconditions.fold(true) { result, precondition ->
+                    result && precondition()
+                } shouldBe false
+        }
     }
 }
diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/util/worker/CWAWorkerFactoryTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/util/worker/CWAWorkerFactoryTest.kt
index fe4e7a5c0a3d9519c5a40c825cd43c56165a3049..f62ca872c48a4d513795d1ee5561e063100a6e83 100644
--- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/util/worker/CWAWorkerFactoryTest.kt
+++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/util/worker/CWAWorkerFactoryTest.kt
@@ -61,5 +61,3 @@ class CWAWorkerFactoryTest : BaseTest() {
         worker1 shouldNotBe worker2
     }
 }
-
-